diff options
537 files changed, 14410 insertions, 15163 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index 3c59e41a13..b37fce7002 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -8,27 +8,44 @@ env: # Global defaults CCACHE_DIR: "/tmp/ccache_dir" CCACHE_NOHASHDIR: "1" # Debug info might contain a stale path if the build dir changes, but this is fine +# A self-hosted machine(s) can be used via Cirrus CI. It can be configured with +# multiple users to run tasks in parallel. No sudo permission is required. +# # https://cirrus-ci.org/guide/persistent-workers/ # -# It is possible to select a specific persistent worker by label. Refer to the +# Generally, a persistent worker must run Ubuntu 23.04+ or Debian 12+. +# +# The following specific types should exist, with the following requirements: +# - small: For an x86_64 machine, recommended to have 2 CPUs and 8 GB of memory. +# - medium: For an x86_64 machine, recommended to have 4 CPUs and 16 GB of memory. +# - arm64: For an aarch64 machine, recommended to have 2 CPUs and 8 GB of memory. +# +# CI jobs for the latter configuration can be run on x86_64 hardware +# by installing qemu-user-static, which works out of the box with +# podman or docker. Background: https://stackoverflow.com/a/72890225/313633 +# +# The above machine types are matched to each task by their label. Refer to the # Cirrus CI docs for more details. # -# Generally, a persistent worker must run Ubuntu 23.04+ or Debian 12+. -# Specifically, +# On machines that are persisted between CI jobs, RESTART_CI_DOCKER_BEFORE_RUN=1 +# ensures that previous containers and artifacts are cleared before each run. +# This requires installing Podman instead of Docker. +# +# Futhermore: # - apt-get is required due to PACKAGE_MANAGER_INSTALL -# - podman-docker-4.1+ is required due to the use of `podman` when -# RESTART_CI_DOCKER_BEFORE_RUN is set and 4.1+ due to the bugfix in 4.1 +# - podman-docker-4.1+ is required due to the bugfix in 4.1 # (https://github.com/bitcoin/bitcoin/pull/21652#issuecomment-1657098200) -# - The ./ci/ depedencies (with cirrus-cli) should be installed: +# - The ./ci/ dependencies (with cirrus-cli) should be installed. One-liner example +# for a single user setup with sudo permission: # # ``` # apt update && apt install git screen python3 bash podman-docker curl -y && curl -L -o cirrus "https://github.com/cirruslabs/cirrus-cli/releases/latest/download/cirrus-linux-$(dpkg --print-architecture)" && mv cirrus /usr/local/bin/cirrus && chmod +x /usr/local/bin/cirrus # ``` # -# - There are no strict requirements on the hardware, because having less CPUs -# runs the same CI script (maybe slower). To avoid rare and intermittent OOM -# due to short memory usage spikes, it is recommended to add (and persist) -# swap: +# - There are no strict requirements on the hardware. Having fewer CPU threads +# than recommended merely causes the CI script to run slower. +# To avoid rare and intermittent OOM due to short memory usage spikes, +# it is recommended to add (and persist) swap: # # ``` # fallocate -l 16G /swapfile_ci && chmod 600 /swapfile_ci && mkswap /swapfile_ci && swapon /swapfile_ci && ( echo '/swapfile_ci none swap sw 0 0' | tee -a /etc/fstab ) @@ -39,12 +56,6 @@ env: # Global defaults # ``` # RESTART_CI_DOCKER_BEFORE_RUN=1 screen cirrus worker run --labels type=todo_fill_in_type --token todo_fill_in_token # ``` -# -# The following specific types should exist, with the following requirements: -# - small: For an x86_64 machine, recommended to have 2 CPUs and 8 GB of memory. -# - medium: For an x86_64 machine, recommended to have 4 CPUs and 16 GB of memory. -# - noble: For a machine running the Linux kernel shipped with exaclty Ubuntu Noble 24.04. The machine is recommended to have 4 CPUs and 16 GB of memory. -# - arm64: For an aarch64 machine, recommended to have 2 CPUs and 8 GB of memory. # https://cirrus-ci.org/guide/tips-and-tricks/#sharing-configuration-between-tasks filter_template: &FILTER_TEMPLATE @@ -160,19 +171,6 @@ task: FILE_ENV: "./ci/test/00_setup_env_native_msan.sh" task: - name: 'ASan + LSan + UBSan + integer, no depends, USDT' - enable_bpfcc_script: - # In the image build step, no external environment variables are available, - # so any settings will need to be written to the settings env file: - - sed -i "s|\${CIRRUS_CI}|true|g" ./ci/test/00_setup_env_native_asan.sh - << : *GLOBAL_TASK_TEMPLATE - persistent_worker: - labels: - type: noble # Must use this specific worker (needed for USDT functional tests) - env: - FILE_ENV: "./ci/test/00_setup_env_native_asan.sh" - -task: name: 'fuzzer,address,undefined,integer, no depends' << : *GLOBAL_TASK_TEMPLATE persistent_worker: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 44521c1af3..54795332e8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,14 +18,13 @@ concurrency: cancel-in-progress: true env: - DANGER_RUN_CI_ON_HOST: 1 CI_FAILFAST_TEST_LEAVE_DANGLING: 1 # GHA does not care about dangling processes and setting this variable avoids killing the CI script itself on error MAKEJOBS: '-j10' jobs: test-each-commit: name: 'test each commit' - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 if: github.event_name == 'pull_request' && github.event.pull_request.commits != 1 timeout-minutes: 360 # Use maximum time, see https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idtimeout-minutes. Assuming a worst case time of 1 hour per commit, this leads to a --max-count=6 below. env: @@ -62,12 +61,12 @@ jobs: echo "TEST_BASE=$(git rev-list -n$((${{ env.MAX_COUNT }} + 1)) --reverse HEAD ^$(git rev-list -n1 --merges HEAD)^@ | head -1)" >> "$GITHUB_ENV" - run: | sudo apt-get update - sudo apt-get install clang-15 ccache build-essential libtool autotools-dev automake pkg-config bsdmainutils python3-zmq libevent-dev libboost-dev libsqlite3-dev libdb++-dev systemtap-sdt-dev libminiupnpc-dev libnatpmp-dev qtbase5-dev qttools5-dev qttools5-dev-tools qtwayland5 libqrencode-dev -y + sudo apt-get install clang ccache build-essential libtool autotools-dev automake pkg-config bsdmainutils python3-zmq libevent-dev libboost-dev libsqlite3-dev libdb++-dev systemtap-sdt-dev libminiupnpc-dev libnatpmp-dev qtbase5-dev qttools5-dev qttools5-dev-tools qtwayland5 libqrencode-dev -y - name: Compile and run tests run: | # Run tests on commits after the last merge commit and before the PR head commit # Use clang++, because it is a bit faster and uses less memory than g++ - git rebase --exec "echo Running test-one-commit on \$( git log -1 ) && ./autogen.sh && CC=clang-15 CXX=clang++-15 ./configure && make clean && make -j $(nproc) check && ./test/functional/test_runner.py -j $(( $(nproc) * 2 ))" ${{ env.TEST_BASE }} + git rebase --exec "echo Running test-one-commit on \$( git log -1 ) && ./autogen.sh && CC=clang CXX=clang++ ./configure && make clean && make -j $(nproc) check && ./test/functional/test_runner.py -j $(( $(nproc) * 2 ))" ${{ env.TEST_BASE }} macos-native-x86_64: name: 'macOS 13 native, x86_64, no depends, sqlite only, gui' @@ -81,6 +80,7 @@ jobs: timeout-minutes: 120 env: + DANGER_RUN_CI_ON_HOST: 1 FILE_ENV: './ci/test/00_setup_env_mac_native.sh' BASE_ROOT_DIR: ${{ github.workspace }} @@ -153,12 +153,10 @@ jobs: - name: Get tool information run: | - msbuild -version | Out-File -FilePath "$env:GITHUB_WORKSPACE\msbuild_version" - Get-Content -Path "$env:GITHUB_WORKSPACE\msbuild_version" - $env:VCToolsVersion | Out-File -FilePath "$env:GITHUB_WORKSPACE\toolset_version" - Write-Host "VCToolsVersion $(Get-Content -Path "$env:GITHUB_WORKSPACE\toolset_version")" - $env:CI_QT_URL | Out-File -FilePath "$env:GITHUB_WORKSPACE\qt_url" - $env:CI_QT_CONF | Out-File -FilePath "$env:GITHUB_WORKSPACE\qt_conf" + msbuild -version | Tee-Object -FilePath "msbuild_version" + $env:VCToolsVersion | Tee-Object -FilePath "toolset_version" + $env:CI_QT_URL | Out-File -FilePath "qt_url" + $env:CI_QT_CONF | Out-File -FilePath "qt_conf" py -3 --version Write-Host "PowerShell version $($PSVersionTable.PSVersion.ToString())" @@ -241,10 +239,8 @@ jobs: run: | Set-Location "$env:VCPKG_INSTALLATION_ROOT" Add-Content -Path "triplets\x64-windows-static.cmake" -Value "set(VCPKG_BUILD_TYPE release)" - Add-Content -Path "triplets\x64-windows-static.cmake" -Value "set(VCPKG_PLATFORM_TOOLSET_VERSION $env:VCToolsVersion)" .\vcpkg.exe --vcpkg-root "$env:VCPKG_INSTALLATION_ROOT" integrate install - git rev-parse HEAD | Out-File -FilePath "$env:GITHUB_WORKSPACE\vcpkg_commit" - Get-Content -Path "$env:GITHUB_WORKSPACE\vcpkg_commit" + git rev-parse HEAD | Tee-Object -FilePath "$env:GITHUB_WORKSPACE\vcpkg_commit" - name: vcpkg tools cache uses: actions/cache@v4 @@ -308,3 +304,46 @@ jobs: BITCOINFUZZ: "${{ github.workspace}}\\src\\fuzz.exe" shell: cmd run: py -3 test\fuzz\test_runner.py --par %NUMBER_OF_PROCESSORS% --loglevel DEBUG %RUNNER_TEMP%\qa-assets\fuzz_seed_corpus + + asan-lsan-ubsan-integer-no-depends-usdt: + name: 'ASan + LSan + UBSan + integer, no depends, USDT' + runs-on: ubuntu-24.04 # has to match container in ci/test/00_setup_env_native_asan.sh for tracing tools + # No need to run on the read-only mirror, unless it is a PR. + if: github.repository != 'bitcoin-core/gui' || github.event_name == 'pull_request' + timeout-minutes: 120 + env: + FILE_ENV: "./ci/test/00_setup_env_native_asan.sh" + DANGER_CI_ON_HOST_CACHE_FOLDERS: 1 + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set Ccache directory + run: echo "CCACHE_DIR=${RUNNER_TEMP}/ccache_dir" >> "$GITHUB_ENV" + + - name: Set base root directory + run: echo "BASE_ROOT_DIR=${RUNNER_TEMP}" >> "$GITHUB_ENV" + + - name: Restore Ccache cache + id: ccache-cache + uses: actions/cache/restore@v4 + with: + path: ${{ env.CCACHE_DIR }} + key: ${{ github.job }}-ccache-${{ github.run_id }} + restore-keys: ${{ github.job }}-ccache- + + - name: Enable bpfcc script + # In the image build step, no external environment variables are available, + # so any settings will need to be written to the settings env file: + run: sed -i "s|\${INSTALL_BCC_TRACING_TOOLS}|true|g" ./ci/test/00_setup_env_native_asan.sh + + - name: CI script + run: ./ci/test_run_all.sh + + - name: Save Ccache cache + uses: actions/cache/save@v4 + if: github.event_name != 'pull_request' && steps.ccache-cache.outputs.cache-hit != 'true' + with: + path: ${{ env.CCACHE_DIR }} + # https://github.com/actions/cache/blob/main/tips-and-workarounds.md#update-a-cache + key: ${{ github.job }}-ccache-${{ github.run_id }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 76a1c2754a..f594172333 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -149,7 +149,7 @@ the pull request affects. Valid areas as: - `net` or `p2p` for changes to the peer-to-peer network code - `refactor` for structural changes that do not change behavior - `rpc`, `rest` or `zmq` for changes to the RPC, REST or ZMQ APIs - - `script` for changes to the scripts and tools + - `contrib` or `cli` for changes to the scripts and tools - `test`, `qa` or `ci` for changes to the unit tests, QA tests or CI code - `util` or `lib` for changes to the utils or libraries - `wallet` for changes to the wallet code diff --git a/Makefile.am b/Makefile.am index e79dc4e21b..2ff6dd0a11 100644 --- a/Makefile.am +++ b/Makefile.am @@ -126,7 +126,7 @@ $(OSX_ZIP): deploydir cd $(APP_DIST_DIR) && find . | sort | $(ZIP) -X@ $@ $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/Bitcoin-Qt: $(OSX_APP_BUILT) $(OSX_PACKAGING) - OTOOL=$(OTOOL) $(PYTHON) $(OSX_DEPLOY_SCRIPT) $(OSX_APP) $(OSX_VOLNAME) -translations-dir=$(QT_TRANSLATION_DIR) + OBJDUMP=$(OBJDUMP) $(PYTHON) $(OSX_DEPLOY_SCRIPT) $(OSX_APP) $(OSX_VOLNAME) -translations-dir=$(QT_TRANSLATION_DIR) deploydir: $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/Bitcoin-Qt endif !BUILD_DARWIN @@ -186,7 +186,7 @@ baseline_filtered.info: baseline.info $(LCOV) -a $@ $(LCOV_OPTS) -o $@ fuzz.info: baseline_filtered.info - @TIMEOUT=15 test/fuzz/test_runner.py $(DIR_FUZZ_SEED_CORPUS) -l DEBUG + @test/fuzz/test_runner.py $(DIR_FUZZ_SEED_CORPUS) -l DEBUG $(LCOV) -c $(LCOV_OPTS) -d $(abs_builddir)/src --t fuzz-tests -o $@ $(LCOV) -z $(LCOV_OPTS) -d $(abs_builddir)/src @@ -204,7 +204,7 @@ test_bitcoin_filtered.info: test_bitcoin.info $(LCOV) -a $@ $(LCOV_OPTS) -o $@ functional_test.info: test_bitcoin_filtered.info - @TIMEOUT=15 test/functional/test_runner.py $(EXTENDED_FUNCTIONAL_TESTS) + @test/functional/test_runner.py $(EXTENDED_FUNCTIONAL_TESTS) $(LCOV) -c $(LCOV_OPTS) -d $(abs_builddir)/src --t functional-tests -o $@ $(LCOV) -z $(LCOV_OPTS) -d $(abs_builddir)/src diff --git a/build-aux/m4/ax_cxx_compile_stdcxx.m4 b/build-aux/m4/ax_cxx_compile_stdcxx.m4 index 8a2df5627f..51a35054d0 100644 --- a/build-aux/m4/ax_cxx_compile_stdcxx.m4 +++ b/build-aux/m4/ax_cxx_compile_stdcxx.m4 @@ -983,7 +983,7 @@ m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_20], [[ #error "This is not a C++ compiler" -#elif __cplusplus < 201709L // Temporary patch on top of upstream to allow g++-10 +#elif __cplusplus < 202002L #error "This is not a C++20 compiler" diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index 337e2208a9..b87c38a6ab 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -70,8 +70,6 @@ AC_DEFUN([BITCOIN_QT_INIT],[ [qt_lib_suffix= ]); bitcoin_qt_want_version=qt5], [qt_lib_suffix= ]) - AS_CASE([$host], [*android*], [qt_lib_suffix=_$ANDROID_ARCH]) - AC_ARG_WITH([qt-incdir],[AS_HELP_STRING([--with-qt-incdir=INC_DIR],[specify qt include path (overridden by pkgconfig)])], [qt_include_path=$withval], []) AC_ARG_WITH([qt-libdir],[AS_HELP_STRING([--with-qt-libdir=LIB_DIR],[specify qt lib path (overridden by pkgconfig)])], [qt_lib_path=$withval], []) AC_ARG_WITH([qt-plugindir],[AS_HELP_STRING([--with-qt-plugindir=PLUGIN_DIR],[specify qt plugin path (overridden by pkgconfig)])], [qt_plugin_path=$withval], []) @@ -80,19 +78,10 @@ AC_DEFUN([BITCOIN_QT_INIT],[ AC_ARG_WITH([qtdbus], [AS_HELP_STRING([--with-qtdbus], - [enable DBus support (default is yes if qt is enabled and QtDBus is found, except on Android)])], + [enable DBus support (default is yes if qt is enabled and QtDBus is found)])], [use_dbus=$withval], [use_dbus=auto]) - dnl Android doesn't support D-Bus and certainly doesn't use it for notifications - case $host in - *android*) - if test "$use_dbus" != "yes"; then - use_dbus=no - fi - ;; - esac - AC_SUBST(QT_TRANSLATION_DIR,$qt_translation_path) ]) @@ -132,16 +121,11 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ if test -d "$qt_plugin_path/accessible"; then QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible" fi - if test -d "$qt_plugin_path/platforms/android"; then - QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms/android -lqtfreetype -lEGL" - fi fi AC_DEFINE([QT_STATICPLUGIN], [1], [Define this symbol if qt plugins are static]) - if test "$TARGET_OS" != "android"; then - _BITCOIN_QT_CHECK_STATIC_PLUGIN([QMinimalIntegrationPlugin], [-lqminimal]) - AC_DEFINE([QT_QPA_PLATFORM_MINIMAL], [1], [Define this symbol if the minimal qt platform exists]) - fi + _BITCOIN_QT_CHECK_STATIC_PLUGIN([QMinimalIntegrationPlugin], [-lqminimal]) + AC_DEFINE([QT_QPA_PLATFORM_MINIMAL], [1], [Define this symbol if the minimal qt platform exists]) if test "$TARGET_OS" = "windows"; then dnl Linking against wtsapi32 is required. See #17749 and dnl https://bugreports.qt.io/browse/QTBUG-27097. @@ -160,9 +144,6 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ _BITCOIN_QT_CHECK_STATIC_PLUGIN([QCocoaIntegrationPlugin], [-lqcocoa]) _BITCOIN_QT_CHECK_STATIC_PLUGIN([QMacStylePlugin], [-lqmacstyle]) AC_DEFINE([QT_QPA_PLATFORM_COCOA], [1], [Define this symbol if the qt platform is cocoa]) - elif test "$TARGET_OS" = "android"; then - QT_LIBS="-Wl,--export-dynamic,--undefined=JNI_OnLoad -lplugins_platforms_qtforandroid${qt_lib_suffix} -ljnigraphics -landroid -lqtfreetype${qt_lib_suffix} $QT_LIBS" - AC_DEFINE([QT_QPA_PLATFORM_ANDROID], [1], [Define this symbol if the qt platform is android]) fi fi CPPFLAGS=$TEMP_CPPFLAGS @@ -357,9 +338,6 @@ AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_LIBS], [ PKG_CHECK_MODULES([QT_SERVICE], [${qt_lib_prefix}ServiceSupport${qt_lib_suffix}], [QT_LIBS="$QT_SERVICE_LIBS $QT_LIBS"]) elif test "$TARGET_OS" = "windows"; then PKG_CHECK_MODULES([QT_WINDOWSUIAUTOMATION], [${qt_lib_prefix}WindowsUIAutomationSupport${qt_lib_suffix}], [QT_LIBS="$QT_WINDOWSUIAUTOMATION_LIBS $QT_LIBS"]) - elif test "$TARGET_OS" = "android"; then - PKG_CHECK_MODULES([QT_EGL], [${qt_lib_prefix}EglSupport${qt_lib_suffix}], [QT_LIBS="$QT_EGL_LIBS $QT_LIBS"]) - PKG_CHECK_MODULES([QT_SERVICE], [${qt_lib_prefix}ServiceSupport${qt_lib_suffix}], [QT_LIBS="$QT_SERVICE_LIBS $QT_LIBS"]) fi ]) diff --git a/ci/lint/04_install.sh b/ci/lint/04_install.sh index 6b12c53f2a..87e3a8fa9b 100755 --- a/ci/lint/04_install.sh +++ b/ci/lint/04_install.sh @@ -57,3 +57,8 @@ SHELLCHECK_VERSION=v0.8.0 curl -sL "https://github.com/koalaman/shellcheck/releases/download/${SHELLCHECK_VERSION}/shellcheck-${SHELLCHECK_VERSION}.linux.x86_64.tar.xz" | \ tar --xz -xf - --directory /tmp/ mv "/tmp/shellcheck-${SHELLCHECK_VERSION}/shellcheck" /usr/bin/ + +MLC_VERSION=v0.16.3 +MLC_BIN=mlc-x86_64-linux +curl -sL "https://github.com/becheran/mlc/releases/download/${MLC_VERSION}/${MLC_BIN}" -o "/usr/bin/mlc" +chmod +x /usr/bin/mlc diff --git a/ci/test/00_setup_env_android.sh b/ci/test/00_setup_env_android.sh deleted file mode 100755 index 97a6bd7318..0000000000 --- a/ci/test/00_setup_env_android.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (c) 2019-present The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -export LC_ALL=C.UTF-8 - -export HOST=aarch64-linux-android -export PACKAGES="unzip openjdk-8-jdk gradle" -export CONTAINER_NAME=ci_android -export CI_IMAGE_NAME_TAG="docker.io/amd64/ubuntu:22.04" - -export RUN_UNIT_TESTS=false -export RUN_FUNCTIONAL_TESTS=false - -export ANDROID_API_LEVEL=28 -export ANDROID_BUILD_TOOLS_VERSION=28.0.3 -export ANDROID_NDK_VERSION=23.2.8568313 -export ANDROID_TOOLS_URL=https://dl.google.com/android/repository/commandlinetools-linux-8512546_latest.zip -export ANDROID_HOME="${DEPENDS_DIR}/SDKs/android" -export ANDROID_NDK_HOME="${ANDROID_HOME}/ndk/${ANDROID_NDK_VERSION}" -export DEP_OPTS="ANDROID_SDK=${ANDROID_HOME} ANDROID_NDK=${ANDROID_NDK_HOME} ANDROID_API_LEVEL=${ANDROID_API_LEVEL} ANDROID_TOOLCHAIN_BIN=${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/" - -export BITCOIN_CONFIG="--disable-tests --enable-gui-tests --disable-bench --disable-fuzz-binary --without-utils --without-libs --without-daemon" diff --git a/ci/test/00_setup_env_arm.sh b/ci/test/00_setup_env_arm.sh index c80036164f..396e782959 100755 --- a/ci/test/00_setup_env_arm.sh +++ b/ci/test/00_setup_env_arm.sh @@ -17,4 +17,4 @@ export RUN_FUNCTIONAL_TESTS=false export GOAL="install" # -Wno-psabi is to disable ABI warnings: "note: parameter passing for argument of type ... changed in GCC 7.1" # This could be removed once the ABI change warning does not show up by default -export BITCOIN_CONFIG="--enable-reduce-exports CXXFLAGS=-Wno-psabi" +export BITCOIN_CONFIG="--enable-reduce-exports CXXFLAGS='-Wno-psabi -Wno-error=maybe-uninitialized'" diff --git a/ci/test/00_setup_env_mac_cross.sh b/ci/test/00_setup_env_mac_cross.sh index 31c4bff6ae..f607c93ae6 100755 --- a/ci/test/00_setup_env_mac_cross.sh +++ b/ci/test/00_setup_env_mac_cross.sh @@ -9,9 +9,9 @@ export LC_ALL=C.UTF-8 export SDK_URL=${SDK_URL:-https://bitcoincore.org/depends-sources/sdks} export CONTAINER_NAME=ci_macos_cross -export CI_IMAGE_NAME_TAG="docker.io/ubuntu:22.04" +export CI_IMAGE_NAME_TAG="docker.io/ubuntu:24.04" export HOST=x86_64-apple-darwin -export PACKAGES="zip" +export PACKAGES="clang lld llvm zip" export XCODE_VERSION=15.0 export XCODE_BUILD_ID=15A240d export RUN_UNIT_TESTS=false diff --git a/ci/test/00_setup_env_native_asan.sh b/ci/test/00_setup_env_native_asan.sh index 668e9ecc8a..23d9180f96 100755 --- a/ci/test/00_setup_env_native_asan.sh +++ b/ci/test/00_setup_env_native_asan.sh @@ -7,8 +7,10 @@ export LC_ALL=C.UTF-8 export CI_IMAGE_NAME_TAG="docker.io/ubuntu:24.04" -# Only install BCC tracing packages in Cirrus CI. -if [[ "${CIRRUS_CI}" == "true" ]]; then + +# Only install BCC tracing packages in CI. Container has to match the host for BCC to work. +if [[ "${INSTALL_BCC_TRACING_TOOLS}" == "true" ]]; then + # Required for USDT functional tests to run BPFCC_PACKAGE="bpfcc-tools linux-headers-$(uname --kernel-release)" export CI_CONTAINER_CAP="--privileged -v /sys/kernel:/sys/kernel:rw" else @@ -24,3 +26,4 @@ export BITCOIN_CONFIG="--enable-usdt --enable-zmq --with-incompatible-bdb --with CPPFLAGS='-DARENA_DEBUG -DDEBUG_LOCKORDER' \ --with-sanitizers=address,float-divide-by-zero,integer,undefined \ CC='clang-18 -ftrivial-auto-var-init=pattern' CXX='clang++-18 -ftrivial-auto-var-init=pattern'" +export CCACHE_MAXSIZE=300M diff --git a/ci/test/00_setup_env_native_valgrind.sh b/ci/test/00_setup_env_native_valgrind.sh index 720e522a6a..ebef590c0a 100755 --- a/ci/test/00_setup_env_native_valgrind.sh +++ b/ci/test/00_setup_env_native_valgrind.sh @@ -11,6 +11,6 @@ export CONTAINER_NAME=ci_native_valgrind export PACKAGES="valgrind clang-16 llvm-16 libclang-rt-16-dev python3-zmq libevent-dev libboost-dev libdb5.3++-dev libminiupnpc-dev libnatpmp-dev libzmq3-dev libsqlite3-dev" export USE_VALGRIND=1 export NO_DEPENDS=1 -export TEST_RUNNER_EXTRA="--exclude rpc_bind,feature_bind_extra" # Excluded for now, see https://github.com/bitcoin/bitcoin/issues/17765#issuecomment-602068547 +export TEST_RUNNER_EXTRA="--exclude feature_init,rpc_bind,feature_bind_extra" # feature_init excluded for now, see https://github.com/bitcoin/bitcoin/issues/30011 ; bind tests excluded for now, see https://github.com/bitcoin/bitcoin/issues/17765#issuecomment-602068547 export GOAL="install" export BITCOIN_CONFIG="--enable-zmq --with-incompatible-bdb --with-gui=no CC=clang-16 CXX=clang++-16" # TODO enable GUI diff --git a/ci/test/01_base_install.sh b/ci/test/01_base_install.sh index 25962a53e5..f16321ba55 100755 --- a/ci/test/01_base_install.sh +++ b/ci/test/01_base_install.sh @@ -86,14 +86,4 @@ if [ -n "$XCODE_VERSION" ] && [ ! -d "${DEPENDS_DIR}/SDKs/${OSX_SDK_BASENAME}" ] tar -C "${DEPENDS_DIR}/SDKs" -xf "$OSX_SDK_PATH" fi -if [ -n "$ANDROID_HOME" ] && [ ! -d "$ANDROID_HOME" ]; then - ANDROID_TOOLS_PATH=${DEPENDS_DIR}/sdk-sources/android-tools.zip - if [ ! -f "$ANDROID_TOOLS_PATH" ]; then - ${CI_RETRY_EXE} curl --location --fail "${ANDROID_TOOLS_URL}" -o "$ANDROID_TOOLS_PATH" - fi - mkdir -p "$ANDROID_HOME" - unzip -o "$ANDROID_TOOLS_PATH" -d "$ANDROID_HOME" - yes | "${ANDROID_HOME}"/cmdline-tools/bin/sdkmanager --sdk_root="${ANDROID_HOME}" --install "build-tools;${ANDROID_BUILD_TOOLS_VERSION}" "platform-tools" "platforms;android-31" "platforms;android-${ANDROID_API_LEVEL}" "ndk;${ANDROID_NDK_VERSION}" -fi - git config --global ${CFG_DONE} "true" diff --git a/ci/test/02_run_container.sh b/ci/test/02_run_container.sh index e6c4a61341..afd447c347 100755 --- a/ci/test/02_run_container.sh +++ b/ci/test/02_run_container.sh @@ -16,6 +16,7 @@ if [ -z "$DANGER_RUN_CI_ON_HOST" ]; then # System-dependent env vars must be kept as is. So read them from the container. docker run --rm "${CI_IMAGE_NAME_TAG}" bash -c "env | grep --extended-regexp '^(HOME|PATH|USER)='" | tee --append "/tmp/env-$USER-$CONTAINER_NAME" echo "Creating $CI_IMAGE_NAME_TAG container to run in" + DOCKER_BUILDKIT=1 docker build \ --file "${BASE_READ_ONLY_DIR}/ci/test_imagefile" \ --build-arg "CI_IMAGE_NAME_TAG=${CI_IMAGE_NAME_TAG}" \ @@ -23,12 +24,32 @@ if [ -z "$DANGER_RUN_CI_ON_HOST" ]; then --label="${CI_IMAGE_LABEL}" \ --tag="${CONTAINER_NAME}" \ "${BASE_READ_ONLY_DIR}" + docker volume create "${CONTAINER_NAME}_ccache" || true docker volume create "${CONTAINER_NAME}_depends" || true docker volume create "${CONTAINER_NAME}_depends_sources" || true - docker volume create "${CONTAINER_NAME}_depends_SDKs_android" || true docker volume create "${CONTAINER_NAME}_previous_releases" || true + CI_CCACHE_MOUNT="type=volume,src=${CONTAINER_NAME}_ccache,dst=$CCACHE_DIR" + CI_DEPENDS_MOUNT="type=volume,src=${CONTAINER_NAME}_depends,dst=$DEPENDS_DIR/built" + CI_DEPENDS_SOURCES_MOUNT="type=volume,src=${CONTAINER_NAME}_depends_sources,dst=$DEPENDS_DIR/sources" + CI_PREVIOUS_RELEASES_MOUNT="type=volume,src=${CONTAINER_NAME}_previous_releases,dst=$PREVIOUS_RELEASES_DIR" + + if [ "$DANGER_CI_ON_HOST_CACHE_FOLDERS" ]; then + # ensure the directories exist + mkdir -p "${CCACHE_DIR}" + mkdir -p "${DEPENDS_DIR}/built" + mkdir -p "${DEPENDS_DIR}/sources" + mkdir -p "${PREVIOUS_RELEASES_DIR}" + + CI_CCACHE_MOUNT="type=bind,src=${CCACHE_DIR},dst=$CCACHE_DIR" + CI_DEPENDS_MOUNT="type=bind,src=${DEPENDS_DIR}/built,dst=$DEPENDS_DIR/built" + CI_DEPENDS_SOURCES_MOUNT="type=bind,src=${DEPENDS_DIR}/sources,dst=$DEPENDS_DIR/sources" + CI_PREVIOUS_RELEASES_MOUNT="type=bind,src=${PREVIOUS_RELEASES_DIR},dst=$PREVIOUS_RELEASES_DIR" + fi + + docker network create --ipv6 --subnet 1111:1111::/112 ci-ip6net || true + if [ -n "${RESTART_CI_DOCKER_BEFORE_RUN}" ] ; then echo "Restart docker before run to stop and clear all containers started with --rm" podman container rm --force --all # Similar to "systemctl restart docker" @@ -49,13 +70,13 @@ if [ -z "$DANGER_RUN_CI_ON_HOST" ]; then # shellcheck disable=SC2086 CI_CONTAINER_ID=$(docker run --cap-add LINUX_IMMUTABLE $CI_CONTAINER_CAP --rm --interactive --detach --tty \ --mount "type=bind,src=$BASE_READ_ONLY_DIR,dst=$BASE_READ_ONLY_DIR,readonly" \ - --mount "type=volume,src=${CONTAINER_NAME}_ccache,dst=$CCACHE_DIR" \ - --mount "type=volume,src=${CONTAINER_NAME}_depends,dst=$DEPENDS_DIR/built" \ - --mount "type=volume,src=${CONTAINER_NAME}_depends_sources,dst=$DEPENDS_DIR/sources" \ - --mount "type=volume,src=${CONTAINER_NAME}_depends_SDKs_android,dst=$DEPENDS_DIR/SDKs/android" \ - --mount "type=volume,src=${CONTAINER_NAME}_previous_releases,dst=$PREVIOUS_RELEASES_DIR" \ + --mount "${CI_CCACHE_MOUNT}" \ + --mount "${CI_DEPENDS_MOUNT}" \ + --mount "${CI_DEPENDS_SOURCES_MOUNT}" \ + --mount "${CI_PREVIOUS_RELEASES_MOUNT}" \ --env-file /tmp/env-$USER-$CONTAINER_NAME \ --name "$CONTAINER_NAME" \ + --network ci-ip6net \ "$CONTAINER_NAME") export CI_CONTAINER_ID export CI_EXEC_CMD_PREFIX="docker exec ${CI_CONTAINER_ID}" diff --git a/ci/test/03_test_script.sh b/ci/test/03_test_script.sh index f5da7bc55d..71d9ad7f72 100755 --- a/ci/test/03_test_script.sh +++ b/ci/test/03_test_script.sh @@ -110,15 +110,6 @@ fi ccache --zero-stats PRINT_CCACHE_STATISTICS="ccache --version | head -n 1 && ccache --show-stats" -if [ -n "$ANDROID_TOOLS_URL" ]; then - make distclean || true - ./autogen.sh - bash -c "./configure $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG" || ( (cat config.log) && false) - make "${MAKEJOBS}" && cd src/qt && ANDROID_HOME=${ANDROID_HOME} ANDROID_NDK_HOME=${ANDROID_NDK_HOME} make apk - bash -c "${PRINT_CCACHE_STATISTICS}" - exit 0 -fi - BITCOIN_CONFIG_ALL="${BITCOIN_CONFIG_ALL} --enable-external-signer --prefix=$BASE_OUTDIR" if [ -n "$CONFIG_SHELL" ]; then diff --git a/configure.ac b/configure.ac index ee4400f21a..af0d1d1505 100644 --- a/configure.ac +++ b/configure.ac @@ -125,6 +125,7 @@ AC_PATH_PROG([GIT], [git]) AC_PATH_PROG([CCACHE], [ccache]) AC_PATH_PROG([XGETTEXT], [xgettext]) AC_PATH_PROG([HEXDUMP], [hexdump]) +AC_PATH_TOOL([OBJDUMP], [objdump]) AC_PATH_TOOL([OBJCOPY], [objcopy]) AC_PATH_PROG([DOXYGEN], [doxygen]) AM_CONDITIONAL([HAVE_DOXYGEN], [test -n "$DOXYGEN"]) @@ -205,9 +206,9 @@ AC_ARG_WITH([qrencode], AC_ARG_ENABLE([hardening], [AS_HELP_STRING([--disable-hardening], - [do not attempt to harden the resulting executables (default is to harden when possible)])], + [do not attempt to harden the resulting executables (default is to harden)])], [use_hardening=$enableval], - [use_hardening=auto]) + [use_hardening=yes]) AC_ARG_ENABLE([reduce-exports], [AS_HELP_STRING([--enable-reduce-exports], @@ -237,18 +238,6 @@ AC_ARG_ENABLE([lcov], [use_lcov=$enableval], [use_lcov=no]) -AC_ARG_ENABLE([lcov-branch-coverage], - [AS_HELP_STRING([--enable-lcov-branch-coverage], - [enable lcov testing branch coverage (default is no)])], - [use_lcov_branch=yes], - [use_lcov_branch=no]) - -AC_ARG_ENABLE([threadlocal], - [AS_HELP_STRING([--enable-threadlocal], - [enable features that depend on the c++ thread_local keyword (currently just thread names in debug logs). (default is to enable if there is platform support)])], - [use_thread_local=$enableval], - [use_thread_local=auto]) - AC_ARG_ENABLE([zmq], [AS_HELP_STRING([--disable-zmq], [disable ZMQ notifications])], @@ -292,13 +281,6 @@ AC_ARG_WITH([sanitizers], [comma separated list of extra sanitizers to build with (default is none enabled)])], [use_sanitizers=$withval]) -dnl Enable gprof profiling -AC_ARG_ENABLE([gprof], - [AS_HELP_STRING([--enable-gprof], - [use gprof profiling compiler flags (default is no)])], - [enable_gprof=$enableval], - [enable_gprof=no]) - dnl Turn warnings into errors AC_ARG_ENABLE([werror], [AS_HELP_STRING([--enable-werror], @@ -422,15 +404,13 @@ AX_CHECK_COMPILE_FLAG([-Wsuggest-override], [WARN_CXXFLAGS="$WARN_CXXFLAGS -Wsug AX_CHECK_COMPILE_FLAG([-Wimplicit-fallthrough], [WARN_CXXFLAGS="$WARN_CXXFLAGS -Wimplicit-fallthrough"], [], [$CXXFLAG_WERROR]) AX_CHECK_COMPILE_FLAG([-Wunreachable-code], [WARN_CXXFLAGS="$WARN_CXXFLAGS -Wunreachable-code"], [], [$CXXFLAG_WERROR]) AX_CHECK_COMPILE_FLAG([-Wdocumentation], [WARN_CXXFLAGS="$WARN_CXXFLAGS -Wdocumentation"], [], [$CXXFLAG_WERROR]) +AX_CHECK_COMPILE_FLAG([-Wself-assign], [WARN_CXXFLAGS="$WARN_CXXFLAGS -Wself-assign"], [], [$CXXFLAG_WERROR]) +AX_CHECK_COMPILE_FLAG([-Wundef], [WARN_CXXFLAGS="$WARN_CXXFLAGS -Wundef"], [], [$CXXFLAG_WERROR]) dnl Some compilers (gcc) ignore unknown -Wno-* options, but warn about all dnl unknown options if any other warning is produced. Test the -Wfoo case, and dnl set the -Wno-foo case if it works. AX_CHECK_COMPILE_FLAG([-Wunused-parameter], [NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-unused-parameter"], [], [$CXXFLAG_WERROR]) -AX_CHECK_COMPILE_FLAG([-Wself-assign], [NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-self-assign"], [], [$CXXFLAG_WERROR]) -if test "$suppress_external_warnings" != "yes" ; then - AX_CHECK_COMPILE_FLAG([-Wdeprecated-copy], [NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-deprecated-copy"], [], [$CXXFLAG_WERROR]) -fi dnl Don't allow extended (non-ASCII) symbols in identifiers. This is easier for code review. AX_CHECK_COMPILE_FLAG([-fno-extended-identifiers], [CORE_CXXFLAGS="$CORE_CXXFLAGS -fno-extended-identifiers"], [], [$CXXFLAG_WERROR]) @@ -760,7 +740,6 @@ case $host in ;; *) AC_PATH_TOOL([DSYMUTIL], [dsymutil], [dsymutil]) - AC_PATH_TOOL([OTOOL], [otool], [otool]) AC_PATH_PROG([ZIP], [zip], [zip]) dnl libtool will try to strip the static lib, which is a problem for @@ -778,22 +757,6 @@ case $host in dnl "'NSUserNotificationCenter' is deprecated: first deprecated in macOS 11.0". OBJCXXFLAGS="$CXXFLAGS -Wno-deprecated-declarations" ;; - *android*) - dnl make sure android stays above linux for hosts like *linux-android* - TARGET_OS=android - case $host in - *x86_64*) - ANDROID_ARCH=x86_64 - ;; - *aarch64*) - ANDROID_ARCH=arm64-v8a - ;; - *armv7a*) - ANDROID_ARCH=armeabi-v7a - ;; - *) AC_MSG_ERROR([Could not determine Android arch, or it is unsupported]) ;; - esac - ;; *linux*) TARGET_OS=linux ;; @@ -843,10 +806,8 @@ if test "$use_lcov" = "yes"; then AX_CHECK_COMPILE_FLAG([--coverage],[CORE_CXXFLAGS="$CORE_CXXFLAGS --coverage"], [AC_MSG_ERROR([lcov testing requested but --coverage flag does not work])]) CORE_CXXFLAGS="$CORE_CXXFLAGS -Og" -fi -if test "$use_lcov_branch" != "no"; then - AC_SUBST(LCOV_OPTS, "$LCOV_OPTS --rc lcov_branch_coverage=1") + AC_SUBST(LCOV_OPTS) fi dnl Check for endianness @@ -877,30 +838,12 @@ if test "$ac_cv_sys_large_files" != "" && CORE_CPPFLAGS="$CORE_CPPFLAGS -D_LARGE_FILES=$ac_cv_sys_large_files" fi -if test "$enable_gprof" = "yes"; then - dnl -pg is incompatible with -pie. Since hardening and profiling together doesn't make sense, - dnl we simply make them mutually exclusive here. Additionally, hardened toolchains may force - dnl -pie by default, in which case it needs to be turned off with -no-pie. - - if test "$use_hardening" = "yes"; then - AC_MSG_ERROR([gprof profiling is not compatible with hardening. Reconfigure with --disable-hardening or --disable-gprof]) - fi - use_hardening=no - AX_CHECK_COMPILE_FLAG([-pg],[GPROF_CXXFLAGS="-pg"], - [AC_MSG_ERROR([gprof profiling requested but not available])], [$CXXFLAG_WERROR]) - - AX_CHECK_LINK_FLAG([-no-pie], [GPROF_LDFLAGS="-no-pie"]) - AX_CHECK_LINK_FLAG([-pg], [GPROF_LDFLAGS="$GPROF_LDFLAGS -pg"], - [AC_MSG_ERROR([gprof profiling requested but not available])], [$GPROF_LDFLAGS]) -fi - if test "$TARGET_OS" != "windows"; then dnl All windows code is PIC, forcing it on just adds useless compile warnings AX_CHECK_COMPILE_FLAG([-fPIC], [PIC_FLAGS="-fPIC"]) fi if test "$use_hardening" != "no"; then - use_hardening=yes AX_CHECK_COMPILE_FLAG([-Wstack-protector], [HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -Wstack-protector"]) AX_CHECK_COMPILE_FLAG([-fstack-protector-all], [HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -fstack-protector-all"]) @@ -954,7 +897,7 @@ if test "$TARGET_OS" = "darwin"; then AX_CHECK_LINK_FLAG([-Wl,-fixup_chains], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,-fixup_chains"], [], [$LDFLAG_WERROR]) fi -AC_CHECK_HEADERS([sys/select.h sys/prctl.h sys/sysctl.h vm/vm_param.h sys/vmmeter.h sys/resources.h]) +AC_CHECK_HEADERS([sys/select.h sys/prctl.h vm/vm_param.h sys/vmmeter.h sys/resources.h]) AC_CHECK_DECLS([getifaddrs, freeifaddrs],[CHECK_SOCKET],, [#include <sys/types.h> @@ -1028,45 +971,6 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([ [AC_MSG_RESULT([no])] ) -if test "$use_thread_local" = "yes" || test "$use_thread_local" = "auto"; then - TEMP_LDFLAGS="$LDFLAGS" - LDFLAGS="$TEMP_LDFLAGS $PTHREAD_CFLAGS" - AC_MSG_CHECKING([for thread_local support]) - AC_LINK_IFELSE([AC_LANG_SOURCE([ - #include <thread> - static thread_local int foo = 0; - static void run_thread() { foo++;} - int main(){ - for(int i = 0; i < 10; i++) { std::thread(run_thread).detach();} - return foo; - } - ])], - [ - case $host in - *mingw*) - dnl mingw32's implementation of thread_local has also been shown to behave - dnl erroneously under concurrent usage; see: - dnl https://gist.github.com/jamesob/fe9a872051a88b2025b1aa37bfa98605 - AC_MSG_RESULT([no]) - ;; - *freebsd*) - dnl FreeBSD's implementation of thread_local is also buggy (per - dnl https://groups.google.com/d/msg/bsdmailinglist/22ncTZAbDp4/Dii_pII5AwAJ) - AC_MSG_RESULT([no]) - ;; - *) - AC_DEFINE([HAVE_THREAD_LOCAL], [1], [Define if thread_local is supported.]) - AC_MSG_RESULT([yes]) - ;; - esac - ], - [ - AC_MSG_RESULT([no]) - ] - ) - LDFLAGS="$TEMP_LDFLAGS" -fi - dnl Check for different ways of gathering OS randomness AC_MSG_CHECKING([for Linux getrandom function]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ @@ -1489,6 +1393,9 @@ if test "$with_libmultiprocess" = "yes" || test "$with_libmultiprocess" = "auto" PKG_CHECK_MODULES([LIBMULTIPROCESS], [libmultiprocess], [ libmultiprocess_found=yes; libmultiprocess_prefix=`$PKG_CONFIG --variable=prefix libmultiprocess`; + if test "$suppress_external_warnings" != "no" ; then + LIBMULTIPROCESS_CFLAGS=SUPPRESS_WARNINGS($LIBMULTIPROCESS_CFLAGS) + fi ], [true]) elif test "$with_libmultiprocess" != "no"; then AC_MSG_ERROR([--with-libmultiprocess=$with_libmultiprocess value is not yes, auto, or no]) @@ -1756,8 +1663,6 @@ AC_SUBST(WARN_CXXFLAGS) AC_SUBST(NOWARN_CXXFLAGS) AC_SUBST(DEBUG_CXXFLAGS) AC_SUBST(ERROR_CXXFLAGS) -AC_SUBST(GPROF_CXXFLAGS) -AC_SUBST(GPROF_LDFLAGS) AC_SUBST(HARDENED_CXXFLAGS) AC_SUBST(HARDENED_CPPFLAGS) AC_SUBST(HARDENED_LDFLAGS) @@ -1789,7 +1694,6 @@ AC_SUBST(HAVE_O_CLOEXEC) AC_SUBST(HAVE_BUILTIN_PREFETCH) AC_SUBST(HAVE_MM_PREFETCH) AC_SUBST(HAVE_STRONG_GETAUXVAL) -AC_SUBST(ANDROID_ARCH) AC_SUBST(HAVE_EVHTTP_CONNECTION_GET_PEER_CONST_CHAR) AC_CONFIG_FILES([Makefile src/Makefile doc/man/Makefile share/setup.nsi share/qt/Info.plist test/config.ini]) AC_CONFIG_FILES([contrib/devtools/split-debug.sh],[chmod +x contrib/devtools/split-debug.sh]) @@ -1816,7 +1720,7 @@ CPPFLAGS="$CPPFLAGS_TEMP" if test -n "$use_sanitizers"; then export SECP_CFLAGS="$SECP_CFLAGS $SANITIZER_CFLAGS" fi -ac_configure_args="${ac_configure_args} --disable-shared --with-pic --enable-benchmark=no --enable-module-recovery --disable-module-ecdh" +ac_configure_args="${ac_configure_args} --disable-shared --with-pic --with-ecmult-gen-kb=86 --enable-benchmark=no --enable-module-recovery --disable-module-ecdh" AC_CONFIG_SUBDIRS([src/secp256k1]) AC_OUTPUT @@ -1866,7 +1770,6 @@ echo " with natpmp = $use_natpmp" echo " USDT tracing = $use_usdt" echo " sanitizers = $use_sanitizers" echo " debug enabled = $enable_debug" -echo " gprof enabled = $enable_gprof" echo " werror = $enable_werror" echo echo " target os = $host_os" @@ -1876,8 +1779,8 @@ echo " CC = $CC" echo " CFLAGS = $PTHREAD_CFLAGS $SANITIZER_CFLAGS $CFLAGS" echo " CPPFLAGS = $DEBUG_CPPFLAGS $HARDENED_CPPFLAGS $CORE_CPPFLAGS $CPPFLAGS" echo " CXX = $CXX" -echo " CXXFLAGS = $CORE_CXXFLAGS $DEBUG_CXXFLAGS $HARDENED_CXXFLAGS $WARN_CXXFLAGS $NOWARN_CXXFLAGS $ERROR_CXXFLAGS $GPROF_CXXFLAGS $SANITIZER_CXXFLAGS $CXXFLAGS" -echo " LDFLAGS = $PTHREAD_LIBS $HARDENED_LDFLAGS $GPROF_LDFLAGS $SANITIZER_LDFLAGS $CORE_LDFLAGS $LDFLAGS" +echo " CXXFLAGS = $CORE_CXXFLAGS $DEBUG_CXXFLAGS $HARDENED_CXXFLAGS $WARN_CXXFLAGS $NOWARN_CXXFLAGS $ERROR_CXXFLAGS $SANITIZER_CXXFLAGS $CXXFLAGS" +echo " LDFLAGS = $PTHREAD_LIBS $HARDENED_LDFLAGS $SANITIZER_LDFLAGS $CORE_LDFLAGS $LDFLAGS" echo " AR = $AR" echo " ARFLAGS = $ARFLAGS" echo diff --git a/contrib/asmap/README.md b/contrib/asmap/README.md new file mode 100644 index 0000000000..5fab4b285e --- /dev/null +++ b/contrib/asmap/README.md @@ -0,0 +1,12 @@ +# ASMap Tool + +Tool for performing various operations on textual and binary asmap files, +particularly encoding/compressing the raw data to the binary format that can +be used in Bitcoin Core with the `-asmap` option. + +Example usage: +``` +python3 asmap-tool.py encode /path/to/input.file /path/to/output.file +python3 asmap-tool.py decode /path/to/input.file /path/to/output.file +python3 asmap-tool.py diff /path/to/first.file /path/to/second.file +``` diff --git a/contrib/asmap/asmap-tool.py b/contrib/asmap/asmap-tool.py new file mode 100755 index 0000000000..09c28725e4 --- /dev/null +++ b/contrib/asmap/asmap-tool.py @@ -0,0 +1,156 @@ +#!/usr/bin/env python3 +# Copyright (c) 2022 Pieter Wuille +# Distributed under the MIT software license, see the accompanying +# file LICENSE or http://www.opensource.org/licenses/mit-license.php. + +import argparse +import sys +import ipaddress +import math + +import asmap + +def load_file(input_file): + try: + contents = input_file.read() + except OSError as err: + sys.exit(f"Input file '{input_file.name}' cannot be read: {err.strerror}.") + try: + bin_asmap = asmap.ASMap.from_binary(contents) + except ValueError: + bin_asmap = None + txt_error = None + entries = None + try: + txt_contents = str(contents, encoding="utf-8") + except UnicodeError: + txt_error = "invalid UTF-8" + txt_contents = None + if txt_contents is not None: + entries = [] + for line in txt_contents.split("\n"): + idx = line.find('#') + if idx >= 0: + line = line[:idx] + line = line.lstrip(' ').rstrip(' \t\r\n') + if len(line) == 0: + continue + fields = line.split(' ') + if len(fields) != 2: + txt_error = f"unparseable line '{line}'" + entries = None + break + prefix, asn = fields + if len(asn) <= 2 or asn[:2] != "AS" or any(c < '0' or c > '9' for c in asn[2:]): + txt_error = f"invalid ASN '{asn}'" + entries = None + break + try: + net = ipaddress.ip_network(prefix) + except ValueError: + txt_error = f"invalid network '{prefix}'" + entries = None + break + entries.append((asmap.net_to_prefix(net), int(asn[2:]))) + if entries is not None and bin_asmap is not None and len(contents) > 0: + sys.exit(f"Input file '{input_file.name}' is ambiguous.") + if entries is not None: + state = asmap.ASMap() + state.update_multi(entries) + return state + if bin_asmap is not None: + return bin_asmap + sys.exit(f"Input file '{input_file.name}' is neither a valid binary asmap file nor valid text input ({txt_error}).") + + +def save_binary(output_file, state, fill): + contents = state.to_binary(fill=fill) + try: + output_file.write(contents) + output_file.close() + except OSError as err: + sys.exit(f"Output file '{output_file.name}' cannot be written to: {err.strerror}.") + +def save_text(output_file, state, fill, overlapping): + for prefix, asn in state.to_entries(fill=fill, overlapping=overlapping): + net = asmap.prefix_to_net(prefix) + try: + print(f"{net} AS{asn}", file=output_file) + except OSError as err: + sys.exit(f"Output file '{output_file.name}' cannot be written to: {err.strerror}.") + try: + output_file.close() + except OSError as err: + sys.exit(f"Output file '{output_file.name}' cannot be written to: {err.strerror}.") + +def main(): + parser = argparse.ArgumentParser(description="Tool for performing various operations on textual and binary asmap files.") + subparsers = parser.add_subparsers(title="valid subcommands", dest="subcommand") + + parser_encode = subparsers.add_parser("encode", help="convert asmap data to binary format") + parser_encode.add_argument('-f', '--fill', dest="fill", default=False, action="store_true", + help="permit reassigning undefined network ranges arbitrarily to reduce size") + parser_encode.add_argument('infile', nargs='?', type=argparse.FileType('rb'), default=sys.stdin.buffer, + help="input asmap file (text or binary); default is stdin") + parser_encode.add_argument('outfile', nargs='?', type=argparse.FileType('wb'), default=sys.stdout.buffer, + help="output binary asmap file; default is stdout") + + parser_decode = subparsers.add_parser("decode", help="convert asmap data to text format") + parser_decode.add_argument('-f', '--fill', dest="fill", default=False, action="store_true", + help="permit reassigning undefined network ranges arbitrarily to reduce length") + parser_decode.add_argument('-n', '--nonoverlapping', dest="overlapping", default=True, action="store_false", + help="output strictly non-overall ping network ranges (increases output size)") + parser_decode.add_argument('infile', nargs='?', type=argparse.FileType('rb'), default=sys.stdin.buffer, + help="input asmap file (text or binary); default is stdin") + parser_decode.add_argument('outfile', nargs='?', type=argparse.FileType('w'), default=sys.stdout, + help="output text file; default is stdout") + + parser_diff = subparsers.add_parser("diff", help="compute the difference between two asmap files") + parser_diff.add_argument('-i', '--ignore-unassigned', dest="ignore_unassigned", default=False, action="store_true", + help="ignore unassigned ranges in the first input (useful when second input is filled)") + parser_diff.add_argument('infile1', type=argparse.FileType('rb'), + help="first file to compare (text or binary)") + parser_diff.add_argument('infile2', type=argparse.FileType('rb'), + help="second file to compare (text or binary)") + + args = parser.parse_args() + if args.subcommand is None: + parser.print_help() + elif args.subcommand == "encode": + state = load_file(args.infile) + save_binary(args.outfile, state, fill=args.fill) + elif args.subcommand == "decode": + state = load_file(args.infile) + save_text(args.outfile, state, fill=args.fill, overlapping=args.overlapping) + elif args.subcommand == "diff": + state1 = load_file(args.infile1) + state2 = load_file(args.infile2) + ipv4_changed = 0 + ipv6_changed = 0 + for prefix, old_asn, new_asn in state1.diff(state2): + if args.ignore_unassigned and old_asn == 0: + continue + net = asmap.prefix_to_net(prefix) + if isinstance(net, ipaddress.IPv4Network): + ipv4_changed += 1 << (32 - net.prefixlen) + elif isinstance(net, ipaddress.IPv6Network): + ipv6_changed += 1 << (128 - net.prefixlen) + if new_asn == 0: + print(f"# {net} was AS{old_asn}") + elif old_asn == 0: + print(f"{net} AS{new_asn} # was unassigned") + else: + print(f"{net} AS{new_asn} # was AS{old_asn}") + ipv4_change_str = "" if ipv4_changed == 0 else f" (2^{math.log2(ipv4_changed):.2f})" + ipv6_change_str = "" if ipv6_changed == 0 else f" (2^{math.log2(ipv6_changed):.2f})" + + print( + f"# {ipv4_changed}{ipv4_change_str} IPv4 addresses changed; " + f"{ipv6_changed}{ipv6_change_str} IPv6 addresses changed" + ) + else: + parser.print_help() + sys.exit("No command provided.") + +if __name__ == '__main__': + main() diff --git a/contrib/seeds/asmap.py b/contrib/asmap/asmap.py index 214805b5a5..2ae84a3f31 100644 --- a/contrib/seeds/asmap.py +++ b/contrib/asmap/asmap.py @@ -489,12 +489,14 @@ class ASMap: if ctx not in ret or cand.size < ret[ctx].size: ret[ctx] = cand - for ctx in set(left) | set(right): + union = set(left) | set(right) + sorted_union = sorted(union, key=lambda x: (x is None, x)) + for ctx in sorted_union: candidate(ctx, left.get(ctx), right.get(ctx), _BinNode.make_branch) candidate(ctx, left.get(None), right.get(ctx), _BinNode.make_branch) candidate(ctx, left.get(ctx), right.get(None), _BinNode.make_branch) if not hole: - for ctx in set(ret) - set([None]): + for ctx in sorted(set(ret) - set([None])): candidate(None, ctx, ret[ctx], _BinNode.make_default) if None in ret: ret = {ctx:enc for ctx, enc in ret.items() diff --git a/contrib/devtools/check-deps.sh b/contrib/devtools/check-deps.sh new file mode 100755 index 0000000000..9d2eebe14d --- /dev/null +++ b/contrib/devtools/check-deps.sh @@ -0,0 +1,203 @@ +#!/usr/bin/env bash + +export LC_ALL=C +set -Eeuo pipefail + +# Declare paths to libraries +declare -A LIBS +LIBS[cli]="libbitcoin_cli.a" +LIBS[common]="libbitcoin_common.a" +LIBS[consensus]="libbitcoin_consensus.a" +LIBS[crypto]="crypto/.libs/libbitcoin_crypto_base.a crypto/.libs/libbitcoin_crypto_x86_shani.a crypto/.libs/libbitcoin_crypto_sse41.a crypto/.libs/libbitcoin_crypto_avx2.a" +LIBS[node]="libbitcoin_node.a" +LIBS[util]="libbitcoin_util.a" +LIBS[wallet]="libbitcoin_wallet.a" +LIBS[wallet_tool]="libbitcoin_wallet_tool.a" + +# Declare allowed dependencies "X Y" where X is allowed to depend on Y. This +# list is taken from doc/design/libraries.md. +ALLOWED_DEPENDENCIES=( + "cli common" + "cli util" + "common consensus" + "common crypto" + "common util" + "consensus crypto" + "node common" + "node consensus" + "node crypto" + "node kernel" + "node util" + "util crypto" + "wallet common" + "wallet crypto" + "wallet util" + "wallet_tool util" + "wallet_tool wallet" +) + +# Add minor dependencies omitted from doc/design/libraries.md to keep the +# dependency diagram simple. +ALLOWED_DEPENDENCIES+=( + "wallet consensus" + "wallet_tool common" + "wallet_tool crypto" +) + +# Declare list of known errors that should be suppressed. +declare -A SUPPRESS +# init.cpp file currently calls Berkeley DB sanity check function on startup, so +# there is an undocumented dependency of the node library on the wallet library. +SUPPRESS["libbitcoin_node_a-init.o libbitcoin_wallet_a-bdb.o _ZN6wallet27BerkeleyDatabaseSanityCheckEv"]=1 +# init/common.cpp file calls InitError and InitWarning from interface_ui which +# is currently part of the node library. interface_ui should just be part of the +# common library instead, and is moved in +# https://github.com/bitcoin/bitcoin/issues/10102 +SUPPRESS["libbitcoin_common_a-common.o libbitcoin_node_a-interface_ui.o _Z11InitWarningRK13bilingual_str"]=1 +SUPPRESS["libbitcoin_common_a-common.o libbitcoin_node_a-interface_ui.o _Z9InitErrorRK13bilingual_str"]=1 +# rpc/external_signer.cpp adds defines node RPC methods but is built as part of the +# common library. It should be moved to the node library instead. +SUPPRESS["libbitcoin_common_a-external_signer.o libbitcoin_node_a-server.o _ZN9CRPCTable13appendCommandERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPK11CRPCCommand"]=1 + +usage() { + echo "Usage: $(basename "${BASH_SOURCE[0]}") [BUILD_DIR]" +} + +# Output makefile targets, converting library .a paths to libtool .la targets +lib_targets() { + for lib in "${!LIBS[@]}"; do + for lib_path in ${LIBS[$lib]}; do + # shellcheck disable=SC2001 + sed 's:/.libs/\(.*\)\.a$:/\1.la:g' <<<"$lib_path" + done + done +} + +# Extract symbol names and object names and write to text files +extract_symbols() { + local temp_dir="$1" + for lib in "${!LIBS[@]}"; do + for lib_path in ${LIBS[$lib]}; do + nm -o "$lib_path" | grep ' T ' | awk '{print $3, $1}' >> "${temp_dir}/${lib}_exports.txt" + nm -o "$lib_path" | grep ' U ' | awk '{print $3, $1}' >> "${temp_dir}/${lib}_imports.txt" + awk '{print $1}' "${temp_dir}/${lib}_exports.txt" | sort -u > "${temp_dir}/${lib}_exported_symbols.txt" + awk '{print $1}' "${temp_dir}/${lib}_imports.txt" | sort -u > "${temp_dir}/${lib}_imported_symbols.txt" + done + done +} + +# Lookup object name(s) corresponding to symbol name in text file +obj_names() { + local symbol="$1" + local txt_file="$2" + sed -n "s/^$symbol [^:]\\+:\\([^:]\\+\\):[^:]*\$/\\1/p" "$txt_file" | sort -u +} + +# Iterate through libraries and find disallowed dependencies +check_libraries() { + local temp_dir="$1" + local result=0 + for src in "${!LIBS[@]}"; do + for dst in "${!LIBS[@]}"; do + if [ "$src" != "$dst" ] && ! is_allowed "$src" "$dst"; then + if ! check_disallowed "$src" "$dst" "$temp_dir"; then + result=1 + fi + fi + done + done + check_not_suppressed + return $result +} + +# Return whether src library is allowed to depend on dst. +is_allowed() { + local src="$1" + local dst="$2" + for allowed in "${ALLOWED_DEPENDENCIES[@]}"; do + if [ "$src $dst" = "$allowed" ]; then + return 0 + fi + done + return 1 +} + +# Return whether src library imports any symbols from dst, assuming src is not +# allowed to depend on dst. +check_disallowed() { + local src="$1" + local dst="$2" + local temp_dir="$3" + local result=0 + + # Loop over symbol names exported by dst and imported by src + while read symbol; do + local dst_obj + dst_obj=$(obj_names "$symbol" "${temp_dir}/${dst}_exports.txt") + while read src_obj; do + if ! check_suppress "$src_obj" "$dst_obj" "$symbol"; then + echo "Error: $src_obj depends on $dst_obj symbol '$(c++filt "$symbol")', can suppess with:" + echo " SUPPRESS[\"$src_obj $dst_obj $symbol\"]=1" + result=1 + fi + done < <(obj_names "$symbol" "${temp_dir}/${src}_imports.txt") + done < <(comm -12 "${temp_dir}/${dst}_exported_symbols.txt" "${temp_dir}/${src}_imported_symbols.txt") + return $result +} + +# Declare array to track errors which were suppressed. +declare -A SUPPRESSED + +# Return whether error should be suppressed and record suppresssion in +# SUPPRESSED array. +check_suppress() { + local src_obj="$1" + local dst_obj="$2" + local symbol="$3" + for suppress in "${!SUPPRESS[@]}"; do + read suppress_src suppress_dst suppress_pattern <<<"$suppress" + if [[ "$src_obj" == "$suppress_src" && "$dst_obj" == "$suppress_dst" && "$symbol" =~ $suppress_pattern ]]; then + SUPPRESSED["$suppress"]=1 + return 0 + fi + done + return 1 +} + +# Warn about error which were supposed to be suppress, but were not encountered. +check_not_suppressed() { + for suppress in "${!SUPPRESS[@]}"; do + if [[ ! -v SUPPRESSED[$suppress] ]]; then + echo >&2 "Warning: suppression '$suppress' was ignored, consider deleting." + fi + done +} + +# Check arguments. +if [ "$#" = 0 ]; then + BUILD_DIR="$(dirname "${BASH_SOURCE[0]}")/../../src" +elif [ "$#" = 1 ]; then + BUILD_DIR="$1" +else + echo >&2 "Error: wrong number of arguments." + usage >&2 + exit 1 +fi +if [ ! -f "$BUILD_DIR/Makefile" ]; then + echo >&2 "Error: directory '$BUILD_DIR' does not contain a makefile, please specify path to build directory for library targets." + usage >&2 + exit 1 +fi + +# Build libraries and run checks. +cd "$BUILD_DIR" +# shellcheck disable=SC2046 +make -j"$(nproc)" $(lib_targets) +TEMP_DIR="$(mktemp -d)" +extract_symbols "$TEMP_DIR" +if check_libraries "$TEMP_DIR"; then + echo "Success! No unexpected dependencies were detected." +else + echo >&2 "Error: Unexpected dependencies were detected. Check previous output." +fi +rm -r "$TEMP_DIR" diff --git a/contrib/devtools/symbol-check.py b/contrib/devtools/symbol-check.py index b3e73bb2b9..c4e6bc81e1 100755 --- a/contrib/devtools/symbol-check.py +++ b/contrib/devtools/symbol-check.py @@ -14,31 +14,31 @@ import sys import lief -# Debian 10 (Buster) EOL: 2024. https://wiki.debian.org/LTS +# Debian 11 (Bullseye) EOL: 2026. https://wiki.debian.org/LTS # -# - libgcc version 8.3.0 (https://packages.debian.org/search?suite=buster&arch=any&searchon=names&keywords=libgcc1) -# - libc version 2.28 (https://packages.debian.org/search?suite=buster&arch=any&searchon=names&keywords=libc6) +# - libgcc version 10.2.1 (https://packages.debian.org/bullseye/libgcc-s1) +# - libc version 2.31 (https://packages.debian.org/source/bullseye/glibc) # -# Ubuntu 18.04 (Bionic) EOL: 2028. https://wiki.ubuntu.com/ReleaseTeam +# Ubuntu 20.04 (Focal) EOL: 2030. https://wiki.ubuntu.com/ReleaseTeam # -# - libgcc version 8.4.0 (https://packages.ubuntu.com/bionic/libgcc1) -# - libc version 2.27 (https://packages.ubuntu.com/bionic/libc6) +# - libgcc version 10.5.0 (https://packages.ubuntu.com/focal/libgcc1) +# - libc version 2.31 (https://packages.ubuntu.com/focal/libc6) # -# CentOS Stream 8 EOL: 2024. https://wiki.centos.org/About/Product +# CentOS Stream 9 EOL: 2027. https://www.centos.org/cl-vs-cs/#end-of-life # -# - libgcc version 8.5.0 (http://mirror.centos.org/centos/8-stream/AppStream/x86_64/os/Packages/) -# - libc version 2.28 (http://mirror.centos.org/centos/8-stream/AppStream/x86_64/os/Packages/) +# - libgcc version 12.2.1 (https://mirror.stream.centos.org/9-stream/AppStream/x86_64/os/Packages/) +# - libc version 2.34 (https://mirror.stream.centos.org/9-stream/AppStream/x86_64/os/Packages/) # # See https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html for more info. MAX_VERSIONS = { 'GCC': (4,3,0), 'GLIBC': { - lief.ELF.ARCH.x86_64: (2,27), - lief.ELF.ARCH.ARM: (2,27), - lief.ELF.ARCH.AARCH64:(2,27), - lief.ELF.ARCH.PPC64: (2,27), - lief.ELF.ARCH.RISCV: (2,27), + lief.ELF.ARCH.x86_64: (2,31), + lief.ELF.ARCH.ARM: (2,31), + lief.ELF.ARCH.AARCH64:(2,31), + lief.ELF.ARCH.PPC64: (2,31), + lief.ELF.ARCH.RISCV: (2,31), }, 'LIBATOMIC': (1,0), 'V': (0,5,0), # xkb (bitcoin-qt only) @@ -212,6 +212,11 @@ def check_exported_symbols(binary) -> bool: ok = False return ok +def check_RUNPATH(binary) -> bool: + assert binary.get(lief.ELF.DYNAMIC_TAGS.RUNPATH) is None + assert binary.get(lief.ELF.DYNAMIC_TAGS.RPATH) is None + return True + def check_ELF_libraries(binary) -> bool: ok: bool = True for library in binary.libraries: @@ -239,8 +244,8 @@ def check_MACHO_sdk(binary) -> bool: return True return False -def check_MACHO_ld64(binary) -> bool: - if binary.build_version.tools[0].version == [711, 0, 0]: +def check_MACHO_lld(binary) -> bool: + if binary.build_version.tools[0].version == [18, 1, 6]: return True return False @@ -277,12 +282,13 @@ lief.EXE_FORMATS.ELF: [ ('LIBRARY_DEPENDENCIES', check_ELF_libraries), ('INTERPRETER_NAME', check_ELF_interpreter), ('ABI', check_ELF_ABI), + ('RUNPATH', check_RUNPATH), ], lief.EXE_FORMATS.MACHO: [ ('DYNAMIC_LIBRARIES', check_MACHO_libraries), ('MIN_OS', check_MACHO_min_os), ('SDK', check_MACHO_sdk), - ('LD64', check_MACHO_ld64), + ('LLD', check_MACHO_lld), ], lief.EXE_FORMATS.PE: [ ('DYNAMIC_LIBRARIES', check_PE_libraries), diff --git a/contrib/devtools/test-security-check.py b/contrib/devtools/test-security-check.py index 48823c7e45..7bfd4d98da 100755 --- a/contrib/devtools/test-security-check.py +++ b/contrib/devtools/test-security-check.py @@ -27,22 +27,24 @@ def clean_files(source, executable): os.remove(source) os.remove(executable) -def call_security_check(cc: str, source: str, executable: str, options) -> tuple: +def env_flags() -> list[str]: # This should behave the same as AC_TRY_LINK, so arrange well-known flags # in the same order as autoconf would. # # See the definitions for ac_link in autoconf's lib/autoconf/c.m4 file for # reference. - env_flags: list[str] = [] + flags: list[str] = [] for var in ['CFLAGS', 'CPPFLAGS', 'LDFLAGS']: - env_flags += filter(None, os.environ.get(var, '').split(' ')) + flags += filter(None, os.environ.get(var, '').split(' ')) + return flags - subprocess.run([*cc,source,'-o',executable] + env_flags + options, check=True) +def call_security_check(cc: str, source: str, executable: str, options) -> tuple: + subprocess.run([*cc,source,'-o',executable] + env_flags() + options, check=True) p = subprocess.run([os.path.join(os.path.dirname(__file__), 'security-check.py'), executable], stdout=subprocess.PIPE, text=True) return (p.returncode, p.stdout.rstrip()) def get_arch(cc, source, executable): - subprocess.run([*cc, source, '-o', executable], check=True) + subprocess.run([*cc, source, '-o', executable] + env_flags(), check=True) binary = lief.parse(executable) arch = binary.abstract.header.architecture os.remove(executable) @@ -57,32 +59,32 @@ class TestSecurityChecks(unittest.TestCase): arch = get_arch(cc, source, executable) if arch == lief.ARCHITECTURES.X86: - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-zexecstack','-fno-stack-protector','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']), - (1, executable+': failed PIE NX RELRO Canary CONTROL_FLOW')) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fno-stack-protector','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']), - (1, executable+': failed PIE RELRO Canary CONTROL_FLOW')) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fstack-protector-all','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']), + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-zexecstack','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']), + (1, executable+': failed PIE NX RELRO CONTROL_FLOW')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']), (1, executable+': failed PIE RELRO CONTROL_FLOW')) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fstack-protector-all','-Wl,-znorelro','-pie','-fPIE', '-Wl,-z,separate-code']), + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']), + (1, executable+': failed PIE RELRO CONTROL_FLOW')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-Wl,-znorelro','-pie','-fPIE', '-Wl,-z,separate-code']), (1, executable+': failed RELRO CONTROL_FLOW')) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fstack-protector-all','-Wl,-zrelro','-Wl,-z,now','-pie','-fPIE', '-Wl,-z,noseparate-code']), + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-Wl,-zrelro','-Wl,-z,now','-pie','-fPIE', '-Wl,-z,noseparate-code']), (1, executable+': failed separate_code CONTROL_FLOW')) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fstack-protector-all','-Wl,-zrelro','-Wl,-z,now','-pie','-fPIE', '-Wl,-z,separate-code']), + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-Wl,-zrelro','-Wl,-z,now','-pie','-fPIE', '-Wl,-z,separate-code']), (1, executable+': failed CONTROL_FLOW')) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fstack-protector-all','-Wl,-zrelro','-Wl,-z,now','-pie','-fPIE', '-Wl,-z,separate-code', '-fcf-protection=full']), + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-Wl,-zrelro','-Wl,-z,now','-pie','-fPIE', '-Wl,-z,separate-code', '-fcf-protection=full']), (0, '')) else: - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-zexecstack','-fno-stack-protector','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']), - (1, executable+': failed PIE NX RELRO Canary')) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fno-stack-protector','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']), - (1, executable+': failed PIE RELRO Canary')) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fstack-protector-all','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']), + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-zexecstack','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']), + (1, executable+': failed PIE NX RELRO')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']), + (1, executable+': failed PIE RELRO')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']), (1, executable+': failed PIE RELRO')) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fstack-protector-all','-Wl,-znorelro','-pie','-fPIE', '-Wl,-z,separate-code']), + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-Wl,-znorelro','-pie','-fPIE', '-Wl,-z,separate-code']), (1, executable+': failed RELRO')) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fstack-protector-all','-Wl,-zrelro','-Wl,-z,now','-pie','-fPIE', '-Wl,-z,noseparate-code']), + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-Wl,-zrelro','-Wl,-z,now','-pie','-fPIE', '-Wl,-z,noseparate-code']), (1, executable+': failed separate_code')) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fstack-protector-all','-Wl,-zrelro','-Wl,-z,now','-pie','-fPIE', '-Wl,-z,separate-code']), + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-Wl,-zrelro','-Wl,-z,now','-pie','-fPIE', '-Wl,-z,separate-code']), (0, '')) clean_files(source, executable) @@ -118,21 +120,15 @@ class TestSecurityChecks(unittest.TestCase): arch = get_arch(cc, source, executable) if arch == lief.ARCHITECTURES.X86: - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-Wl,-allow_stack_execute','-fno-stack-protector', '-Wl,-no_fixup_chains']), - (1, executable+': failed NOUNDEFS Canary FIXUP_CHAINS PIE NX CONTROL_FLOW')) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-Wl,-allow_stack_execute','-fno-stack-protector', '-Wl,-fixup_chains']), - (1, executable+': failed NOUNDEFS Canary PIE NX CONTROL_FLOW')) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-Wl,-allow_stack_execute','-fstack-protector-all', '-Wl,-fixup_chains']), - (1, executable+': failed NOUNDEFS PIE NX CONTROL_FLOW')) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-fstack-protector-all', '-Wl,-fixup_chains']), - (1, executable+': failed NOUNDEFS PIE CONTROL_FLOW')) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-fstack-protector-all', '-Wl,-fixup_chains']), - (1, executable+': failed PIE CONTROL_FLOW')) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-fstack-protector-all', '-Wl,-fixup_chains']), - (1, executable+': failed PIE CONTROL_FLOW')) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-fstack-protector-all', '-fcf-protection=full', '-Wl,-fixup_chains']), - (1, executable+': failed PIE')) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-pie','-fstack-protector-all', '-fcf-protection=full', '-Wl,-fixup_chains']), + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-fno-stack-protector', '-Wl,-no_fixup_chains']), + (1, executable+': failed NOUNDEFS Canary FIXUP_CHAINS PIE CONTROL_FLOW')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-flat_namespace','-fno-stack-protector', '-Wl,-fixup_chains']), + (1, executable+': failed NOUNDEFS Canary CONTROL_FLOW')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-flat_namespace','-fstack-protector-all', '-Wl,-fixup_chains']), + (1, executable+': failed NOUNDEFS CONTROL_FLOW')) + self.assertEqual(call_security_check(cc, source, executable, ['-fstack-protector-all', '-Wl,-fixup_chains']), + (1, executable+': failed CONTROL_FLOW')) + self.assertEqual(call_security_check(cc, source, executable, ['-fstack-protector-all', '-fcf-protection=full', '-Wl,-fixup_chains']), (0, '')) else: # arm64 darwin doesn't support non-PIE binaries, control flow or executable stacks diff --git a/contrib/devtools/test-symbol-check.py b/contrib/devtools/test-symbol-check.py index 0140decb25..b00004586c 100755 --- a/contrib/devtools/test-symbol-check.py +++ b/contrib/devtools/test-symbol-check.py @@ -27,10 +27,6 @@ def call_symbol_check(cc: list[str], source, executable, options): os.remove(executable) return (p.returncode, p.stdout.rstrip()) -def get_machine(cc: list[str]): - p = subprocess.run([*cc,'-dumpmachine'], stdout=subprocess.PIPE, text=True) - return p.stdout.rstrip() - class TestSymbolChecks(unittest.TestCase): def test_ELF(self): source = 'test1.c' diff --git a/contrib/guix/guix-build b/contrib/guix/guix-build index 870938cb52..2ea574fe4b 100755 --- a/contrib/guix/guix-build +++ b/contrib/guix/guix-build @@ -361,6 +361,10 @@ INFO: Building ${VERSION:?not set} for platform triple ${HOST:?not set}: ...bind-mounted in container to: '$(DISTSRC_BASE=/distsrc-base && distsrc_for_host "$HOST")' ...outputting in: '$(outdir_for_host "$HOST")' ...bind-mounted in container to: '$(OUTDIR_BASE=/outdir-base && outdir_for_host "$HOST")' + ADDITIONAL FLAGS (if set) + ADDITIONAL_GUIX_COMMON_FLAGS: ${ADDITIONAL_GUIX_COMMON_FLAGS} + ADDITIONAL_GUIX_ENVIRONMENT_FLAGS: ${ADDITIONAL_GUIX_ENVIRONMENT_FLAGS} + ADDITIONAL_GUIX_TIMEMACHINE_FLAGS: ${ADDITIONAL_GUIX_TIMEMACHINE_FLAGS} EOF # Run the build script 'contrib/guix/libexec/build.sh' in the build diff --git a/contrib/guix/libexec/build.sh b/contrib/guix/libexec/build.sh index 1e9b682f3f..9bc8c0e75d 100755 --- a/contrib/guix/libexec/build.sh +++ b/contrib/guix/libexec/build.sh @@ -133,18 +133,7 @@ for p in "${PATHS[@]}"; do done # Disable Guix ld auto-rpath behavior -case "$HOST" in - *darwin*) - # The auto-rpath behavior is necessary for darwin builds as some native - # tools built by depends refer to and depend on Guix-built native - # libraries - # - # After the native packages in depends are built, the ld wrapper should - # no longer affect our build, as clang would instead reach for - # x86_64-apple-darwin-ld from cctools - ;; - *) export GUIX_LD_WRAPPER_DISABLE_RPATH=yes ;; -esac +export GUIX_LD_WRAPPER_DISABLE_RPATH=yes # Make /usr/bin if it doesn't exist [ -e /usr/bin ] || mkdir -p /usr/bin @@ -173,16 +162,6 @@ esac # Environment variables for determinism export TAR_OPTIONS="--owner=0 --group=0 --numeric-owner --mtime='@${SOURCE_DATE_EPOCH}' --sort=name" export TZ="UTC" -case "$HOST" in - *darwin*) - # cctools AR, unlike GNU binutils AR, does not have a deterministic mode - # or a configure flag to enable determinism by default, it only - # understands if this env-var is set or not. See: - # - # https://github.com/tpoechtrager/cctools-port/blob/55562e4073dea0fbfd0b20e0bf69ffe6390c7f97/cctools/ar/archive.c#L334 - export ZERO_AR_DATE=yes - ;; -esac #################### # Depends Building # @@ -199,8 +178,7 @@ make -C depends --jobs="$JOBS" HOST="$HOST" \ x86_64_linux_AR=x86_64-linux-gnu-gcc-ar \ x86_64_linux_RANLIB=x86_64-linux-gnu-gcc-ranlib \ x86_64_linux_NM=x86_64-linux-gnu-gcc-nm \ - x86_64_linux_STRIP=x86_64-linux-gnu-strip \ - FORCE_USE_SYSTEM_CLANG=1 + x86_64_linux_STRIP=x86_64-linux-gnu-strip ########################### diff --git a/contrib/guix/libexec/prelude.bash b/contrib/guix/libexec/prelude.bash index ce6a9562b4..80bfb2875f 100644 --- a/contrib/guix/libexec/prelude.bash +++ b/contrib/guix/libexec/prelude.bash @@ -51,7 +51,7 @@ fi time-machine() { # shellcheck disable=SC2086 guix time-machine --url=https://git.savannah.gnu.org/git/guix.git \ - --commit=dc4842797bfdc5f9f3f5f725bf189c2b68bd6b5a \ + --commit=f0bb724211872cd6158fce6162e0b8c73efed126 \ --cores="$JOBS" \ --keep-failed \ --fallback \ diff --git a/contrib/guix/manifest.scm b/contrib/guix/manifest.scm index 96818c7748..44fbfa1c0b 100644 --- a/contrib/guix/manifest.scm +++ b/contrib/guix/manifest.scm @@ -98,7 +98,7 @@ chain for " target " development.")) #:key (base-gcc-for-libc linux-base-gcc) (base-kernel-headers base-linux-kernel-headers) - (base-libc glibc-2.27) + (base-libc glibc-2.31) (base-gcc linux-base-gcc)) "Convenience wrapper around MAKE-CROSS-TOOLCHAIN with default values desirable for building Bitcoin Core release binaries." @@ -440,24 +440,21 @@ inspecting signatures in Mach-O binaries.") (("-rpath=") "-rpath-link=")) #t)))))))) -(define-public glibc-2.27 +(define-public glibc-2.31 + (let ((commit "8e30f03744837a85e33d84ccd34ed3abe30d37c3")) (package - (inherit glibc-2.31) - (version "2.27") + (inherit glibc) ;; 2.35 + (version "2.31") (source (origin (method git-fetch) (uri (git-reference (url "https://sourceware.org/git/glibc.git") - (commit "73886db6218e613bd6d4edf529f11e008a6c2fa6"))) - (file-name (git-file-name "glibc" "73886db6218e613bd6d4edf529f11e008a6c2fa6")) + (commit commit))) + (file-name (git-file-name "glibc" commit)) (sha256 (base32 - "0azpb9cvnbv25zg8019rqz48h8i2257ngyjg566dlnp74ivrs9vq")) - (patches (search-our-patches "glibc-2.27-riscv64-Use-__has_include-to-include-asm-syscalls.h.patch" - "glibc-2.27-fcommon.patch" - "glibc-2.27-guix-prefix.patch" - "glibc-2.27-no-librt.patch" - "glibc-2.27-powerpc-ldbrx.patch")))) + "1zi0s9yy5zkisw823vivn7zlj8w6g9p3mm7lmlqiixcxdkz4dbn6")) + (patches (search-our-patches "glibc-guix-prefix.patch")))) (arguments (substitute-keyword-arguments (package-arguments glibc) ((#:configure-flags flags) @@ -473,12 +470,13 @@ inspecting signatures in Mach-O binaries.") (lambda* (#:key outputs #:allow-other-keys) ;; Install the rpc data base file under `$out/etc/rpc'. ;; Otherwise build will fail with "Permission denied." + ;; Can be removed when we are building 2.32 or later. (let ((out (assoc-ref outputs "out"))) (substitute* "sunrpc/Makefile" (("^\\$\\(inst_sysconfdir\\)/rpc(.*)$" _ suffix) (string-append out "/etc/rpc" suffix "\n")) (("^install-others =.*$") - (string-append "install-others = " out "/etc/rpc\n")))))))))))) + (string-append "install-others = " out "/etc/rpc\n"))))))))))))) (packages->manifest (append @@ -532,8 +530,9 @@ inspecting signatures in Mach-O binaries.") ((string-contains target "darwin") (list ;; Native GCC 11 toolchain gcc-toolchain-11 - binutils - clang-toolchain-17 + clang-toolchain-18 + lld-18 + (make-lld-wrapper lld-18 #:lld-as-ld? #t) python-signapple zip)) (else '()))))) diff --git a/contrib/guix/patches/glibc-2.27-fcommon.patch b/contrib/guix/patches/glibc-2.27-fcommon.patch deleted file mode 100644 index f8d14837fc..0000000000 --- a/contrib/guix/patches/glibc-2.27-fcommon.patch +++ /dev/null @@ -1,34 +0,0 @@ -commit 264a4a0dbe1f4369db315080034b500bed66016c -Author: fanquake <fanquake@gmail.com> -Date: Fri May 6 11:03:04 2022 +0100 - - build: use -fcommon to retain legacy behaviour with GCC 10 - - GCC 10 started using -fno-common by default, which causes issues with - the powerpc builds using gibc 2.27. A patch was committed to glibc to fix - the issue, 18363b4f010da9ba459b13310b113ac0647c2fcc but is non-trvial - to backport, and was broken in at least one way, see the followup in - commit 7650321ce037302bfc2f026aa19e0213b8d02fe6. - - For now, retain the legacy GCC behaviour by passing -fcommon when - building glibc. - - https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html. - https://sourceware.org/git/?p=glibc.git;a=commit;h=18363b4f010da9ba459b13310b113ac0647c2fcc - https://sourceware.org/git/?p=glibc.git;a=commit;h=7650321ce037302bfc2f026aa19e0213b8d02fe6 - - This patch can be dropped when we are building with glibc 2.31+. - -diff --git a/Makeconfig b/Makeconfig -index 86a71e5802..aa2166be60 100644 ---- a/Makeconfig -+++ b/Makeconfig -@@ -896,7 +896,7 @@ ifeq "$(strip $(+cflags))" "" - endif # $(+cflags) == "" - - +cflags += $(cflags-cpu) $(+gccwarn) $(+merge-constants) $(+math-flags) \ -- $(+stack-protector) -+ $(+stack-protector) -fcommon - +gcc-nowarn := -w - - # Don't duplicate options if we inherited variables from the parent. diff --git a/contrib/guix/patches/glibc-2.27-no-librt.patch b/contrib/guix/patches/glibc-2.27-no-librt.patch deleted file mode 100644 index 4f2092ba7e..0000000000 --- a/contrib/guix/patches/glibc-2.27-no-librt.patch +++ /dev/null @@ -1,53 +0,0 @@ -This patch can be dropped when we are building with glibc 2.30+. - -commit 6e41ef56c9baab719a02f1377b1e7ce7bff61e73 -Author: Florian Weimer <fweimer@redhat.com> -Date: Fri Feb 8 10:21:56 2019 +0100 - - rt: Turn forwards from librt to libc into compat symbols [BZ #24194] - - As the result of commit 6e6249d0b461b952d0f544792372663feb6d792a - ("BZ#14743: Move clock_* symbols from librt to libc."), in glibc 2.17, - clock_gettime, clock_getres, clock_settime, clock_getcpuclockid, - clock_nanosleep were added to libc, and the file rt/clock-compat.c - was added with forwarders to the actual implementations in libc. - These forwarders were wrapped in - - #if SHLIB_COMPAT (librt, GLIBC_2_2, GLIBC_2_17) - - so that they are not present for newer architectures (such as - powerpc64le) with a 2.17 or later ABI baseline. But the forwarders - were not marked as compatibility symbols. As a result, on older - architectures, historic configure checks such as - - AC_CHECK_LIB(rt, clock_gettime) - - still cause linking against librt, even though this is completely - unnecessary. It also creates a needless porting hazard because - architectures behave differently when it comes to symbol availability. - - Reviewed-by: Carlos O'Donell <carlos@redhat.com> - -diff --git a/rt/clock-compat.c b/rt/clock-compat.c -index f816973c05..11e71aa890 100644 ---- a/rt/clock-compat.c -+++ b/rt/clock-compat.c -@@ -30,14 +30,16 @@ - #if HAVE_IFUNC - # undef INIT_ARCH - # define INIT_ARCH() --# define COMPAT_REDIRECT(name, proto, arglist) libc_ifunc (name, &__##name) -+# define COMPAT_REDIRECT(name, proto, arglist) libc_ifunc (name, &__##name) \ -+ compat_symbol (librt, name, name, GLIBC_2_2); - #else - # define COMPAT_REDIRECT(name, proto, arglist) \ - int \ - name proto \ - { \ - return __##name arglist; \ -- } -+ } \ -+ compat_symbol (librt, name, name, GLIBC_2_2); - #endif - - COMPAT_REDIRECT (clock_getres, diff --git a/contrib/guix/patches/glibc-2.27-powerpc-ldbrx.patch b/contrib/guix/patches/glibc-2.27-powerpc-ldbrx.patch deleted file mode 100644 index 26716054c8..0000000000 --- a/contrib/guix/patches/glibc-2.27-powerpc-ldbrx.patch +++ /dev/null @@ -1,245 +0,0 @@ -From 50b0b3c9ff71ffd7ebbd74ae46844c3566478123 Mon Sep 17 00:00:00 2001 -From: "Gabriel F. T. Gomes" <gabrielftg@linux.ibm.com> -Date: Mon, 27 May 2019 15:21:22 -0300 -Subject: [PATCH] powerpc: Fix build failures with current GCC - -Since GCC commit 271500 (svn), also known as the following commit on the -git mirror: - -commit e154242724b084380e3221df7c08fcdbd8460674 -Author: amodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4> -Date: Wed May 22 04:34:26 2019 +0000 - - [RS6000] Don't pass -many to the assembler - -glibc builds are failing when an assembly implementation does not -declare the correct '.machine' directive, or when no such directive is -declared at all. For example, when a POWER6 instruction is used, but -'.machine power6' is not declared, the assembler will fail with an error -similar to the following: - - ../sysdeps/powerpc/powerpc64/power8/strcmp.S: Assembler messages: - 24 ../sysdeps/powerpc/powerpc64/power8/strcmp.S:55: Error: unrecognized opcode: `cmpb' - -This patch adds '.machine powerN' directives where none existed, as well -as it updates '.machine power7' directives on POWER8 files, because the -minimum binutils version required to build glibc (binutils 2.25) now -provides this machine version. It also adds '-many' to the assembler -command used to build tst-set_ppr.c. - -Tested for powerpc, powerpc64, and powerpc64le, as well as with -build-many-glibcs.py for powerpc targets. - -Reviewed-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com> ---- - sysdeps/powerpc/Makefile | 5 +++ - sysdeps/powerpc/powerpc64/power4/memcmp.S | 7 ++++ - sysdeps/powerpc/powerpc64/power7/strncmp.S | 1 + - .../powerpc/powerpc64/power8/fpu/s_llround.S | 1 + - sysdeps/powerpc/powerpc64/power8/strcasecmp.S | 36 ++++++------------- - sysdeps/powerpc/powerpc64/power8/strcasestr.S | 14 ++------ - sysdeps/powerpc/powerpc64/power8/strcmp.S | 1 + - 7 files changed, 28 insertions(+), 37 deletions(-) - -diff --git a/sysdeps/powerpc/Makefile b/sysdeps/powerpc/Makefile -index 6aa683b03f..23126147df 100644 ---- a/sysdeps/powerpc/Makefile -+++ b/sysdeps/powerpc/Makefile -@@ -45,6 +45,11 @@ ifeq ($(subdir),misc) - sysdep_headers += sys/platform/ppc.h - tests += test-gettimebase - tests += tst-set_ppr -+ -+# This test is expected to run and exit with EXIT_UNSUPPORTED on -+# processors that do not implement the Power ISA 2.06 or greater. -+# But the test makes use of instructions from Power ISA 2.06 and 2.07. -+CFLAGS-tst-set_ppr.c += -Wa,-many - endif - - ifneq (,$(filter %le,$(config-machine))) -diff --git a/sysdeps/powerpc/powerpc64/power4/memcmp.S b/sysdeps/powerpc/powerpc64/power4/memcmp.S -index e5319f101f..38dcf4c9a1 100644 ---- a/sysdeps/powerpc/powerpc64/power4/memcmp.S -+++ b/sysdeps/powerpc/powerpc64/power4/memcmp.S -@@ -26,7 +26,14 @@ - # define MEMCMP memcmp - #endif - -+#ifndef __LITTLE_ENDIAN__ - .machine power4 -+#else -+/* Little endian is only available since POWER8, so it's safe to -+ specify .machine as power8 (or older), even though this is a POWER4 -+ file. Since the little-endian code uses 'ldbrx', power7 is enough. */ -+ .machine power7 -+#endif - ENTRY_TOCLESS (MEMCMP, 4) - CALL_MCOUNT 3 - -diff --git a/sysdeps/powerpc/powerpc64/power7/strncmp.S b/sysdeps/powerpc/powerpc64/power7/strncmp.S -index 0c7429d19f..10f898c5a3 100644 ---- a/sysdeps/powerpc/powerpc64/power7/strncmp.S -+++ b/sysdeps/powerpc/powerpc64/power7/strncmp.S -@@ -28,6 +28,7 @@ - const char *s2 [r4], - size_t size [r5]) */ - -+ .machine power7 - ENTRY_TOCLESS (STRNCMP, 5) - CALL_MCOUNT 3 - -diff --git a/sysdeps/powerpc/powerpc64/power8/fpu/s_llround.S b/sysdeps/powerpc/powerpc64/power8/fpu/s_llround.S -index a22fc63bb3..84c76ba0f9 100644 ---- a/sysdeps/powerpc/powerpc64/power8/fpu/s_llround.S -+++ b/sysdeps/powerpc/powerpc64/power8/fpu/s_llround.S -@@ -26,6 +26,7 @@ - - /* long long [r3] llround (float x [fp1]) */ - -+ .machine power8 - ENTRY_TOCLESS (__llround) - CALL_MCOUNT 0 - frin fp1,fp1 /* Round to nearest +-0.5. */ -diff --git a/sysdeps/powerpc/powerpc64/power8/strcasecmp.S b/sysdeps/powerpc/powerpc64/power8/strcasecmp.S -index 3a2efe2a64..eeacd40c7f 100644 ---- a/sysdeps/powerpc/powerpc64/power8/strcasecmp.S -+++ b/sysdeps/powerpc/powerpc64/power8/strcasecmp.S -@@ -91,21 +91,7 @@ - 3: \ - TOLOWER() - --#ifdef _ARCH_PWR8 --# define VCLZD_V8_v7 vclzd v8, v7; --# define MFVRD_R3_V1 mfvrd r3, v1; --# define VSUBUDM_V9_V8 vsubudm v9, v9, v8; --# define VPOPCNTD_V8_V8 vpopcntd v8, v8; --# define VADDUQM_V7_V8 vadduqm v9, v7, v8; --#else --# define VCLZD_V8_v7 .long 0x11003fc2 --# define MFVRD_R3_V1 .long 0x7c230067 --# define VSUBUDM_V9_V8 .long 0x112944c0 --# define VPOPCNTD_V8_V8 .long 0x110047c3 --# define VADDUQM_V7_V8 .long 0x11274100 --#endif -- -- .machine power7 -+ .machine power8 - - ENTRY (__STRCASECMP) - #ifdef USE_AS_STRNCASECMP -@@ -265,15 +251,15 @@ L(different): - #ifdef __LITTLE_ENDIAN__ - /* Count trailing zero. */ - vspltisb v8, -1 -- VADDUQM_V7_V8 -+ vadduqm v9, v7, v8 - vandc v8, v9, v7 -- VPOPCNTD_V8_V8 -+ vpopcntd v8, v8 - vspltb v6, v8, 15 - vcmpequb. v6, v6, v1 - blt cr6, L(shift8) - #else - /* Count leading zero. */ -- VCLZD_V8_v7 -+ vclzd v8, v7 - vspltb v6, v8, 7 - vcmpequb. v6, v6, v1 - blt cr6, L(shift8) -@@ -291,7 +277,7 @@ L(skipsum): - /* Merge and move to GPR. */ - vmrglb v6, v6, v7 - vslo v1, v6, v1 -- MFVRD_R3_V1 -+ mfvrd r3, v1 - /* Place the characters that are different in first position. */ - sldi rSTR2, rRTN, 56 - srdi rSTR2, rSTR2, 56 -@@ -301,7 +287,7 @@ L(skipsum): - vslo v6, v5, v8 - vslo v7, v4, v8 - vmrghb v1, v6, v7 -- MFVRD_R3_V1 -+ mfvrd r3, v1 - srdi rSTR2, rRTN, 48 - sldi rSTR2, rSTR2, 56 - srdi rSTR2, rSTR2, 56 -@@ -320,15 +306,15 @@ L(null_found): - #ifdef __LITTLE_ENDIAN__ - /* Count trailing zero. */ - vspltisb v8, -1 -- VADDUQM_V7_V8 -+ vadduqm v9, v7, v8 - vandc v8, v9, v7 -- VPOPCNTD_V8_V8 -+ vpopcntd v8, v8 - vspltb v6, v8, 15 - vcmpequb. v6, v6, v10 - blt cr6, L(shift_8) - #else - /* Count leading zero. */ -- VCLZD_V8_v7 -+ vclzd v8, v7 - vspltb v6, v8, 7 - vcmpequb. v6, v6, v10 - blt cr6, L(shift_8) -@@ -343,10 +329,10 @@ L(skipsum1): - vspltisb v10, 7 - vslb v10, v10, v10 - vsldoi v9, v0, v10, 1 -- VSUBUDM_V9_V8 -+ vsubudm v9, v9, v8 - vspltisb v8, 8 - vsldoi v8, v0, v8, 1 -- VSUBUDM_V9_V8 -+ vsubudm v9, v9, v8 - /* Shift and remove junk after null character. */ - #ifdef __LITTLE_ENDIAN__ - vslo v5, v5, v9 -diff --git a/sysdeps/powerpc/powerpc64/power8/strcasestr.S b/sysdeps/powerpc/powerpc64/power8/strcasestr.S -index 9fc24c29f9..e10f06fd86 100644 ---- a/sysdeps/powerpc/powerpc64/power8/strcasestr.S -+++ b/sysdeps/powerpc/powerpc64/power8/strcasestr.S -@@ -73,18 +73,8 @@ - vor reg, v8, reg; \ - vcmpequb. v6, reg, v4; - --/* TODO: change these to the actual instructions when the minimum required -- binutils allows it. */ --#ifdef _ARCH_PWR8 --#define VCLZD_V8_v7 vclzd v8, v7; --#else --#define VCLZD_V8_v7 .long 0x11003fc2 --#endif -- - #define FRAMESIZE (FRAME_MIN_SIZE+48) --/* TODO: change this to .machine power8 when the minimum required binutils -- allows it. */ -- .machine power7 -+ .machine power8 - ENTRY (STRCASESTR, 4) - CALL_MCOUNT 2 - mflr r0 /* Load link register LR to r0. */ -@@ -291,7 +281,7 @@ L(nullchk1): - vcmpequb. v6, v0, v7 - /* Shift r3 by 16 bytes and proceed. */ - blt cr6, L(shift16) -- VCLZD_V8_v7 -+ vclzd v8, v7 - #ifdef __LITTLE_ENDIAN__ - vspltb v6, v8, 15 - #else -diff --git a/sysdeps/powerpc/powerpc64/power8/strcmp.S b/sysdeps/powerpc/powerpc64/power8/strcmp.S -index 15e7351d1b..d592266d1d 100644 ---- a/sysdeps/powerpc/powerpc64/power8/strcmp.S -+++ b/sysdeps/powerpc/powerpc64/power8/strcmp.S -@@ -31,6 +31,7 @@ - 64K as default, the page cross handling assumes minimum page size of - 4k. */ - -+ .machine power8 - ENTRY_TOCLESS (STRCMP, 4) - li r0,0 - --- -2.41.0 diff --git a/contrib/guix/patches/glibc-2.27-riscv64-Use-__has_include-to-include-asm-syscalls.h.patch b/contrib/guix/patches/glibc-2.27-riscv64-Use-__has_include-to-include-asm-syscalls.h.patch deleted file mode 100644 index ab8ae9c023..0000000000 --- a/contrib/guix/patches/glibc-2.27-riscv64-Use-__has_include-to-include-asm-syscalls.h.patch +++ /dev/null @@ -1,78 +0,0 @@ -Note that this has been modified from the original commit, to use __has_include -instead of __has_include__, as the later was causing build failures with GCC 10. -See also: http://lists.busybox.net/pipermail/buildroot/2020-July/590376.html. - -https://sourceware.org/git/?p=glibc.git;a=commit;h=0b9c84906f653978fb8768c7ebd0ee14a47e662e - -This patch can be dropped when we are building with glibc 2.28+. - -From 562c52cc81a4e456a62e6455feb32732049e9070 Mon Sep 17 00:00:00 2001 -From: "H.J. Lu" <hjl.tools@gmail.com> -Date: Mon, 31 Dec 2018 09:26:42 -0800 -Subject: [PATCH] riscv: Use __has_include__ to include <asm/syscalls.h> [BZ - #24022] - -<asm/syscalls.h> has been removed by - -commit 27f8899d6002e11a6e2d995e29b8deab5aa9cc25 -Author: David Abdurachmanov <david.abdurachmanov@gmail.com> -Date: Thu Nov 8 20:02:39 2018 +0100 - - riscv: add asm/unistd.h UAPI header - - Marcin Juszkiewicz reported issues while generating syscall table for riscv - using 4.20-rc1. The patch refactors our unistd.h files to match some other - architectures. - - - Add asm/unistd.h UAPI header, which has __ARCH_WANT_NEW_STAT only for 64-bit - - Remove asm/syscalls.h UAPI header and merge to asm/unistd.h - - Adjust kernel asm/unistd.h - - So now asm/unistd.h UAPI header should show all syscalls for riscv. - -<asm/syscalls.h> may be restored by - -Subject: [PATCH] riscv: restore asm/syscalls.h UAPI header -Date: Tue, 11 Dec 2018 09:09:35 +0100 - -UAPI header asm/syscalls.h was merged into UAPI asm/unistd.h header, -which did resolve issue with missing syscalls macros resulting in -glibc (2.28) build failure. It also broke glibc in a different way: -asm/syscalls.h is being used by glibc. I noticed this while doing -Fedora 30/Rawhide mass rebuild. - -The patch returns asm/syscalls.h header and incl. it into asm/unistd.h. -I plan to send a patch to glibc to use asm/unistd.h instead of -asm/syscalls.h - -In the meantime, we use __has_include__, which was added to GCC 5, to -check if <asm/syscalls.h> exists before including it. Tested with -build-many-glibcs.py for riscv against kernel 4.19.12 and 4.20-rc7. - - [BZ #24022] - * sysdeps/unix/sysv/linux/riscv/flush-icache.c: Check if - <asm/syscalls.h> exists with __has_include__ before including it. ---- - sysdeps/unix/sysv/linux/riscv/flush-icache.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/sysdeps/unix/sysv/linux/riscv/flush-icache.c b/sysdeps/unix/sysv/linux/riscv/flush-icache.c -index d612ef4c6c..0b2042620b 100644 ---- a/sysdeps/unix/sysv/linux/riscv/flush-icache.c -+++ b/sysdeps/unix/sysv/linux/riscv/flush-icache.c -@@ -21,7 +21,11 @@ - #include <stdlib.h> - #include <atomic.h> - #include <sys/cachectl.h> --#include <asm/syscalls.h> -+#if __has_include (<asm/syscalls.h>) -+# include <asm/syscalls.h> -+#else -+# include <asm/unistd.h> -+#endif - - typedef int (*func_type) (void *, void *, unsigned long int); - --- -2.31.1 - diff --git a/contrib/guix/patches/glibc-2.27-guix-prefix.patch b/contrib/guix/patches/glibc-guix-prefix.patch index dc515907ff..60e12ca525 100644 --- a/contrib/guix/patches/glibc-2.27-guix-prefix.patch +++ b/contrib/guix/patches/glibc-guix-prefix.patch @@ -4,19 +4,13 @@ hash for the same package will differ when on different architectures. In order to be reproducible regardless of the architecture used to build the package, map all guix store prefixes to something fixed, e.g. /usr. -We might be able to drop this in favour of using --with-nonshared-cflags -when we begin using newer versions of glibc. - --- a/Makeconfig +++ b/Makeconfig -@@ -992,6 +992,10 @@ object-suffixes := +@@ -1007,6 +1007,7 @@ object-suffixes := CPPFLAGS-.o = $(pic-default) # libc.a must be compiled with -fPIE/-fpie for static PIE. CFLAGS-.o = $(filter %frame-pointer,$(+cflags)) $(pie-default) -+ -+# Map Guix store paths to /usr +CFLAGS-.o += `find /gnu/store -maxdepth 1 -mindepth 1 -type d -exec echo -n " -ffile-prefix-map={}=/usr" \;` -+ libtype.o := lib%.a object-suffixes += .o ifeq (yes,$(build-shared)) diff --git a/contrib/macdeploy/README.md b/contrib/macdeploy/README.md index d1df3062f8..d47ee6774e 100644 --- a/contrib/macdeploy/README.md +++ b/contrib/macdeploy/README.md @@ -56,45 +56,22 @@ The `sha256sum` should be `c0c2e7bb92c1fee0c4e9f3a485e4530786732d6c6dd9e9f418c28 ## Deterministic macOS App Notes -macOS Applications are created in Linux by combining a recent `clang` and the Apple -`binutils` (`ld`, `ar`, etc). +macOS Applications are created on Linux using a recent LLVM. -Apple uses `clang` extensively for development and has upstreamed the necessary -functionality so that a vanilla clang can take advantage. It supports the use of `-F`, -`-target`, `-mmacosx-version-min`, and `-isysroot`, which are all necessary when -building for macOS. +All builds must target an Apple SDK. These SDKs are free to download, but not redistributable. +See the SDK Extraction notes above for how to obtain it. -Apple's version of `binutils` (called `cctools`) contains lots of functionality missing in the -FSF's `binutils`. In addition to extra linker options for frameworks and sysroots, several -other tools are needed as well. These do not build under Linux, so they have been patched to -do so. The work here was used as a starting point: [mingwandroid/toolchain4](https://github.com/mingwandroid/toolchain4). +The Guix build process has been designed to avoid including the SDK's files in Guix's outputs. +All interim tarballs are fully deterministic and may be freely redistributed. -In order to build a working toolchain, the following source packages are needed from -Apple: `cctools`, `dyld`, and `ld64`. - -These tools inject timestamps by default, which produce non-deterministic binaries. The -`ZERO_AR_DATE` environment variable is used to disable that. - -This version of `cctools` has been patched to use the current version of `clang`'s headers -and its `libLTO.so` rather than those from `llvmgcc`, as it was originally done in `toolchain4`. - -To complicate things further, all builds must target an Apple SDK. These SDKs are free to -download, but not redistributable. See the SDK Extraction notes above for how to obtain it. - -The Guix process builds 2 sets of files: Linux tools, then Apple binaries which are -created using these tools. The build process has been designed to avoid including the -SDK's files in Guix's outputs. All interim tarballs are fully deterministic and may be freely -redistributed. - -As of OS X 10.9 Mavericks, using an Apple-blessed key to sign binaries is a requirement in -order to satisfy the new Gatekeeper requirements. Because this private key cannot be -shared, we'll have to be a bit creative in order for the build process to remain somewhat -deterministic. Here's how it works: +Using an Apple-blessed key to sign binaries is a requirement to produce (distributable) macOS +binaries. Because this private key cannot be shared, we'll have to be a bit creative in order +for the build process to remain somewhat deterministic. Here's how it works: - Builders use Guix to create an unsigned release. This outputs an unsigned ZIP which - users may choose to bless and run. It also outputs an unsigned app structure in the form - of a tarball. + users may choose to bless, self-codesign, and run. It also outputs an unsigned app structure + in the form of a tarball. - The Apple keyholder uses this unsigned app to create a detached signature, using the - script that is also included there. Detached signatures are available from this [repository](https://github.com/bitcoin-core/bitcoin-detached-sigs). -- Builders feed the unsigned app + detached signature back into Guix. It uses the - pre-built tools to recombine the pieces into a deterministic ZIP. + included script. Detached signatures are available from this [repository](https://github.com/bitcoin-core/bitcoin-detached-sigs). +- Builders feed the unsigned app + detached signature back into Guix, which combines the + pieces into a deterministic ZIP. diff --git a/contrib/macdeploy/gen-sdk b/contrib/macdeploy/gen-sdk index b73f5cba14..86a6262b5c 100755 --- a/contrib/macdeploy/gen-sdk +++ b/contrib/macdeploy/gen-sdk @@ -8,21 +8,6 @@ import gzip import os import contextlib -# monkey-patch Python 3.8 and older to fix wrong TAR header handling -# see https://github.com/bitcoin/bitcoin/pull/24534 -# and https://github.com/python/cpython/pull/18080 for more info -if sys.version_info < (3, 9): - _old_create_header = tarfile.TarInfo._create_header - def _create_header(info, format, encoding, errors): - buf = _old_create_header(info, format, encoding, errors) - # replace devmajor/devminor with binary zeroes - buf = buf[:329] + bytes(16) + buf[345:] - # recompute checksum - chksum = tarfile.calc_chksums(buf)[0] - buf = buf[:-364] + bytes("%06o\0" % chksum, "ascii") + buf[-357:] - return buf - tarfile.TarInfo._create_header = staticmethod(_create_header) - @contextlib.contextmanager def cd(path): """Context manager that restores PWD even if an exception was raised.""" diff --git a/contrib/macdeploy/macdeployqtplus b/contrib/macdeploy/macdeployqtplus index 4b1d72650d..eaa7b896be 100755 --- a/contrib/macdeploy/macdeployqtplus +++ b/contrib/macdeploy/macdeployqtplus @@ -77,7 +77,7 @@ class FrameworkInfo(object): bundleBinaryDirectory = "Contents/MacOS" @classmethod - def fromOtoolLibraryLine(cls, line: str) -> Optional['FrameworkInfo']: + def fromLibraryLine(cls, line: str) -> Optional['FrameworkInfo']: # Note: line must be trimmed if line == "": return None @@ -88,7 +88,7 @@ class FrameworkInfo(object): m = cls.reOLine.match(line) if m is None: - raise RuntimeError(f"otool line could not be parsed: {line}") + raise RuntimeError(f"Line could not be parsed: {line}") path = m.group(1) @@ -120,7 +120,7 @@ class FrameworkInfo(object): break i += 1 if i == len(parts): - raise RuntimeError(f"Could not find .framework or .dylib in otool line: {line}") + raise RuntimeError(f"Could not find .framework or .dylib in line: {line}") info.frameworkName = parts[i] info.frameworkDirectory = "/".join(parts[:i]) @@ -182,24 +182,24 @@ class DeploymentInfo(object): return False def getFrameworks(binaryPath: str, verbose: int) -> list[FrameworkInfo]: + objdump = os.getenv("OBJDUMP", "objdump") if verbose: - print(f"Inspecting with otool: {binaryPath}") - otoolbin=os.getenv("OTOOL", "otool") - otool = run([otoolbin, "-L", binaryPath], stdout=PIPE, stderr=PIPE, text=True) - if otool.returncode != 0: - sys.stderr.write(otool.stderr) + print(f"Inspecting with {objdump}: {binaryPath}") + output = run([objdump, "--macho", "--dylibs-used", binaryPath], stdout=PIPE, stderr=PIPE, text=True) + if output.returncode != 0: + sys.stderr.write(output.stderr) sys.stderr.flush() - raise RuntimeError(f"otool failed with return code {otool.returncode}") + raise RuntimeError(f"{objdump} failed with return code {output.returncode}") - otoolLines = otool.stdout.split("\n") - otoolLines.pop(0) # First line is the inspected binary + lines = output.stdout.split("\n") + lines.pop(0) # First line is the inspected binary if ".framework" in binaryPath or binaryPath.endswith(".dylib"): - otoolLines.pop(0) # Frameworks and dylibs list themselves as a dependency. + lines.pop(0) # Frameworks and dylibs list themselves as a dependency. libraries = [] - for line in otoolLines: + for line in lines: line = line.replace("@loader_path", os.path.dirname(binaryPath)) - info = FrameworkInfo.fromOtoolLibraryLine(line.strip()) + info = FrameworkInfo.fromLibraryLine(line.strip()) if info is not None: if verbose: print("Found framework:") diff --git a/contrib/seeds/generate-seeds.py b/contrib/seeds/generate-seeds.py index e921757802..f67e7b0f4c 100755 --- a/contrib/seeds/generate-seeds.py +++ b/contrib/seeds/generate-seeds.py @@ -29,7 +29,6 @@ These should be pasted into `src/chainparamsseeds.h`. from base64 import b32decode from enum import Enum -import struct import sys import os import re @@ -115,13 +114,13 @@ def parse_spec(s): def ser_compact_size(l): r = b"" if l < 253: - r = struct.pack("B", l) + r = l.to_bytes(1, "little") elif l < 0x10000: - r = struct.pack("<BH", 253, l) + r = (253).to_bytes(1, "little") + l.to_bytes(2, "little") elif l < 0x100000000: - r = struct.pack("<BI", 254, l) + r = (254).to_bytes(1, "little") + l.to_bytes(4, "little") else: - r = struct.pack("<BQ", 255, l) + r = (255).to_bytes(1, "little") + l.to_bytes(8, "little") return r def bip155_serialize(spec): @@ -129,10 +128,10 @@ def bip155_serialize(spec): Serialize (networkID, addr, port) tuple to BIP155 binary format. ''' r = b"" - r += struct.pack('B', spec[0].value) + r += spec[0].value.to_bytes(1, "little") r += ser_compact_size(len(spec[1])) r += spec[1] - r += struct.pack('>H', spec[2]) + r += spec[2].to_bytes(2, "big") return r def process_nodes(g, f, structname): diff --git a/contrib/seeds/makeseeds.py b/contrib/seeds/makeseeds.py index 79bb178b21..7fd0f7158e 100755 --- a/contrib/seeds/makeseeds.py +++ b/contrib/seeds/makeseeds.py @@ -9,11 +9,14 @@ import argparse import collections import ipaddress +from pathlib import Path import re import sys from typing import Union -from asmap import ASMap, net_to_prefix +asmap_dir = Path(__file__).parent.parent / "asmap" +sys.path.append(str(asmap_dir)) +from asmap import ASMap, net_to_prefix # noqa: E402 NSEEDS=512 diff --git a/contrib/signet/miner b/contrib/signet/miner index e5daf9f993..4216ada5fa 100755 --- a/contrib/signet/miner +++ b/contrib/signet/miner @@ -52,20 +52,20 @@ def signet_txs(block, challenge): mroot = block.get_merkle_root(hashes) sd = b"" - sd += struct.pack("<i", block.nVersion) + sd += block.nVersion.to_bytes(4, "little", signed=True) sd += ser_uint256(block.hashPrevBlock) sd += ser_uint256(mroot) - sd += struct.pack("<I", block.nTime) + sd += block.nTime.to_bytes(4, "little") to_spend = CTransaction() - to_spend.nVersion = 0 + to_spend.version = 0 to_spend.nLockTime = 0 to_spend.vin = [CTxIn(COutPoint(0, 0xFFFFFFFF), b"\x00" + CScriptOp.encode_op_pushdata(sd), 0)] to_spend.vout = [CTxOut(0, challenge)] to_spend.rehash() spend = CTransaction() - spend.nVersion = 0 + spend.version = 0 spend.nLockTime = 0 spend.vin = [CTxIn(COutPoint(to_spend.sha256, 0), b"", 0)] spend.vout = [CTxOut(0, b"\x6a")] diff --git a/contrib/verify-binaries/README.md b/contrib/verify-binaries/README.md index 04d683e69b..0f3e16a5bc 100644 --- a/contrib/verify-binaries/README.md +++ b/contrib/verify-binaries/README.md @@ -50,6 +50,7 @@ Get JSON output and don't prompt for user input (no auto key import): ```sh ./contrib/verify-binaries/verify.py --json pub 22.0-x86 +./contrib/verify-binaries/verify.py --json pub 23.0-rc5-linux-gnu ``` Rely only on local GPG state and manually specified keys, while requiring a @@ -57,14 +58,15 @@ threshold of at least 10 trusted signatures: ```sh ./contrib/verify-binaries/verify.py \ --trusted-keys 74E2DEF5D77260B98BC19438099BAD163C70FBFA,9D3CC86A72F8494342EA5FD10A41BDC3F4FAFF1C \ - --min-good-sigs 10 pub 22.0-x86 + --min-good-sigs 10 pub 22.0-linux ``` -If you only want to download the binaries for a certain platform, add the corresponding suffix, e.g.: +If you only want to download the binaries for a certain architecture and/or platform, add the corresponding suffix, e.g.: ```sh -./contrib/verify-binaries/verify.py pub 24.0.1-darwin -./contrib/verify-binaries/verify.py pub 23.1-rc1-win64 +./contrib/verify-binaries/verify.py pub 25.2-x86_64-linux +./contrib/verify-binaries/verify.py pub 24.1-rc1-darwin +./contrib/verify-binaries/verify.py pub 27.0-win64-setup.exe ``` If you do not want to keep the downloaded binaries, specify the cleanup option. diff --git a/contrib/verify-binaries/test.py b/contrib/verify-binaries/test.py index 22d718ece3..875606ec22 100755 --- a/contrib/verify-binaries/test.py +++ b/contrib/verify-binaries/test.py @@ -12,6 +12,21 @@ def main(): expect_code(run_verify("", "pub", '0.32.awefa.12f9h'), 11, "Malformed version should fail") expect_code(run_verify('--min-good-sigs 20', "pub", "22.0"), 9, "--min-good-sigs 20 should fail") + print("- testing verification (22.0-x86_64-linux-gnu.tar.gz)", flush=True) + _220_x86_64_linux_gnu = run_verify("--json", "pub", "22.0-x86_64-linux-gnu.tar.gz") + try: + result = json.loads(_220_x86_64_linux_gnu.stdout.decode()) + except Exception: + print("failed on 22.0-x86_64-linux-gnu.tar.gz --json:") + print_process_failure(_220_x86_64_linux_gnu) + raise + + expect_code(_220_x86_64_linux_gnu, 0, "22.0-x86_64-linux-gnu.tar.gz should succeed") + v = result['verified_binaries'] + assert result['good_trusted_sigs'] + assert len(v) == 1 + assert v['bitcoin-22.0-x86_64-linux-gnu.tar.gz'] == '59ebd25dd82a51638b7a6bb914586201e67db67b919b2a1ff08925a7936d1b16' + print("- testing verification (22.0)", flush=True) _220 = run_verify("--json", "pub", "22.0") try: diff --git a/contrib/verify-binaries/verify.py b/contrib/verify-binaries/verify.py index 12e6e10d8a..6c07b36c9d 100755 --- a/contrib/verify-binaries/verify.py +++ b/contrib/verify-binaries/verify.py @@ -97,23 +97,17 @@ def bool_from_env(key, default=False) -> bool: VERSION_FORMAT = "<major>.<minor>[.<patch>][-rc[0-9]][-platform]" -VERSION_EXAMPLE = "22.0-x86_64 or 23.1-rc1-darwin" +VERSION_EXAMPLE = "22.0 or 23.1-rc1-darwin.dmg or 27.0-x86_64-linux-gnu" def parse_version_string(version_str): - parts = version_str.split('-') - version_base = parts[0] - version_rc = "" - version_os = "" - if len(parts) == 2: # "<version>-rcN" or "version-platform" - if "rc" in parts[1]: - version_rc = parts[1] - else: - version_os = parts[1] - elif len(parts) == 3: # "<version>-rcN-platform" - version_rc = parts[1] - version_os = parts[2] + # "<version>[-rcN][-platform]" + version_base, _, platform = version_str.partition('-') + rc = "" + if platform.startswith("rc"): # "<version>-rcN[-platform]" + rc, _, platform = platform.partition('-') + # else "<version>" or "<version>-platform" - return version_base, version_rc, version_os + return version_base, rc, platform def download_with_wget(remote_file, local_file): @@ -514,7 +508,9 @@ def verify_published_handler(args: argparse.Namespace) -> ReturnCode: # Extract hashes and filenames hashes_to_verify = parse_sums_file(SUMS_FILENAME, [os_filter]) if not hashes_to_verify: - log.error("no files matched the platform specified") + available_versions = ["-".join(line[1].split("-")[2:]) for line in parse_sums_file(SUMS_FILENAME, [])] + closest_match = difflib.get_close_matches(os_filter, available_versions, cutoff=0, n=1)[0] + log.error(f"No files matched the platform specified. Did you mean: {closest_match}") return ReturnCode.NO_BINARIES_MATCH # remove binaries that are known not to be hosted by bitcoincore.org diff --git a/contrib/windeploy/win-codesign.cert b/contrib/windeploy/win-codesign.cert index 22f17296b6..ec60a3018d 100644 --- a/contrib/windeploy/win-codesign.cert +++ b/contrib/windeploy/win-codesign.cert @@ -1,8 +1,8 @@ -----BEGIN CERTIFICATE-----
-MIIHfDCCBWSgAwIBAgIQCmVvdQal72U2QxbUTT3SRTANBgkqhkiG9w0BAQsFADBp
+MIIHeTCCBWGgAwIBAgIQBzR46J2yq3g++NbQS/BBVDANBgkqhkiG9w0BAQsFADBp
MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNVBAMT
OERpZ2lDZXJ0IFRydXN0ZWQgRzQgQ29kZSBTaWduaW5nIFJTQTQwOTYgU0hBMzg0
-IDIwMjEgQ0ExMB4XDTIyMDUyNDAwMDAwMFoXDTI0MDUyOTIzNTk1OVowgYAxCzAJ
+IDIwMjEgQ0ExMB4XDTI0MDUyMjAwMDAwMFoXDTI3MDUzMTIzNTk1OVowgYAxCzAJ
BgNVBAYTAlVTMREwDwYDVQQIEwhEZWxhd2FyZTEOMAwGA1UEBxMFTGV3ZXMxJjAk
BgNVBAoTHUJpdGNvaW4gQ29yZSBDb2RlIFNpZ25pbmcgTExDMSYwJAYDVQQDEx1C
aXRjb2luIENvcmUgQ29kZSBTaWduaW5nIExMQzCCAiIwDQYJKoZIhvcNAQEBBQAD
@@ -17,28 +17,28 @@ CDvScIgnQXmk+cbKMBtg9kM0F+aLWsN2xVf0uAj3U7sdXLrfJeW0DZIktWtTBQzX O/OE4Ka+1WFnDg0HJIih0cTjl9YYvfe53L4pCGy+qGt/XGBRqCMfXp3g+H9FGR5r
pensVVcsrv3GbTfYdlpdmp9OHH5G57GTAZueobCZg7r7RKK0zPU9EiTLJxzyXuai
v/Ksd8eIhHRjewMaQuAtQM1tO+oKAbLF0v2M7v7/aVT76X32JllYAizm3zjvAgMB
-AAGjggIGMIICAjAfBgNVHSMEGDAWgBRoN+Drtjv4XxGG+/5hewiIZfROQjAdBgNV
-HQ4EFgQUvCpU58PIuofv0kHJ3Ty0YDKEy3cwDgYDVR0PAQH/BAQDAgeAMBMGA1Ud
-JQQMMAoGCCsGAQUFBwMDMIG1BgNVHR8Ega0wgaowU6BRoE+GTWh0dHA6Ly9jcmwz
-LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNENvZGVTaWduaW5nUlNBNDA5
-NlNIQTM4NDIwMjFDQTEuY3JsMFOgUaBPhk1odHRwOi8vY3JsNC5kaWdpY2VydC5j
-b20vRGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JTQTQwOTZTSEEzODQyMDIx
-Q0ExLmNybDA+BgNVHSAENzA1MDMGBmeBDAEEATApMCcGCCsGAQUFBwIBFhtodHRw
-Oi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwgZQGCCsGAQUFBwEBBIGHMIGEMCQGCCsG
+AAGjggIDMIIB/zAfBgNVHSMEGDAWgBRoN+Drtjv4XxGG+/5hewiIZfROQjAdBgNV
+HQ4EFgQUvCpU58PIuofv0kHJ3Ty0YDKEy3cwPgYDVR0gBDcwNTAzBgZngQwBBAEw
+KTAnBggrBgEFBQcCARYbaHR0cDovL3d3dy5kaWdpY2VydC5jb20vQ1BTMA4GA1Ud
+DwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzCBtQYDVR0fBIGtMIGqMFOg
+UaBPhk1odHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRD
+b2RlU2lnbmluZ1JTQTQwOTZTSEEzODQyMDIxQ0ExLmNybDBToFGgT4ZNaHR0cDov
+L2NybDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0Q29kZVNpZ25pbmdS
+U0E0MDk2U0hBMzg0MjAyMUNBMS5jcmwwgZQGCCsGAQUFBwEBBIGHMIGEMCQGCCsG
AQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wXAYIKwYBBQUHMAKGUGh0
dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNENvZGVT
-aWduaW5nUlNBNDA5NlNIQTM4NDIwMjFDQTEuY3J0MAwGA1UdEwEB/wQCMAAwDQYJ
-KoZIhvcNAQELBQADggIBABhpTZufRws1vrtI0xB1/UWrSEJxdPHivfpXE708dzum
-Jh3TFzpsEUCQX5BJJet1l7x92sKNeAL7votA+8O8YvMD64Kim7VKA2BB8AOHKQbp
-r1c2iZBwwofInviRYvsrvQta6KBy2KOe1L/l0KnpUazL9Tv4VKvuWAw/Qc0/eTQr
-NZRsmADORxnZ1qW+SpF+/WbazIYjod/Oqb1U3on+PzyiGD3SjzNhsdFRptqzrIaY
-UVV+2XHG4fN6A8wkyQL5NIVXGiK7rqS5VrRAv58Lf1ZZTghdAL+5SySE0OsR9t0K
-W73ZB9pxbuZZ6Zfxjotjw+IilCEm3ADbc7Eb2ijI4x8mix0XWMUrhL34s7/jRyDi
-P+30aSgjWp611tp/EYRW5kpIaFR8AesDdM0DSSCCRXOMwQG2Tq2+CnqItB5oLNPp
-2XySwlIWvmjbzsREfIpE3yh3bxmHY+vFIc2R0nNkbWNIT6AGtaEQ7oWkgpK8YMkA
-QCf4EUC4Qa7qHiH6YSmYJhjApBLC7UDwevgwxuDrwimWAj+tDkzdnENMcBp4SAy6
-LwUuDi2IU6HRSXWdh2YEkDbc3FdwknnnEWaB4dlRL85YjHyLXN0KiE7SKTj1LfR4
-dGeDqVUlDj9D5+X4a7F89wLP/um40/52HUQv5t5WcNr/47r9aVkx9DHs1b8oUnLg
+aWduaW5nUlNBNDA5NlNIQTM4NDIwMjFDQTEuY3J0MAkGA1UdEwQCMAAwDQYJKoZI
+hvcNAQELBQADggIBADdniG9IY9oOfw1e3+uc2lR4hoZqquJQRrCnbWJ1npnCTavI
+CfcEEMuQ5ztg4TR7tQNj2KcaHWKuPYxEz2bg8HpSPG27lnXaz4pLgfqvjdZWNH2v
+W6DGRUAwuMQHSV0qhuRcJPZuhwSFx/8y4r++jIcBxCbt/Jprt/bqc8vZZZzTDPfG
+M6cGaKMDvF//OkUPVzh4s557kV7+LoaX8CigiACZky3Zj3tkQfJYkEvdQseNvX49
+CMJ+cjN+fGweshbn/DszAT5oXW5l2PXeceyGrE+5Ex1ELXCPqNj8ZSn+S9IKZOag
+zDFBA93RTVD438peXPz//xgusgnmSqSPS5tCp9KSvew81acu4v/+egg9EgSSx5Ho
+9fkOX7JuygvN3r3UZqsddxdwf2dPvBDYlMdieF8qsR7H5DQPQoaTVrIhW4TFtJl/
+UPjVlnDwu+yvMC70F+CaVgQs01uZ0VKuG3KNkkEj6+V/SM54NVVgcY/Q7llKIFA8
+Qk8Ip8/83cVBptKW+OU+i2ZwoYskLbdfDE31X2knUIouNZgBBMhzc5WjJCEGXAPm
+9xYZMn87cc+ejxCw6/WC4b6tDCziO8drq76Pl6LTNPOtRkEVqt12p8Uqi9PgznUB
+bdHeoF5XHt1Ca2ySpSYuMz5djwIC2ws8kiMm44/AyTm6dwRcesiOTqnaRc+t
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE----- MIIGsDCCBJigAwIBAgIQCK1AsmDSnEyfXs2pvZOu2TANBgkqhkiG9w0BAQwFADBi diff --git a/depends/Makefile b/depends/Makefile index 005d9696fb..52a9a14e56 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -101,10 +101,6 @@ host_os+=$(findstring netbsd,$(full_host_os)) host_os+=$(findstring openbsd,$(full_host_os)) host_os+=$(findstring mingw32,$(full_host_os)) -ifeq (android,$(findstring android,$(full_host_os))) -host_os:=android -endif - host_os:=$(strip $(host_os)) ifeq ($(host_os),) host_os=$(full_host_os) @@ -185,9 +181,6 @@ all_packages = $(packages) $(native_packages) meta_depends = Makefile config.guess config.sub funcs.mk builders/default.mk hosts/default.mk hosts/$(host_os).mk builders/$(build_os).mk -$(host_arch)_$(host_os)_native_binutils?=$($(host_os)_native_binutils) -$(host_arch)_$(host_os)_native_toolchain?=$($(host_os)_native_toolchain) - include funcs.mk final_build_id_long+=$(shell $(build_SHA256SUM) config.site.in) @@ -217,9 +210,8 @@ $(host_prefix)/.stamp_$(final_build_id): $(native_packages) $(packages) # tool needs to be available in $PATH at all times. # # 2. If the tool is _**not**_ expected to be available in $PATH at all times -# (such as is the case for our native_cctools binutils tools), it needs to -# be referred to by its absolute path, such as would be output by the -# AC_PATH_{PROG,TOOL} macros. +# it needs to be referred to by its absolute path, such as would be output +# by the AC_PATH_{PROG,TOOL} macros. # # Minor note: it is also okay to refer to tools by their absolute path even if # we expect them to be available in $PATH at all times, more specificity does @@ -233,7 +225,7 @@ $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_ -e 's|@RANLIB@|$(host_RANLIB)|' \ -e 's|@NM@|$(host_NM)|' \ -e 's|@STRIP@|$(host_STRIP)|' \ - -e 's|@OTOOL@|$(host_OTOOL)|' \ + -e 's|@OBJDUMP@|$(host_OBJDUMP)|' \ -e 's|@DSYMUTIL@|$(host_DSYMUTIL)|' \ -e 's|@build_os@|$(build_os)|' \ -e 's|@host_os@|$(host_os)|' \ diff --git a/depends/README.md b/depends/README.md index 10e0985cf4..adaeed468f 100644 --- a/depends/README.md +++ b/depends/README.md @@ -38,21 +38,22 @@ Common `host-platform-triplet`s for cross compilation are: - `riscv32-linux-gnu` for Linux RISC-V 32 bit - `riscv64-linux-gnu` for Linux RISC-V 64 bit - `s390x-linux-gnu` for Linux S390X -- `armv7a-linux-android` for Android ARM 32 bit -- `aarch64-linux-android` for Android ARM 64 bit -- `x86_64-linux-android` for Android x86 64 bit -The paths are automatically configured and no other options are needed unless targeting [Android](../doc/build-android.md). +The paths are automatically configured and no other options are needed. ### Install the required dependencies: Ubuntu & Debian +#### Common + + apt install automake bison cmake curl libtool make patch pkg-config python3 xz-utils + #### For macOS cross compilation - sudo apt-get install curl bsdmainutils cmake zip + apt install clang lld llvm g++ zip -Note: You must obtain the macOS SDK before proceeding with a cross-compile. -Under the depends directory, create a subdirectory named `SDKs`. -Then, place the extracted SDK under this new directory. +Clang 18 or later is required. You must also obtain the macOS SDK before +proceeding with a cross-compile. Under the depends directory, create a +subdirectory named `SDKs`. Then, place the extracted SDK under this new directory. For more information, see [SDK Extraction](../contrib/macdeploy/README.md#sdk-extraction). #### For Win64 cross compilation @@ -63,7 +64,7 @@ For more information, see [SDK Extraction](../contrib/macdeploy/README.md#sdk-ex Common linux dependencies: - sudo apt-get install make automake cmake curl g++-multilib libtool binutils bsdmainutils pkg-config python3 patch bison + sudo apt-get install g++-multilib binutils For linux ARM cross compilation: @@ -118,9 +119,6 @@ The following can be set when running make: `make FOO=bar` - `DEBUG`: Disable some optimizations and enable more runtime checking - `HOST_ID_SALT`: Optional salt to use when generating host package ids - `BUILD_ID_SALT`: Optional salt to use when generating build package ids -- `FORCE_USE_SYSTEM_CLANG`: (EXPERTS ONLY) When cross-compiling for macOS, use Clang found in the - system's `$PATH` rather than the default prebuilt release of Clang - from llvm.org. Clang 8 or later is required - `LOG`: Use file-based logging for individual packages. During a package build its log file resides in the `depends` directory, and the log file is printed out automatically in case of build error. After successful build log files are moved along with package archives diff --git a/depends/builders/darwin.mk b/depends/builders/darwin.mk index 554bfd2c3e..2b59353e84 100644 --- a/depends/builders/darwin.mk +++ b/depends/builders/darwin.mk @@ -3,7 +3,7 @@ build_darwin_CXX:=$(shell xcrun -f clang++) -isysroot$(shell xcrun --show-sdk-pa build_darwin_AR:=$(shell xcrun -f ar) build_darwin_RANLIB:=$(shell xcrun -f ranlib) build_darwin_STRIP:=$(shell xcrun -f strip) -build_darwin_OTOOL:=$(shell xcrun -f otool) +build_darwin_OBJDUMP:=$(shell xcrun -f objdump) build_darwin_NM:=$(shell xcrun -f nm) build_darwin_DSYMUTIL:=$(shell xcrun -f dsymutil) build_darwin_SHA256SUM=shasum -a 256 @@ -15,11 +15,9 @@ darwin_CXX:=$(shell xcrun -f clang++) -stdlib=libc++ -isysroot$(shell xcrun --sh darwin_AR:=$(shell xcrun -f ar) darwin_RANLIB:=$(shell xcrun -f ranlib) darwin_STRIP:=$(shell xcrun -f strip) -darwin_OTOOL:=$(shell xcrun -f otool) +darwin_OBJDUMP:=$(shell xcrun -f objdump) darwin_NM:=$(shell xcrun -f nm) darwin_DSYMUTIL:=$(shell xcrun -f dsymutil) -darwin_native_binutils= -darwin_native_toolchain= x86_64_darwin_CFLAGS += -arch x86_64 x86_64_darwin_CXXFLAGS += -arch x86_64 diff --git a/depends/builders/default.mk b/depends/builders/default.mk index 50869cd8a2..2a1709d98a 100644 --- a/depends/builders/default.mk +++ b/depends/builders/default.mk @@ -1,6 +1,7 @@ default_build_CC = gcc default_build_CXX = g++ default_build_AR = ar +default_build_OBJDUMP = objdump default_build_TAR = tar default_build_RANLIB = ranlib default_build_STRIP = strip @@ -12,7 +13,7 @@ build_$(build_os)_$1 ?= $$(default_build_$1) build_$(build_arch)_$(build_os)_$1 ?= $$(build_$(build_os)_$1) build_$1=$$(build_$(build_arch)_$(build_os)_$1) endef -$(foreach var,CC CXX AR TAR RANLIB NM STRIP SHA256SUM DOWNLOAD OTOOL DSYMUTIL TOUCH,$(eval $(call add_build_tool_func,$(var)))) +$(foreach var,CC CXX AR TAR RANLIB NM STRIP SHA256SUM DOWNLOAD OBJDUMP DSYMUTIL TOUCH,$(eval $(call add_build_tool_func,$(var)))) define add_build_flags_func build_$(build_arch)_$(build_os)_$1 += $(build_$(build_os)_$1) build_$1=$$(build_$(build_arch)_$(build_os)_$1) diff --git a/depends/config.site.in b/depends/config.site.in index 81975f02b9..f6bed6a9d4 100644 --- a/depends/config.site.in +++ b/depends/config.site.in @@ -118,9 +118,9 @@ if test -n "@STRIP@"; then fi if test "@host_os@" = darwin; then - if test -n "@OTOOL@"; then - OTOOL="@OTOOL@" - ac_cv_path_OTOOL="${OTOOL}" + if test -n "@OBJDUMP@"; then + OBJDUMP="@OBJDUMP@" + ac_cv_path_OBJDUMP="${OBJDUMP}" fi if test -n "@DSYMUTIL@"; then diff --git a/depends/funcs.mk b/depends/funcs.mk index d8a72421b4..3c0dc7a7fc 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -46,7 +46,7 @@ endef define int_get_build_id $(eval $(1)_dependencies += $($(1)_$(host_arch)_$(host_os)_dependencies) $($(1)_$(host_os)_dependencies)) -$(eval $(1)_all_dependencies:=$(call int_get_all_dependencies,$(1),$($($(1)_type)_native_toolchain) $($($(1)_type)_native_binutils) $($(1)_dependencies))) +$(eval $(1)_all_dependencies:=$(call int_get_all_dependencies,$(1),$($(1)_dependencies))) $(foreach dep,$($(1)_all_dependencies),$(eval $(1)_build_id_deps+=$(dep)-$($(dep)_version)-$($(dep)_recipe_hash))) $(eval $(1)_build_id_long:=$(1)-$($(1)_version)-$($(1)_recipe_hash)-$(release_type) $($(1)_build_id_deps) $($($(1)_type)_id)) $(eval $(1)_build_id:=$(shell echo -n "$($(1)_build_id_long)" | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH))) @@ -180,6 +180,9 @@ $(1)_cmake=env CC="$$($(1)_cc)" \ CXXFLAGS="$$($(1)_cppflags) $$($(1)_cxxflags)" \ LDFLAGS="$$($(1)_ldflags)" \ cmake -DCMAKE_INSTALL_PREFIX:PATH="$$($($(1)_type)_prefix)" \ + -DCMAKE_AR=`which $$($(1)_ar)` \ + -DCMAKE_NM=`which $$($(1)_nm)` \ + -DCMAKE_RANLIB=`which $$($(1)_ranlib)` \ -DCMAKE_INSTALL_LIBDIR=lib/ \ -DCMAKE_POSITION_INDEPENDENT_CODE=ON \ -DCMAKE_VERBOSE_MAKEFILE:BOOL=$(V) \ @@ -294,6 +297,3 @@ $(foreach package,$(all_packages),$(eval $(call int_config_attach_build_config,$ #create build targets $(foreach package,$(all_packages),$(eval $(call int_add_cmds,$(package)))) - -#special exception: if a toolchain package exists, all non-native packages depend on it -$(foreach package,$(packages),$(eval $($(package)_extracted): |$($($(host_arch)_$(host_os)_native_toolchain)_cached) $($($(host_arch)_$(host_os)_native_binutils)_cached) )) diff --git a/depends/gen_id b/depends/gen_id index 8518b4e674..e2e2273b2d 100755 --- a/depends/gen_id +++ b/depends/gen_id @@ -53,7 +53,6 @@ echo "BEGIN AR" bash -c "${AR} --version" env | grep '^AR_' - echo "ZERO_AR_DATE=${ZERO_AR_DATE}" echo "END AR" echo "BEGIN NM" diff --git a/depends/hosts/android.mk b/depends/hosts/android.mk deleted file mode 100644 index a1c8c56dba..0000000000 --- a/depends/hosts/android.mk +++ /dev/null @@ -1,15 +0,0 @@ -ifeq ($(HOST),armv7a-linux-android) -android_CXX=$(ANDROID_TOOLCHAIN_BIN)/$(HOST)eabi$(ANDROID_API_LEVEL)-clang++ -android_CC=$(ANDROID_TOOLCHAIN_BIN)/$(HOST)eabi$(ANDROID_API_LEVEL)-clang -else -android_CXX=$(ANDROID_TOOLCHAIN_BIN)/$(HOST)$(ANDROID_API_LEVEL)-clang++ -android_CC=$(ANDROID_TOOLCHAIN_BIN)/$(HOST)$(ANDROID_API_LEVEL)-clang -endif - -android_CFLAGS=-std=$(C_STANDARD) -android_CXXFLAGS=-std=$(CXX_STANDARD) - -android_AR=$(ANDROID_TOOLCHAIN_BIN)/llvm-ar -android_RANLIB=$(ANDROID_TOOLCHAIN_BIN)/llvm-ranlib - -android_cmake_system=Android diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk index 639259ace3..564381d1e9 100644 --- a/depends/hosts/darwin.mk +++ b/depends/hosts/darwin.mk @@ -2,29 +2,10 @@ OSX_MIN_VERSION=11.0 OSX_SDK_VERSION=14.0 XCODE_VERSION=15.0 XCODE_BUILD_ID=15A240d -LD64_VERSION=711 +LLD_VERSION=711 OSX_SDK=$(SDK_PATH)/Xcode-$(XCODE_VERSION)-$(XCODE_BUILD_ID)-extracted-SDK-with-libcxx-headers -darwin_native_binutils=native_cctools - -ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) -# FORCE_USE_SYSTEM_CLANG is empty, so we use our depends-managed, pinned clang -# from llvm.org - -# Clang is a dependency of native_cctools when FORCE_USE_SYSTEM_CLANG is empty -darwin_native_toolchain=native_cctools - -clang_prog=$(build_prefix)/bin/clang -clangxx_prog=$(clang_prog)++ -llvm_config_prog=$(build_prefix)/bin/llvm-config - -else -# FORCE_USE_SYSTEM_CLANG is non-empty, so we use the clang from the user's -# system - -darwin_native_toolchain= - # We can't just use $(shell command -v clang) because GNU Make handles builtins # in a special way and doesn't know that `command` is a POSIX-standard builtin # prior to 1af314465e5dfe3e8baa839a32a72e83c04f26ef, first released in v4.2.90. @@ -34,20 +15,13 @@ darwin_native_toolchain= # Source: https://lists.gnu.org/archive/html/bug-make/2017-11/msg00017.html clang_prog=$(shell $(SHELL) $(.SHELLFLAGS) "command -v clang") clangxx_prog=$(shell $(SHELL) $(.SHELLFLAGS) "command -v clang++") -llvm_config_prog=$(shell $(SHELL) $(.SHELLFLAGS) "command -v llvm-config") - -llvm_lib_dir=$(shell $(llvm_config_prog) --libdir) -endif - -cctools_TOOLS=AR RANLIB STRIP NM OTOOL DSYMUTIL -# Make-only lowercase function -lc = $(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(subst G,g,$(subst H,h,$(subst I,i,$(subst J,j,$(subst K,k,$(subst L,l,$(subst M,m,$(subst N,n,$(subst O,o,$(subst P,p,$(subst Q,q,$(subst R,r,$(subst S,s,$(subst T,t,$(subst U,u,$(subst V,v,$(subst W,w,$(subst X,x,$(subst Y,y,$(subst Z,z,$1)))))))))))))))))))))))))) - -# For well-known tools provided by cctools, make sure that their well-known -# variable is set to the full path of the tool, just like how AC_PATH_{TOO,PROG} -# would. -$(foreach TOOL,$(cctools_TOOLS),$(eval darwin_$(TOOL) = $$(build_prefix)/bin/$$(host)-$(call lc,$(TOOL)))) +darwin_AR=$(shell $(SHELL) $(.SHELLFLAGS) "command -v llvm-ar") +darwin_DSYMUTIL=$(shell $(SHELL) $(.SHELLFLAGS) "command -v dsymutil") +darwin_NM=$(shell $(SHELL) $(.SHELLFLAGS) "command -v llvm-nm") +darwin_OBJDUMP=$(shell $(SHELL) $(.SHELLFLAGS) "command -v llvm-objdump") +darwin_RANLIB=$(shell $(SHELL) $(.SHELLFLAGS) "command -v llvm-ranlib") +darwin_STRIP=$(shell $(SHELL) $(.SHELLFLAGS) "command -v llvm-strip") # Flag explanations: # @@ -56,11 +30,6 @@ $(foreach TOOL,$(cctools_TOOLS),$(eval darwin_$(TOOL) = $$(build_prefix)/bin/$$( # Ensures that modern linker features are enabled. See here for more # details: https://github.com/bitcoin/bitcoin/pull/19407. # -# -B$(build_prefix)/bin -# -# Explicitly point to our binaries (e.g. cctools) so that they are -# ensured to be found and preferred over other possibilities. -# # -isysroot$(OSX_SDK) -nostdlibinc # # Disable default include paths built into the compiler as well as @@ -75,12 +44,16 @@ $(foreach TOOL,$(cctools_TOOLS),$(eval darwin_$(TOOL) = $$(build_prefix)/bin/$$( # # Indicate to the linker the platform, the oldest supported version, # and the SDK used. +# +# -no_adhoc_codesign +# +# Disable adhoc codesigning (for now) when using LLVM tooling, to avoid +# non-determinism issues with the Identifier field. darwin_CC=env -u C_INCLUDE_PATH -u CPLUS_INCLUDE_PATH \ -u OBJC_INCLUDE_PATH -u OBJCPLUS_INCLUDE_PATH -u CPATH \ -u LIBRARY_PATH \ $(clang_prog) --target=$(host) \ - -B$(build_prefix)/bin \ -isysroot$(OSX_SDK) -nostdlibinc \ -iwithsysroot/usr/include -iframeworkwithsysroot/System/Library/Frameworks @@ -88,18 +61,18 @@ darwin_CXX=env -u C_INCLUDE_PATH -u CPLUS_INCLUDE_PATH \ -u OBJC_INCLUDE_PATH -u OBJCPLUS_INCLUDE_PATH -u CPATH \ -u LIBRARY_PATH \ $(clangxx_prog) --target=$(host) \ - -B$(build_prefix)/bin \ -isysroot$(OSX_SDK) -nostdlibinc \ -iwithsysroot/usr/include/c++/v1 \ -iwithsysroot/usr/include -iframeworkwithsysroot/System/Library/Frameworks -darwin_CFLAGS=-pipe -std=$(C_STANDARD) -mmacosx-version-min=$(OSX_MIN_VERSION) -darwin_CXXFLAGS=-pipe -std=$(CXX_STANDARD) -mmacosx-version-min=$(OSX_MIN_VERSION) +darwin_CFLAGS=-pipe -std=$(C_STANDARD) -mmacos-version-min=$(OSX_MIN_VERSION) +darwin_CXXFLAGS=-pipe -std=$(CXX_STANDARD) -mmacos-version-min=$(OSX_MIN_VERSION) darwin_LDFLAGS=-Wl,-platform_version,macos,$(OSX_MIN_VERSION),$(OSX_SDK_VERSION) ifneq ($(build_os),darwin) -darwin_CFLAGS += -mlinker-version=$(LD64_VERSION) -darwin_CXXFLAGS += -mlinker-version=$(LD64_VERSION) +darwin_CFLAGS += -mlinker-version=$(LLD_VERSION) +darwin_CXXFLAGS += -mlinker-version=$(LLD_VERSION) +darwin_LDFLAGS += -Wl,-no_adhoc_codesign -fuse-ld=lld endif darwin_release_CFLAGS=-O2 diff --git a/depends/hosts/default.mk b/depends/hosts/default.mk index 6a6cab6cc6..d82c33f29c 100644 --- a/depends/hosts/default.mk +++ b/depends/hosts/default.mk @@ -38,5 +38,5 @@ host_$1 = $$($(host_arch)_$(host_os)_$1) host_$(release_type)_$1 = $$($(host_arch)_$(host_os)_$(release_type)_$1) endef -$(foreach tool,CC CXX AR RANLIB STRIP NM OBJCOPY OTOOL DSYMUTIL,$(eval $(call add_host_tool_func,$(tool)))) +$(foreach tool,CC CXX AR RANLIB STRIP NM OBJCOPY OBJDUMP DSYMUTIL,$(eval $(call add_host_tool_func,$(tool)))) $(foreach flags,CFLAGS CXXFLAGS CPPFLAGS LDFLAGS, $(eval $(call add_host_flags_func,$(flags)))) diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk index 7f0389b30d..938e9971ba 100644 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -1,6 +1,6 @@ package=boost $(package)_version=1.81.0 -$(package)_download_path=https://boostorg.jfrog.io/artifactory/main/release/$($(package)_version)/source/ +$(package)_download_path=https://archives.boost.io/release/$($(package)_version)/source/ $(package)_file_name=boost_$(subst .,_,$($(package)_version)).tar.gz $(package)_sha256_hash=205666dea9f6a7cfed87c7a6dfbeb52a2c1b9de55712c9c1a87735d7181452b6 diff --git a/depends/packages/miniupnpc.mk b/depends/packages/miniupnpc.mk index 077e3bb1ee..341031b5f8 100644 --- a/depends/packages/miniupnpc.mk +++ b/depends/packages/miniupnpc.mk @@ -1,6 +1,6 @@ package=miniupnpc $(package)_version=2.2.7 -$(package)_download_path=https://miniupnp.tuxfamily.org/files/ +$(package)_download_path=http://miniupnp.free.fr/files/ $(package)_file_name=$(package)-$($(package)_version).tar.gz $(package)_sha256_hash=b0c3a27056840fd0ec9328a5a9bac3dc5e0ec6d2e8733349cf577b0aa1e70ac1 $(package)_patches=dont_leak_info.patch cmake_get_src_addr.patch fix_windows_snprintf.patch diff --git a/depends/packages/native_cctools.mk b/depends/packages/native_cctools.mk deleted file mode 100644 index 3148e51048..0000000000 --- a/depends/packages/native_cctools.mk +++ /dev/null @@ -1,39 +0,0 @@ -package=native_cctools -$(package)_version=c74fafe86076713cb8e6f937af43b6df6da1f42d -$(package)_download_path=https://github.com/tpoechtrager/cctools-port/archive -$(package)_file_name=$($(package)_version).tar.gz -$(package)_sha256_hash=e2c1588d505a69c32e079f4e616e0f117d5478429040e394f624f43f2796e6bc -$(package)_build_subdir=cctools -$(package)_dependencies=native_libtapi - -define $(package)_set_vars - $(package)_config_opts=--target=$(host) --enable-lto-support - $(package)_config_opts+=--with-llvm-config=$(llvm_config_prog) - $(package)_ldflags+=-Wl,-rpath=\\$$$$$$$$\$$$$$$$$ORIGIN/../lib - $(package)_cc=$(clang_prog) - $(package)_cxx=$(clangxx_prog) -endef - -ifneq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) -define $(package)_preprocess_cmds - mkdir -p $($(package)_staging_prefix_dir)/lib && \ - cp $(llvm_lib_dir)/libLTO.so $($(package)_staging_prefix_dir)/lib/ -endef -else -endif - -define $(package)_config_cmds - $($(package)_autoconf) -endef - -define $(package)_build_cmds - $(MAKE) -endef - -define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) install -endef - -define $(package)_postprocess_cmds - rm -rf share -endef diff --git a/depends/packages/native_libtapi.mk b/depends/packages/native_libtapi.mk deleted file mode 100644 index fb5ab0b4dc..0000000000 --- a/depends/packages/native_libtapi.mk +++ /dev/null @@ -1,22 +0,0 @@ -package=native_libtapi -$(package)_version=eb33a59f2e30ff9724dc1ea8bee8b5229b0557c9 -$(package)_download_path=https://github.com/tpoechtrager/apple-libtapi/archive -$(package)_file_name=$($(package)_version).tar.gz -$(package)_sha256_hash=d4d46c64622f13d6938cecf989046d9561011bb59e8ee835f8f39825d67f578f -$(package)_patches=disable_zlib.patch - -ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) -$(package)_dependencies=native_llvm -endif - -define $(package)_preprocess_cmds - patch -p1 < $($(package)_patch_dir)/disable_zlib.patch -endef - -define $(package)_build_cmds - CC=$(clang_prog) CXX=$(clangxx_prog) INSTALLPREFIX=$($(package)_staging_prefix_dir) ./build.sh -endef - -define $(package)_stage_cmds - ./install.sh -endef diff --git a/depends/packages/native_llvm.mk b/depends/packages/native_llvm.mk deleted file mode 100644 index 09994eb012..0000000000 --- a/depends/packages/native_llvm.mk +++ /dev/null @@ -1,25 +0,0 @@ -package=native_llvm -$(package)_version=17.0.6 -$(package)_major_version=$(firstword $(subst ., ,$($(package)_version))) -$(package)_download_path=https://github.com/llvm/llvm-project/releases/download/llvmorg-$($(package)_version) -ifneq (,$(findstring aarch64,$(BUILD))) -$(package)_file_name=clang+llvm-$($(package)_version)-aarch64-linux-gnu.tar.xz -$(package)_sha256_hash=6dd62762285326f223f40b8e4f2864b5c372de3f7de0731cb7cd55ca5287b75a -else -$(package)_file_name=clang+llvm-$($(package)_version)-x86_64-linux-gnu-ubuntu-22.04.tar.xz -$(package)_sha256_hash=884ee67d647d77e58740c1e645649e29ae9e8a6fe87c1376be0f3a30f3cc9ab3 -endif - -define $(package)_stage_cmds - mkdir -p $($(package)_staging_prefix_dir)/lib/clang/$($(package)_major_version)/include && \ - mkdir -p $($(package)_staging_prefix_dir)/bin && \ - mkdir -p $($(package)_staging_prefix_dir)/include/llvm-c && \ - cp bin/clang $($(package)_staging_prefix_dir)/bin/ && \ - cp -P bin/clang++ $($(package)_staging_prefix_dir)/bin/ && \ - cp bin/dsymutil $($(package)_staging_prefix_dir)/bin/$(host)-dsymutil && \ - cp bin/llvm-config $($(package)_staging_prefix_dir)/bin/ && \ - cp include/llvm-c/ExternC.h $($(package)_staging_prefix_dir)/include/llvm-c && \ - cp include/llvm-c/lto.h $($(package)_staging_prefix_dir)/include/llvm-c && \ - cp lib/libLTO.so $($(package)_staging_prefix_dir)/lib/ && \ - cp -r lib/clang/$($(package)_major_version)/include/* $($(package)_staging_prefix_dir)/lib/clang/$($(package)_major_version)/include/ -endef diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index fb52fd4499..01ed0d7a92 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -5,12 +5,10 @@ boost_packages = boost libevent_packages = libevent qrencode_linux_packages = qrencode -qrencode_android_packages = qrencode qrencode_darwin_packages = qrencode qrencode_mingw32_packages = qrencode qt_linux_packages:=qt expat libxcb xcb_proto libXau xproto freetype fontconfig libxkbcommon libxcb_util libxcb_util_render libxcb_util_keysyms libxcb_util_image libxcb_util_wm -qt_android_packages=qt qt_darwin_packages=qt qt_mingw32_packages=qt @@ -26,14 +24,3 @@ multiprocess_packages = libmultiprocess capnp multiprocess_native_packages = native_libmultiprocess native_capnp usdt_linux_packages=systemtap - -darwin_native_packages = - -ifneq ($(build_os),darwin) -darwin_native_packages += native_cctools native_libtapi - -ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) -darwin_native_packages+= native_llvm -endif - -endif diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index d057b2d410..d35139dd2d 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -1,9 +1,9 @@ package=qt -$(package)_version=5.15.13 +$(package)_version=5.15.14 $(package)_download_path=https://download.qt.io/official_releases/qt/5.15/$($(package)_version)/submodules $(package)_suffix=everywhere-opensource-src-$($(package)_version).tar.xz $(package)_file_name=qtbase-$($(package)_suffix) -$(package)_sha256_hash=4cca51dcc1f22ceeee6b3e33cd1c3a60b14e85e24644dca3af89a2c2989ab809 +$(package)_sha256_hash=500d3b390048e9538c28b5f523dfea6936f9c2e10d24ab46580ff57d430b98be $(package)_linux_dependencies=freetype fontconfig libxcb libxkbcommon libxcb_util libxcb_util_render libxcb_util_keysyms libxcb_util_image libxcb_util_wm $(package)_qt_libs=corelib network widgets gui plugins testlib $(package)_linguist_tools = lrelease lupdate lconvert @@ -12,23 +12,24 @@ $(package)_patches += qttools_src.pro $(package)_patches += mac-qmake.conf $(package)_patches += fix_qt_pkgconfig.patch $(package)_patches += no-xlib.patch -$(package)_patches += fix_android_jni_static.patch $(package)_patches += dont_hardcode_pwd.patch $(package)_patches += qtbase-moc-ignore-gcc-macro.patch +$(package)_patches += no_warnings_for_symbols.patch $(package)_patches += rcc_hardcode_timestamp.patch $(package)_patches += duplicate_lcqpafonts.patch $(package)_patches += guix_cross_lib_path.patch $(package)_patches += fix-macos-linker.patch $(package)_patches += memory_resource.patch +$(package)_patches += clang_18_libpng.patch $(package)_patches += utc_from_string_no_optimize.patch $(package)_patches += windows_lto.patch $(package)_patches += zlib-timebits64.patch $(package)_qttranslations_file_name=qttranslations-$($(package)_suffix) -$(package)_qttranslations_sha256_hash=24d4c58bc2a40c0f44f59ee64af4192c7d0038c1e45af61646cfc5b65058f271 +$(package)_qttranslations_sha256_hash=5b94d1a11b566908622fcca2f8b799744d2f8a68da20be4caa5953ed63b10489 $(package)_qttools_file_name=qttools-$($(package)_suffix) -$(package)_qttools_sha256_hash=57c9794c572c4e02871f2e7581525752b0cf85ea16cfab23a4ac9ba7b39a5d34 +$(package)_qttools_sha256_hash=12061a85baf5f4de8fbc795e1d3872b706f340211b9e70962caeffc6f5e89563 $(package)_extra_sources = $($(package)_qttranslations_file_name) $(package)_extra_sources += $($(package)_qttools_file_name) @@ -138,7 +139,7 @@ ifneq ($(build_os),darwin) $(package)_config_opts_darwin += -xplatform macx-clang-linux $(package)_config_opts_darwin += -device-option MAC_SDK_PATH=$(OSX_SDK) $(package)_config_opts_darwin += -device-option MAC_SDK_VERSION=$(OSX_SDK_VERSION) -$(package)_config_opts_darwin += -device-option CROSS_COMPILE="$(host)-" +$(package)_config_opts_darwin += -device-option CROSS_COMPILE="llvm-" $(package)_config_opts_darwin += -device-option MAC_TARGET=$(host) $(package)_config_opts_darwin += -device-option XCODE_VERSION=$(XCODE_VERSION) endif @@ -185,24 +186,6 @@ $(package)_config_opts_mingw32 += -pch ifneq ($(LTO),) $(package)_config_opts_mingw32 += -ltcg endif - -$(package)_config_opts_android = -xplatform android-clang -$(package)_config_opts_android += -android-sdk $(ANDROID_SDK) -$(package)_config_opts_android += -android-ndk $(ANDROID_NDK) -$(package)_config_opts_android += -android-ndk-platform android-$(ANDROID_API_LEVEL) -$(package)_config_opts_android += -egl -$(package)_config_opts_android += -no-dbus -$(package)_config_opts_android += -opengl es2 -$(package)_config_opts_android += -qt-freetype -$(package)_config_opts_android += -no-fontconfig -$(package)_config_opts_android += -L $(host_prefix)/lib -$(package)_config_opts_android += -I $(host_prefix)/include -$(package)_config_opts_android += -pch -$(package)_config_opts_android += -no-feature-vulkan - -$(package)_config_opts_aarch64_android += -android-arch arm64-v8a -$(package)_config_opts_armv7a_android += -android-arch armeabi-v7a -$(package)_config_opts_x86_64_android += -android-arch x86_64 endef define $(package)_fetch_cmds @@ -243,10 +226,11 @@ define $(package)_preprocess_cmds patch -p1 -i $($(package)_patch_dir)/fix-macos-linker.patch && \ patch -p1 -i $($(package)_patch_dir)/dont_hardcode_pwd.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_qt_pkgconfig.patch && \ - patch -p1 -i $($(package)_patch_dir)/fix_android_jni_static.patch && \ patch -p1 -i $($(package)_patch_dir)/no-xlib.patch && \ patch -p1 -i $($(package)_patch_dir)/qtbase-moc-ignore-gcc-macro.patch && \ patch -p1 -i $($(package)_patch_dir)/memory_resource.patch && \ + patch -p1 -i $($(package)_patch_dir)/no_warnings_for_symbols.patch && \ + patch -p1 -i $($(package)_patch_dir)/clang_18_libpng.patch && \ patch -p1 -i $($(package)_patch_dir)/rcc_hardcode_timestamp.patch && \ patch -p1 -i $($(package)_patch_dir)/duplicate_lcqpafonts.patch && \ patch -p1 -i $($(package)_patch_dir)/utc_from_string_no_optimize.patch && \ diff --git a/depends/patches/native_libtapi/disable_zlib.patch b/depends/patches/native_libtapi/disable_zlib.patch deleted file mode 100644 index 6c7691214a..0000000000 --- a/depends/patches/native_libtapi/disable_zlib.patch +++ /dev/null @@ -1,17 +0,0 @@ -build: disable zlib - -This isn't needed, and causes issues when clang-tblgen -is built, but trys to reach for a system libz.so. - -diff --git a/build.sh b/build.sh -index e25d2f732..ec8422621 100755 ---- a/build.sh -+++ b/build.sh -@@ -66,6 +66,7 @@ cmake ../src/llvm \ - -DCMAKE_INSTALL_PREFIX=$INSTALLPREFIX \ - -DTAPI_REPOSITORY_STRING=$TAPI_VERSION \ - -DTAPI_FULL_VERSION=$TAPI_VERSION \ -+ -DLLVM_ENABLE_ZLIB=OFF \ - $CMAKE_EXTRA_ARGS - - echo "" diff --git a/depends/patches/qt/clang_18_libpng.patch b/depends/patches/qt/clang_18_libpng.patch new file mode 100644 index 0000000000..e807905b32 --- /dev/null +++ b/depends/patches/qt/clang_18_libpng.patch @@ -0,0 +1,40 @@ +fix Qt macOS build with Clang 18 + + See: + https://github.com/pnggroup/libpng/commit/893b8113f04d408cc6177c6de19c9889a48faa24. + + In a similar manner as zlib (madler/zlib#895), + libpng contains a header configuration that's no longer valid and + hasn't been exercised for the macOS target. + + - The target OS conditional macros are misused. Specifically + `TARGET_OS_MAC` covers all Apple targets, including iOS, and it + should not be checked with `#if defined` as they would always be + defined (to either 1 or 0) on Apple platforms. + - `#include <fp.h>` no longer works for the macOS target and results + in a compilation failure. macOS ships all required functions in + `math.h`, and clients should use `math.h` instead. + +--- a/qtbase/src/3rdparty/libpng/pngpriv.h ++++ b/qtbase/src/3rdparty/libpng/pngpriv.h +@@ -514,18 +514,8 @@ + */ + # include <float.h> + +-# if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \ +- defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC) +- /* We need to check that <math.h> hasn't already been included earlier +- * as it seems it doesn't agree with <fp.h>, yet we should really use +- * <fp.h> if possible. +- */ +-# if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__) +-# include <fp.h> +-# endif +-# else +-# include <math.h> +-# endif ++# include <math.h> ++ + # if defined(_AMIGA) && defined(__SASC) && defined(_M68881) + /* Amiga SAS/C: We must include builtin FPU functions when compiling using + * MATH=68881 diff --git a/depends/patches/qt/fix_android_jni_static.patch b/depends/patches/qt/fix_android_jni_static.patch deleted file mode 100644 index 79824f244a..0000000000 --- a/depends/patches/qt/fix_android_jni_static.patch +++ /dev/null @@ -1,17 +0,0 @@ ---- old/qtbase/src/plugins/platforms/android/androidjnimain.cpp -+++ new/qtbase/src/plugins/platforms/android/androidjnimain.cpp -@@ -979,6 +979,14 @@ Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void */*reserved*/) - __android_log_print(ANDROID_LOG_FATAL, "Qt", "registerNatives failed"); - return -1; - } -+ -+ const jint ret = QT_PREPEND_NAMESPACE(QtAndroidPrivate::initJNI(vm, env)); -+ if (ret != 0) -+ { -+ __android_log_print(ANDROID_LOG_FATAL, "Qt", "initJNI failed"); -+ return ret; -+ } -+ - QWindowSystemInterfacePrivate::TabletEvent::setPlatformSynthesizesMouse(false); - - m_javaVM = vm; diff --git a/depends/patches/qt/mac-qmake.conf b/depends/patches/qt/mac-qmake.conf index cb94bf07b4..a29db20004 100644 --- a/depends/patches/qt/mac-qmake.conf +++ b/depends/patches/qt/mac-qmake.conf @@ -13,6 +13,7 @@ QMAKE_MAC_SDK.macosx.Path = $${MAC_SDK_PATH} QMAKE_MAC_SDK.macosx.platform_name = macosx QMAKE_MAC_SDK.macosx.SDKVersion = $${MAC_SDK_VERSION} QMAKE_MAC_SDK.macosx.PlatformPath = /phony +QMAKE_CXXFLAGS += -fuse-ld=lld !host_build: QMAKE_CFLAGS += -target $${MAC_TARGET} !host_build: QMAKE_OBJECTIVE_CFLAGS += $$QMAKE_CFLAGS !host_build: QMAKE_CXXFLAGS += -target $${MAC_TARGET} diff --git a/depends/patches/qt/no_warnings_for_symbols.patch b/depends/patches/qt/no_warnings_for_symbols.patch new file mode 100644 index 0000000000..11cdc599ed --- /dev/null +++ b/depends/patches/qt/no_warnings_for_symbols.patch @@ -0,0 +1,11 @@ +--- a/qtbase/mkspecs/features/mac/no_warn_empty_obj_files.prf ++++ b/qtbase/mkspecs/features/mac/no_warn_empty_obj_files.prf +@@ -1,7 +1,7 @@ + # Prevent warnings about object files without any symbols. This is a common + # thing in Qt as we tend to build files unconditionally, and then use ifdefs + # to compile out parts that are not relevant. +-QMAKE_RANLIB += -no_warning_for_no_symbols ++# QMAKE_RANLIB += -no_warning_for_no_symbols + + # We have to tell 'ar' to not run ranlib by itself + QMAKE_AR += -S diff --git a/doc/JSON-RPC-interface.md b/doc/JSON-RPC-interface.md index ec332d23eb..10d8ee52eb 100644 --- a/doc/JSON-RPC-interface.md +++ b/doc/JSON-RPC-interface.md @@ -33,10 +33,10 @@ requests when multiple wallets are in use. ```sh # Get block count from the / endpoint when rpcuser=alice and rpcport=38332 -$ curl --user alice --data-binary '{"jsonrpc": "1.0", "id": "0", "method": "getblockcount", "params": []}' -H 'content-type: text/plain;' localhost:38332/ +$ curl --user alice --data-binary '{"jsonrpc": "2.0", "id": "0", "method": "getblockcount", "params": []}' -H 'content-type: application/json' localhost:38332/ # Get balance from the /wallet/walletname endpoint when rpcuser=alice, rpcport=38332 and rpcwallet=desc-wallet -$ curl --user alice --data-binary '{"jsonrpc": "1.0", "id": "0", "method": "getbalance", "params": []}' -H 'content-type: text/plain;' localhost:38332/wallet/desc-wallet +$ curl --user alice --data-binary '{"jsonrpc": "2.0", "id": "0", "method": "getbalance", "params": []}' -H 'content-type: application/json' localhost:38332/wallet/desc-wallet ``` @@ -74,6 +74,22 @@ major version via the `-deprecatedrpc=` command line option. The release notes of a new major release come with detailed instructions on what RPC features were deprecated and how to re-enable them temporarily. +## JSON-RPC 1.1 vs 2.0 + +The server recognizes [JSON-RPC v2.0](https://www.jsonrpc.org/specification) requests +and responds accordingly. A 2.0 request is identified by the presence of +`"jsonrpc": "2.0"` in the request body. If that key + value is not present in a request, +the legacy JSON-RPC v1.1 protocol is followed instead, which was the only available +protocol in v27.0 and prior releases. + +|| 1.1 | 2.0 | +|-|-|-| +| Request marker | `"version": "1.1"` (or none) | `"jsonrpc": "2.0"` | +| Response marker | (none) | `"jsonrpc": "2.0"` | +| `"error"` and `"result"` fields in response | both present | only one is present | +| HTTP codes in response | `200` unless there is any kind of RPC error (invalid parameters, method not found, etc) | Always `200` unless there is an actual HTTP server error (request parsing error, endpoint not found, etc) | +| Notifications: requests that get no reply | (not supported) | Supported for requests that exclude the "id" field. Returns HTTP status `204` "No Content" | + ## Security The RPC interface allows other programs to control Bitcoin Core, diff --git a/doc/README.md b/doc/README.md index 7b6dacaf4f..74a85b04e6 100644 --- a/doc/README.md +++ b/doc/README.md @@ -45,7 +45,6 @@ The following are developer notes on how to build Bitcoin Core on your native pl - [FreeBSD Build Notes](build-freebsd.md) - [OpenBSD Build Notes](build-openbsd.md) - [NetBSD Build Notes](build-netbsd.md) -- [Android Build Notes](build-android.md) Development --------------------- diff --git a/doc/bips.md b/doc/bips.md index 8309ee7e92..19a8091f55 100644 --- a/doc/bips.md +++ b/doc/bips.md @@ -69,3 +69,4 @@ BIPs that are implemented by Bitcoin Core: [`385`](https://github.com/bitcoin/bips/blob/master/bip-0385.mediawiki): Output Script Descriptors, and most of Script Expressions are implemented as of **v0.17.0** ([PR 13697](https://github.com/bitcoin/bitcoin/pull/13697)). * [`BIP 386`](https://github.com/bitcoin/bips/blob/master/bip-0386.mediawiki): tr() Output Script Descriptors are implemented as of **v22.0** ([PR 22051](https://github.com/bitcoin/bitcoin/pull/22051)). +* [`BIP 431`](https://github.com/bitcoin/bips/blob/master/bip-0431.mediawiki): transactions with nVersion=3 are standard and treated as Topologically Restricted Until Confirmation as of **v28.0** ([PR 29496](https://github.com/bitcoin/bitcoin/pull/29496)). diff --git a/doc/bitcoin-conf.md b/doc/bitcoin-conf.md index 1ebfb4c1de..76711d0e7d 100644 --- a/doc/bitcoin-conf.md +++ b/doc/bitcoin-conf.md @@ -59,7 +59,7 @@ The `includeconf=<file>` option in the `bitcoin.conf` file can be used to includ Operating System | Data Directory | Example Path -- | -- | -- -Windows | `%APPDATA%\Bitcoin\` | `C:\Users\username\AppData\Roaming\Bitcoin\bitcoin.conf` +Windows | `%LOCALAPPDATA%\Bitcoin\` | `C:\Users\username\AppData\Local\Bitcoin\bitcoin.conf` Linux | `$HOME/.bitcoin/` | `/home/username/.bitcoin/bitcoin.conf` macOS | `$HOME/Library/Application Support/Bitcoin/` | `/Users/username/Library/Application Support/Bitcoin/bitcoin.conf` diff --git a/doc/build-android.md b/doc/build-android.md deleted file mode 100644 index 2f2e01c441..0000000000 --- a/doc/build-android.md +++ /dev/null @@ -1,25 +0,0 @@ -ANDROID BUILD NOTES -====================== - -This guide describes how to build and package the `bitcoin-qt` GUI for Android on Linux and macOS. - - -## Dependencies - -Before proceeding with an Android build one needs to get the [Android SDK](https://developer.android.com/studio) and use the "SDK Manager" tool to download the NDK and one or more "Platform packages" (these are Android versions and have a corresponding API level). - -The minimum supported Android NDK version is [r23](https://github.com/android/ndk/wiki/Changelog-r23). - -In order to build `ANDROID_API_LEVEL` (API level corresponding to the Android version targeted, e.g. Android 9.0 Pie is 28 and its "Platform package" needs to be available) and `ANDROID_TOOLCHAIN_BIN` (path to toolchain binaries depending on the platform the build is being performed on) need to be set. - -API levels from 24 to 29 have been tested to work. - -If the build includes Qt, environment variables `ANDROID_SDK` and `ANDROID_NDK` need to be set as well but can otherwise be omitted. -This is an example command for a default build with no disabled dependencies: - - ANDROID_SDK=/home/user/Android/Sdk ANDROID_NDK=/home/user/Android/Sdk/ndk-bundle make HOST=aarch64-linux-android ANDROID_API_LEVEL=28 ANDROID_TOOLCHAIN_BIN=/home/user/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin - - -## Building and packaging - -After the depends are built configure with one of the resulting prefixes and run `make && make apk` in `src/qt`.
\ No newline at end of file diff --git a/doc/build-netbsd.md b/doc/build-netbsd.md index 0f05cdcba7..5f54fd6d9a 100644 --- a/doc/build-netbsd.md +++ b/doc/build-netbsd.md @@ -1,6 +1,6 @@ # NetBSD Build Guide -Updated for NetBSD [9.2](https://netbsd.org/releases/formal-9/NetBSD-9.2.html). +**Updated for NetBSD [10.0](https://netbsd.org/releases/formal-10/NetBSD-10.0.html)** This guide describes how to build bitcoind, command-line utilities, and GUI on NetBSD. @@ -12,23 +12,23 @@ Install the required dependencies the usual way you [install software on NetBSD] The example commands below use `pkgin`. ```bash -pkgin install autoconf automake libtool pkg-config git gmake boost libevent +pkgin install autoconf automake libtool pkg-config git gmake boost-headers libevent ``` NetBSD currently ships with an older version of `gcc` than is needed to build. You should upgrade your `gcc` and then pass this new version to the configure script. -For example, grab `gcc9`: +For example, grab `gcc12`: ``` -pkgin install gcc9 +pkgin install gcc12 ``` Then, when configuring, pass the following: ```bash ./configure ... - CC="/usr/pkg/gcc9/bin/gcc" \ - CXX="/usr/pkg/gcc9/bin/g++" \ + CC="/usr/pkg/gcc12/bin/gcc" \ + CXX="/usr/pkg/gcc12/bin/g++" \ ... ``` @@ -66,10 +66,10 @@ pkgin install db4 #### GUI Dependencies -Bitcoin Core includes a GUI built with the cross-platform Qt Framework. To compile the GUI, we need to install `qt5`. +Bitcoin Core includes a GUI built with the cross-platform Qt Framework. To compile the GUI, Qt 5 is required. ```bash -pkgin install qt5 +pkgin install qt5-qtbase qt5-qttools ``` The GUI can encode addresses in a QR Code. To build in QR support for the GUI, install `qrencode`. @@ -84,7 +84,7 @@ There is an included test suite that is useful for testing code changes when dev To run the test suite (recommended), you will need to have Python 3 installed: ```bash -pkgin install python37 +pkgin install python39 ``` ### Building Bitcoin Core diff --git a/doc/dependencies.md b/doc/dependencies.md index 2b9d9128d3..63c505c9cb 100644 --- a/doc/dependencies.md +++ b/doc/dependencies.md @@ -19,7 +19,7 @@ You can find installation instructions in the `build-*.md` file for your platfor | --- | --- | --- | --- | --- | | [Boost](../depends/packages/boost.mk) | [link](https://www.boost.org/users/download/) | [1.81.0](https://github.com/bitcoin/bitcoin/pull/26557) | [1.73.0](https://github.com/bitcoin/bitcoin/pull/29066) | No | | [libevent](../depends/packages/libevent.mk) | [link](https://github.com/libevent/libevent/releases) | [2.1.12-stable](https://github.com/bitcoin/bitcoin/pull/21991) | [2.1.8](https://github.com/bitcoin/bitcoin/pull/24681) | No | -| glibc | [link](https://www.gnu.org/software/libc/) | N/A | [2.27](https://github.com/bitcoin/bitcoin/pull/27029) | Yes | +| glibc | [link](https://www.gnu.org/software/libc/) | N/A | [2.31](https://github.com/bitcoin/bitcoin/pull/29987) | Yes | | Linux Kernel | [link](https://www.kernel.org/) | N/A | [3.17.0](https://github.com/bitcoin/bitcoin/pull/27699) | Yes | ## Optional @@ -30,7 +30,7 @@ You can find installation instructions in the `build-*.md` file for your platfor | [Fontconfig](../depends/packages/fontconfig.mk) | [link](https://www.freedesktop.org/wiki/Software/fontconfig/) | [2.12.6](https://github.com/bitcoin/bitcoin/pull/23495) | 2.6 | Yes | | [FreeType](../depends/packages/freetype.mk) | [link](https://freetype.org) | [2.11.0](https://github.com/bitcoin/bitcoin/commit/01544dd78ccc0b0474571da854e27adef97137fb) | 2.3.0 | Yes | | [qrencode](../depends/packages/qrencode.mk) | [link](https://fukuchi.org/works/qrencode/) | [4.1.1](https://github.com/bitcoin/bitcoin/pull/27312) | | No | -| [Qt](../depends/packages/qt.mk) | [link](https://download.qt.io/official_releases/qt/) | [5.15.13](https://github.com/bitcoin/bitcoin/pull/29732) | [5.11.3](https://github.com/bitcoin/bitcoin/pull/24132) | No | +| [Qt](../depends/packages/qt.mk) | [link](https://download.qt.io/official_releases/qt/) | [5.15.14](https://github.com/bitcoin/bitcoin/pull/30198) | [5.11.3](https://github.com/bitcoin/bitcoin/pull/24132) | No | ### Networking | Dependency | Releases | Version used | Minimum required | Runtime | diff --git a/doc/design/libraries.md b/doc/design/libraries.md index 3346c8e81b..aa8034ab37 100644 --- a/doc/design/libraries.md +++ b/doc/design/libraries.md @@ -5,6 +5,7 @@ | *libbitcoin_cli* | RPC client functionality used by *bitcoin-cli* executable | | *libbitcoin_common* | Home for common functionality shared by different executables and libraries. Similar to *libbitcoin_util*, but higher-level (see [Dependencies](#dependencies)). | | *libbitcoin_consensus* | Stable, backwards-compatible consensus functionality used by *libbitcoin_node* and *libbitcoin_wallet*. | +| *libbitcoin_crypto* | Hardware-optimized functions for data encryption, hashing, message authentication, and key derivation. | | *libbitcoin_kernel* | Consensus engine and support library used for validation by *libbitcoin_node*. | | *libbitcoinqt* | GUI functionality used by *bitcoin-qt* and *bitcoin-gui* executables. | | *libbitcoin_ipc* | IPC functionality used by *bitcoin-node*, *bitcoin-wallet*, *bitcoin-gui* executables to communicate when [`--enable-multiprocess`](multiprocess.md) is used. | @@ -53,13 +54,18 @@ bitcoin-wallet[bitcoin-wallet]-->libbitcoin_wallet_tool; libbitcoin_cli-->libbitcoin_util; libbitcoin_cli-->libbitcoin_common; +libbitcoin_consensus-->libbitcoin_crypto; + libbitcoin_common-->libbitcoin_consensus; +libbitcoin_common-->libbitcoin_crypto; libbitcoin_common-->libbitcoin_util; libbitcoin_kernel-->libbitcoin_consensus; +libbitcoin_kernel-->libbitcoin_crypto; libbitcoin_kernel-->libbitcoin_util; libbitcoin_node-->libbitcoin_consensus; +libbitcoin_node-->libbitcoin_crypto; libbitcoin_node-->libbitcoin_kernel; libbitcoin_node-->libbitcoin_common; libbitcoin_node-->libbitcoin_util; @@ -67,7 +73,10 @@ libbitcoin_node-->libbitcoin_util; libbitcoinqt-->libbitcoin_common; libbitcoinqt-->libbitcoin_util; +libbitcoin_util-->libbitcoin_crypto; + libbitcoin_wallet-->libbitcoin_common; +libbitcoin_wallet-->libbitcoin_crypto; libbitcoin_wallet-->libbitcoin_util; libbitcoin_wallet_tool-->libbitcoin_wallet; @@ -78,24 +87,25 @@ class bitcoin-qt,bitcoind,bitcoin-cli,bitcoin-wallet bold ``` </td></tr><tr><td> -**Dependency graph**. Arrows show linker symbol dependencies. *Consensus* lib depends on nothing. *Util* lib is depended on by everything. *Kernel* lib depends only on consensus and util. +**Dependency graph**. Arrows show linker symbol dependencies. *Crypto* lib depends on nothing. *Util* lib is depended on by everything. *Kernel* lib depends only on consensus, crypto, and util. </td></tr></table> - The graph shows what _linker symbols_ (functions and variables) from each library other libraries can call and reference directly, but it is not a call graph. For example, there is no arrow connecting *libbitcoin_wallet* and *libbitcoin_node* libraries, because these libraries are intended to be modular and not depend on each other's internal implementation details. But wallet code is still able to call node code indirectly through the `interfaces::Chain` abstract class in [`interfaces/chain.h`](../../src/interfaces/chain.h) and node code calls wallet code through the `interfaces::ChainClient` and `interfaces::Chain::Notifications` abstract classes in the same file. In general, defining abstract classes in [`src/interfaces/`](../../src/interfaces/) can be a convenient way of avoiding unwanted direct dependencies or circular dependencies between libraries. -- *libbitcoin_consensus* should be a standalone dependency that any library can depend on, and it should not depend on any other libraries itself. +- *libbitcoin_crypto* should be a standalone dependency that any library can depend on, and it should not depend on any other libraries itself. -- *libbitcoin_util* should also be a standalone dependency that any library can depend on, and it should not depend on other internal libraries. +- *libbitcoin_consensus* should only depend on *libbitcoin_crypto*, and all other libraries besides *libbitcoin_crypto* should be allowed to depend on it. -- *libbitcoin_common* should serve a similar function as *libbitcoin_util* and be a place for miscellaneous code used by various daemon, GUI, and CLI applications and libraries to live. It should not depend on anything other than *libbitcoin_util* and *libbitcoin_consensus*. The boundary between _util_ and _common_ is a little fuzzy but historically _util_ has been used for more generic, lower-level things like parsing hex, and _common_ has been used for bitcoin-specific, higher-level things like parsing base58. The difference between util and common is mostly important because *libbitcoin_kernel* is not supposed to depend on *libbitcoin_common*, only *libbitcoin_util*. In general, if it is ever unclear whether it is better to add code to *util* or *common*, it is probably better to add it to *common* unless it is very generically useful or useful particularly to include in the kernel. +- *libbitcoin_util* should be a standalone dependency that any library can depend on, and it should not depend on other libraries except *libbitcoin_crypto*. It provides basic utilities that fill in gaps in the C++ standard library and provide lightweight abstractions over platform-specific features. Since the util library is distributed with the kernel and is usable by kernel applications, it shouldn't contain functions that external code shouldn't call, like higher level code targetted at the node or wallet. (*libbitcoin_common* is a better place for higher level code, or code that is meant to be used by internal applications only.) +- *libbitcoin_common* is a home for miscellaneous shared code used by different Bitcoin Core applications. It should not depend on anything other than *libbitcoin_util*, *libbitcoin_consensus*, and *libbitcoin_crypto*. -- *libbitcoin_kernel* should only depend on *libbitcoin_util* and *libbitcoin_consensus*. +- *libbitcoin_kernel* should only depend on *libbitcoin_util*, *libbitcoin_consensus*, and *libbitcoin_crypto*. -- The only thing that should depend on *libbitcoin_kernel* internally should be *libbitcoin_node*. GUI and wallet libraries *libbitcoinqt* and *libbitcoin_wallet* in particular should not depend on *libbitcoin_kernel* and the unneeded functionality it would pull in, like block validation. To the extent that GUI and wallet code need scripting and signing functionality, they should be get able it from *libbitcoin_consensus*, *libbitcoin_common*, and *libbitcoin_util*, instead of *libbitcoin_kernel*. +- The only thing that should depend on *libbitcoin_kernel* internally should be *libbitcoin_node*. GUI and wallet libraries *libbitcoinqt* and *libbitcoin_wallet* in particular should not depend on *libbitcoin_kernel* and the unneeded functionality it would pull in, like block validation. To the extent that GUI and wallet code need scripting and signing functionality, they should be get able it from *libbitcoin_consensus*, *libbitcoin_common*, *libbitcoin_crypto*, and *libbitcoin_util*, instead of *libbitcoin_kernel*. -- GUI, node, and wallet code internal implementations should all be independent of each other, and the *libbitcoinqt*, *libbitcoin_node*, *libbitcoin_wallet* libraries should never reference each other's symbols. They should only call each other through [`src/interfaces/`](`../../src/interfaces/`) abstract interfaces. +- GUI, node, and wallet code internal implementations should all be independent of each other, and the *libbitcoinqt*, *libbitcoin_node*, *libbitcoin_wallet* libraries should never reference each other's symbols. They should only call each other through [`src/interfaces/`](../../src/interfaces/) abstract interfaces. ## Work in progress diff --git a/doc/design/multiprocess.md b/doc/design/multiprocess.md index 636d78d905..49410a4213 100644 --- a/doc/design/multiprocess.md +++ b/doc/design/multiprocess.md @@ -142,7 +142,7 @@ In the current design, class names, method names, and parameter names are duplic An alternate approach could use custom [C++ Attributes](https://en.cppreference.com/w/cpp/language/attributes) embedded in interface declarations to automatically generate `.capnp` files from C++ headers. This has not been pursued because parsing C++ headers is more complicated than parsing Cap’n Proto interface definitions, especially portably on multiple platforms. -In the meantime, the developer guide [Internal interface guidelines](developer-notes.md#internal-interface-guidelines) can provide guidance on keeping interfaces consistent and functional and avoiding compile errors. +In the meantime, the developer guide [Internal interface guidelines](../developer-notes.md#internal-interface-guidelines) can provide guidance on keeping interfaces consistent and functional and avoiding compile errors. ### Interface Stability diff --git a/doc/developer-notes.md b/doc/developer-notes.md index cc3f0518e5..d9d5b392c5 100644 --- a/doc/developer-notes.md +++ b/doc/developer-notes.md @@ -13,7 +13,6 @@ Developer Notes - [Development tips and tricks](#development-tips-and-tricks) - [Compiling for debugging](#compiling-for-debugging) - [Show sources in debugging](#show-sources-in-debugging) - - [Compiling for gprof profiling](#compiling-for-gprof-profiling) - [`debug.log`](#debuglog) - [Signet, testnet, and regtest modes](#signet-testnet-and-regtest-modes) - [DEBUG_LOCKORDER](#debug_lockorder) @@ -334,7 +333,7 @@ Recommendations: - Avoid linking to external documentation; links can break. - Javadoc and all valid Doxygen comments are stripped from Doxygen source code - previews (`STRIP_CODE_COMMENTS = YES` in [Doxyfile.in](doc/Doxyfile.in)). If + previews (`STRIP_CODE_COMMENTS = YES` in [Doxyfile.in](/doc/Doxyfile.in)). If you want a comment to be preserved, it must instead use `//` or `/* */`. ### Generating Documentation @@ -386,10 +385,6 @@ ln -s /path/to/project/root/src src 3. Use `debugedit` to modify debug information in the binary. -### Compiling for gprof profiling - -Run configure with the `--enable-gprof` option, then make. - ### `debug.log` If the code is behaving strangely, take a look in the `debug.log` file in the data directory; @@ -497,6 +492,10 @@ make cov # unit and functional tests. ``` +Additional LCOV options can be specified using `LCOV_OPTS`, but may be dependant +on the version of LCOV. For example, when using LCOV `2.x`, branch coverage can be +enabled by setting `LCOV_OPTS="--rc branch_coverage=1"`, when configuring. + ### Performance profiling with perf Profiling is a good way to get a precise idea of where time is being spent in @@ -1335,8 +1334,7 @@ Release notes should be written for any PR that: Release notes should be added to a PR-specific release note file at `/doc/release-notes-<PR number>.md` to avoid conflicts between multiple PRs. -All `release-notes*` files are merged into a single -[/doc/release-notes.md](/doc/release-notes.md) file prior to the release. +All `release-notes*` files are merged into a single `release-notes-<version>.md` file prior to the release. RPC interface guidelines -------------------------- @@ -1459,8 +1457,9 @@ independent (node, wallet, GUI), are defined in there are [`interfaces::Chain`](../src/interfaces/chain.h), used by wallet to access the node's latest chain state, [`interfaces::Node`](../src/interfaces/node.h), used by the GUI to control the -node, and [`interfaces::Wallet`](../src/interfaces/wallet.h), used by the GUI -to control an individual wallet. There are also more specialized interface +node, [`interfaces::Wallet`](../src/interfaces/wallet.h), used by the GUI +to control an individual wallet and [`interfaces::Mining`](../src/interfaces/mining.h), +used by RPC to generate block templates. There are also more specialized interface types like [`interfaces::Handler`](../src/interfaces/handler.h) [`interfaces::ChainClient`](../src/interfaces/chain.h) passed to and from various interface methods. diff --git a/doc/files.md b/doc/files.md index f88d3f91a1..03e52f02c9 100644 --- a/doc/files.md +++ b/doc/files.md @@ -28,7 +28,7 @@ Platform | Data directory path ---------|-------------------- Linux | `$HOME/.bitcoin/` macOS | `$HOME/Library/Application Support/Bitcoin/` -Windows | `%APPDATA%\Bitcoin\` <sup>[\[1\]](#note1)</sup> +Windows | `%LOCALAPPDATA%\Bitcoin\` <sup>[\[1\]](#note1)</sup> 2. A custom data directory path can be specified with the `-datadir` option. diff --git a/doc/init.md b/doc/init.md index d0b73593c0..b570fed22c 100644 --- a/doc/init.md +++ b/doc/init.md @@ -45,8 +45,8 @@ This allows for running bitcoind without having to do any manual configuration. `conf`, `pid`, and `wallet` accept relative paths which are interpreted as relative to the data directory. `wallet` *only* supports relative paths. -For an example configuration file that describes the configuration settings, -see `share/examples/bitcoin.conf`. +To generate an example configuration file that describes the configuration settings, +see [contrib/devtools/README.md](../contrib/devtools/README.md#gen-bitcoin-confsh). Paths --------------------------------- diff --git a/doc/managing-wallets.md b/doc/managing-wallets.md index b99d88877b..1cfd2e5123 100644 --- a/doc/managing-wallets.md +++ b/doc/managing-wallets.md @@ -20,7 +20,7 @@ By default, wallets are created in the `wallets` folder of the data directory, w | Operating System | Default wallet directory | | -----------------|:------------------------------------------------------------| | Linux | `/home/<user>/.bitcoin/wallets` | -| Windows | `C:\Users\<user>\AppData\Roaming\Bitcoin\wallets` | +| Windows | `C:\Users\<user>\AppData\Local\Bitcoin\wallets` | | macOS | `/Users/<user>/Library/Application Support/Bitcoin/wallets` | ### 1.2 Encrypting the Wallet diff --git a/doc/policy/mempool-replacements.md b/doc/policy/mempool-replacements.md index 3fd7ff2ad2..d5642eaccc 100644 --- a/doc/policy/mempool-replacements.md +++ b/doc/policy/mempool-replacements.md @@ -12,7 +12,7 @@ other consensus and policy rules, each of the following conditions are met: 1. The directly conflicting transactions all signal replaceability explicitly. A transaction is signaling BIP125 replaceability if any of its inputs have an nSequence number less than (0xffffffff - 1). - A transaction also signals replaceability if its nVersion field is set to 3. + A transaction also signals replaceability if its version field is set to 3. *Rationale*: See [BIP125 explanation](https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki#motivation). diff --git a/doc/policy/packages.md b/doc/policy/packages.md index dba270e494..a220bdd17f 100644 --- a/doc/policy/packages.md +++ b/doc/policy/packages.md @@ -36,10 +36,29 @@ The following rules are enforced for all packages: * Packages cannot have conflicting transactions, i.e. no two transactions in a package can spend the same inputs. Packages cannot have duplicate transactions. (#20833) -* No transaction in a package can conflict with a mempool transaction. Replace By Fee is - currently disabled for packages. (#20833) +* Only limited package replacements are currently considered. (#28984) - - Package RBF may be enabled in the future. + - All direct conflicts must signal replacement (or have `-mempoolfullrbf=1` set). + + - Packages are 1-parent-1-child, with no in-mempool ancestors of the package. + + - All conflicting clusters(connected components of mempool transactions) must be clusters of up to size 2. + + - No more than MAX_REPLACEMENT_CANDIDATES transactions can be replaced, analogous to + regular [replacement rule](./mempool-replacements.md) 5). + + - Replacements must pay more total total fees at the incremental relay fee (analogous to + regular [replacement rules](./mempool-replacements.md) 3 and 4). + + - Parent feerate must be lower than package feerate. + + - Must improve [feerate diagram](https://delvingbitcoin.org/t/mempool-incentive-compatibility/553). (#29242) + + - *Rationale*: Basic support for package RBF can be used by wallets + by making chains of no longer than two, then directly conflicting + those chains when needed. Combined with V3 transactions this can + result in more robust fee bumping. More general package RBF may be + enabled in the future. * When packages are evaluated against ancestor/descendant limits, the union of all transactions' descendants and ancestors is considered. (#21800) @@ -48,8 +67,13 @@ The following rules are enforced for all packages: heavily connected, i.e. some transaction in the package is the ancestor or descendant of all the other transactions. -The following rules are only enforced for packages to be submitted to the mempool (not enforced for -test accepts): +* [CPFP Carve Out](./mempool-limits.md#CPFP-Carve-Out) is disabled in packaged contexts. (#21800) + + - *Rationale*: This carve out cannot be accurately applied when there are multiple transactions' + ancestors and descendants being considered at the same time. + +The following rules are only enforced for packages to be submitted to the mempool (not +enforced for test accepts): * Packages must be child-with-unconfirmed-parents packages. This also means packages must contain at least 2 transactions. (#22674) diff --git a/doc/release-28984.md b/doc/release-28984.md new file mode 100644 index 0000000000..3da64f6578 --- /dev/null +++ b/doc/release-28984.md @@ -0,0 +1,6 @@ +P2P and network changes +----------------------- + +- Limited package RBF is now enabled, where the proposed conflicting package would result in + a connected component, aka cluster, of size 2 in the mempool. All clusters being conflicted + against must be of size 2 or lower. diff --git a/doc/release-notes-27101.md b/doc/release-notes-27101.md new file mode 100644 index 0000000000..7ce1e9a8c1 --- /dev/null +++ b/doc/release-notes-27101.md @@ -0,0 +1,6 @@ +JSON-RPC +-------- + +The JSON-RPC server now recognizes JSON-RPC 2.0 requests and responds with +strict adherence to the [specification](https://www.jsonrpc.org/specification). +See [JSON-RPC-interface.md](/doc/JSON-RPC-interface.md#json-rpc-11-vs-20) for details.
\ No newline at end of file diff --git a/doc/release-notes-29091-29165.md b/doc/release-notes-29091-29165.md new file mode 100644 index 0000000000..9c9f8e4e50 --- /dev/null +++ b/doc/release-notes-29091-29165.md @@ -0,0 +1,5 @@ +Build +----- + +GCC 11.1 or later, or Clang 15+ or later, +are now required to compile Bitcoin Core. diff --git a/doc/release-notes-29612.md b/doc/release-notes-29612.md new file mode 100644 index 0000000000..31af3cab09 --- /dev/null +++ b/doc/release-notes-29612.md @@ -0,0 +1,8 @@ +RPC +--- + +- The `dumptxoutset` RPC now returns the UTXO set dump in a new and + improved format. At the same time the `loadtxoutset` RPC now + expects this new format in dumps it tries to load. Dumps with the + old format are no longer supported and need to be recreated using + the new format in order to be usable. diff --git a/doc/release-notes-29987.md b/doc/release-notes-29987.md new file mode 100644 index 0000000000..4d4c2358d1 --- /dev/null +++ b/doc/release-notes-29987.md @@ -0,0 +1,6 @@ +Compatibility +============= + +The minimum required glibc to run Bitcoin Core is now +2.31. This means that RHEL 8 and Ubuntu 18.04 (Bionic) +are no-longer supported. (#29987)
\ No newline at end of file diff --git a/doc/release-notes-30058.md b/doc/release-notes-30058.md new file mode 100644 index 0000000000..47e7ae704e --- /dev/null +++ b/doc/release-notes-30058.md @@ -0,0 +1,7 @@ +- When running with -alertnotify, an alert can now be raised multiple +times instead of just once. Previously, it was only raised when unknown +new consensus rules were activated, whereas the scope has now been +increased to include all kernel warnings. Specifically, alerts will now +also be raised when an invalid chain with a large amount of work has +been detected. Additional warnings may be added in the future. +(#30058) diff --git a/doc/release-notes-30192.md b/doc/release-notes-30192.md new file mode 100644 index 0000000000..2a6c17d455 --- /dev/null +++ b/doc/release-notes-30192.md @@ -0,0 +1,6 @@ +Build +----- + +`--enable-lcov-branch-coverage` has been removed, given +incompatibilities between lcov version 1 & 2. `LCOV_OPTS` +should be used to set any options instead. diff --git a/doc/release-notes/release-notes-27.1.md b/doc/release-notes/release-notes-27.1.md new file mode 100644 index 0000000000..b19d70da33 --- /dev/null +++ b/doc/release-notes/release-notes-27.1.md @@ -0,0 +1,114 @@ +27.1 Release Notes +===================== + +Bitcoin Core version 27.1 is now available from: + + <https://bitcoincore.org/bin/bitcoin-core-27.1/> + +This release includes various bug fixes and performance +improvements, as well as updated translations. + +Please report bugs using the issue tracker at GitHub: + + <https://github.com/bitcoin/bitcoin/issues> + +To receive security and update notifications, please subscribe to: + + <https://bitcoincore.org/en/list/announcements/join/> + +How to Upgrade +============== + +If you are running an older version, shut it down. Wait until it has completely +shut down (which might take a few minutes in some cases), then run the +installer (on Windows) or just copy over `/Applications/Bitcoin-Qt` (on macOS) +or `bitcoind`/`bitcoin-qt` (on Linux). + +Upgrading directly from a version of Bitcoin Core that has reached its EOL is +possible, but it might take some time if the data directory needs to be migrated. Old +wallet versions of Bitcoin Core are generally supported. + +Compatibility +============== + +Bitcoin Core is supported and extensively tested on operating systems +using the Linux Kernel 3.17+, macOS 11.0+, and Windows 7 and newer. Bitcoin +Core should also work on most other Unix-like systems but is not as +frequently tested on them. It is not recommended to use Bitcoin Core on +unsupported systems. + +Notable changes +=============== + +### Miniscript + +- #29853 sign: don't assume we are parsing a sane TapMiniscript + +### RPC + +- #29869 rpc, bugfix: Enforce maximum value for setmocktime +- #29870 rpc: Reword SighashFromStr error message +- #30094 rpc: move UniValue in blockToJSON + +### Index + +- #29776 Fix #29767, set m_synced = true after Commit() + +### Gui + +- #gui812 Fix create unsigned transaction fee bump +- #gui813 Don't permit port in proxy IP option + +### Test + +- #29892 test: Fix failing univalue float test + +### P2P + +- #30085 p2p: detect addnode cjdns peers in GetAddedNodeInfo() + +### Build + +- #29747 depends: fix mingw-w64 Qt DEBUG=1 build +- #29859 build: Fix false positive CHECK_ATOMIC test +- #29985 depends: Fix build of Qt for 32-bit platforms with recent glibc +- #30097 crypto: disable asan for sha256_sse4 with clang and -O0 +- #30151 depends: Fetch miniupnpc sources from an alternative website +- #30216 build: Fix building fuzz binary on on SunOS / illumos +- #30217 depends: Update Boost download link + +### Doc + +- #29934 doc: add LLVM instruction for macOS < 13 + +### CI + +- #29856 ci: Bump s390x to ubuntu:24.04 + +### Misc + +- #29691 Change Luke Dashjr seed to dashjr-list-of-p2p-nodes.us +- #30149 contrib: Renew Windows code signing certificate + +Credits +======= + +Thanks to everyone who directly contributed to this release: + +- Antoine Poinsot +- Ava Chow +- Cory Fields +- dergoegge +- fanquake +- furszy +- Hennadii Stepanov +- Jon Atack +- laanwj +- Luke Dashjr +- MarcoFalke +- nanlour +- Sjors Provoost +- willcl-ark + +As well as to everyone that helped with translations on +[Transifex](https://www.transifex.com/bitcoin/bitcoin/). diff --git a/doc/release-notes/release-notes-27064.md b/doc/release-notes/release-notes-27064.md new file mode 100644 index 0000000000..be3ecee1b8 --- /dev/null +++ b/doc/release-notes/release-notes-27064.md @@ -0,0 +1,7 @@ +Files +----- + +The default data directory on Windows has been moved from `C:\Users\Username\AppData\Roaming\Bitcoin` +to `C:\Users\Username\AppData\Local\Bitcoin`. Bitcoin Core will check the existence +of the old directory first and continue to use that directory for backwards +compatibility if it is present.
\ No newline at end of file diff --git a/src/.clang-tidy b/src/.clang-tidy index a00400f083..61adce1d50 100644 --- a/src/.clang-tidy +++ b/src/.clang-tidy @@ -2,6 +2,7 @@ Checks: ' -*, bitcoin-*, bugprone-argument-comment, +bugprone-move-forwarding-reference, bugprone-string-constructor, bugprone-use-after-move, bugprone-lambda-function-name, diff --git a/src/Makefile.am b/src/Makefile.am index 639aecf3b3..0c47a737d0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,8 +8,8 @@ print-%: FORCE DIST_SUBDIRS = secp256k1 -AM_LDFLAGS = $(LIBTOOL_LDFLAGS) $(HARDENED_LDFLAGS) $(GPROF_LDFLAGS) $(SANITIZER_LDFLAGS) $(CORE_LDFLAGS) -AM_CXXFLAGS = $(CORE_CXXFLAGS) $(DEBUG_CXXFLAGS) $(HARDENED_CXXFLAGS) $(WARN_CXXFLAGS) $(NOWARN_CXXFLAGS) $(ERROR_CXXFLAGS) $(GPROF_CXXFLAGS) $(SANITIZER_CXXFLAGS) +AM_LDFLAGS = $(LIBTOOL_LDFLAGS) $(HARDENED_LDFLAGS) $(SANITIZER_LDFLAGS) $(CORE_LDFLAGS) +AM_CXXFLAGS = $(CORE_CXXFLAGS) $(DEBUG_CXXFLAGS) $(HARDENED_CXXFLAGS) $(WARN_CXXFLAGS) $(NOWARN_CXXFLAGS) $(ERROR_CXXFLAGS) $(SANITIZER_CXXFLAGS) AM_OBJCXXFLAGS = $(AM_CXXFLAGS) AM_CPPFLAGS = $(DEBUG_CPPFLAGS) $(HARDENED_CPPFLAGS) $(CORE_CPPFLAGS) AM_LIBTOOLFLAGS = --preserve-dup-deps @@ -137,13 +137,16 @@ BITCOIN_CORE_H = \ common/bloom.h \ common/init.h \ common/run_command.h \ + common/types.h \ common/url.h \ compat/assumptions.h \ compat/byteswap.h \ compat/compat.h \ compat/cpuid.h \ compat/endian.h \ + common/messages.h \ common/settings.h \ + common/signmessage.h \ common/system.h \ compressor.h \ consensus/consensus.h \ @@ -174,6 +177,7 @@ BITCOIN_CORE_H = \ interfaces/handler.h \ interfaces/init.h \ interfaces/ipc.h \ + interfaces/mining.h \ interfaces/node.h \ interfaces/wallet.h \ kernel/blockmanager_opts.h \ @@ -193,6 +197,7 @@ BITCOIN_CORE_H = \ kernel/messagestartchars.h \ kernel/notifications_interface.h \ kernel/validation_cache_sizes.h \ + kernel/warning.h \ key.h \ key_io.h \ logging.h \ @@ -233,8 +238,10 @@ BITCOIN_CORE_H = \ node/timeoffsets.h \ node/transaction.h \ node/txreconciliation.h \ + node/types.h \ node/utxo_snapshot.h \ node/validation_cache_args.h \ + node/warnings.h \ noui.h \ outputtype.h \ policy/v3_policy.h \ @@ -267,6 +274,7 @@ BITCOIN_CORE_H = \ script/descriptor.h \ script/keyorigin.h \ script/miniscript.h \ + script/parsing.h \ script/sigcache.h \ script/sign.h \ script/signingprovider.h \ @@ -292,15 +300,14 @@ BITCOIN_CORE_H = \ util/batchpriority.h \ util/bip32.h \ util/bitdeque.h \ + util/bitset.h \ util/bytevectorhash.h \ util/chaintype.h \ util/check.h \ util/epochguard.h \ - util/error.h \ util/exception.h \ util/fastrange.h \ util/feefrac.h \ - util/fees.h \ util/fs.h \ util/fs_helpers.h \ util/golombrice.h \ @@ -308,7 +315,6 @@ BITCOIN_CORE_H = \ util/hasher.h \ util/insert.h \ util/macros.h \ - util/message.h \ util/moneystr.h \ util/overflow.h \ util/overloaded.h \ @@ -318,7 +324,7 @@ BITCOIN_CORE_H = \ util/serfloat.h \ util/signalinterrupt.h \ util/sock.h \ - util/spanparsing.h \ + util/strencodings.h \ util/string.h \ util/subprocess.h \ util/syserror.h \ @@ -333,6 +339,7 @@ BITCOIN_CORE_H = \ util/translation.h \ util/types.h \ util/ui_change_type.h \ + util/vecdeque.h \ util/vector.h \ validation.h \ validationinterface.h \ @@ -348,6 +355,7 @@ BITCOIN_CORE_H = \ wallet/feebumper.h \ wallet/fees.h \ wallet/load.h \ + wallet/migrate.h \ wallet/receive.h \ wallet/rpc/util.h \ wallet/rpc/wallet.h \ @@ -362,7 +370,6 @@ BITCOIN_CORE_H = \ wallet/wallettool.h \ wallet/walletutil.h \ walletinitinterface.h \ - warnings.h \ zmq/zmqabstractnotifier.h \ zmq/zmqnotificationinterface.h \ zmq/zmqpublishnotifier.h \ @@ -439,6 +446,7 @@ libbitcoin_node_a_SOURCES = \ node/txreconciliation.cpp \ node/utxo_snapshot.cpp \ node/validation_cache_args.cpp \ + node/warnings.cpp \ noui.cpp \ policy/v3_policy.cpp \ policy/fees.cpp \ @@ -508,6 +516,7 @@ libbitcoin_wallet_a_SOURCES = \ wallet/fees.cpp \ wallet/interfaces.cpp \ wallet/load.cpp \ + wallet/migrate.cpp \ wallet/receive.cpp \ wallet/rpc/addresses.cpp \ wallet/rpc/backup.cpp \ @@ -565,6 +574,8 @@ crypto_libbitcoin_crypto_base_la_SOURCES = \ crypto/chacha20poly1305.h \ crypto/chacha20poly1305.cpp \ crypto/common.h \ + crypto/hex_base.cpp \ + crypto/hex_base.h \ crypto/hkdf_sha256_32.cpp \ crypto/hkdf_sha256_32.h \ crypto/hmac_sha256.cpp \ @@ -587,7 +598,8 @@ crypto_libbitcoin_crypto_base_la_SOURCES = \ crypto/sha512.cpp \ crypto/sha512.h \ crypto/siphash.cpp \ - crypto/siphash.h + crypto/siphash.h \ + support/cleanse.cpp # See explanation for -static in crypto_libbitcoin_crypto_base_la's LDFLAGS and # CXXFLAGS above @@ -657,9 +669,7 @@ libbitcoin_consensus_a_SOURCES = \ span.h \ tinyformat.h \ uint256.cpp \ - uint256.h \ - util/strencodings.cpp \ - util/strencodings.h + uint256.h # # common # @@ -669,6 +679,7 @@ libbitcoin_common_a_SOURCES = \ addresstype.cpp \ base58.cpp \ bech32.cpp \ + chainparamsbase.cpp \ chainparams.cpp \ coins.cpp \ common/args.cpp \ @@ -676,8 +687,10 @@ libbitcoin_common_a_SOURCES = \ common/config.cpp \ common/init.cpp \ common/interfaces.cpp \ + common/messages.cpp \ common/run_command.cpp \ common/settings.cpp \ + common/signmessage.cpp \ common/system.cpp \ common/url.cpp \ compressor.cpp \ @@ -707,10 +720,10 @@ libbitcoin_common_a_SOURCES = \ scheduler.cpp \ script/descriptor.cpp \ script/miniscript.cpp \ + script/parsing.cpp \ script/sign.cpp \ script/signingprovider.cpp \ script/solver.cpp \ - warnings.cpp \ $(BITCOIN_CORE_H) # @@ -719,13 +732,11 @@ libbitcoin_util_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) libbitcoin_util_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_util_a_SOURCES = \ support/lockedpool.cpp \ - chainparamsbase.cpp \ clientversion.cpp \ logging.cpp \ random.cpp \ randomenv.cpp \ streams.cpp \ - support/cleanse.cpp \ sync.cpp \ util/asmap.cpp \ util/batchpriority.cpp \ @@ -733,16 +744,13 @@ libbitcoin_util_a_SOURCES = \ util/bytevectorhash.cpp \ util/chaintype.cpp \ util/check.cpp \ - util/error.cpp \ util/exception.cpp \ util/feefrac.cpp \ - util/fees.cpp \ util/fs.cpp \ util/fs_helpers.cpp \ util/hasher.cpp \ util/sock.cpp \ util/syserror.cpp \ - util/message.cpp \ util/moneystr.cpp \ util/rbf.cpp \ util/readwritefile.cpp \ @@ -751,7 +759,6 @@ libbitcoin_util_a_SOURCES = \ util/threadinterrupt.cpp \ util/threadnames.cpp \ util/serfloat.cpp \ - util/spanparsing.cpp \ util/strencodings.cpp \ util/string.cpp \ util/time.cpp \ @@ -945,7 +952,6 @@ libbitcoinkernel_la_SOURCES = \ kernel/disconnected_transactions.cpp \ kernel/mempool_persist.cpp \ kernel/mempool_removal_reason.cpp \ - key.cpp \ logging.cpp \ node/blockstorage.cpp \ node/chainstate.cpp \ @@ -969,13 +975,11 @@ libbitcoinkernel_la_SOURCES = \ script/solver.cpp \ signet.cpp \ streams.cpp \ - support/cleanse.cpp \ support/lockedpool.cpp \ sync.cpp \ txdb.cpp \ txmempool.cpp \ uint256.cpp \ - util/batchpriority.cpp \ util/chaintype.cpp \ util/check.cpp \ util/feefrac.cpp \ @@ -994,8 +998,7 @@ libbitcoinkernel_la_SOURCES = \ util/tokenpipe.cpp \ validation.cpp \ validationinterface.cpp \ - versionbits.cpp \ - warnings.cpp + versionbits.cpp # Required for obj/build.h to be generated first. # More details: https://www.gnu.org/software/automake/manual/html_node/Built-Sources-Example.html @@ -1086,7 +1089,7 @@ libbitcoin_ipc_a_SOURCES = \ ipc/process.cpp \ ipc/process.h \ ipc/protocol.h -libbitcoin_ipc_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +libbitcoin_ipc_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BOOST_CPPFLAGS) libbitcoin_ipc_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) $(LIBMULTIPROCESS_CFLAGS) include $(MPGEN_PREFIX)/include/mpgen.mk diff --git a/src/Makefile.bench.include b/src/Makefile.bench.include index 7ba0111fa6..2ba72c9e76 100644 --- a/src/Makefile.bench.include +++ b/src/Makefile.bench.include @@ -23,6 +23,7 @@ bench_bench_bitcoin_SOURCES = \ bench/ccoins_caching.cpp \ bench/chacha20.cpp \ bench/checkblock.cpp \ + bench/checkblockindex.cpp \ bench/checkqueue.cpp \ bench/crypto_hash.cpp \ bench/data.cpp \ diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index c235c3c4da..1ac6b74688 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -392,20 +392,6 @@ bitcoin_qt_clean: FORCE bitcoin_qt : qt/bitcoin-qt$(EXEEXT) -APK_LIB_DIR = qt/android/libs/$(ANDROID_ARCH) -QT_BASE_VERSION = $(lastword $(shell $(MOC) --version)) -QT_BASE_PATH = $(shell find ../depends/sources/ -maxdepth 1 -type f -regex ".*qtbase.*$(QT_BASE_VERSION)\.tar.xz") -QT_BASE_TLD = $(shell tar tf $(QT_BASE_PATH) --exclude='*/*') - -bitcoin_qt_apk: FORCE - mkdir -p $(APK_LIB_DIR) - cp $(dir $(lastword $(CC)))../sysroot/usr/lib/$(host_alias)/libc++_shared.so $(APK_LIB_DIR) - tar xf $(QT_BASE_PATH) -C qt/android/src/ $(QT_BASE_TLD)src/android/jar/src --strip-components=5 - tar xf $(QT_BASE_PATH) -C qt/android/src/ $(QT_BASE_TLD)src/android/java/src --strip-components=5 - cp qt/bitcoin-qt $(APK_LIB_DIR)/libbitcoin-qt_$(ANDROID_ARCH).so - cd qt/android && gradle wrapper --gradle-version=6.6.1 - cd qt/android && ./gradlew build - ui_%.h: %.ui @test -f $(UIC) || (echo "uic $(UIC) not found, but is required for generating ui headers"; exit 1) @$(MKDIR_P) $(@D) diff --git a/src/Makefile.test.include b/src/Makefile.test.include index cfd28b0a4d..633d0776f5 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -118,6 +118,7 @@ BITCOIN_TESTS =\ test/net_peer_eviction_tests.cpp \ test/net_tests.cpp \ test/netbase_tests.cpp \ + test/node_warnings_tests.cpp \ test/orphanage_tests.cpp \ test/peerman_tests.cpp \ test/pmt_tests.cpp \ @@ -203,8 +204,10 @@ endif FUZZ_WALLET_SRC = \ wallet/test/fuzz/coincontrol.cpp \ wallet/test/fuzz/coinselection.cpp \ + wallet/test/fuzz/crypter.cpp \ wallet/test/fuzz/fees.cpp \ - wallet/test/fuzz/parse_iso8601.cpp + wallet/test/fuzz/parse_iso8601.cpp \ + wallet/test/fuzz/wallet_bdb_parser.cpp if USE_SQLITE FUZZ_WALLET_SRC += \ @@ -276,7 +279,7 @@ FUZZ_SUITE_LD_COMMON += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) endif if ENABLE_FUZZ_BINARY -test_fuzz_fuzz_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BOOST_CPPFLAGS) +test_fuzz_fuzz_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BOOST_CPPFLAGS) $(EVENT_CFLAGS) test_fuzz_fuzz_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) test_fuzz_fuzz_LDADD = $(FUZZ_SUITE_LD_COMMON) test_fuzz_fuzz_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) $(PTHREAD_FLAGS) @@ -292,6 +295,7 @@ test_fuzz_fuzz_SOURCES = \ test/fuzz/bech32.cpp \ test/fuzz/bip324.cpp \ test/fuzz/bitdeque.cpp \ + test/fuzz/bitset.cpp \ test/fuzz/block.cpp \ test/fuzz/block_header.cpp \ test/fuzz/blockfilter.cpp \ @@ -325,6 +329,7 @@ test_fuzz_fuzz_SOURCES = \ test/fuzz/headerssync.cpp \ test/fuzz/hex.cpp \ test/fuzz/http_request.cpp \ + test/fuzz/i2p.cpp \ test/fuzz/integer.cpp \ test/fuzz/key.cpp \ test/fuzz/key_io.cpp \ @@ -371,6 +376,7 @@ test_fuzz_fuzz_SOURCES = \ test/fuzz/script_format.cpp \ test/fuzz/script_interpreter.cpp \ test/fuzz/script_ops.cpp \ + test/fuzz/script_parsing.cpp \ test/fuzz/script_sigcache.cpp \ test/fuzz/script_sign.cpp \ test/fuzz/scriptnum_ops.cpp \ @@ -380,7 +386,6 @@ test_fuzz_fuzz_SOURCES = \ test/fuzz/signet.cpp \ test/fuzz/socks5.cpp \ test/fuzz/span.cpp \ - test/fuzz/spanparsing.cpp \ test/fuzz/string.cpp \ test/fuzz/strprintf.cpp \ test/fuzz/system.cpp \ @@ -395,6 +400,7 @@ test_fuzz_fuzz_SOURCES = \ test/fuzz/utxo_snapshot.cpp \ test/fuzz/utxo_total_supply.cpp \ test/fuzz/validation_load_mempool.cpp \ + test/fuzz/vecdeque.cpp \ test/fuzz/versionbits.cpp endif # ENABLE_FUZZ_BINARY diff --git a/src/addrman.cpp b/src/addrman.cpp index eb9c372550..d0b820ee65 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -173,7 +173,7 @@ void AddrManImpl::Serialize(Stream& s_) const */ // Always serialize in the latest version (FILE_FORMAT). - ParamsStream s{CAddress::V2_DISK, s_}; + ParamsStream s{s_, CAddress::V2_DISK}; s << static_cast<uint8_t>(FILE_FORMAT); @@ -238,7 +238,7 @@ void AddrManImpl::Unserialize(Stream& s_) s_ >> Using<CustomUintFormatter<1>>(format); const auto ser_params = (format >= Format::V3_BIP155 ? CAddress::V2_DISK : CAddress::V1_DISK); - ParamsStream s{ser_params, s_}; + ParamsStream s{s_, ser_params}; uint8_t compat; s >> compat; diff --git a/src/banman.h b/src/banman.h index c6df7ec3c3..57ba2ac23c 100644 --- a/src/banman.h +++ b/src/banman.h @@ -34,7 +34,7 @@ class CSubNet; // disk on shutdown and reloaded on startup. Banning can be used to // prevent connections with spy nodes or other griefers. // -// 2. Discouragement. If a peer misbehaves enough (see Misbehaving() in +// 2. Discouragement. If a peer misbehaves (see Misbehaving() in // net_processing.cpp), we'll mark that address as discouraged. We still allow // incoming connections from them, but they're preferred for eviction when // we receive new incoming connections. We never make outgoing connections to diff --git a/src/base58.cpp b/src/base58.cpp index cf5d62f164..f9165ed55f 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -14,6 +14,8 @@ #include <limits> +using util::ContainsNoNUL; + /** All alphanumeric characters except for "0", "I", "O", and "l" */ static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; static const int8_t mapBase58[256] = { diff --git a/src/bech32.cpp b/src/bech32.cpp index ba3c419d8b..d8d31a415c 100644 --- a/src/bech32.cpp +++ b/src/bech32.cpp @@ -19,6 +19,9 @@ namespace typedef std::vector<uint8_t> data; +/** The Bech32 and Bech32m checksum size */ +constexpr size_t CHECKSUM_SIZE = 6; + /** The Bech32 and Bech32m character set for encoding. */ const char* CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"; @@ -308,18 +311,18 @@ bool CheckCharacters(const std::string& str, std::vector<int>& errors) return errors.empty(); } -/** Expand a HRP for use in checksum computation. */ -data ExpandHRP(const std::string& hrp) +std::vector<unsigned char> PreparePolynomialCoefficients(const std::string& hrp, const data& values) { data ret; - ret.reserve(hrp.size() + 90); - ret.resize(hrp.size() * 2 + 1); - for (size_t i = 0; i < hrp.size(); ++i) { - unsigned char c = hrp[i]; - ret[i] = c >> 5; - ret[i + hrp.size() + 1] = c & 0x1f; - } - ret[hrp.size()] = 0; + ret.reserve(hrp.size() + 1 + hrp.size() + values.size() + CHECKSUM_SIZE); + + /** Expand a HRP for use in checksum computation. */ + for (size_t i = 0; i < hrp.size(); ++i) ret.push_back(hrp[i] >> 5); + ret.push_back(0); + for (size_t i = 0; i < hrp.size(); ++i) ret.push_back(hrp[i] & 0x1f); + + ret.insert(ret.end(), values.begin(), values.end()); + return ret; } @@ -331,7 +334,8 @@ Encoding VerifyChecksum(const std::string& hrp, const data& values) // list of values would result in a new valid list. For that reason, Bech32 requires the // resulting checksum to be 1 instead. In Bech32m, this constant was amended. See // https://gist.github.com/sipa/14c248c288c3880a3b191f978a34508e for details. - const uint32_t check = PolyMod(Cat(ExpandHRP(hrp), values)); + auto enc = PreparePolynomialCoefficients(hrp, values); + const uint32_t check = PolyMod(enc); if (check == EncodingConstant(Encoding::BECH32)) return Encoding::BECH32; if (check == EncodingConstant(Encoding::BECH32M)) return Encoding::BECH32M; return Encoding::INVALID; @@ -340,11 +344,11 @@ Encoding VerifyChecksum(const std::string& hrp, const data& values) /** Create a checksum. */ data CreateChecksum(Encoding encoding, const std::string& hrp, const data& values) { - data enc = Cat(ExpandHRP(hrp), values); - enc.resize(enc.size() + 6); // Append 6 zeroes + auto enc = PreparePolynomialCoefficients(hrp, values); + enc.insert(enc.end(), CHECKSUM_SIZE, 0x00); uint32_t mod = PolyMod(enc) ^ EncodingConstant(encoding); // Determine what to XOR into those 6 zeroes. - data ret(6); - for (size_t i = 0; i < 6; ++i) { + data ret(CHECKSUM_SIZE); + for (size_t i = 0; i < CHECKSUM_SIZE; ++i) { // Convert the 5-bit groups in mod to checksum values. ret[i] = (mod >> (5 * (5 - i))) & 31; } @@ -359,22 +363,23 @@ std::string Encode(Encoding encoding, const std::string& hrp, const data& values // to return a lowercase Bech32/Bech32m string, but if given an uppercase HRP, the // result will always be invalid. for (const char& c : hrp) assert(c < 'A' || c > 'Z'); - data checksum = CreateChecksum(encoding, hrp, values); - data combined = Cat(values, checksum); - std::string ret = hrp + '1'; - ret.reserve(ret.size() + combined.size()); - for (const auto c : combined) { - ret += CHARSET[c]; - } + + std::string ret; + ret.reserve(hrp.size() + 1 + values.size() + CHECKSUM_SIZE); + ret += hrp; + ret += '1'; + for (const uint8_t& i : values) ret += CHARSET[i]; + for (const uint8_t& i : CreateChecksum(encoding, hrp, values)) ret += CHARSET[i]; return ret; } /** Decode a Bech32 or Bech32m string. */ -DecodeResult Decode(const std::string& str) { +DecodeResult Decode(const std::string& str, CharLimit limit) { std::vector<int> errors; if (!CheckCharacters(str, errors)) return {}; size_t pos = str.rfind('1'); - if (str.size() > 90 || pos == str.npos || pos == 0 || pos + 7 > str.size()) { + if (str.size() > limit) return {}; + if (pos == str.npos || pos == 0 || pos + CHECKSUM_SIZE >= str.size()) { return {}; } data values(str.size() - 1 - pos); @@ -388,21 +393,22 @@ DecodeResult Decode(const std::string& str) { values[i] = rev; } std::string hrp; + hrp.reserve(pos); for (size_t i = 0; i < pos; ++i) { hrp += LowerCase(str[i]); } Encoding result = VerifyChecksum(hrp, values); if (result == Encoding::INVALID) return {}; - return {result, std::move(hrp), data(values.begin(), values.end() - 6)}; + return {result, std::move(hrp), data(values.begin(), values.end() - CHECKSUM_SIZE)}; } /** Find index of an incorrect character in a Bech32 string. */ -std::pair<std::string, std::vector<int>> LocateErrors(const std::string& str) { +std::pair<std::string, std::vector<int>> LocateErrors(const std::string& str, CharLimit limit) { std::vector<int> error_locations{}; - if (str.size() > 90) { - error_locations.resize(str.size() - 90); - std::iota(error_locations.begin(), error_locations.end(), 90); + if (str.size() > limit) { + error_locations.resize(str.size() - limit); + std::iota(error_locations.begin(), error_locations.end(), static_cast<int>(limit)); return std::make_pair("Bech32 string too long", std::move(error_locations)); } @@ -414,12 +420,13 @@ std::pair<std::string, std::vector<int>> LocateErrors(const std::string& str) { if (pos == str.npos) { return std::make_pair("Missing separator", std::vector<int>{}); } - if (pos == 0 || pos + 7 > str.size()) { + if (pos == 0 || pos + CHECKSUM_SIZE >= str.size()) { error_locations.push_back(pos); return std::make_pair("Invalid separator position", std::move(error_locations)); } std::string hrp; + hrp.reserve(pos); for (size_t i = 0; i < pos; ++i) { hrp += LowerCase(str[i]); } @@ -441,9 +448,10 @@ std::pair<std::string, std::vector<int>> LocateErrors(const std::string& str) { std::optional<Encoding> error_encoding; for (Encoding encoding : {Encoding::BECH32, Encoding::BECH32M}) { std::vector<int> possible_errors; - // Recall that (ExpandHRP(hrp) ++ values) is interpreted as a list of coefficients of a polynomial + // Recall that (expanded hrp + values) is interpreted as a list of coefficients of a polynomial // over GF(32). PolyMod computes the "remainder" of this polynomial modulo the generator G(x). - uint32_t residue = PolyMod(Cat(ExpandHRP(hrp), values)) ^ EncodingConstant(encoding); + auto enc = PreparePolynomialCoefficients(hrp, values); + uint32_t residue = PolyMod(enc) ^ EncodingConstant(encoding); // All valid codewords should be multiples of G(x), so this remainder (after XORing with the encoding // constant) should be 0 - hence 0 indicates there are no errors present. diff --git a/src/bech32.h b/src/bech32.h index 5e89e6efda..fe2a276ae0 100644 --- a/src/bech32.h +++ b/src/bech32.h @@ -28,6 +28,14 @@ enum class Encoding { BECH32M, //!< Bech32m encoding as defined in BIP350 }; +/** Character limits for Bech32(m) encoded strings. Character limits are how we provide error location guarantees. + * These values should never exceed 2^31 - 1 (max value for a 32-bit int), since there are places where we may need to + * convert the CharLimit::VALUE to an int. In practice, this should never happen since this CharLimit applies to an address encoding + * and we would never encode an address with such a massive value */ +enum CharLimit : size_t { + BECH32 = 90, //!< BIP173/350 imposed character limit for Bech32(m) encoded addresses. This guarantees finding up to 4 errors. +}; + /** Encode a Bech32 or Bech32m string. If hrp contains uppercase characters, this will cause an * assertion error. Encoding must be one of BECH32 or BECH32M. */ std::string Encode(Encoding encoding, const std::string& hrp, const std::vector<uint8_t>& values); @@ -43,10 +51,10 @@ struct DecodeResult }; /** Decode a Bech32 or Bech32m string. */ -DecodeResult Decode(const std::string& str); +DecodeResult Decode(const std::string& str, CharLimit limit = CharLimit::BECH32); /** Return the positions of errors in a Bech32 string. */ -std::pair<std::string, std::vector<int>> LocateErrors(const std::string& str); +std::pair<std::string, std::vector<int>> LocateErrors(const std::string& str, CharLimit limit = CharLimit::BECH32); } // namespace bech32 diff --git a/src/bench/bench.cpp b/src/bench/bench.cpp index a13a693ad7..733f8085ca 100644 --- a/src/bench/bench.cpp +++ b/src/bench/bench.cpp @@ -18,6 +18,7 @@ #include <vector> using namespace std::chrono_literals; +using util::Join; const std::function<void(const std::string&)> G_TEST_LOG_FUN{}; diff --git a/src/bench/bench_bitcoin.cpp b/src/bench/bench_bitcoin.cpp index 8c421c3fec..a1b880e40b 100644 --- a/src/bench/bench_bitcoin.cpp +++ b/src/bench/bench_bitcoin.cpp @@ -16,6 +16,8 @@ #include <sstream> #include <vector> +using util::SplitString; + static const char* DEFAULT_BENCH_FILTER = ".*"; static constexpr int64_t DEFAULT_MIN_TIME_MS{10}; /** Priority level default value, run "all" priority levels */ diff --git a/src/bench/bip324_ecdh.cpp b/src/bench/bip324_ecdh.cpp index fb10c2957e..88f3932ad8 100644 --- a/src/bench/bip324_ecdh.cpp +++ b/src/bench/bip324_ecdh.cpp @@ -14,7 +14,7 @@ static void BIP324_ECDH(benchmark::Bench& bench) { - ECC_Start(); + ECC_Context ecc_context{}; FastRandomContext rng; std::array<std::byte, 32> key_data; @@ -44,8 +44,6 @@ static void BIP324_ECDH(benchmark::Bench& bench) // - Copy 16 bytes from the resulting shared secret into the middle of their ellswift key. std::copy(ret.begin() + 16, ret.end(), their_ellswift_data.begin() + 24); }); - - ECC_Stop(); } BENCHMARK(BIP324_ECDH, benchmark::PriorityLevel::HIGH); diff --git a/src/bench/ccoins_caching.cpp b/src/bench/ccoins_caching.cpp index 4a3ec67c2b..05b2f5435c 100644 --- a/src/bench/ccoins_caching.cpp +++ b/src/bench/ccoins_caching.cpp @@ -18,7 +18,7 @@ // (https://github.com/bitcoin/bitcoin/issues/7883#issuecomment-224807484) static void CCoinsCaching(benchmark::Bench& bench) { - ECC_Start(); + ECC_Context ecc_context{}; FillableSigningProvider keystore; CCoinsView coinsDummy; @@ -47,7 +47,6 @@ static void CCoinsCaching(benchmark::Bench& bench) bool success{AreInputsStandard(tx_1, coins)}; assert(success); }); - ECC_Stop(); } BENCHMARK(CCoinsCaching, benchmark::PriorityLevel::HIGH); diff --git a/src/bench/checkblockindex.cpp b/src/bench/checkblockindex.cpp new file mode 100644 index 0000000000..e8a848dbd4 --- /dev/null +++ b/src/bench/checkblockindex.cpp @@ -0,0 +1,20 @@ +// Copyright (c) 2023-present The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <bench/bench.h> +#include <test/util/setup_common.h> +#include <validation.h> + +static void CheckBlockIndex(benchmark::Bench& bench) +{ + auto testing_setup{MakeNoLogFileContext<TestChain100Setup>()}; + // Mine some more blocks + testing_setup->mineBlocks(1000); + bench.run([&] { + testing_setup->m_node.chainman->CheckBlockIndex(); + }); +} + + +BENCHMARK(CheckBlockIndex, benchmark::PriorityLevel::HIGH); diff --git a/src/bench/checkqueue.cpp b/src/bench/checkqueue.cpp index 114dd9d39c..c973fe9f71 100644 --- a/src/bench/checkqueue.cpp +++ b/src/bench/checkqueue.cpp @@ -25,7 +25,7 @@ static void CCheckQueueSpeedPrevectorJob(benchmark::Bench& bench) // We shouldn't ever be running with the checkqueue on a single core machine. if (GetNumCores() <= 1) return; - ECC_Start(); + ECC_Context ecc_context{}; struct PrevectorJob { prevector<PREVECTOR_SIZE, uint8_t> p; @@ -62,6 +62,5 @@ static void CCheckQueueSpeedPrevectorJob(benchmark::Bench& bench) // it is done explicitly here for clarity control.Wait(); }); - ECC_Stop(); } BENCHMARK(CCheckQueueSpeedPrevectorJob, benchmark::PriorityLevel::HIGH); diff --git a/src/bench/coin_selection.cpp b/src/bench/coin_selection.cpp index 249b76ee85..171c61c46f 100644 --- a/src/bench/coin_selection.cpp +++ b/src/bench/coin_selection.cpp @@ -71,15 +71,15 @@ static void CoinSelection(benchmark::Bench& bench) /*change_output_size=*/ 34, /*change_spend_size=*/ 148, /*min_change_target=*/ CHANGE_LOWER, - /*effective_feerate=*/ CFeeRate(0), - /*long_term_feerate=*/ CFeeRate(0), - /*discard_feerate=*/ CFeeRate(0), + /*effective_feerate=*/ CFeeRate(20'000), + /*long_term_feerate=*/ CFeeRate(10'000), + /*discard_feerate=*/ CFeeRate(3000), /*tx_noinputs_size=*/ 0, /*avoid_partial=*/ false, }; auto group = wallet::GroupOutputs(wallet, available_coins, coin_selection_params, {{filter_standard}})[filter_standard]; bench.run([&] { - auto result = AttemptSelection(wallet.chain(), 1003 * COIN, group, coin_selection_params, /*allow_mixed_output_types=*/true); + auto result = AttemptSelection(wallet.chain(), 1002.99 * COIN, group, coin_selection_params, /*allow_mixed_output_types=*/true); assert(result); assert(result->GetSelectedValue() == 1003 * COIN); assert(result->GetInputSet().size() == 2); diff --git a/src/bench/descriptors.cpp b/src/bench/descriptors.cpp index fbef1395fb..5d6bcb8ce8 100644 --- a/src/bench/descriptors.cpp +++ b/src/bench/descriptors.cpp @@ -12,7 +12,7 @@ static void ExpandDescriptor(benchmark::Bench& bench) { - ECC_Start(); + ECC_Context ecc_context{}; const auto desc_str = "sh(wsh(multi(16,03669b8afcec803a0d323e9a17f3ea8e68e8abe5a278020a929adbec52421adbd0,0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600,0362a74e399c39ed5593852a30147f2959b56bb827dfa3e60e464b02ccf87dc5e8,0261345b53de74a4d721ef877c255429961b7e43714171ac06168d7e08c542a8b8,02da72e8b46901a65d4374fe6315538d8f368557dda3a1dcf9ea903f3afe7314c8,0318c82dd0b53fd3a932d16e0ba9e278fcc937c582d5781be626ff16e201f72286,0297ccef1ef99f9d73dec9ad37476ddb232f1238aff877af19e72ba04493361009,02e502cfd5c3f972fe9a3e2a18827820638f96b6f347e54d63deb839011fd5765d,03e687710f0e3ebe81c1037074da939d409c0025f17eb86adb9427d28f0f7ae0e9,02c04d3a5274952acdbc76987f3184b346a483d43be40874624b29e3692c1df5af,02ed06e0f418b5b43a7ec01d1d7d27290fa15f75771cb69b642a51471c29c84acd,036d46073cbb9ffee90473f3da429abc8de7f8751199da44485682a989a4bebb24,02f5d1ff7c9029a80a4e36b9a5497027ef7f3e73384a4a94fbfe7c4e9164eec8bc,02e41deffd1b7cce11cde209a781adcffdabd1b91c0ba0375857a2bfd9302419f3,02d76625f7956a7fc505ab02556c23ee72d832f1bac391bcd2d3abce5710a13d06,0399eb0a5487515802dc14544cf10b3666623762fbed2ec38a3975716e2c29c232)))"; const std::pair<int64_t, int64_t> range = {0, 1000}; @@ -27,8 +27,6 @@ static void ExpandDescriptor(benchmark::Bench& bench) assert(success); } }); - - ECC_Stop(); } BENCHMARK(ExpandDescriptor, benchmark::PriorityLevel::HIGH); diff --git a/src/bench/ellswift.cpp b/src/bench/ellswift.cpp index 9441b4863e..4780db8e1c 100644 --- a/src/bench/ellswift.cpp +++ b/src/bench/ellswift.cpp @@ -9,7 +9,7 @@ static void EllSwiftCreate(benchmark::Bench& bench) { - ECC_Start(); + ECC_Context ecc_context{}; CKey key = GenerateRandomKey(); uint256 entropy = GetRandHash(); @@ -22,8 +22,6 @@ static void EllSwiftCreate(benchmark::Bench& bench) /* Use the last 32 bytes of the ellswift encoded public key as next entropy. */ std::copy(ret.begin() + 32, ret.begin() + 64, MakeWritableByteSpan(entropy).begin()); }); - - ECC_Stop(); } BENCHMARK(EllSwiftCreate, benchmark::PriorityLevel::HIGH); diff --git a/src/bench/readblock.cpp b/src/bench/readblock.cpp index 0545c6b017..2b2bfe069e 100644 --- a/src/bench/readblock.cpp +++ b/src/bench/readblock.cpp @@ -18,7 +18,7 @@ static FlatFilePos WriteBlockToDisk(ChainstateManager& chainman) CBlock block; stream >> TX_WITH_WITNESS(block); - return chainman.m_blockman.SaveBlockToDisk(block, 0, nullptr); + return chainman.m_blockman.SaveBlockToDisk(block, 0); } static void ReadBlockFromDiskTest(benchmark::Bench& bench) diff --git a/src/bench/verify_script.cpp b/src/bench/verify_script.cpp index ee750bc1f8..f38aa49a23 100644 --- a/src/bench/verify_script.cpp +++ b/src/bench/verify_script.cpp @@ -15,7 +15,7 @@ // modified to measure performance of other types of scripts. static void VerifyScriptBench(benchmark::Bench& bench) { - ECC_Start(); + ECC_Context ecc_context{}; const uint32_t flags{SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH}; const int witnessversion = 0; @@ -57,7 +57,6 @@ static void VerifyScriptBench(benchmark::Bench& bench) assert(err == SCRIPT_ERR_OK); assert(success); }); - ECC_Stop(); } static void VerifyNestedIfScript(benchmark::Bench& bench) diff --git a/src/bench/wallet_create.cpp b/src/bench/wallet_create.cpp index 618d5bc80c..5c0557bf6f 100644 --- a/src/bench/wallet_create.cpp +++ b/src/bench/wallet_create.cpp @@ -34,14 +34,15 @@ static void WalletCreate(benchmark::Bench& bench, bool encrypted) bilingual_str error_string; std::vector<bilingual_str> warnings; - fs::path wallet_path = test_setup->m_path_root / strprintf("test_wallet_%d", random.rand32()).c_str(); + auto wallet_path = fs::PathToString(test_setup->m_path_root / "test_wallet"); bench.run([&] { - auto wallet = CreateWallet(context, wallet_path.utf8string(), /*load_on_start=*/std::nullopt, options, status, error_string, warnings); + auto wallet = CreateWallet(context, wallet_path, /*load_on_start=*/std::nullopt, options, status, error_string, warnings); assert(status == DatabaseStatus::SUCCESS); assert(wallet != nullptr); - // Cleanup - wallet.reset(); + // Release wallet + RemoveWallet(context, wallet, /*load_on_start=*/ std::nullopt); + UnloadWallet(std::move(wallet)); fs::remove_all(wallet_path); }); } @@ -49,14 +50,9 @@ static void WalletCreate(benchmark::Bench& bench, bool encrypted) static void WalletCreatePlain(benchmark::Bench& bench) { WalletCreate(bench, /*encrypted=*/false); } static void WalletCreateEncrypted(benchmark::Bench& bench) { WalletCreate(bench, /*encrypted=*/true); } -#ifndef _MSC_VER -// TODO: Being built with MSVC, the fs::remove_all() call in -// the WalletCreate() fails with the error "The process cannot -// access the file because it is being used by another process." #ifdef USE_SQLITE BENCHMARK(WalletCreatePlain, benchmark::PriorityLevel::LOW); BENCHMARK(WalletCreateEncrypted, benchmark::PriorityLevel::LOW); #endif -#endif } // namespace wallet diff --git a/src/bitcoin-chainstate.cpp b/src/bitcoin-chainstate.cpp index 642af06e82..ecbdcd48bb 100644 --- a/src/bitcoin-chainstate.cpp +++ b/src/bitcoin-chainstate.cpp @@ -16,6 +16,7 @@ #include <kernel/checks.h> #include <kernel/context.h> #include <kernel/validation_cache_sizes.h> +#include <kernel/warning.h> #include <consensus/validation.h> #include <core_io.h> @@ -26,7 +27,9 @@ #include <script/sigcache.h> #include <util/chaintype.h> #include <util/fs.h> +#include <util/signalinterrupt.h> #include <util/task_runner.h> +#include <util/translation.h> #include <validation.h> #include <validationinterface.h> @@ -85,9 +88,13 @@ int main(int argc, char* argv[]) { std::cout << "Progress: " << title.original << ", " << progress_percent << ", " << resume_possible << std::endl; } - void warning(const bilingual_str& warning) override + void warningSet(kernel::Warning id, const bilingual_str& message) override { - std::cout << "Warning: " << warning.original << std::endl; + std::cout << "Warning " << static_cast<int>(id) << " set: " << message.original << std::endl; + } + void warningUnset(kernel::Warning id) override + { + std::cout << "Warning " << static_cast<int>(id) << " unset" << std::endl; } void flushError(const bilingual_str& message) override { @@ -150,7 +157,7 @@ int main(int argc, char* argv[]) { LOCK(chainman.GetMutex()); std::cout - << "\t" << "Reindexing: " << std::boolalpha << node::fReindex.load() << std::noboolalpha << std::endl + << "\t" << "Blockfiles Indexed: " << std::boolalpha << chainman.m_blockman.m_blockfiles_indexed.load() << std::noboolalpha << std::endl << "\t" << "Snapshot Active: " << std::boolalpha << chainman.IsSnapshotActive() << std::noboolalpha << std::endl << "\t" << "Active Height: " << chainman.ActiveHeight() << std::endl << "\t" << "Active IBD: " << std::boolalpha << chainman.IsInitialBlockDownload() << std::noboolalpha << std::endl; diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index c7ba2204c3..44fc273163 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -42,6 +42,9 @@ #include <event2/keyvalq_struct.h> #include <support/events.h> +using util::Join; +using util::ToString; + // The server returns time values from a mockable system clock, but it is not // trivial to get the mocked time from the server, nor is it needed for now, so // just use a plain system_clock. @@ -297,8 +300,8 @@ public: total += counts.at(i); } addresses.pushKV("total", total); - result.pushKV("addresses_known", addresses); - return JSONRPCReplyObj(result, NullUniValue, 1); + result.pushKV("addresses_known", std::move(addresses)); + return JSONRPCReplyObj(std::move(result), NullUniValue, /*id=*/1, JSONRPCVersion::V2); } }; @@ -348,7 +351,7 @@ public: connections.pushKV("in", batch[ID_NETWORKINFO]["result"]["connections_in"]); connections.pushKV("out", batch[ID_NETWORKINFO]["result"]["connections_out"]); connections.pushKV("total", batch[ID_NETWORKINFO]["result"]["connections"]); - result.pushKV("connections", connections); + result.pushKV("connections", std::move(connections)); result.pushKV("networks", batch[ID_NETWORKINFO]["result"]["networks"]); result.pushKV("difficulty", batch[ID_BLOCKCHAININFO]["result"]["difficulty"]); @@ -367,7 +370,7 @@ public: } result.pushKV("relayfee", batch[ID_NETWORKINFO]["result"]["relayfee"]); result.pushKV("warnings", batch[ID_NETWORKINFO]["result"]["warnings"]); - return JSONRPCReplyObj(result, NullUniValue, 1); + return JSONRPCReplyObj(std::move(result), NullUniValue, /*id=*/1, JSONRPCVersion::V2); } }; @@ -622,7 +625,7 @@ public: } } - return JSONRPCReplyObj(UniValue{result}, NullUniValue, 1); + return JSONRPCReplyObj(UniValue{result}, NullUniValue, /*id=*/1, JSONRPCVersion::V2); } const std::string m_help_doc{ @@ -709,7 +712,7 @@ public: UniValue result(UniValue::VOBJ); result.pushKV("address", address_str); result.pushKV("blocks", reply.get_obj()["result"]); - return JSONRPCReplyObj(result, NullUniValue, 1); + return JSONRPCReplyObj(std::move(result), NullUniValue, /*id=*/1, JSONRPCVersion::V2); } protected: std::string address_str; @@ -743,8 +746,41 @@ static UniValue CallRPC(BaseRequestHandler* rh, const std::string& strMethod, co // 2. port in -rpcconnect (ie following : in ipv4 or ]: in ipv6) // 3. default port for chain uint16_t port{BaseParams().RPCPort()}; - SplitHostPort(gArgs.GetArg("-rpcconnect", DEFAULT_RPCCONNECT), port, host); - port = static_cast<uint16_t>(gArgs.GetIntArg("-rpcport", port)); + { + uint16_t rpcconnect_port{0}; + const std::string rpcconnect_str = gArgs.GetArg("-rpcconnect", DEFAULT_RPCCONNECT); + if (!SplitHostPort(rpcconnect_str, rpcconnect_port, host)) { + // Uses argument provided as-is + // (rather than value parsed) + // to aid the user in troubleshooting + throw std::runtime_error(strprintf("Invalid port provided in -rpcconnect: %s", rpcconnect_str)); + } else { + if (rpcconnect_port != 0) { + // Use the valid port provided in rpcconnect + port = rpcconnect_port; + } // else, no port was provided in rpcconnect (continue using default one) + } + + if (std::optional<std::string> rpcport_arg = gArgs.GetArg("-rpcport")) { + // -rpcport was specified + const uint16_t rpcport_int{ToIntegral<uint16_t>(rpcport_arg.value()).value_or(0)}; + if (rpcport_int == 0) { + // Uses argument provided as-is + // (rather than value parsed) + // to aid the user in troubleshooting + throw std::runtime_error(strprintf("Invalid port provided in -rpcport: %s", rpcport_arg.value())); + } + + // Use the valid port provided + port = rpcport_int; + + // If there was a valid port provided in rpcconnect, + // rpcconnect_port is non-zero. + if (rpcconnect_port != 0) { + tfm::format(std::cerr, "Warning: Port specified in both -rpcconnect and -rpcport. Using -rpcport %u\n", port); + } + } + } // Obtain event base raii_event_base base = obtain_event_base(); @@ -940,7 +976,7 @@ static void GetWalletBalances(UniValue& result) const UniValue& balance = getbalances.find_value("result")["mine"]["trusted"]; balances.pushKV(wallet_name, balance); } - result.pushKV("balances", balances); + result.pushKV("balances", std::move(balances)); } /** diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 1c5b0c074c..89faa0123a 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -32,6 +32,11 @@ #include <functional> #include <memory> +using util::SplitString; +using util::ToString; +using util::TrimString; +using util::TrimStringView; + static bool fCreateBlank; static std::map<std::string,UniValue> registers; static const int CONTINUE_EXECUTION=-1; @@ -203,12 +208,12 @@ static CAmount ExtractAndValidateValue(const std::string& strValue) static void MutateTxVersion(CMutableTransaction& tx, const std::string& cmdVal) { - int64_t newVersion; - if (!ParseInt64(cmdVal, &newVersion) || newVersion < 1 || newVersion > TX_MAX_STANDARD_VERSION) { + uint32_t newVersion; + if (!ParseUInt32(cmdVal, &newVersion) || newVersion < 1 || newVersion > TX_MAX_STANDARD_VERSION) { throw std::runtime_error("Invalid TX version requested: '" + cmdVal + "'"); } - tx.nVersion = (int) newVersion; + tx.version = newVersion; } static void MutateTxLocktime(CMutableTransaction& tx, const std::string& cmdVal) @@ -692,21 +697,10 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr) tx = mergedTx; } -class Secp256k1Init -{ -public: - Secp256k1Init() { - ECC_Start(); - } - ~Secp256k1Init() { - ECC_Stop(); - } -}; - static void MutateTx(CMutableTransaction& tx, const std::string& command, const std::string& commandVal) { - std::unique_ptr<Secp256k1Init> ecc; + std::unique_ptr<ECC_Context> ecc; if (command == "nversion") MutateTxVersion(tx, commandVal); @@ -726,10 +720,10 @@ static void MutateTx(CMutableTransaction& tx, const std::string& command, else if (command == "outaddr") MutateTxAddOutAddr(tx, commandVal); else if (command == "outpubkey") { - ecc.reset(new Secp256k1Init()); + ecc.reset(new ECC_Context()); MutateTxAddOutPubKey(tx, commandVal); } else if (command == "outmultisig") { - ecc.reset(new Secp256k1Init()); + ecc.reset(new ECC_Context()); MutateTxAddOutMultiSig(tx, commandVal); } else if (command == "outscript") MutateTxAddOutScript(tx, commandVal); @@ -737,7 +731,7 @@ static void MutateTx(CMutableTransaction& tx, const std::string& command, MutateTxAddOutData(tx, commandVal); else if (command == "sign") { - ecc.reset(new Secp256k1Init()); + ecc.reset(new ECC_Context()); MutateTxSign(tx, commandVal); } diff --git a/src/bitcoin-wallet.cpp b/src/bitcoin-wallet.cpp index bee052bc46..b6f5c3f15d 100644 --- a/src/bitcoin-wallet.cpp +++ b/src/bitcoin-wallet.cpp @@ -24,6 +24,8 @@ #include <string> #include <tuple> +using util::Join; + const std::function<std::string(const char*)> G_TRANSLATION_FUN = nullptr; static void SetupWalletToolArgs(ArgsManager& argsman) @@ -40,6 +42,7 @@ static void SetupWalletToolArgs(ArgsManager& argsman) argsman.AddArg("-legacy", "Create legacy wallet. Only for 'create'", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); argsman.AddArg("-format=<format>", "The format of the wallet file to create. Either \"bdb\" or \"sqlite\". Only used with 'createfromdump'", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); argsman.AddArg("-printtoconsole", "Send trace/debug info to console (default: 1 when no -debug is true, 0 otherwise).", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); + argsman.AddArg("-withinternalbdb", "Use the internal Berkeley DB parser when dumping a Berkeley DB wallet file (default: false)", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); argsman.AddCommand("info", "Get wallet info"); argsman.AddCommand("create", "Create new wallet file"); @@ -128,10 +131,9 @@ MAIN_FUNCTION return EXIT_FAILURE; } - ECC_Start(); + ECC_Context ecc_context{}; if (!wallet::WalletTool::ExecuteWalletToolFunc(args, command->command)) { return EXIT_FAILURE; } - ECC_Stop(); return EXIT_SUCCESS; } diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index 7685bdea79..a09bb5c9da 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -14,11 +14,14 @@ #include <init.h> #include <interfaces/chain.h> #include <interfaces/init.h> +#include <kernel/context.h> #include <node/context.h> #include <node/interface_ui.h> +#include <node/warnings.h> #include <noui.h> #include <util/check.h> #include <util/exception.h> +#include <util/signalinterrupt.h> #include <util/strencodings.h> #include <util/syserror.h> #include <util/threadnames.h> @@ -179,7 +182,10 @@ static bool AppInit(NodeContext& node) return false; } + node.warnings = std::make_unique<node::Warnings>(); + node.kernel = std::make_unique<kernel::Context>(); + node.ecc_context = std::make_unique<ECC_Context>(); if (!AppInitSanityChecks(*node.kernel)) { // InitError will have been called with detailed error, which ends up on console diff --git a/src/blockfilter.cpp b/src/blockfilter.cpp index e045b88513..5e6702ccc3 100644 --- a/src/blockfilter.cpp +++ b/src/blockfilter.cpp @@ -16,6 +16,8 @@ #include <util/golombrice.h> #include <util/string.h> +using util::Join; + static const std::map<BlockFilterType, std::string> g_filter_types = { {BlockFilterType::BASIC, "basic"}, }; diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 539578085b..5d4401b719 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -21,6 +21,8 @@ #include <stdexcept> #include <vector> +using util::SplitString; + void ReadSigNetArgs(const ArgsManager& args, CChainParams::SigNetOptions& options) { if (args.IsArgSet("-signetseednode")) { diff --git a/src/clientversion.cpp b/src/clientversion.cpp index 3a5e060a39..e52703c8bf 100644 --- a/src/clientversion.cpp +++ b/src/clientversion.cpp @@ -5,14 +5,16 @@ #include <config/bitcoin-config.h> // IWYU pragma: keep #include <clientversion.h> +#include <util/string.h> #include <util/translation.h> #include <tinyformat.h> -#include <sstream> #include <string> #include <vector> +using util::Join; + /** * Name of client reported in the 'version' message. Report the same name * for both bitcoind and bitcoin-qt, to make it harder for attackers to @@ -64,19 +66,9 @@ std::string FormatFullVersion() */ std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector<std::string>& comments) { - std::ostringstream ss; - ss << "/"; - ss << name << ":" << FormatVersion(nClientVersion); - if (!comments.empty()) - { - std::vector<std::string>::const_iterator it(comments.begin()); - ss << "(" << *it; - for(++it; it != comments.end(); ++it) - ss << "; " << *it; - ss << ")"; - } - ss << "/"; - return ss.str(); + std::string comments_str; + if (!comments.empty()) comments_str = strprintf("(%s)", Join(comments, "; ")); + return strprintf("/%s:%s%s/", name, FormatVersion(nClientVersion), comments_str); } std::string CopyrightHolders(const std::string& strPrefix) diff --git a/src/coins.cpp b/src/coins.cpp index b62653e0de..a4e4d4ad32 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -361,7 +361,7 @@ static bool ExecuteBackedWrapper(Func func, const std::vector<std::function<void for (const auto& f : err_callbacks) { f(); } - LogPrintf("Error reading from database: %s\n", e.what()); + LogError("Error reading from database: %s\n", e.what()); // Starting the shutdown sequence and returning false to the caller would be // interpreted as 'entry not found' (as opposed to unable to read data), and // could lead to invalid interpretation. Just exit immediately, as we can't diff --git a/src/common/args.cpp b/src/common/args.cpp index c90eb0c685..caff36fdb3 100644 --- a/src/common/args.cpp +++ b/src/common/args.cpp @@ -696,12 +696,19 @@ bool HasTestOption(const ArgsManager& args, const std::string& test_option) fs::path GetDefaultDataDir() { - // Windows: C:\Users\Username\AppData\Roaming\Bitcoin + // Windows: + // old: C:\Users\Username\AppData\Roaming\Bitcoin + // new: C:\Users\Username\AppData\Local\Bitcoin // macOS: ~/Library/Application Support/Bitcoin // Unix-like: ~/.bitcoin #ifdef WIN32 // Windows - return GetSpecialFolderPath(CSIDL_APPDATA) / "Bitcoin"; + // Check for existence of datadir in old location and keep it there + fs::path legacy_path = GetSpecialFolderPath(CSIDL_APPDATA) / "Bitcoin"; + if (fs::exists(legacy_path)) return legacy_path; + + // Otherwise, fresh installs can start in the new, "proper" location + return GetSpecialFolderPath(CSIDL_LOCAL_APPDATA) / "Bitcoin"; #else fs::path pathRet; char* pszHome = getenv("HOME"); diff --git a/src/common/config.cpp b/src/common/config.cpp index 1c85273f69..98223fc3e3 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -27,6 +27,9 @@ #include <utility> #include <vector> +using util::TrimString; +using util::TrimStringView; + static bool GetConfigOptions(std::istream& stream, const std::string& filepath, std::string& error, std::vector<std::pair<std::string, std::string>>& options, std::list<SectionInfo>& sections) { std::string str, prefix; diff --git a/src/common/messages.cpp b/src/common/messages.cpp new file mode 100644 index 0000000000..9e88ca8b0f --- /dev/null +++ b/src/common/messages.cpp @@ -0,0 +1,139 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2022 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <common/messages.h> + +#include <common/types.h> +#include <policy/fees.h> +#include <node/types.h> +#include <tinyformat.h> +#include <util/strencodings.h> +#include <util/string.h> +#include <util/translation.h> + +#include <cassert> +#include <map> +#include <string> +#include <utility> +#include <vector> + +using node::TransactionError; +using util::Join; + +namespace common { +std::string StringForFeeReason(FeeReason reason) +{ + static const std::map<FeeReason, std::string> fee_reason_strings = { + {FeeReason::NONE, "None"}, + {FeeReason::HALF_ESTIMATE, "Half Target 60% Threshold"}, + {FeeReason::FULL_ESTIMATE, "Target 85% Threshold"}, + {FeeReason::DOUBLE_ESTIMATE, "Double Target 95% Threshold"}, + {FeeReason::CONSERVATIVE, "Conservative Double Target longer horizon"}, + {FeeReason::MEMPOOL_MIN, "Mempool Min Fee"}, + {FeeReason::PAYTXFEE, "PayTxFee set"}, + {FeeReason::FALLBACK, "Fallback fee"}, + {FeeReason::REQUIRED, "Minimum Required Fee"}, + }; + auto reason_string = fee_reason_strings.find(reason); + + if (reason_string == fee_reason_strings.end()) return "Unknown"; + + return reason_string->second; +} + +const std::vector<std::pair<std::string, FeeEstimateMode>>& FeeModeMap() +{ + static const std::vector<std::pair<std::string, FeeEstimateMode>> FEE_MODES = { + {"unset", FeeEstimateMode::UNSET}, + {"economical", FeeEstimateMode::ECONOMICAL}, + {"conservative", FeeEstimateMode::CONSERVATIVE}, + }; + return FEE_MODES; +} + +std::string FeeModes(const std::string& delimiter) +{ + return Join(FeeModeMap(), delimiter, [&](const std::pair<std::string, FeeEstimateMode>& i) { return i.first; }); +} + +std::string InvalidEstimateModeErrorMessage() +{ + return "Invalid estimate_mode parameter, must be one of: \"" + FeeModes("\", \"") + "\""; +} + +bool FeeModeFromString(const std::string& mode_string, FeeEstimateMode& fee_estimate_mode) +{ + auto searchkey = ToUpper(mode_string); + for (const auto& pair : FeeModeMap()) { + if (ToUpper(pair.first) == searchkey) { + fee_estimate_mode = pair.second; + return true; + } + } + return false; +} + +bilingual_str PSBTErrorString(PSBTError err) +{ + switch (err) { + case PSBTError::MISSING_INPUTS: + return Untranslated("Inputs missing or spent"); + case PSBTError::SIGHASH_MISMATCH: + return Untranslated("Specified sighash value does not match value stored in PSBT"); + case PSBTError::EXTERNAL_SIGNER_NOT_FOUND: + return Untranslated("External signer not found"); + case PSBTError::EXTERNAL_SIGNER_FAILED: + return Untranslated("External signer failed to sign"); + case PSBTError::UNSUPPORTED: + return Untranslated("Signer does not support PSBT"); + // no default case, so the compiler can warn about missing cases + } + assert(false); +} + +bilingual_str TransactionErrorString(const TransactionError err) +{ + switch (err) { + case TransactionError::OK: + return Untranslated("No error"); + case TransactionError::MISSING_INPUTS: + return Untranslated("Inputs missing or spent"); + case TransactionError::ALREADY_IN_CHAIN: + return Untranslated("Transaction already in block chain"); + case TransactionError::MEMPOOL_REJECTED: + return Untranslated("Transaction rejected by mempool"); + case TransactionError::MEMPOOL_ERROR: + return Untranslated("Mempool internal error"); + case TransactionError::MAX_FEE_EXCEEDED: + return Untranslated("Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)"); + case TransactionError::MAX_BURN_EXCEEDED: + return Untranslated("Unspendable output exceeds maximum configured by user (maxburnamount)"); + case TransactionError::INVALID_PACKAGE: + return Untranslated("Transaction rejected due to invalid package"); + // no default case, so the compiler can warn about missing cases + } + assert(false); +} + +bilingual_str ResolveErrMsg(const std::string& optname, const std::string& strBind) +{ + return strprintf(_("Cannot resolve -%s address: '%s'"), optname, strBind); +} + +bilingual_str InvalidPortErrMsg(const std::string& optname, const std::string& invalid_value) +{ + return strprintf(_("Invalid port specified in %s: '%s'"), optname, invalid_value); +} + +bilingual_str AmountHighWarn(const std::string& optname) +{ + return strprintf(_("%s is set very high!"), optname); +} + +bilingual_str AmountErrMsg(const std::string& optname, const std::string& strValue) +{ + return strprintf(_("Invalid amount for -%s=<amount>: '%s'"), optname, strValue); +} +} // namespace common diff --git a/src/common/messages.h b/src/common/messages.h new file mode 100644 index 0000000000..68e7bb2169 --- /dev/null +++ b/src/common/messages.h @@ -0,0 +1,38 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2020 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +//! @file common/messages.h is a home for simple string functions returning +//! descriptive messages that are used in RPC and GUI interfaces or log +//! messages, and are called in different parts of the codebase across +//! node/wallet/gui boundaries. + +#ifndef BITCOIN_COMMON_MESSAGES_H +#define BITCOIN_COMMON_MESSAGES_H + +#include <string> + +struct bilingual_str; + +enum class FeeEstimateMode; +enum class FeeReason; +namespace node { +enum class TransactionError; +} // namespace node + +namespace common { +enum class PSBTError; +bool FeeModeFromString(const std::string& mode_string, FeeEstimateMode& fee_estimate_mode); +std::string StringForFeeReason(FeeReason reason); +std::string FeeModes(const std::string& delimiter); +std::string InvalidEstimateModeErrorMessage(); +bilingual_str PSBTErrorString(PSBTError error); +bilingual_str TransactionErrorString(const node::TransactionError error); +bilingual_str ResolveErrMsg(const std::string& optname, const std::string& strBind); +bilingual_str InvalidPortErrMsg(const std::string& optname, const std::string& strPort); +bilingual_str AmountHighWarn(const std::string& optname); +bilingual_str AmountErrMsg(const std::string& optname, const std::string& strValue); +} // namespace common + +#endif // BITCOIN_COMMON_MESSAGES_H diff --git a/src/util/message.cpp b/src/common/signmessage.cpp index 1afb28cc10..1612751e44 100644 --- a/src/util/message.cpp +++ b/src/common/signmessage.cpp @@ -3,12 +3,12 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <common/signmessage.h> #include <hash.h> #include <key.h> #include <key_io.h> #include <pubkey.h> #include <uint256.h> -#include <util/message.h> #include <util/strencodings.h> #include <cassert> diff --git a/src/util/message.h b/src/common/signmessage.h index d0e2422574..215b563bbb 100644 --- a/src/util/message.h +++ b/src/common/signmessage.h @@ -3,8 +3,8 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#ifndef BITCOIN_UTIL_MESSAGE_H -#define BITCOIN_UTIL_MESSAGE_H +#ifndef BITCOIN_COMMON_SIGNMESSAGE_H +#define BITCOIN_COMMON_SIGNMESSAGE_H #include <uint256.h> @@ -74,4 +74,4 @@ uint256 MessageHash(const std::string& message); std::string SigningResultString(const SigningResult res); -#endif // BITCOIN_UTIL_MESSAGE_H +#endif // BITCOIN_COMMON_SIGNMESSAGE_H diff --git a/src/common/system.cpp b/src/common/system.cpp index ddd0feda3b..6d04c8a7bc 100644 --- a/src/common/system.cpp +++ b/src/common/system.cpp @@ -28,6 +28,8 @@ #include <string> #include <thread> +using util::ReplaceAll; + // Application startup time (used for uptime calculation) const int64_t nStartupTime = GetTime(); diff --git a/src/common/types.h b/src/common/types.h new file mode 100644 index 0000000000..0d9cb67ce9 --- /dev/null +++ b/src/common/types.h @@ -0,0 +1,26 @@ +// Copyright (c) 2010-2021 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +//! @file common/types.h is a home for simple enum and struct type definitions +//! that can be used internally by functions in the libbitcoin_common library, +//! but also used externally by node, wallet, and GUI code. +//! +//! This file is intended to define only simple types that do not have external +//! dependencies. More complicated types should be defined in dedicated header +//! files. + +#ifndef BITCOIN_COMMON_TYPES_H +#define BITCOIN_COMMON_TYPES_H + +namespace common { +enum class PSBTError { + MISSING_INPUTS, + SIGHASH_MISMATCH, + EXTERNAL_SIGNER_NOT_FOUND, + EXTERNAL_SIGNER_FAILED, + UNSUPPORTED, +}; +} // namespace common + +#endif // BITCOIN_COMMON_TYPES_H diff --git a/src/compressor.h b/src/compressor.h index 0968454679..a0970c595e 100644 --- a/src/compressor.h +++ b/src/compressor.h @@ -55,8 +55,8 @@ struct ScriptCompression { /** * make this static for now (there are only 6 special scripts defined) - * this can potentially be extended together with a new nVersion for - * transactions, in which case this value becomes dependent on nVersion + * this can potentially be extended together with a new version for + * transactions, in which case this value becomes dependent on version * and nHeight of the enclosing transaction. */ static const unsigned int nSpecialScripts = 6; diff --git a/src/consensus/tx_verify.cpp b/src/consensus/tx_verify.cpp index 154146f08d..95466b759c 100644 --- a/src/consensus/tx_verify.cpp +++ b/src/consensus/tx_verify.cpp @@ -48,11 +48,7 @@ std::pair<int, int64_t> CalculateSequenceLocks(const CTransaction &tx, int flags int nMinHeight = -1; int64_t nMinTime = -1; - // tx.nVersion is signed integer so requires cast to unsigned otherwise - // we would be doing a signed comparison and half the range of nVersion - // wouldn't support BIP 68. - bool fEnforceBIP68 = static_cast<uint32_t>(tx.nVersion) >= 2 - && flags & LOCKTIME_VERIFY_SEQUENCE; + bool fEnforceBIP68 = tx.version >= 2 && flags & LOCKTIME_VERIFY_SEQUENCE; // Do not enforce sequence numbers as a relative lock time // unless we have been instructed to diff --git a/src/core_read.cpp b/src/core_read.cpp index 5956d9df5f..114f92fc45 100644 --- a/src/core_read.cpp +++ b/src/core_read.cpp @@ -16,6 +16,8 @@ #include <algorithm> #include <string> +using util::SplitString; + namespace { class OpCodeParser { diff --git a/src/core_write.cpp b/src/core_write.cpp index 63f2c36b5a..253dfde100 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -174,9 +174,7 @@ void TxToUniv(const CTransaction& tx, const uint256& block_hash, UniValue& entry entry.pushKV("txid", tx.GetHash().GetHex()); entry.pushKV("hash", tx.GetWitnessHash().GetHex()); - // Transaction version is actually unsigned in consensus checks, just signed in memory, - // so cast to unsigned before giving it to the user. - entry.pushKV("version", static_cast<int64_t>(static_cast<uint32_t>(tx.nVersion))); + entry.pushKV("version", tx.version); entry.pushKV("size", tx.GetTotalSize()); entry.pushKV("vsize", (GetTransactionWeight(tx) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR); entry.pushKV("weight", GetTransactionWeight(tx)); @@ -201,14 +199,14 @@ void TxToUniv(const CTransaction& tx, const uint256& block_hash, UniValue& entry UniValue o(UniValue::VOBJ); o.pushKV("asm", ScriptToAsmStr(txin.scriptSig, true)); o.pushKV("hex", HexStr(txin.scriptSig)); - in.pushKV("scriptSig", o); + in.pushKV("scriptSig", std::move(o)); } if (!tx.vin[i].scriptWitness.IsNull()) { UniValue txinwitness(UniValue::VARR); for (const auto& item : tx.vin[i].scriptWitness.stack) { txinwitness.push_back(HexStr(item)); } - in.pushKV("txinwitness", txinwitness); + in.pushKV("txinwitness", std::move(txinwitness)); } if (have_undo) { const Coin& prev_coin = txundo->vprevout[i]; @@ -224,14 +222,14 @@ void TxToUniv(const CTransaction& tx, const uint256& block_hash, UniValue& entry p.pushKV("generated", bool(prev_coin.fCoinBase)); p.pushKV("height", uint64_t(prev_coin.nHeight)); p.pushKV("value", ValueFromAmount(prev_txout.nValue)); - p.pushKV("scriptPubKey", o_script_pub_key); - in.pushKV("prevout", p); + p.pushKV("scriptPubKey", std::move(o_script_pub_key)); + in.pushKV("prevout", std::move(p)); } } in.pushKV("sequence", (int64_t)txin.nSequence); - vin.push_back(in); + vin.push_back(std::move(in)); } - entry.pushKV("vin", vin); + entry.pushKV("vin", std::move(vin)); UniValue vout(UniValue::VARR); for (unsigned int i = 0; i < tx.vout.size(); i++) { @@ -244,14 +242,14 @@ void TxToUniv(const CTransaction& tx, const uint256& block_hash, UniValue& entry UniValue o(UniValue::VOBJ); ScriptToUniv(txout.scriptPubKey, /*out=*/o, /*include_hex=*/true, /*include_address=*/true); - out.pushKV("scriptPubKey", o); - vout.push_back(out); + out.pushKV("scriptPubKey", std::move(o)); + vout.push_back(std::move(out)); if (have_undo) { amt_total_out += txout.nValue; } } - entry.pushKV("vout", vout); + entry.pushKV("vout", std::move(vout)); if (have_undo) { const CAmount fee = amt_total_in - amt_total_out; diff --git a/src/crypto/hex_base.cpp b/src/crypto/hex_base.cpp new file mode 100644 index 0000000000..67d691b63e --- /dev/null +++ b/src/crypto/hex_base.cpp @@ -0,0 +1,67 @@ +// Copyright (c) 2009-present The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <crypto/hex_base.h> + +#include <array> +#include <cstring> +#include <string> + +namespace { + +using ByteAsHex = std::array<char, 2>; + +constexpr std::array<ByteAsHex, 256> CreateByteToHexMap() +{ + constexpr char hexmap[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + + std::array<ByteAsHex, 256> byte_to_hex{}; + for (size_t i = 0; i < byte_to_hex.size(); ++i) { + byte_to_hex[i][0] = hexmap[i >> 4]; + byte_to_hex[i][1] = hexmap[i & 15]; + } + return byte_to_hex; +} + +} // namespace + +std::string HexStr(const Span<const uint8_t> s) +{ + std::string rv(s.size() * 2, '\0'); + static constexpr auto byte_to_hex = CreateByteToHexMap(); + static_assert(sizeof(byte_to_hex) == 512); + + char* it = rv.data(); + for (uint8_t v : s) { + std::memcpy(it, byte_to_hex[v].data(), 2); + it += 2; + } + + assert(it == rv.data() + rv.size()); + return rv; +} + +const signed char p_util_hexdigit[256] = +{ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + 0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1, + -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, }; + +signed char HexDigit(char c) +{ + return p_util_hexdigit[(unsigned char)c]; +} + diff --git a/src/crypto/hex_base.h b/src/crypto/hex_base.h new file mode 100644 index 0000000000..cdfea68c29 --- /dev/null +++ b/src/crypto/hex_base.h @@ -0,0 +1,23 @@ +// Copyright (c) 2009-present The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_CRYPTO_HEX_BASE_H +#define BITCOIN_CRYPTO_HEX_BASE_H + +#include <span.h> + +#include <cstddef> +#include <cstdint> +#include <string> + +/** + * Convert a span of bytes to a lower-case hexadecimal string. + */ +std::string HexStr(const Span<const uint8_t> s); +inline std::string HexStr(const Span<const char> s) { return HexStr(MakeUCharSpan(s)); } +inline std::string HexStr(const Span<const std::byte> s) { return HexStr(MakeUCharSpan(s)); } + +signed char HexDigit(char c); + +#endif // BITCOIN_CRYPTO_HEX_BASE_H diff --git a/src/crypto/sha256_sse4.cpp b/src/crypto/sha256_sse4.cpp index f4557291ce..f0e255a23c 100644 --- a/src/crypto/sha256_sse4.cpp +++ b/src/crypto/sha256_sse4.cpp @@ -13,6 +13,13 @@ namespace sha256_sse4 { void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks) +#if defined(__clang__) && !defined(__OPTIMIZE__) + /* + clang is unable to compile this with -O0 and -fsanitize=address. + See upstream bug: https://github.com/llvm/llvm-project/issues/92182 + */ + __attribute__((no_sanitize("address"))) +#endif { static const uint32_t K256 alignas(16) [] = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, diff --git a/src/dummywallet.cpp b/src/dummywallet.cpp index 9160ec19e6..42282c32d1 100644 --- a/src/dummywallet.cpp +++ b/src/dummywallet.cpp @@ -53,6 +53,7 @@ void DummyWalletInit::AddWalletOptions(ArgsManager& argsman) const "-walletrejectlongchains", "-walletcrosschain", "-unsafesqlitesync", + "-swapbdbendian", }); } diff --git a/src/httprpc.cpp b/src/httprpc.cpp index 66e0591c44..af809eaf38 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -26,6 +26,9 @@ #include <string> #include <vector> +using util::SplitString; +using util::TrimStringView; + /** WWW-Authenticate to present with 401 Unauthorized response */ static const char* WWW_AUTH_HEADER_DATA = "Basic realm=\"jsonrpc\""; @@ -76,8 +79,11 @@ static std::vector<std::vector<std::string>> g_rpcauth; static std::map<std::string, std::set<std::string>> g_rpc_whitelist; static bool g_rpc_whitelist_default = false; -static void JSONErrorReply(HTTPRequest* req, const UniValue& objError, const UniValue& id) +static void JSONErrorReply(HTTPRequest* req, UniValue objError, const JSONRPCRequest& jreq) { + // Sending HTTP errors is a legacy JSON-RPC behavior. + Assume(jreq.m_json_version != JSONRPCVersion::V2); + // Send error reply from json-rpc error object int nStatus = HTTP_INTERNAL_SERVER_ERROR; int code = objError.find_value("code").getInt<int>(); @@ -87,7 +93,7 @@ static void JSONErrorReply(HTTPRequest* req, const UniValue& objError, const Uni else if (code == RPC_METHOD_NOT_FOUND) nStatus = HTTP_NOT_FOUND; - std::string strReply = JSONRPCReply(NullUniValue, objError, id); + std::string strReply = JSONRPCReplyObj(NullUniValue, std::move(objError), jreq.id, jreq.m_json_version).write() + "\n"; req->WriteHeader("Content-Type", "application/json"); req->WriteReply(nStatus, strReply); @@ -188,7 +194,7 @@ static bool HTTPReq_JSONRPC(const std::any& context, HTTPRequest* req) // Set the URI jreq.URI = req->GetURI(); - std::string strReply; + UniValue reply; bool user_has_whitelist = g_rpc_whitelist.count(jreq.authUser); if (!user_has_whitelist && g_rpc_whitelist_default) { LogPrintf("RPC User %s not allowed to call any methods\n", jreq.authUser); @@ -203,13 +209,23 @@ static bool HTTPReq_JSONRPC(const std::any& context, HTTPRequest* req) req->WriteReply(HTTP_FORBIDDEN); return false; } - UniValue result = tableRPC.execute(jreq); - // Send reply - strReply = JSONRPCReply(result, NullUniValue, jreq.id); + // Legacy 1.0/1.1 behavior is for failed requests to throw + // exceptions which return HTTP errors and RPC errors to the client. + // 2.0 behavior is to catch exceptions and return HTTP success with + // RPC errors, as long as there is not an actual HTTP server error. + const bool catch_errors{jreq.m_json_version == JSONRPCVersion::V2}; + reply = JSONRPCExec(jreq, catch_errors); + + if (jreq.IsNotification()) { + // Even though we do execute notifications, we do not respond to them + req->WriteReply(HTTP_NO_CONTENT); + return true; + } // array of requests } else if (valRequest.isArray()) { + // Check authorization for each request's method if (user_has_whitelist) { for (unsigned int reqIdx = 0; reqIdx < valRequest.size(); reqIdx++) { if (!valRequest[reqIdx].isObject()) { @@ -226,18 +242,49 @@ static bool HTTPReq_JSONRPC(const std::any& context, HTTPRequest* req) } } } - strReply = JSONRPCExecBatch(jreq, valRequest.get_array()); + + // Execute each request + reply = UniValue::VARR; + for (size_t i{0}; i < valRequest.size(); ++i) { + // Batches never throw HTTP errors, they are always just included + // in "HTTP OK" responses. Notifications never get any response. + UniValue response; + try { + jreq.parse(valRequest[i]); + response = JSONRPCExec(jreq, /*catch_errors=*/true); + } catch (UniValue& e) { + response = JSONRPCReplyObj(NullUniValue, std::move(e), jreq.id, jreq.m_json_version); + } catch (const std::exception& e) { + response = JSONRPCReplyObj(NullUniValue, JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id, jreq.m_json_version); + } + if (!jreq.IsNotification()) { + reply.push_back(std::move(response)); + } + } + // Return no response for an all-notification batch, but only if the + // batch request is non-empty. Technically according to the JSON-RPC + // 2.0 spec, an empty batch request should also return no response, + // However, if the batch request is empty, it means the request did + // not contain any JSON-RPC version numbers, so returning an empty + // response could break backwards compatibility with old RPC clients + // relying on previous behavior. Return an empty array instead of an + // empty response in this case to favor being backwards compatible + // over complying with the JSON-RPC 2.0 spec in this case. + if (reply.size() == 0 && valRequest.size() > 0) { + req->WriteReply(HTTP_NO_CONTENT); + return true; + } } else throw JSONRPCError(RPC_PARSE_ERROR, "Top-level object parse error"); req->WriteHeader("Content-Type", "application/json"); - req->WriteReply(HTTP_OK, strReply); - } catch (const UniValue& objError) { - JSONErrorReply(req, objError, jreq.id); + req->WriteReply(HTTP_OK, reply.write() + "\n"); + } catch (UniValue& e) { + JSONErrorReply(req, std::move(e), jreq); return false; } catch (const std::exception& e) { - JSONErrorReply(req, JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id); + JSONErrorReply(req, JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq); return false; } return true; diff --git a/src/httpserver.cpp b/src/httpserver.cpp index b1d4dc9234..b6c6db8b35 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -26,6 +26,7 @@ #include <deque> #include <memory> #include <optional> +#include <span> #include <string> #include <unordered_map> @@ -634,7 +635,7 @@ void HTTPRequest::WriteHeader(const std::string& hdr, const std::string& value) * Replies must be sent in the main loop in the main http thread, * this cannot be done from worker threads. */ -void HTTPRequest::WriteReply(int nStatus, const std::string& strReply) +void HTTPRequest::WriteReply(int nStatus, std::span<const std::byte> reply) { assert(!replySent && req); if (m_interrupt) { @@ -643,7 +644,7 @@ void HTTPRequest::WriteReply(int nStatus, const std::string& strReply) // Send event to main http thread to send reply message struct evbuffer* evb = evhttp_request_get_output_buffer(req); assert(evb); - evbuffer_add(evb, strReply.data(), strReply.size()); + evbuffer_add(evb, reply.data(), reply.size()); auto req_copy = req; HTTPEvent* ev = new HTTPEvent(eventBase, true, [req_copy, nStatus]{ evhttp_send_reply(req_copy, nStatus, nullptr, nullptr); diff --git a/src/httpserver.h b/src/httpserver.h index 9a49877f09..991081bab8 100644 --- a/src/httpserver.h +++ b/src/httpserver.h @@ -7,6 +7,7 @@ #include <functional> #include <optional> +#include <span> #include <string> namespace util { @@ -123,12 +124,16 @@ public: /** * Write HTTP reply. * nStatus is the HTTP status code to send. - * strReply is the body of the reply. Keep it empty to send a standard message. + * reply is the body of the reply. Keep it empty to send a standard message. * * @note Can be called only once. As this will give the request back to the * main thread, do not call any other HTTPRequest methods after calling this. */ - void WriteReply(int nStatus, const std::string& strReply = ""); + void WriteReply(int nStatus, std::string_view reply = "") + { + WriteReply(nStatus, std::as_bytes(std::span{reply.data(), reply.size()})); + } + void WriteReply(int nStatus, std::span<const std::byte> reply); }; /** Get the query parameter value from request uri for a specified key, or std::nullopt if the key diff --git a/src/i2p.cpp b/src/i2p.cpp index 962adb124d..0420bc9238 100644 --- a/src/i2p.cpp +++ b/src/i2p.cpp @@ -12,12 +12,12 @@ #include <netaddress.h> #include <netbase.h> #include <random.h> +#include <script/parsing.h> #include <sync.h> #include <tinyformat.h> #include <util/fs.h> #include <util/readwritefile.h> #include <util/sock.h> -#include <util/spanparsing.h> #include <util/strencodings.h> #include <util/threadinterrupt.h> @@ -26,6 +26,8 @@ #include <stdexcept> #include <string> +using util::Split; + namespace i2p { /** @@ -146,7 +148,7 @@ bool Session::Listen(Connection& conn) conn.sock = StreamAccept(); return true; } catch (const std::runtime_error& e) { - Log("Error listening: %s", e.what()); + LogPrintLevel(BCLog::I2P, BCLog::Level::Error, "Couldn't listen: %s\n", e.what()); CheckControlSock(); } return false; @@ -202,7 +204,11 @@ bool Session::Accept(Connection& conn) return true; } - Log("Error accepting%s: %s", disconnect ? " (will close the session)" : "", errmsg); + if (*m_interrupt) { + LogPrintLevel(BCLog::I2P, BCLog::Level::Debug, "Accept was interrupted\n"); + } else { + LogPrintLevel(BCLog::I2P, BCLog::Level::Debug, "Error accepting%s: %s\n", disconnect ? " (will close the session)" : "", errmsg); + } if (disconnect) { LOCK(m_mutex); Disconnect(); @@ -217,7 +223,7 @@ bool Session::Connect(const CService& to, Connection& conn, bool& proxy_error) // Refuse connecting to arbitrary ports. We don't specify any destination port to the SAM proxy // when connecting (SAM 3.1 does not use ports) and it forces/defaults it to I2P_SAM31_PORT. if (to.GetPort() != I2P_SAM31_PORT) { - Log("Error connecting to %s, connection refused due to arbitrary port %s", to.ToStringAddrPort(), to.GetPort()); + LogPrintLevel(BCLog::I2P, BCLog::Level::Debug, "Error connecting to %s, connection refused due to arbitrary port %s\n", to.ToStringAddrPort(), to.GetPort()); proxy_error = false; return false; } @@ -265,7 +271,7 @@ bool Session::Connect(const CService& to, Connection& conn, bool& proxy_error) throw std::runtime_error(strprintf("\"%s\"", connect_reply.full)); } catch (const std::runtime_error& e) { - Log("Error connecting to %s: %s", to.ToStringAddrPort(), e.what()); + LogPrintLevel(BCLog::I2P, BCLog::Level::Debug, "Error connecting to %s: %s\n", to.ToStringAddrPort(), e.what()); CheckControlSock(); return false; } @@ -283,12 +289,6 @@ std::string Session::Reply::Get(const std::string& key) const return pos->second.value(); } -template <typename... Args> -void Session::Log(const std::string& fmt, const Args&... args) const -{ - LogPrint(BCLog::I2P, "%s\n", tfm::format(fmt, args...)); -} - Session::Reply Session::SendRequestAndGetReply(const Sock& sock, const std::string& request, bool check_result_ok) const @@ -308,7 +308,7 @@ Session::Reply Session::SendRequestAndGetReply(const Sock& sock, reply.full = sock.RecvUntilTerminator('\n', recv_timeout, *m_interrupt, MAX_MSG_SIZE); - for (const auto& kv : spanparsing::Split(reply.full, ' ')) { + for (const auto& kv : Split(reply.full, ' ')) { const auto& pos = std::find(kv.begin(), kv.end(), '='); if (pos != kv.end()) { reply.keys.emplace(std::string{kv.begin(), pos}, std::string{pos + 1, kv.end()}); @@ -344,7 +344,7 @@ void Session::CheckControlSock() std::string errmsg; if (m_control_sock && !m_control_sock->IsConnected(errmsg)) { - Log("Control socket error: %s", errmsg); + LogPrintLevel(BCLog::I2P, BCLog::Level::Debug, "Control socket error: %s\n", errmsg); Disconnect(); } } @@ -414,7 +414,7 @@ void Session::CreateIfNotCreatedAlready() const auto session_type = m_transient ? "transient" : "persistent"; const auto session_id = GetRandHash().GetHex().substr(0, 10); // full is overkill, too verbose in the logs - Log("Creating %s SAM session %s with %s", session_type, session_id, m_control_host.ToString()); + LogPrintLevel(BCLog::I2P, BCLog::Level::Debug, "Creating %s SAM session %s with %s\n", session_type, session_id, m_control_host.ToString()); auto sock = Hello(); @@ -451,7 +451,7 @@ void Session::CreateIfNotCreatedAlready() m_session_id = session_id; m_control_sock = std::move(sock); - Log("%s SAM session %s created, my address=%s", + LogPrintLevel(BCLog::I2P, BCLog::Level::Info, "%s SAM session %s created, my address=%s\n", Capitalize(session_type), m_session_id, m_my_addr.ToStringAddrPort()); @@ -482,9 +482,9 @@ void Session::Disconnect() { if (m_control_sock) { if (m_session_id.empty()) { - Log("Destroying incomplete SAM session"); + LogPrintLevel(BCLog::I2P, BCLog::Level::Info, "Destroying incomplete SAM session\n"); } else { - Log("Destroying SAM session %s", m_session_id); + LogPrintLevel(BCLog::I2P, BCLog::Level::Info, "Destroying SAM session %s\n", m_session_id); } m_control_sock.reset(); } @@ -157,14 +157,6 @@ private: }; /** - * Log a message in the `BCLog::I2P` category. - * @param[in] fmt printf(3)-like format string. - * @param[in] args printf(3)-like arguments that correspond to `fmt`. - */ - template <typename... Args> - void Log(const std::string& fmt, const Args&... args) const; - - /** * Send request and get a reply from the SAM proxy. * @param[in] sock A socket that is connected to the SAM proxy. * @param[in] request Raw request to send, a newline terminator is appended to it. diff --git a/src/index/base.cpp b/src/index/base.cpp index e66c89f9e4..955d7b67c9 100644 --- a/src/index/base.cpp +++ b/src/index/base.cpp @@ -17,7 +17,6 @@ #include <util/thread.h> #include <util/translation.h> #include <validation.h> // For g_chainman -#include <warnings.h> #include <string> #include <utility> @@ -31,7 +30,7 @@ template <typename... Args> void BaseIndex::FatalErrorf(const char* fmt, const Args&... args) { auto message = tfm::format(fmt, args...); - node::AbortNode(m_chain->context()->shutdown, m_chain->context()->exit_status, Untranslated(message)); + node::AbortNode(m_chain->context()->shutdown, m_chain->context()->exit_status, Untranslated(message), m_chain->context()->warnings.get()); } CBlockLocator GetLocator(interfaces::Chain& chain, const uint256& block_hash) diff --git a/src/init.cpp b/src/init.cpp index 6bbc0827bd..c9405153b4 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -31,7 +31,10 @@ #include <init/common.h> #include <interfaces/chain.h> #include <interfaces/init.h> +#include <interfaces/mining.h> #include <interfaces/node.h> +#include <kernel/context.h> +#include <key.h> #include <logging.h> #include <mapport.h> #include <net.h> @@ -69,12 +72,14 @@ #include <txdb.h> #include <txmempool.h> #include <util/asmap.h> +#include <util/batchpriority.h> #include <util/chaintype.h> #include <util/check.h> #include <util/fs.h> #include <util/fs_helpers.h> #include <util/moneystr.h> #include <util/result.h> +#include <util/signalinterrupt.h> #include <util/strencodings.h> #include <util/string.h> #include <util/syserror.h> @@ -105,12 +110,15 @@ #include <boost/signals2/signal.hpp> -#if ENABLE_ZMQ +#ifdef ENABLE_ZMQ #include <zmq/zmqabstractnotifier.h> #include <zmq/zmqnotificationinterface.h> #include <zmq/zmqrpc.h> #endif +using common::AmountErrMsg; +using common::InvalidPortErrMsg; +using common::ResolveErrMsg; using kernel::DumpMempool; using kernel::LoadMempool; using kernel::ValidationCacheSizes; @@ -122,7 +130,6 @@ using node::CalculateCacheSizes; using node::DEFAULT_PERSIST_MEMPOOL; using node::DEFAULT_PRINTPRIORITY; using node::DEFAULT_STOPATHEIGHT; -using node::fReindex; using node::KernelNotifications; using node::LoadChainstate; using node::MempoolPath; @@ -130,6 +137,9 @@ using node::NodeContext; using node::ShouldPersistMempool; using node::ImportBlocks; using node::VerifyLoadedChainstate; +using util::Join; +using util::ReplaceAll; +using util::ToString; static constexpr bool DEFAULT_PROXYRANDOMIZE{true}; static constexpr bool DEFAULT_REST_ENABLE{false}; @@ -355,7 +365,7 @@ void Shutdown(NodeContext& node) client->stop(); } -#if ENABLE_ZMQ +#ifdef ENABLE_ZMQ if (g_zmq_notification_interface) { if (node.validation_signals) node.validation_signals->UnregisterValidationInterface(g_zmq_notification_interface.get()); g_zmq_notification_interface.reset(); @@ -371,6 +381,7 @@ void Shutdown(NodeContext& node) node.chainman.reset(); node.validation_signals.reset(); node.scheduler.reset(); + node.ecc_context.reset(); node.kernel.reset(); RemovePidFile(*node.args); @@ -399,7 +410,7 @@ static void HandleSIGHUP(int) static BOOL WINAPI consoleCtrlHandler(DWORD dwCtrlType) { if (!(*Assert(g_shutdown))()) { - LogPrintf("Error: failed to send shutdown signal on Ctrl-C\n"); + LogError("Failed to send shutdown signal on Ctrl-C\n"); return false; } Sleep(INFINITE); @@ -521,7 +532,7 @@ void SetupServerArgs(ArgsManager& argsman) argsman.AddArg("-maxreceivebuffer=<n>", strprintf("Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)", DEFAULT_MAXRECEIVEBUFFER), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); argsman.AddArg("-maxsendbuffer=<n>", strprintf("Maximum per-connection memory usage for the send buffer, <n>*1000 bytes (default: %u)", DEFAULT_MAXSENDBUFFER), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); argsman.AddArg("-maxuploadtarget=<n>", strprintf("Tries to keep outbound traffic under the given target per 24h. Limit does not apply to peers with 'download' permission or blocks created within past week. 0 = no limit (default: %s). Optional suffix units [k|K|m|M|g|G|t|T] (default: M). Lowercase is 1000 base while uppercase is 1024 base", DEFAULT_MAX_UPLOAD_TARGET), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); -#if HAVE_SOCKADDR_UN +#ifdef HAVE_SOCKADDR_UN argsman.AddArg("-onion=<ip:port|path>", "Use separate SOCKS5 proxy to reach peers via Tor onion services, set -noonion to disable (default: -proxy). May be a local file path prefixed with 'unix:'.", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); #else argsman.AddArg("-onion=<ip:port>", "Use separate SOCKS5 proxy to reach peers via Tor onion services, set -noonion to disable (default: -proxy)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); @@ -533,10 +544,8 @@ void SetupServerArgs(ArgsManager& argsman) argsman.AddArg("-peerbloomfilters", strprintf("Support filtering of blocks and transaction with bloom filters (default: %u)", DEFAULT_PEERBLOOMFILTERS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); argsman.AddArg("-peerblockfilters", strprintf("Serve compact block filters to peers per BIP 157 (default: %u)", DEFAULT_PEERBLOCKFILTERS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); argsman.AddArg("-txreconciliation", strprintf("Enable transaction reconciliations per BIP 330 (default: %d)", DEFAULT_TXRECONCILIATION_ENABLE), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CONNECTION); - // TODO: remove the sentence "Nodes not using ... incoming connections." once the changes from - // https://github.com/bitcoin/bitcoin/pull/23542 have become widespread. - argsman.AddArg("-port=<port>", strprintf("Listen for connections on <port>. Nodes not using the default ports (default: %u, testnet: %u, signet: %u, regtest: %u) are unlikely to get incoming connections. Not relevant for I2P (see doc/i2p.md).", defaultChainParams->GetDefaultPort(), testnetChainParams->GetDefaultPort(), signetChainParams->GetDefaultPort(), regtestChainParams->GetDefaultPort()), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION); -#if HAVE_SOCKADDR_UN + argsman.AddArg("-port=<port>", strprintf("Listen for connections on <port> (default: %u, testnet: %u, signet: %u, regtest: %u). Not relevant for I2P (see doc/i2p.md).", defaultChainParams->GetDefaultPort(), testnetChainParams->GetDefaultPort(), signetChainParams->GetDefaultPort(), regtestChainParams->GetDefaultPort()), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION); +#ifdef HAVE_SOCKADDR_UN argsman.AddArg("-proxy=<ip:port|path>", "Connect through SOCKS5 proxy, set -noproxy to disable (default: disabled). May be a local file path prefixed with 'unix:' if the proxy supports it.", ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_ELISION, OptionsCategory::CONNECTION); #else argsman.AddArg("-proxy=<ip:port>", "Connect through SOCKS5 proxy, set -noproxy to disable (default: disabled)", ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_ELISION, OptionsCategory::CONNECTION); @@ -570,7 +579,7 @@ void SetupServerArgs(ArgsManager& argsman) g_wallet_init_interface.AddWalletOptions(argsman); -#if ENABLE_ZMQ +#ifdef ENABLE_ZMQ argsman.AddArg("-zmqpubhashblock=<address>", "Enable publish hash block in <address>", ArgsManager::ALLOW_ANY, OptionsCategory::ZMQ); argsman.AddArg("-zmqpubhashtx=<address>", "Enable publish hash transaction in <address>", ArgsManager::ALLOW_ANY, OptionsCategory::ZMQ); argsman.AddArg("-zmqpubrawblock=<address>", "Enable publish raw block in <address>", ArgsManager::ALLOW_ANY, OptionsCategory::ZMQ); @@ -596,7 +605,7 @@ void SetupServerArgs(ArgsManager& argsman) argsman.AddArg("-checkblocks=<n>", strprintf("How many blocks to check at startup (default: %u, 0 = all)", DEFAULT_CHECKBLOCKS), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST); argsman.AddArg("-checklevel=<n>", strprintf("How thorough the block verification of -checkblocks is: %s (0-4, default: %u)", Join(CHECKLEVEL_DOC, ", "), DEFAULT_CHECKLEVEL), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST); - argsman.AddArg("-checkblockindex", strprintf("Do a consistency check for the block tree, chainstate, and other validation data structures occasionally. (default: %u, regtest: %u)", defaultChainParams->DefaultConsistencyChecks(), regtestChainParams->DefaultConsistencyChecks()), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST); + argsman.AddArg("-checkblockindex", strprintf("Do a consistency check for the block tree, chainstate, and other validation data structures every <n> operations. Use 0 to disable. (default: %u, regtest: %u)", defaultChainParams->DefaultConsistencyChecks(), regtestChainParams->DefaultConsistencyChecks()), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST); argsman.AddArg("-checkaddrman=<n>", strprintf("Run addrman consistency checks every <n> operations. Use 0 to disable. (default: %u)", DEFAULT_ADDRMAN_CONSISTENCY_CHECKS), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST); argsman.AddArg("-checkmempool=<n>", strprintf("Run mempool consistency checks every <n> transactions. Use 0 to disable. (default: %u, regtest: %u)", defaultChainParams->DefaultConsistencyChecks(), regtestChainParams->DefaultConsistencyChecks()), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST); argsman.AddArg("-checkpoints", strprintf("Enable rejection of any forks from the known historical chain until block %s (default: %u)", defaultChainParams->Checkpoints().GetHeight(), DEFAULT_CHECKPOINTS_ENABLED), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST); @@ -833,7 +842,7 @@ std::set<BlockFilterType> g_enabled_filter_types; // Since LogPrintf may itself allocate memory, set the handler directly // to terminate first. std::set_new_handler(std::terminate); - LogPrintf("Error: Out of memory. Terminating.\n"); + LogError("Out of memory. Terminating.\n"); // The log was successful, terminate now. std::terminate(); @@ -1085,6 +1094,10 @@ bool AppInitSanityChecks(const kernel::Context& kernel) return InitError(strprintf(_("Initialization sanity check failed. %s is shutting down."), PACKAGE_NAME)); } + if (!ECC_InitSanityCheck()) { + return InitError(strprintf(_("Elliptic curve cryptography sanity check failure. %s is shutting down."), PACKAGE_NAME)); + } + // Probe the data directory lock to give an early error message, if possible // We cannot hold the data directory lock here, as the forking for daemon() hasn't yet happened, // and a fork will cause weird behavior to it. @@ -1106,6 +1119,7 @@ bool AppInitLockDataDirectory() bool AppInitInterfaces(NodeContext& node) { node.chain = node.init->makeChain(); + node.mining = node.init->makeMining(); return true; } @@ -1164,9 +1178,9 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) scheduler.scheduleEvery([&args, &node]{ constexpr uint64_t min_disk_space = 50 << 20; // 50 MB if (!CheckDiskSpace(args.GetBlocksDirPath(), min_disk_space)) { - LogPrintf("Shutting down due to lack of disk space!\n"); + LogError("Shutting down due to lack of disk space!\n"); if (!(*Assert(node.shutdown))()) { - LogPrintf("Error: failed to send shutdown signal after disk space check\n"); + LogError("Failed to send shutdown signal after disk space check\n"); } } }, std::chrono::minutes{5}); @@ -1189,7 +1203,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) for (const auto& client : node.chain_clients) { client->registerRpcs(); } -#if ENABLE_ZMQ +#ifdef ENABLE_ZMQ RegisterZMQRPCCommands(tableRPC); #endif @@ -1314,7 +1328,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) std::string host_out; uint16_t port_out{0}; if (!SplitHostPort(socket_addr, port_out, host_out)) { -#if HAVE_SOCKADDR_UN +#ifdef HAVE_SOCKADDR_UN // Allow unix domain sockets for some options e.g. unix:/some/file/path if (!unix || socket_addr.find(ADDR_PREFIX_UNIX) != 0) { return InitError(InvalidPortErrMsg(arg, socket_addr)); @@ -1461,7 +1475,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) return InitError(ResolveErrMsg("externalip", strAddr)); } -#if ENABLE_ZMQ +#ifdef ENABLE_ZMQ g_zmq_notification_interface = CZMQNotificationInterface::Create( [&chainman = node.chainman](std::vector<uint8_t>& block, const CBlockIndex& index) { assert(chainman); @@ -1475,10 +1489,8 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) // ********************************************************* Step 7: load block chain - node.notifications = std::make_unique<KernelNotifications>(*Assert(node.shutdown), node.exit_status); + node.notifications = std::make_unique<KernelNotifications>(*Assert(node.shutdown), node.exit_status, *Assert(node.warnings)); ReadNotificationArgs(args, *node.notifications); - fReindex = args.GetBoolArg("-reindex", false); - bool fReindexChainState = args.GetBoolArg("-reindex-chainstate", false); ChainstateManager::Options chainman_opts{ .chainparams = chainparams, .datadir = args.GetDataDirNet(), @@ -1519,16 +1531,17 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) if (!result) { return InitError(util::ErrorString(result)); } - mempool_opts.check_ratio = std::clamp<int>(mempool_opts.check_ratio, 0, 1'000'000); - int64_t descendant_limit_bytes = mempool_opts.limits.descendant_size_vbytes * 40; - if (mempool_opts.max_size_bytes < 0 || mempool_opts.max_size_bytes < descendant_limit_bytes) { - return InitError(strprintf(_("-maxmempool must be at least %d MB"), std::ceil(descendant_limit_bytes / 1'000'000.0))); - } - LogPrintf("* Using %.1f MiB for in-memory UTXO set (plus up to %.1f MiB of unused mempool space)\n", cache_sizes.coins * (1.0 / 1024 / 1024), mempool_opts.max_size_bytes * (1.0 / 1024 / 1024)); + bool do_reindex{args.GetBoolArg("-reindex", false)}; + const bool do_reindex_chainstate{args.GetBoolArg("-reindex-chainstate", false)}; for (bool fLoaded = false; !fLoaded && !ShutdownRequested(node);) { - node.mempool = std::make_unique<CTxMemPool>(mempool_opts); + bilingual_str mempool_error; + node.mempool = std::make_unique<CTxMemPool>(mempool_opts, mempool_error); + if (!mempool_error.empty()) { + return InitError(mempool_error); + } + LogPrintf("* Using %.1f MiB for in-memory UTXO set (plus up to %.1f MiB of unused mempool space)\n", cache_sizes.coins * (1.0 / 1024 / 1024), mempool_opts.max_size_bytes * (1.0 / 1024 / 1024)); node.chainman = std::make_unique<ChainstateManager>(*Assert(node.shutdown), chainman_opts, blockman_opts); ChainstateManager& chainman = *node.chainman; @@ -1554,8 +1567,8 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) node::ChainstateLoadOptions options; options.mempool = Assert(node.mempool.get()); - options.reindex = node::fReindex; - options.reindex_chainstate = fReindexChainState; + options.wipe_block_tree_db = do_reindex; + options.wipe_chainstate_db = do_reindex || do_reindex_chainstate; options.prune = chainman.m_blockman.IsPruneMode(); options.check_blocks = args.GetIntArg("-checkblocks", DEFAULT_CHECKBLOCKS); options.check_level = args.GetIntArg("-checklevel", DEFAULT_CHECKLEVEL); @@ -1572,7 +1585,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) try { return f(); } catch (const std::exception& e) { - LogPrintf("%s\n", e.what()); + LogError("%s\n", e.what()); return std::make_tuple(node::ChainstateLoadStatus::FAILURE, _("Error opening block database")); } }; @@ -1596,18 +1609,18 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) if (!fLoaded && !ShutdownRequested(node)) { // first suggest a reindex - if (!options.reindex) { + if (!do_reindex) { bool fRet = uiInterface.ThreadSafeQuestion( error + Untranslated(".\n\n") + _("Do you want to rebuild the block database now?"), error.original + ".\nPlease restart with -reindex or -reindex-chainstate to recover.", "", CClientUIInterface::MSG_ERROR | CClientUIInterface::BTN_ABORT); if (fRet) { - fReindex = true; + do_reindex = true; if (!Assert(node.shutdown)->reset()) { - LogPrintf("Internal error: failed to reset shutdown signal.\n"); + LogError("Internal error: failed to reset shutdown signal.\n"); } } else { - LogPrintf("Aborted block database rebuild. Exiting.\n"); + LogError("Aborted block database rebuild. Exiting.\n"); return false; } } else { @@ -1629,23 +1642,24 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) assert(!node.peerman); node.peerman = PeerManager::make(*node.connman, *node.addrman, node.banman.get(), chainman, - *node.mempool, peerman_opts); + *node.mempool, *node.warnings, + peerman_opts); validation_signals.RegisterValidationInterface(node.peerman.get()); // ********************************************************* Step 8: start indexers if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) { - g_txindex = std::make_unique<TxIndex>(interfaces::MakeChain(node), cache_sizes.tx_index, false, fReindex); + g_txindex = std::make_unique<TxIndex>(interfaces::MakeChain(node), cache_sizes.tx_index, false, do_reindex); node.indexes.emplace_back(g_txindex.get()); } for (const auto& filter_type : g_enabled_filter_types) { - InitBlockFilterIndex([&]{ return interfaces::MakeChain(node); }, filter_type, cache_sizes.filter_index, false, fReindex); + InitBlockFilterIndex([&]{ return interfaces::MakeChain(node); }, filter_type, cache_sizes.filter_index, false, do_reindex); node.indexes.emplace_back(GetBlockFilterIndex(filter_type)); } if (args.GetBoolArg("-coinstatsindex", DEFAULT_COINSTATSINDEX)) { - g_coin_stats_index = std::make_unique<CoinStatsIndex>(interfaces::MakeChain(node), /*cache_size=*/0, false, fReindex); + g_coin_stats_index = std::make_unique<CoinStatsIndex>(interfaces::MakeChain(node), /*cache_size=*/0, false, do_reindex); node.indexes.emplace_back(g_coin_stats_index.get()); } @@ -1664,7 +1678,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) // if pruning, perform the initial blockstore prune // after any wallet rescanning has taken place. if (chainman.m_blockman.IsPruneMode()) { - if (!fReindex) { + if (chainman.m_blockman.m_blockfiles_indexed) { LOCK(cs_main); for (Chainstate* chainstate : chainman.GetAll()) { uiInterface.InitMessage(_("Pruning blockstore…").translated); @@ -1690,7 +1704,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) int chain_active_height = WITH_LOCK(cs_main, return chainman.ActiveChain().Height()); // On first startup, warn on low block storage space - if (!fReindex && !fReindexChainState && chain_active_height <= 1) { + if (!do_reindex && !do_reindex_chainstate && chain_active_height <= 1) { uint64_t assumed_chain_bytes{chainparams.AssumedBlockchainSize() * 1024 * 1024 * 1024}; uint64_t additional_bytes_needed{ chainman.m_blockman.IsPruneMode() ? @@ -1736,12 +1750,13 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) } chainman.m_thread_load = std::thread(&util::TraceThread, "initload", [=, &chainman, &args, &node] { + ScheduleBatchPriority(); // Import blocks ImportBlocks(chainman, vImportFiles); if (args.GetBoolArg("-stopafterblockimport", DEFAULT_STOPAFTERBLOCKIMPORT)) { LogPrintf("Stopping after block import\n"); if (!(*Assert(node.shutdown))()) { - LogPrintf("Error: failed to send shutdown signal after finishing block import\n"); + LogError("Failed to send shutdown signal after finishing block import\n"); } return; } diff --git a/src/init/bitcoin-node.cpp b/src/init/bitcoin-node.cpp index 97b8dc1161..00a3822791 100644 --- a/src/init/bitcoin-node.cpp +++ b/src/init/bitcoin-node.cpp @@ -30,6 +30,7 @@ public: } std::unique_ptr<interfaces::Node> makeNode() override { return interfaces::MakeNode(m_node); } std::unique_ptr<interfaces::Chain> makeChain() override { return interfaces::MakeChain(m_node); } + std::unique_ptr<interfaces::Mining> makeMining() override { return interfaces::MakeMining(m_node); } std::unique_ptr<interfaces::WalletLoader> makeWalletLoader(interfaces::Chain& chain) override { return MakeWalletLoader(chain, *Assert(m_node.args)); diff --git a/src/init/bitcoin-qt.cpp b/src/init/bitcoin-qt.cpp index 3003a8fde1..5209c72973 100644 --- a/src/init/bitcoin-qt.cpp +++ b/src/init/bitcoin-qt.cpp @@ -6,6 +6,7 @@ #include <interfaces/chain.h> #include <interfaces/echo.h> #include <interfaces/init.h> +#include <interfaces/mining.h> #include <interfaces/node.h> #include <interfaces/wallet.h> #include <node/context.h> @@ -25,6 +26,7 @@ public: } std::unique_ptr<interfaces::Node> makeNode() override { return interfaces::MakeNode(m_node); } std::unique_ptr<interfaces::Chain> makeChain() override { return interfaces::MakeChain(m_node); } + std::unique_ptr<interfaces::Mining> makeMining() override { return interfaces::MakeMining(m_node); } std::unique_ptr<interfaces::WalletLoader> makeWalletLoader(interfaces::Chain& chain) override { return MakeWalletLoader(chain, *Assert(m_node.args)); diff --git a/src/init/bitcoind.cpp b/src/init/bitcoind.cpp index b5df764017..48be8831d2 100644 --- a/src/init/bitcoind.cpp +++ b/src/init/bitcoind.cpp @@ -6,6 +6,7 @@ #include <interfaces/chain.h> #include <interfaces/echo.h> #include <interfaces/init.h> +#include <interfaces/mining.h> #include <interfaces/node.h> #include <interfaces/wallet.h> #include <node/context.h> @@ -27,6 +28,7 @@ public: } std::unique_ptr<interfaces::Node> makeNode() override { return interfaces::MakeNode(m_node); } std::unique_ptr<interfaces::Chain> makeChain() override { return interfaces::MakeChain(m_node); } + std::unique_ptr<interfaces::Mining> makeMining() override { return interfaces::MakeMining(m_node); } std::unique_ptr<interfaces::WalletLoader> makeWalletLoader(interfaces::Chain& chain) override { return MakeWalletLoader(chain, *Assert(m_node.args)); diff --git a/src/init/common.cpp b/src/init/common.cpp index 3a6df3e8bd..00ef879dc1 100644 --- a/src/init/common.cpp +++ b/src/init/common.cpp @@ -20,6 +20,8 @@ #include <string> #include <vector> +using util::SplitString; + namespace init { void AddLoggingArgs(ArgsManager& argsman) { @@ -31,11 +33,7 @@ void AddLoggingArgs(ArgsManager& argsman) argsman.AddArg("-logips", strprintf("Include IP addresses in debug output (default: %u)", DEFAULT_LOGIPS), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); argsman.AddArg("-loglevel=<level>|<category>:<level>", strprintf("Set the global or per-category severity level for logging categories enabled with the -debug configuration option or the logging RPC. Possible values are %s (default=%s). The following levels are always logged: error, warning, info. If <category>:<level> is supplied, the setting will override the global one and may be specified multiple times to set multiple category-specific levels. <category> can be: %s.", LogInstance().LogLevelsString(), LogInstance().LogLevelToStr(BCLog::DEFAULT_LOG_LEVEL), LogInstance().LogCategoriesString()), ArgsManager::DISALLOW_NEGATION | ArgsManager::DISALLOW_ELISION | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST); argsman.AddArg("-logtimestamps", strprintf("Prepend debug output with timestamp (default: %u)", DEFAULT_LOGTIMESTAMPS), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); -#ifdef HAVE_THREAD_LOCAL - argsman.AddArg("-logthreadnames", strprintf("Prepend debug output with name of the originating thread (only available on platforms supporting thread_local) (default: %u)", DEFAULT_LOGTHREADNAMES), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); -#else - argsman.AddHiddenArgs({"-logthreadnames"}); -#endif + argsman.AddArg("-logthreadnames", strprintf("Prepend debug output with name of the originating thread (default: %u)", DEFAULT_LOGTHREADNAMES), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); argsman.AddArg("-logsourcelocations", strprintf("Prepend debug output with name of the originating source location (source file, line number and function name) (default: %u)", DEFAULT_LOGSOURCELOCATIONS), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); argsman.AddArg("-logtimemicros", strprintf("Add microsecond precision to debug timestamps (default: %u)", DEFAULT_LOGTIMEMICROS), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST); argsman.AddArg("-loglevelalways", strprintf("Always prepend a category and level (default: %u)", DEFAULT_LOGLEVELALWAYS), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); @@ -50,9 +48,7 @@ void SetLoggingOptions(const ArgsManager& args) LogInstance().m_print_to_console = args.GetBoolArg("-printtoconsole", !args.GetBoolArg("-daemon", false)); LogInstance().m_log_timestamps = args.GetBoolArg("-logtimestamps", DEFAULT_LOGTIMESTAMPS); LogInstance().m_log_time_micros = args.GetBoolArg("-logtimemicros", DEFAULT_LOGTIMEMICROS); -#ifdef HAVE_THREAD_LOCAL LogInstance().m_log_threadnames = args.GetBoolArg("-logthreadnames", DEFAULT_LOGTHREADNAMES); -#endif LogInstance().m_log_sourcelocations = args.GetBoolArg("-logsourcelocations", DEFAULT_LOGSOURCELOCATIONS); LogInstance().m_always_print_category_level = args.GetBoolArg("-loglevelalways", DEFAULT_LOGLEVELALWAYS); diff --git a/src/interfaces/init.h b/src/interfaces/init.h index addc45aa26..094ead399d 100644 --- a/src/interfaces/init.h +++ b/src/interfaces/init.h @@ -7,6 +7,7 @@ #include <interfaces/chain.h> #include <interfaces/echo.h> +#include <interfaces/mining.h> #include <interfaces/node.h> #include <interfaces/wallet.h> @@ -32,6 +33,7 @@ public: virtual ~Init() = default; virtual std::unique_ptr<Node> makeNode() { return nullptr; } virtual std::unique_ptr<Chain> makeChain() { return nullptr; } + virtual std::unique_ptr<Mining> makeMining() { return nullptr; } virtual std::unique_ptr<WalletLoader> makeWalletLoader(Chain& chain) { return nullptr; } virtual std::unique_ptr<Echo> makeEcho() { return nullptr; } virtual Ipc* ipc() { return nullptr; } diff --git a/src/interfaces/mining.h b/src/interfaces/mining.h new file mode 100644 index 0000000000..b96881f67c --- /dev/null +++ b/src/interfaces/mining.h @@ -0,0 +1,82 @@ +// Copyright (c) 2024 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_INTERFACES_MINING_H +#define BITCOIN_INTERFACES_MINING_H + +#include <optional> +#include <uint256.h> + +namespace node { +struct CBlockTemplate; +struct NodeContext; +} // namespace node + +class BlockValidationState; +class CBlock; +class CScript; + +namespace interfaces { + +//! Interface giving clients (RPC, Stratum v2 Template Provider in the future) +//! ability to create block templates. + +class Mining +{ +public: + virtual ~Mining() {} + + //! If this chain is exclusively used for testing + virtual bool isTestChain() = 0; + + //! Returns whether IBD is still in progress. + virtual bool isInitialBlockDownload() = 0; + + //! Returns the hash for the tip of this chain + virtual std::optional<uint256> getTipHash() = 0; + + /** + * Construct a new block template + * + * @param[in] script_pub_key the coinbase output + * @param[in] use_mempool set false to omit mempool transactions + * @returns a block template + */ + virtual std::unique_ptr<node::CBlockTemplate> createNewBlock(const CScript& script_pub_key, bool use_mempool = true) = 0; + /** + * Processes new block. A valid new block is automatically relayed to peers. + * + * @param[in] block The block we want to process. + * @param[out] new_block A boolean which is set to indicate if the block was first received via this call + * @returns If the block was processed, independently of block validity + */ + virtual bool processNewBlock(const std::shared_ptr<const CBlock>& block, bool* new_block) = 0; + + //! Return the number of transaction updates in the mempool, + //! used to decide whether to make a new block template. + virtual unsigned int getTransactionsUpdated() = 0; + + /** + * Check a block is completely valid from start to finish. + * Only works on top of our current best block. + * Does not check proof-of-work. + * + * @param[out] state details of why a block failed to validate + * @param[in] block the block to validate + * @param[in] check_merkle_root call CheckMerkleRoot() + * @returns false if any of the checks fail + */ + virtual bool testBlockValidity(BlockValidationState& state, const CBlock& block, bool check_merkle_root = true) = 0; + + //! Get internal node context. Useful for RPC and testing, + //! but not accessible across processes. + virtual node::NodeContext* context() { return nullptr; } +}; + +//! Return implementation of Mining interface. +std::unique_ptr<Mining> MakeMining(node::NodeContext& node); + +} // namespace interfaces + +#endif // BITCOIN_INTERFACES_MINING_H diff --git a/src/interfaces/node.h b/src/interfaces/node.h index aeb2612c07..2bb895dd47 100644 --- a/src/interfaces/node.h +++ b/src/interfaces/node.h @@ -30,10 +30,10 @@ class RPCTimerInterface; class UniValue; class Proxy; enum class SynchronizationState; -enum class TransactionError; struct CNodeStateStats; struct bilingual_str; namespace node { +enum class TransactionError; struct NodeContext; } // namespace node namespace wallet { @@ -208,7 +208,7 @@ public: virtual std::optional<Coin> getUnspentOutput(const COutPoint& output) = 0; //! Broadcast transaction. - virtual TransactionError broadcastTransaction(CTransactionRef tx, CAmount max_tx_fee, std::string& err_string) = 0; + virtual node::TransactionError broadcastTransaction(CTransactionRef tx, CAmount max_tx_fee, std::string& err_string) = 0; //! Get wallet loader. virtual WalletLoader& walletLoader() = 0; diff --git a/src/interfaces/wallet.h b/src/interfaces/wallet.h index c41f35829d..f7bcca58cf 100644 --- a/src/interfaces/wallet.h +++ b/src/interfaces/wallet.h @@ -6,13 +6,13 @@ #define BITCOIN_INTERFACES_WALLET_H #include <addresstype.h> +#include <common/signmessage.h> #include <consensus/amount.h> #include <interfaces/chain.h> #include <pubkey.h> #include <script/script.h> #include <support/allocators/secure.h> #include <util/fs.h> -#include <util/message.h> #include <util/result.h> #include <util/ui_change_type.h> @@ -30,9 +30,14 @@ class CFeeRate; class CKey; enum class FeeReason; enum class OutputType; -enum class TransactionError; struct PartiallySignedTransaction; struct bilingual_str; +namespace common { +enum class PSBTError; +} // namespace common +namespace node { +enum class TransactionError; +} // namespace node namespace wallet { class CCoinControl; class CWallet; @@ -202,7 +207,7 @@ public: int& num_blocks) = 0; //! Fill PSBT. - virtual TransactionError fillPSBT(int sighash_type, + virtual std::optional<common::PSBTError> fillPSBT(int sighash_type, bool sign, bool bip32derivs, size_t* n_signed, diff --git a/src/kernel/chainparams.cpp b/src/kernel/chainparams.cpp index 26c261eba2..bf3a340cb8 100644 --- a/src/kernel/chainparams.cpp +++ b/src/kernel/chainparams.cpp @@ -29,7 +29,7 @@ static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward) { CMutableTransaction txNew; - txNew.nVersion = 1; + txNew.version = 1; txNew.vin.resize(1); txNew.vout.resize(1); txNew.vin[0].scriptSig = CScript() << 486604799 << CScriptNum(4) << std::vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); @@ -140,6 +140,7 @@ public: vSeeds.emplace_back("seed.bitcoin.sprovoost.nl."); // Sjors Provoost vSeeds.emplace_back("dnsseed.emzy.de."); // Stephan Oeste vSeeds.emplace_back("seed.bitcoin.wiz.biz."); // Jason Maurice + vSeeds.emplace_back("seed.mainnet.achownodes.xyz."); // Ava Chow, only supports x1, x5, x9, x49, x809, x849, xd, x400, x404, x408, x448, xc08, xc48, x40c base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,0); base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,5); @@ -246,6 +247,7 @@ public: vSeeds.emplace_back("seed.tbtc.petertodd.net."); vSeeds.emplace_back("seed.testnet.bitcoin.sprovoost.nl."); vSeeds.emplace_back("testnet-seed.bluematt.me."); // Just a static list of stable node(s), only supports x9 + vSeeds.emplace_back("seed.testnet.achownodes.xyz."); // Ava Chow, only supports x1, x5, x9, x49, x809, x849, xd, x400, x404, x408, x448, xc08, xc48, x40c base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,111); base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,196); @@ -297,6 +299,7 @@ public: if (!options.challenge) { bin = ParseHex("512103ad5e0edad18cb1f0fc0d28a3d4f1f3e445640337489abb10404f2d1e086be430210359ef5021964fe22d6f8e05b2463c9540ce96883fe3b278760f048f5189f2e6c452ae"); vSeeds.emplace_back("seed.signet.bitcoin.sprovoost.nl."); + vSeeds.emplace_back("seed.signet.achownodes.xyz."); // Ava Chow, only supports x1, x5, x9, x49, x809, x849, xd, x400, x404, x408, x448, xc08, xc48, x40c // Hardcoded nodes can be removed once there are more DNS seeds vSeeds.emplace_back("178.128.221.177"); @@ -542,3 +545,33 @@ std::unique_ptr<const CChainParams> CChainParams::TestNet() { return std::make_unique<const CTestNetParams>(); } + +std::vector<int> CChainParams::GetAvailableSnapshotHeights() const +{ + std::vector<int> heights; + heights.reserve(m_assumeutxo_data.size()); + + for (const auto& data : m_assumeutxo_data) { + heights.emplace_back(data.height); + } + return heights; +} + +std::optional<ChainType> GetNetworkForMagic(const MessageStartChars& message) +{ + const auto mainnet_msg = CChainParams::Main()->MessageStart(); + const auto testnet_msg = CChainParams::TestNet()->MessageStart(); + const auto regtest_msg = CChainParams::RegTest({})->MessageStart(); + const auto signet_msg = CChainParams::SigNet({})->MessageStart(); + + if (std::equal(message.begin(), message.end(), mainnet_msg.data())) { + return ChainType::MAIN; + } else if (std::equal(message.begin(), message.end(), testnet_msg.data())) { + return ChainType::TESTNET; + } else if (std::equal(message.begin(), message.end(), regtest_msg.data())) { + return ChainType::REGTEST; + } else if (std::equal(message.begin(), message.end(), signet_msg.data())) { + return ChainType::SIGNET; + } + return std::nullopt; +} diff --git a/src/kernel/chainparams.h b/src/kernel/chainparams.h index 7a5539bc71..05ebd07ec7 100644 --- a/src/kernel/chainparams.h +++ b/src/kernel/chainparams.h @@ -93,6 +93,7 @@ public: const Consensus::Params& GetConsensus() const { return consensus; } const MessageStartChars& MessageStart() const { return pchMessageStart; } uint16_t GetDefaultPort() const { return nDefaultPort; } + std::vector<int> GetAvailableSnapshotHeights() const; const CBlock& GenesisBlock() const { return genesis; } /** Default value for -checkmempool and -checkblockindex argument */ @@ -183,4 +184,6 @@ protected: ChainTxData chainTxData; }; +std::optional<ChainType> GetNetworkForMagic(const MessageStartChars& pchMessageStart); + #endif // BITCOIN_KERNEL_CHAINPARAMS_H diff --git a/src/kernel/chainstatemanager_opts.h b/src/kernel/chainstatemanager_opts.h index de5f78494a..076841c3c9 100644 --- a/src/kernel/chainstatemanager_opts.h +++ b/src/kernel/chainstatemanager_opts.h @@ -33,7 +33,7 @@ namespace kernel { struct ChainstateManagerOpts { const CChainParams& chainparams; fs::path datadir; - std::optional<bool> check_block_index{}; + std::optional<int32_t> check_block_index{}; bool checkpoints_enabled{DEFAULT_CHECKPOINTS_ENABLED}; //! If set, it will override the minimum work we will assume exists on some valid chain. std::optional<arith_uint256> minimum_chain_work{}; diff --git a/src/kernel/checks.cpp b/src/kernel/checks.cpp index 45a5e25093..e4a13ee4cc 100644 --- a/src/kernel/checks.cpp +++ b/src/kernel/checks.cpp @@ -4,8 +4,8 @@ #include <kernel/checks.h> -#include <key.h> #include <random.h> +#include <util/result.h> #include <util/translation.h> #include <memory> @@ -14,10 +14,6 @@ namespace kernel { util::Result<void> SanityChecks(const Context&) { - if (!ECC_InitSanityCheck()) { - return util::Error{Untranslated("Elliptic curve cryptography sanity check failure. Aborting.")}; - } - if (!Random_SanityCheck()) { return util::Error{Untranslated("OS cryptographic RNG sanity check failure. Aborting.")}; } diff --git a/src/kernel/context.cpp b/src/kernel/context.cpp index c60f1638d1..bfb17915fd 100644 --- a/src/kernel/context.cpp +++ b/src/kernel/context.cpp @@ -5,9 +5,7 @@ #include <kernel/context.h> #include <crypto/sha256.h> -#include <key.h> #include <logging.h> -#include <pubkey.h> #include <random.h> #include <string> @@ -19,12 +17,7 @@ Context::Context() std::string sha256_algo = SHA256AutoDetect(); LogPrintf("Using the '%s' SHA256 implementation\n", sha256_algo); RandomInit(); - ECC_Start(); } -Context::~Context() -{ - ECC_Stop(); -} } // namespace kernel diff --git a/src/kernel/context.h b/src/kernel/context.h index ff4df20473..159af12689 100644 --- a/src/kernel/context.h +++ b/src/kernel/context.h @@ -5,10 +5,6 @@ #ifndef BITCOIN_KERNEL_CONTEXT_H #define BITCOIN_KERNEL_CONTEXT_H -#include <util/signalinterrupt.h> - -#include <memory> - namespace kernel { //! Context struct holding the kernel library's logically global state, and //! passed to external libbitcoin_kernel functions which need access to this @@ -19,7 +15,6 @@ namespace kernel { //! should be stored to std::unique_ptr members pointing to opaque types. struct Context { Context(); - ~Context(); }; } // namespace kernel diff --git a/src/kernel/mempool_persist.cpp b/src/kernel/mempool_persist.cpp index f06f609379..53028a45ae 100644 --- a/src/kernel/mempool_persist.cpp +++ b/src/kernel/mempool_persist.cpp @@ -96,7 +96,7 @@ bool LoadMempool(CTxMemPool& pool, const fs::path& load_path, Chainstate& active if (amountdelta && opts.apply_fee_delta_priority) { pool.PrioritiseTransaction(tx->GetHash(), amountdelta); } - if (nTime > TicksSinceEpoch<std::chrono::seconds>(now - pool.m_expiry)) { + if (nTime > TicksSinceEpoch<std::chrono::seconds>(now - pool.m_opts.expiry)) { LOCK(cs_main); const auto& accepted = AcceptToMemoryPool(active_chainstate, tx, nTime, /*bypass_limits=*/false, /*test_accept=*/false); if (accepted.m_result_type == MempoolAcceptResult::ResultType::VALID) { @@ -174,11 +174,11 @@ bool DumpMempool(const CTxMemPool& pool, const fs::path& dump_path, FopenFn mock } try { - const uint64_t version{pool.m_persist_v1_dat ? MEMPOOL_DUMP_VERSION_NO_XOR_KEY : MEMPOOL_DUMP_VERSION}; + const uint64_t version{pool.m_opts.persist_v1_dat ? MEMPOOL_DUMP_VERSION_NO_XOR_KEY : MEMPOOL_DUMP_VERSION}; file << version; std::vector<std::byte> xor_key(8); - if (!pool.m_persist_v1_dat) { + if (!pool.m_opts.persist_v1_dat) { FastRandomContext{}.fillrand(xor_key); file << xor_key; } diff --git a/src/kernel/notifications_interface.h b/src/kernel/notifications_interface.h index 7283a88e86..8e090dd7db 100644 --- a/src/kernel/notifications_interface.h +++ b/src/kernel/notifications_interface.h @@ -16,6 +16,8 @@ namespace kernel { //! Result type for use with std::variant to indicate that an operation should be interrupted. struct Interrupted{}; +enum class Warning; + //! Simple result type for functions that need to propagate an interrupt status and don't have other return values. using InterruptResult = std::variant<std::monostate, Interrupted>; @@ -38,7 +40,8 @@ public: [[nodiscard]] virtual InterruptResult blockTip(SynchronizationState state, CBlockIndex& index) { return {}; } virtual void headerTip(SynchronizationState state, int64_t height, int64_t timestamp, bool presync) {} virtual void progress(const bilingual_str& title, int progress_percent, bool resume_possible) {} - virtual void warning(const bilingual_str& warning) {} + virtual void warningSet(Warning id, const bilingual_str& message) {} + virtual void warningUnset(Warning id) {} //! The flush error notification is sent to notify the user that an error //! occurred while flushing block data to disk. Kernel code may ignore flush diff --git a/src/kernel/warning.h b/src/kernel/warning.h new file mode 100644 index 0000000000..453f36c552 --- /dev/null +++ b/src/kernel/warning.h @@ -0,0 +1,14 @@ +// Copyright (c) 2024-present The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_KERNEL_WARNING_H +#define BITCOIN_KERNEL_WARNING_H + +namespace kernel { +enum class Warning { + UNKNOWN_NEW_RULES_ACTIVATED, + LARGE_WORK_INVALID_CHAIN, +}; +} // namespace kernel +#endif // BITCOIN_KERNEL_WARNING_H diff --git a/src/key.cpp b/src/key.cpp index 2bd6396298..97d7821e74 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -166,12 +166,6 @@ void CKey::MakeNewKey(bool fCompressedIn) { fCompressed = fCompressedIn; } -bool CKey::Negate() -{ - assert(keydata); - return secp256k1_ec_seckey_negate(secp256k1_context_sign, keydata->data()); -} - CPrivKey CKey::GetPrivKey() const { assert(keydata); CPrivKey seckey; @@ -432,7 +426,8 @@ bool ECC_InitSanityCheck() { return key.VerifyPubKey(pubkey); } -void ECC_Start() { +/** Initialize the elliptic curve support. May not be called twice without calling ECC_Stop first. */ +static void ECC_Start() { assert(secp256k1_context_sign == nullptr); secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); @@ -449,7 +444,8 @@ void ECC_Start() { secp256k1_context_sign = ctx; } -void ECC_Stop() { +/** Deinitialize the elliptic curve support. No-op if ECC_Start wasn't called first. */ +static void ECC_Stop() { secp256k1_context *ctx = secp256k1_context_sign; secp256k1_context_sign = nullptr; @@ -457,3 +453,13 @@ void ECC_Stop() { secp256k1_context_destroy(ctx); } } + +ECC_Context::ECC_Context() +{ + ECC_Start(); +} + +ECC_Context::~ECC_Context() +{ + ECC_Stop(); +} @@ -124,9 +124,6 @@ public: //! Generate a new private key using a cryptographic PRNG. void MakeNewKey(bool fCompressed); - //! Negate private key - bool Negate(); - /** * Convert the private key to a CPrivKey (serialized OpenSSL private key data). * This is expensive. @@ -236,13 +233,21 @@ struct CExtKey { void SetSeed(Span<const std::byte> seed); }; -/** Initialize the elliptic curve support. May not be called twice without calling ECC_Stop first. */ -void ECC_Start(); - -/** Deinitialize the elliptic curve support. No-op if ECC_Start wasn't called first. */ -void ECC_Stop(); - /** Check that required EC support is available at runtime. */ bool ECC_InitSanityCheck(); +/** + * RAII class initializing and deinitializing global state for elliptic curve support. + * Only one instance may be initialized at a time. + * + * In the future global ECC state could be removed, and this class could contain + * state and be passed as an argument to ECC key functions. + */ +class ECC_Context +{ +public: + ECC_Context(); + ~ECC_Context(); +}; + #endif // BITCOIN_KEY_H diff --git a/src/leveldb/include/leveldb/status.h b/src/leveldb/include/leveldb/status.h index e3273144e4..68efe3001a 100644 --- a/src/leveldb/include/leveldb/status.h +++ b/src/leveldb/include/leveldb/status.h @@ -103,6 +103,8 @@ class LEVELDB_EXPORT Status { inline Status::Status(const Status& rhs) { state_ = (rhs.state_ == nullptr) ? nullptr : CopyState(rhs.state_); } + +// NOLINTBEGIN(bugprone-unhandled-self-assignment) inline Status& Status::operator=(const Status& rhs) { // The following condition catches both aliasing (when this == &rhs), // and the common case where both rhs and *this are ok. @@ -112,6 +114,8 @@ inline Status& Status::operator=(const Status& rhs) { } return *this; } +// NOLINTEND(bugprone-unhandled-self-assignment) + inline Status& Status::operator=(Status&& rhs) noexcept { std::swap(state_, rhs.state_); return *this; diff --git a/src/logging.cpp b/src/logging.cpp index 578650f856..a9fea433be 100644 --- a/src/logging.cpp +++ b/src/logging.cpp @@ -13,6 +13,10 @@ #include <map> #include <optional> +using util::Join; +using util::RemovePrefix; +using util::ToString; + const char * const DEFAULT_DEBUGLOGFILE = "debug.log"; constexpr auto MAX_USER_SETABLE_SEVERITY_LEVEL{BCLog::Level::Info}; diff --git a/src/logging.h b/src/logging.h index cfef65221f..fe6b7051ba 100644 --- a/src/logging.h +++ b/src/logging.h @@ -189,7 +189,7 @@ namespace BCLog { /** Returns a string with the log categories in alphabetical order. */ std::string LogCategoriesString() const { - return Join(LogCategoriesList(), ", ", [&](const LogCategory& i) { return i.category; }); + return util::Join(LogCategoriesList(), ", ", [&](const LogCategory& i) { return i.category; }); }; //! Returns a string with all user-selectable log levels. diff --git a/src/mapport.cpp b/src/mapport.cpp index 80670230c7..1920297be6 100644 --- a/src/mapport.cpp +++ b/src/mapport.cpp @@ -161,8 +161,11 @@ static bool ProcessUpnp() struct UPNPUrls urls; struct IGDdatas data; int r; - +#if MINIUPNPC_API_VERSION <= 17 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr)); +#else + r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr), nullptr, 0); +#endif if (r == 1) { if (fDiscover) { diff --git a/src/minisketch/configure.ac b/src/minisketch/configure.ac index cd52d7f412..65a47b45c2 100644 --- a/src/minisketch/configure.ac +++ b/src/minisketch/configure.ac @@ -102,6 +102,7 @@ case $host in esac AX_CHECK_COMPILE_FLAG([-Wall],[WARN_CXXFLAGS="$WARN_CXXFLAGS -Wall"],,[[$CXXFLAG_WERROR]]) +AX_CHECK_COMPILE_FLAG([-Wundef], [WARN_CXXFLAGS="$WARN_CXXFLAGS -Wundef"], [], [$CXXFLAG_WERROR]) AX_CHECK_COMPILE_FLAG([-fvisibility=hidden],[CXXFLAGS="$CXXFLAGS -fvisibility=hidden"],[],[$CXXFLAG_WERROR]) if test "x$use_ccache" != "xno"; then diff --git a/src/minisketch/include/minisketch.h b/src/minisketch/include/minisketch.h index 24d6b4e1c0..b0571d2788 100644 --- a/src/minisketch/include/minisketch.h +++ b/src/minisketch/include/minisketch.h @@ -239,7 +239,7 @@ public: /** Make this Minisketch a clone of the specified one. */ Minisketch& operator=(const Minisketch& sketch) noexcept { - if (sketch.m_minisketch) { + if (this != &sketch && sketch.m_minisketch) { m_minisketch = std::unique_ptr<minisketch, Deleter>(minisketch_clone(sketch.m_minisketch.get())); } return *this; diff --git a/src/minisketch/src/false_positives.h b/src/minisketch/src/false_positives.h index 44ebb3e94c..9d0358997f 100644 --- a/src/minisketch/src/false_positives.h +++ b/src/minisketch/src/false_positives.h @@ -81,7 +81,8 @@ uint64_t BaseFPBits(uint32_t bits, uint32_t capacity) { size_t ComputeCapacity(uint32_t bits, size_t max_elements, uint32_t fpbits) { if (bits == 0) return 0; - uint64_t base_fpbits = BaseFPBits(bits, max_elements); + if (max_elements > 0xffffffff) return max_elements; + uint64_t base_fpbits = BaseFPBits(bits, static_cast<uint32_t>(max_elements)); // The fpbits provided by the base max_elements==capacity case are sufficient. if (base_fpbits >= fpbits) return max_elements; // Otherwise, increment capacity by ceil(fpbits / bits) beyond that. @@ -90,6 +91,7 @@ size_t ComputeCapacity(uint32_t bits, size_t max_elements, uint32_t fpbits) { size_t ComputeMaxElements(uint32_t bits, size_t capacity, uint32_t fpbits) { if (bits == 0) return 0; + if (capacity > 0xffffffff) return capacity; // Start with max_elements=capacity, and decrease max_elements until the corresponding capacity is capacity. size_t max_elements = capacity; while (true) { diff --git a/src/minisketch/src/int_utils.h b/src/minisketch/src/int_utils.h index 2b3d8cb402..a6b89cd63c 100644 --- a/src/minisketch/src/int_utils.h +++ b/src/minisketch/src/int_utils.h @@ -159,7 +159,7 @@ static inline int CountBits(I val, int max) { } if (!ret) return 0; return index + 1; -#elif HAVE_CLZ +#elif defined(HAVE_CLZ) (void)max; if (val == 0) return 0; if (std::numeric_limits<unsigned>::digits >= std::numeric_limits<I>::digits) { @@ -210,7 +210,7 @@ public: static constexpr inline int TopBits(I val) { static_assert(Count > 0, "BitsInt::TopBits needs Count > 0"); static_assert(Count <= BITS, "BitsInt::TopBits needs Offset <= BITS"); - return val >> (BITS - Count); + return static_cast<int>(val >> (BITS - Count)); } static inline constexpr I CondXorWith(I val, bool cond, I v) { diff --git a/src/minisketch/src/minisketch.cpp b/src/minisketch/src/minisketch.cpp index d003fdf755..2e45409243 100644 --- a/src/minisketch/src/minisketch.cpp +++ b/src/minisketch/src/minisketch.cpp @@ -468,7 +468,7 @@ size_t minisketch_merge(minisketch* sketch, const minisketch* other_sketch) { ssize_t minisketch_decode(const minisketch* sketch, size_t max_elements, uint64_t* output) { const Sketch* s = (const Sketch*)sketch; s->Check(); - return s->Decode(max_elements, output); + return s->Decode(static_cast<int>(max_elements), output); } void minisketch_set_seed(minisketch* sketch, uint64_t seed) { diff --git a/src/minisketch/src/sketch.h b/src/minisketch/src/sketch.h index 3e9bad793d..662b4e982f 100644 --- a/src/minisketch/src/sketch.h +++ b/src/minisketch/src/sketch.h @@ -29,7 +29,7 @@ public: virtual ~Sketch() {} virtual size_t Syndromes() const = 0; - virtual void Init(int syndromes) = 0; + virtual void Init(size_t syndromes) = 0; virtual void Add(uint64_t element) = 0; virtual void Serialize(unsigned char*) const = 0; virtual void Deserialize(const unsigned char*) = 0; diff --git a/src/minisketch/src/sketch_impl.h b/src/minisketch/src/sketch_impl.h index 4547b742f2..c357f0e823 100644 --- a/src/minisketch/src/sketch_impl.h +++ b/src/minisketch/src/sketch_impl.h @@ -92,7 +92,8 @@ template<typename F> void Sqr(std::vector<typename F::Elem>& poly, const F& field) { if (poly.size() == 0) return; poly.resize(poly.size() * 2 - 1); - for (int x = poly.size() - 1; x >= 0; --x) { + for (size_t i = 0; i < poly.size(); ++i) { + auto x = poly.size() - i - 1; poly[x] = (x & 1) ? 0 : field.Sqr(poly[x / 2]); } } @@ -217,7 +218,7 @@ bool RecFindRoots(std::vector<std::vector<typename F::Elem>>& stack, size_t pos, } if (fully_factorizable) { - // Every succesful iteration of this algorithm splits the input + // Every successful iteration of this algorithm splits the input // polynomial further into buckets, each corresponding to a subset // of 2^(BITS-depth) roots. If after depth splits the degree of // the polynomial is >= 2^(BITS-depth), something is wrong. @@ -297,7 +298,7 @@ std::vector<typename F::Elem> BerlekampMassey(const std::vector<typename F::Elem auto discrepancy = syndromes[n]; for (size_t i = 1; i < current.size(); ++i) discrepancy ^= table[n - i](current[i]); if (discrepancy != 0) { - int x = n + 1 - (current.size() - 1) - (prev.size() - 1); + int x = static_cast<int>(n + 1 - (current.size() - 1) - (prev.size() - 1)); if (!b_have_inv) { b_inv = field.Inv(b); b_have_inv = true; @@ -366,7 +367,7 @@ public: } size_t Syndromes() const override { return m_syndromes.size(); } - void Init(int count) override { m_syndromes.assign(count, 0); } + void Init(size_t count) override { m_syndromes.assign(count, 0); } void Add(uint64_t val) override { @@ -405,7 +406,7 @@ public: for (const auto& root : roots) { *(out++) = m_field.ToUint64(root); } - return roots.size(); + return static_cast<int>(roots.size()); } size_t Merge(const Sketch* other_sketch) override diff --git a/src/net.cpp b/src/net.cpp index ad1e464667..990c58ee3d 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -196,8 +196,7 @@ static std::vector<CAddress> ConvertSeeds(const std::vector<uint8_t> &vSeedsIn) const auto one_week{7 * 24h}; std::vector<CAddress> vSeedsOut; FastRandomContext rng; - DataStream underlying_stream{vSeedsIn}; - ParamsStream s{CAddress::V2_NETWORK, underlying_stream}; + ParamsStream s{DataStream{vSeedsIn}, CAddress::V2_NETWORK}; while (!s.eof()) { CService endpoint; s >> endpoint; @@ -2832,7 +2831,7 @@ std::vector<AddedNodeInfo> CConnman::GetAddedNodeInfo(bool include_connected) co } for (const auto& addr : lAddresses) { - CService service(LookupNumeric(addr.m_added_node, GetDefaultPort(addr.m_added_node))); + CService service{MaybeFlipIPv6toCJDNS(LookupNumeric(addr.m_added_node, GetDefaultPort(addr.m_added_node)))}; AddedNodeInfo addedNode{addr, CService(), false, false}; if (service.IsValid()) { // strAddNode is an IP:port @@ -3030,7 +3029,7 @@ bool CConnman::BindListenPort(const CService& addrBind, bilingual_str& strError, return false; } - std::unique_ptr<Sock> sock = CreateSock(addrBind.GetSAFamily()); + std::unique_ptr<Sock> sock = CreateSock(addrBind.GetSAFamily(), SOCK_STREAM, IPPROTO_TCP); if (!sock) { strError = strprintf(Untranslated("Couldn't open socket for incoming connections (socket returned error %s)"), NetworkErrorString(WSAGetLastError())); LogPrintLevel(BCLog::NET, BCLog::Level::Error, "%s\n", strError.original); @@ -3737,8 +3736,9 @@ CNode::CNode(NodeId idIn, { if (inbound_onion) assert(conn_type_in == ConnectionType::INBOUND); - for (const std::string &msg : getAllNetMessageTypes()) + for (const auto& msg : ALL_NET_MESSAGE_TYPES) { mapRecvBytesPerMsgType[msg] = 0; + } mapRecvBytesPerMsgType[NET_MESSAGE_TYPE_OTHER] = 0; if (fLogIPs) { diff --git a/src/net_permissions.cpp b/src/net_permissions.cpp index b01b2f643d..8f0042c141 100644 --- a/src/net_permissions.cpp +++ b/src/net_permissions.cpp @@ -2,12 +2,14 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <common/messages.h> #include <common/system.h> #include <net_permissions.h> #include <netbase.h> -#include <util/error.h> #include <util/translation.h> +using common::ResolveErrMsg; + const std::vector<std::string> NET_PERMISSIONS_DOC{ "bloomfilter (allow requesting BIP37 filtered blocks and transactions)", "noban (do not ban for misbehavior; implies download)", diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 9b5983b9d0..89b9488584 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -25,6 +25,7 @@ #include <node/blockstorage.h> #include <node/timeoffsets.h> #include <node/txreconciliation.h> +#include <node/warnings.h> #include <policy/fees.h> #include <policy/policy.h> #include <policy/settings.h> @@ -118,6 +119,7 @@ static const unsigned int MAX_HEADERS_RESULTS = 2000; static const int MAX_CMPCTBLOCK_DEPTH = 5; /** Maximum depth of blocks we're willing to respond to GETBLOCKTXN requests for. */ static const int MAX_BLOCKTXN_DEPTH = 10; +static_assert(MAX_BLOCKTXN_DEPTH <= MIN_BLOCKS_TO_KEEP, "MAX_BLOCKTXN_DEPTH too high"); /** Size of the "block download window": how far ahead of our current height do we fetch? * Larger windows tolerate larger download speed differences between peer, but increase the potential * degree of disordering of blocks on disk (which make reindexing and pruning harder). We'll probably @@ -129,8 +131,6 @@ static constexpr double BLOCK_DOWNLOAD_TIMEOUT_BASE = 1; static constexpr double BLOCK_DOWNLOAD_TIMEOUT_PER_PEER = 0.5; /** Maximum number of headers to announce when relaying blocks with headers message.*/ static const unsigned int MAX_BLOCKS_TO_ANNOUNCE = 8; -/** Maximum number of unconnecting headers announcements before DoS score */ -static const int MAX_NUM_UNCONNECTING_HEADERS_MSGS = 10; /** Minimum blocks required to signal NODE_NETWORK_LIMITED */ static const unsigned int NODE_NETWORK_LIMITED_MIN_BLOCKS = 288; /** Window, in blocks, for connecting to NODE_NETWORK_LIMITED peers */ @@ -224,8 +224,6 @@ struct Peer { /** Protects misbehavior data members */ Mutex m_misbehavior_mutex; - /** Accumulated misbehavior score for this peer */ - int m_misbehavior_score GUARDED_BY(m_misbehavior_mutex){0}; /** Whether this peer should be disconnected and marked as discouraged (unless it has NetPermissionFlags::NoBan permission). */ bool m_should_discourage GUARDED_BY(m_misbehavior_mutex){false}; @@ -381,9 +379,6 @@ struct Peer { /** Whether we've sent our peer a sendheaders message. **/ std::atomic<bool> m_sent_sendheaders{false}; - /** Length of current-streak of unconnecting headers announcements */ - int m_num_unconnecting_headers_msgs GUARDED_BY(NetEventsInterface::g_msgproc_mutex){0}; - /** When to potentially disconnect peer for stalling headers download */ std::chrono::microseconds m_headers_sync_timeout GUARDED_BY(NetEventsInterface::g_msgproc_mutex){0us}; @@ -488,7 +483,7 @@ class PeerManagerImpl final : public PeerManager public: PeerManagerImpl(CConnman& connman, AddrMan& addrman, BanMan* banman, ChainstateManager& chainman, - CTxMemPool& pool, Options opts); + CTxMemPool& pool, node::Warnings& warnings, Options opts); /** Overridden from CValidationInterface. */ void BlockConnected(ChainstateRole role, const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexConnected) override @@ -525,7 +520,7 @@ public: m_best_height = height; m_best_block_time = time; }; - void UnitTestMisbehaving(NodeId peer_id, int howmuch) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex) { Misbehaving(*Assert(GetPeerRef(peer_id)), howmuch, ""); }; + void UnitTestMisbehaving(NodeId peer_id) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex) { Misbehaving(*Assert(GetPeerRef(peer_id)), ""); }; void ProcessMessage(CNode& pfrom, const std::string& msg_type, DataStream& vRecv, const std::chrono::microseconds time_received, const std::atomic<bool>& interruptMsgProc) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, !m_recent_confirmed_transactions_mutex, !m_most_recent_block_mutex, !m_headers_presync_mutex, g_msgproc_mutex); @@ -550,11 +545,9 @@ private: * May return an empty shared_ptr if the Peer object can't be found. */ PeerRef RemovePeer(NodeId id) EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex); - /** - * Increment peer's misbehavior score. If the new value >= DISCOURAGEMENT_THRESHOLD, mark the node - * to be discouraged, meaning the peer might be disconnected and added to the discouragement filter. - */ - void Misbehaving(Peer& peer, int howmuch, const std::string& message); + /** Mark a peer as misbehaving, which will cause it to be disconnected and its + * address discouraged. */ + void Misbehaving(Peer& peer, const std::string& message); /** * Potentially mark a node discouraged based on the contents of a BlockValidationState object @@ -563,19 +556,15 @@ private: * punish peers differently depending on whether the data was provided in a compact * block message or not. If the compact block had a valid header, but contained invalid * txs, the peer should not be punished. See BIP 152. - * - * @return Returns true if the peer was punished (probably disconnected) */ - bool MaybePunishNodeForBlock(NodeId nodeid, const BlockValidationState& state, + void MaybePunishNodeForBlock(NodeId nodeid, const BlockValidationState& state, bool via_compact_block, const std::string& message = "") EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex); /** * Potentially disconnect and discourage a node based on the contents of a TxValidationState object - * - * @return Returns true if the peer was punished (probably disconnected) */ - bool MaybePunishNodeForTx(NodeId nodeid, const TxValidationState& state) + void MaybePunishNodeForTx(NodeId nodeid, const TxValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex); /** Maybe disconnect a peer and discourage future connections from its address. @@ -666,10 +655,10 @@ private: bool CheckHeadersPoW(const std::vector<CBlockHeader>& headers, const Consensus::Params& consensusParams, Peer& peer); /** Calculate an anti-DoS work threshold for headers chains */ arith_uint256 GetAntiDoSWorkThreshold(); - /** Deal with state tracking and headers sync for peers that send the - * occasional non-connecting header (this can happen due to BIP 130 headers + /** Deal with state tracking and headers sync for peers that send + * non-connecting headers (this can happen due to BIP 130 headers * announcements for blocks interacting with the 2hr (MAX_FUTURE_BLOCK_TIME) rule). */ - void HandleFewUnconnectingHeaders(CNode& pfrom, Peer& peer, const std::vector<CBlockHeader>& headers) EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex); + void HandleUnconnectingHeaders(CNode& pfrom, Peer& peer, const std::vector<CBlockHeader>& headers) EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex); /** Return true if the headers connect to each other, false otherwise */ bool CheckHeadersAreContinuous(const std::vector<CBlockHeader>& headers) const; /** Try to continue a low-work headers sync that has already begun. @@ -789,7 +778,8 @@ private: /** Next time to check for stale tip */ std::chrono::seconds m_stale_tip_check_time GUARDED_BY(cs_main){0s}; - TimeOffsets m_outbound_time_offsets; + node::Warnings& m_warnings; + TimeOffsets m_outbound_time_offsets{m_warnings}; const Options m_opts; @@ -1174,7 +1164,7 @@ private: void PushAddress(Peer& peer, const CAddress& addr) EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex); }; -const CNodeState* PeerManagerImpl::State(NodeId pnode) const EXCLUSIVE_LOCKS_REQUIRED(cs_main) +const CNodeState* PeerManagerImpl::State(NodeId pnode) const { std::map<NodeId, CNodeState>::const_iterator it = m_node_states.find(pnode); if (it == m_node_states.end()) @@ -1182,7 +1172,7 @@ const CNodeState* PeerManagerImpl::State(NodeId pnode) const EXCLUSIVE_LOCKS_REQ return &it->second; } -CNodeState* PeerManagerImpl::State(NodeId pnode) EXCLUSIVE_LOCKS_REQUIRED(cs_main) +CNodeState* PeerManagerImpl::State(NodeId pnode) { return const_cast<CNodeState*>(std::as_const(*this).State(pnode)); } @@ -1715,7 +1705,6 @@ void PeerManagerImpl::ReattemptInitialBroadcast(CScheduler& scheduler) void PeerManagerImpl::FinalizeNode(const CNode& node) { NodeId nodeid = node.GetId(); - int misbehavior{0}; { LOCK(cs_main); { @@ -1726,7 +1715,6 @@ void PeerManagerImpl::FinalizeNode(const CNode& node) // destructed. PeerRef peer = RemovePeer(nodeid); assert(peer != nullptr); - misbehavior = WITH_LOCK(peer->m_misbehavior_mutex, return peer->m_misbehavior_score); m_wtxid_relay_peers -= peer->m_wtxid_relay; assert(m_wtxid_relay_peers >= 0); } @@ -1769,7 +1757,7 @@ void PeerManagerImpl::FinalizeNode(const CNode& node) assert(m_orphanage.Size() == 0); } } // cs_main - if (node.fSuccessfullyConnected && misbehavior == 0 && + if (node.fSuccessfullyConnected && !node.IsBlockOnlyConn() && !node.IsInboundConn()) { // Only change visible addrman state for full outbound peers. We don't // call Connected() for feeler connections since they don't have @@ -1890,28 +1878,16 @@ void PeerManagerImpl::AddToCompactExtraTransactions(const CTransactionRef& tx) vExtraTxnForCompactIt = (vExtraTxnForCompactIt + 1) % m_opts.max_extra_txs; } -void PeerManagerImpl::Misbehaving(Peer& peer, int howmuch, const std::string& message) +void PeerManagerImpl::Misbehaving(Peer& peer, const std::string& message) { - assert(howmuch > 0); - LOCK(peer.m_misbehavior_mutex); - const int score_before{peer.m_misbehavior_score}; - peer.m_misbehavior_score += howmuch; - const int score_now{peer.m_misbehavior_score}; const std::string message_prefixed = message.empty() ? "" : (": " + message); - std::string warning; - - if (score_now >= DISCOURAGEMENT_THRESHOLD && score_before < DISCOURAGEMENT_THRESHOLD) { - warning = " DISCOURAGE THRESHOLD EXCEEDED"; - peer.m_should_discourage = true; - } - - LogPrint(BCLog::NET, "Misbehaving: peer=%d (%d -> %d)%s%s\n", - peer.m_id, score_before, score_now, warning, message_prefixed); + peer.m_should_discourage = true; + LogPrint(BCLog::NET, "Misbehaving: peer=%d%s\n", peer.m_id, message_prefixed); } -bool PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidationState& state, +void PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidationState& state, bool via_compact_block, const std::string& message) { PeerRef peer{GetPeerRef(nodeid)}; @@ -1926,8 +1902,8 @@ bool PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidati case BlockValidationResult::BLOCK_CONSENSUS: case BlockValidationResult::BLOCK_MUTATED: if (!via_compact_block) { - if (peer) Misbehaving(*peer, 100, message); - return true; + if (peer) Misbehaving(*peer, message); + return; } break; case BlockValidationResult::BLOCK_CACHED_INVALID: @@ -1941,21 +1917,20 @@ bool PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidati // Discourage outbound (but not inbound) peers if on an invalid chain. // Exempt HB compact block peers. Manual connections are always protected from discouragement. if (!via_compact_block && !node_state->m_is_inbound) { - if (peer) Misbehaving(*peer, 100, message); - return true; + if (peer) Misbehaving(*peer, message); + return; } break; } case BlockValidationResult::BLOCK_INVALID_HEADER: case BlockValidationResult::BLOCK_CHECKPOINT: case BlockValidationResult::BLOCK_INVALID_PREV: - if (peer) Misbehaving(*peer, 100, message); - return true; + if (peer) Misbehaving(*peer, message); + return; // Conflicting (but not necessarily invalid) data or different policy: case BlockValidationResult::BLOCK_MISSING_PREV: - // TODO: Handle this much more gracefully (10 DoS points is super arbitrary) - if (peer) Misbehaving(*peer, 10, message); - return true; + if (peer) Misbehaving(*peer, message); + return; case BlockValidationResult::BLOCK_RECENT_CONSENSUS_CHANGE: case BlockValidationResult::BLOCK_TIME_FUTURE: break; @@ -1963,10 +1938,9 @@ bool PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidati if (message != "") { LogPrint(BCLog::NET, "peer=%d: %s\n", nodeid, message); } - return false; } -bool PeerManagerImpl::MaybePunishNodeForTx(NodeId nodeid, const TxValidationState& state) +void PeerManagerImpl::MaybePunishNodeForTx(NodeId nodeid, const TxValidationState& state) { PeerRef peer{GetPeerRef(nodeid)}; switch (state.GetResult()) { @@ -1974,8 +1948,8 @@ bool PeerManagerImpl::MaybePunishNodeForTx(NodeId nodeid, const TxValidationStat break; // The node is providing invalid data: case TxValidationResult::TX_CONSENSUS: - if (peer) Misbehaving(*peer, 100, ""); - return true; + if (peer) Misbehaving(*peer, ""); + return; // Conflicting (but not necessarily invalid) data or different policy: case TxValidationResult::TX_RECENT_CONSENSUS_CHANGE: case TxValidationResult::TX_INPUTS_NOT_STANDARD: @@ -1991,7 +1965,6 @@ bool PeerManagerImpl::MaybePunishNodeForTx(NodeId nodeid, const TxValidationStat case TxValidationResult::TX_UNKNOWN: break; } - return false; } bool PeerManagerImpl::BlockRequestAllowed(const CBlockIndex* pindex) @@ -2041,14 +2014,14 @@ std::optional<std::string> PeerManagerImpl::FetchBlock(NodeId peer_id, const CBl std::unique_ptr<PeerManager> PeerManager::make(CConnman& connman, AddrMan& addrman, BanMan* banman, ChainstateManager& chainman, - CTxMemPool& pool, Options opts) + CTxMemPool& pool, node::Warnings& warnings, Options opts) { - return std::make_unique<PeerManagerImpl>(connman, addrman, banman, chainman, pool, opts); + return std::make_unique<PeerManagerImpl>(connman, addrman, banman, chainman, pool, warnings, opts); } PeerManagerImpl::PeerManagerImpl(CConnman& connman, AddrMan& addrman, BanMan* banman, ChainstateManager& chainman, - CTxMemPool& pool, Options opts) + CTxMemPool& pool, node::Warnings& warnings, Options opts) : m_rng{opts.deterministic_rng}, m_fee_filter_rounder{CFeeRate{DEFAULT_MIN_RELAY_TX_FEE}, m_rng}, m_chainparams(chainman.GetParams()), @@ -2057,6 +2030,7 @@ PeerManagerImpl::PeerManagerImpl(CConnman& connman, AddrMan& addrman, m_banman(banman), m_chainman(chainman), m_mempool(pool), + m_warnings{warnings}, m_opts{opts} { // While Erlay support is incomplete, it must be enabled explicitly via -txreconciliation. @@ -2292,7 +2266,23 @@ bool PeerManagerImpl::AlreadyHaveTx(const GenTxid& gtxid, bool include_reconside const uint256& hash = gtxid.GetHash(); - if (m_orphanage.HaveTx(gtxid)) return true; + if (gtxid.IsWtxid()) { + // Normal query by wtxid. + if (m_orphanage.HaveTx(Wtxid::FromUint256(hash))) return true; + } else { + // Never query by txid: it is possible that the transaction in the orphanage has the same + // txid but a different witness, which would give us a false positive result. If we decided + // not to request the transaction based on this result, an attacker could prevent us from + // downloading a transaction by intentionally creating a malleated version of it. While + // only one (or none!) of these transactions can ultimately be confirmed, we have no way of + // discerning which one that is, so the orphanage can store multiple transactions with the + // same txid. + // + // While we won't query by txid, we can try to "guess" what the wtxid is based on the txid. + // A non-segwit transaction's txid == wtxid. Query this txid "casted" to a wtxid. This will + // help us find non-segwit transactions, saving bandwidth, and should have no false positives. + if (m_orphanage.HaveTx(Wtxid::FromUint256(hash))) return true; + } if (include_reconsiderable && m_recent_rejects_reconsiderable.contains(hash)) return true; @@ -2420,38 +2410,48 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv& } } - LOCK(cs_main); - const CBlockIndex* pindex = m_chainman.m_blockman.LookupBlockIndex(inv.hash); - if (!pindex) { - return; - } - if (!BlockRequestAllowed(pindex)) { - LogPrint(BCLog::NET, "%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom.GetId()); - return; - } - // disconnect node in case we have reached the outbound limit for serving historical blocks - if (m_connman.OutboundTargetReached(true) && - (((m_chainman.m_best_header != nullptr) && (m_chainman.m_best_header->GetBlockTime() - pindex->GetBlockTime() > HISTORICAL_BLOCK_AGE)) || inv.IsMsgFilteredBlk()) && - !pfrom.HasPermission(NetPermissionFlags::Download) // nodes with the download permission may exceed target - ) { - LogPrint(BCLog::NET, "historical block serving limit reached, disconnect peer=%d\n", pfrom.GetId()); - pfrom.fDisconnect = true; - return; - } - // Avoid leaking prune-height by never sending blocks below the NODE_NETWORK_LIMITED threshold - if (!pfrom.HasPermission(NetPermissionFlags::NoBan) && ( - (((peer.m_our_services & NODE_NETWORK_LIMITED) == NODE_NETWORK_LIMITED) && ((peer.m_our_services & NODE_NETWORK) != NODE_NETWORK) && (m_chainman.ActiveChain().Tip()->nHeight - pindex->nHeight > (int)NODE_NETWORK_LIMITED_MIN_BLOCKS + 2 /* add two blocks buffer extension for possible races */) ) - )) { - LogPrint(BCLog::NET, "Ignore block request below NODE_NETWORK_LIMITED threshold, disconnect peer=%d\n", pfrom.GetId()); - //disconnect node and prevent it from stalling (would otherwise wait for the missing block) - pfrom.fDisconnect = true; - return; - } - // Pruned nodes may have deleted the block, so check whether - // it's available before trying to send. - if (!(pindex->nStatus & BLOCK_HAVE_DATA)) { - return; + const CBlockIndex* pindex{nullptr}; + const CBlockIndex* tip{nullptr}; + bool can_direct_fetch{false}; + FlatFilePos block_pos{}; + { + LOCK(cs_main); + pindex = m_chainman.m_blockman.LookupBlockIndex(inv.hash); + if (!pindex) { + return; + } + if (!BlockRequestAllowed(pindex)) { + LogPrint(BCLog::NET, "%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom.GetId()); + return; + } + // disconnect node in case we have reached the outbound limit for serving historical blocks + if (m_connman.OutboundTargetReached(true) && + (((m_chainman.m_best_header != nullptr) && (m_chainman.m_best_header->GetBlockTime() - pindex->GetBlockTime() > HISTORICAL_BLOCK_AGE)) || inv.IsMsgFilteredBlk()) && + !pfrom.HasPermission(NetPermissionFlags::Download) // nodes with the download permission may exceed target + ) { + LogPrint(BCLog::NET, "historical block serving limit reached, disconnect peer=%d\n", pfrom.GetId()); + pfrom.fDisconnect = true; + return; + } + tip = m_chainman.ActiveChain().Tip(); + // Avoid leaking prune-height by never sending blocks below the NODE_NETWORK_LIMITED threshold + if (!pfrom.HasPermission(NetPermissionFlags::NoBan) && ( + (((peer.m_our_services & NODE_NETWORK_LIMITED) == NODE_NETWORK_LIMITED) && ((peer.m_our_services & NODE_NETWORK) != NODE_NETWORK) && (tip->nHeight - pindex->nHeight > (int)NODE_NETWORK_LIMITED_MIN_BLOCKS + 2 /* add two blocks buffer extension for possible races */) ) + )) { + LogPrint(BCLog::NET, "Ignore block request below NODE_NETWORK_LIMITED threshold, disconnect peer=%d\n", pfrom.GetId()); + //disconnect node and prevent it from stalling (would otherwise wait for the missing block) + pfrom.fDisconnect = true; + return; + } + // Pruned nodes may have deleted the block, so check whether + // it's available before trying to send. + if (!(pindex->nStatus & BLOCK_HAVE_DATA)) { + return; + } + can_direct_fetch = CanDirectFetch(); + block_pos = pindex->GetBlockPos(); } + std::shared_ptr<const CBlock> pblock; if (a_recent_block && a_recent_block->GetHash() == pindex->GetBlockHash()) { pblock = a_recent_block; @@ -2459,16 +2459,28 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv& // Fast-path: in this case it is possible to serve the block directly from disk, // as the network format matches the format on disk std::vector<uint8_t> block_data; - if (!m_chainman.m_blockman.ReadRawBlockFromDisk(block_data, pindex->GetBlockPos())) { - assert(!"cannot load block from disk"); + if (!m_chainman.m_blockman.ReadRawBlockFromDisk(block_data, block_pos)) { + if (WITH_LOCK(m_chainman.GetMutex(), return m_chainman.m_blockman.IsBlockPruned(*pindex))) { + LogPrint(BCLog::NET, "Block was pruned before it could be read, disconnect peer=%s\n", pfrom.GetId()); + } else { + LogError("Cannot load block from disk, disconnect peer=%d\n", pfrom.GetId()); + } + pfrom.fDisconnect = true; + return; } MakeAndPushMessage(pfrom, NetMsgType::BLOCK, Span{block_data}); // Don't set pblock as we've sent the block } else { // Send block from disk std::shared_ptr<CBlock> pblockRead = std::make_shared<CBlock>(); - if (!m_chainman.m_blockman.ReadBlockFromDisk(*pblockRead, *pindex)) { - assert(!"cannot load block from disk"); + if (!m_chainman.m_blockman.ReadBlockFromDisk(*pblockRead, block_pos)) { + if (WITH_LOCK(m_chainman.GetMutex(), return m_chainman.m_blockman.IsBlockPruned(*pindex))) { + LogPrint(BCLog::NET, "Block was pruned before it could be read, disconnect peer=%s\n", pfrom.GetId()); + } else { + LogError("Cannot load block from disk, disconnect peer=%d\n", pfrom.GetId()); + } + pfrom.fDisconnect = true; + return; } pblock = pblockRead; } @@ -2506,7 +2518,7 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv& // they won't have a useful mempool to match against a compact block, // and we don't feel like constructing the object for them, so // instead we respond with the full, non-compact block. - if (CanDirectFetch() && pindex->nHeight >= m_chainman.ActiveChain().Height() - MAX_CMPCTBLOCK_DEPTH) { + if (can_direct_fetch && pindex->nHeight >= tip->nHeight - MAX_CMPCTBLOCK_DEPTH) { if (a_recent_compact_block && a_recent_compact_block->header.GetHash() == pindex->GetBlockHash()) { MakeAndPushMessage(pfrom, NetMsgType::CMPCTBLOCK, *a_recent_compact_block); } else { @@ -2527,7 +2539,7 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv& // and we want it right after the last block so they don't // wait for other stuff first. std::vector<CInv> vInv; - vInv.emplace_back(MSG_BLOCK, m_chainman.ActiveChain().Tip()->GetBlockHash()); + vInv.emplace_back(MSG_BLOCK, tip->GetBlockHash()); MakeAndPushMessage(pfrom, NetMsgType::INV, vInv); peer.m_continuation_block.SetNull(); } @@ -2637,7 +2649,7 @@ void PeerManagerImpl::SendBlockTransactions(CNode& pfrom, Peer& peer, const CBlo BlockTransactions resp(req); for (size_t i = 0; i < req.indexes.size(); i++) { if (req.indexes[i] >= block.vtx.size()) { - Misbehaving(peer, 100, "getblocktxn with out-of-bounds tx indices"); + Misbehaving(peer, "getblocktxn with out-of-bounds tx indices"); return; } resp.txn[i] = block.vtx[req.indexes[i]]; @@ -2650,13 +2662,13 @@ bool PeerManagerImpl::CheckHeadersPoW(const std::vector<CBlockHeader>& headers, { // Do these headers have proof-of-work matching what's claimed? if (!HasValidProofOfWork(headers, consensusParams)) { - Misbehaving(peer, 100, "header with invalid proof of work"); + Misbehaving(peer, "header with invalid proof of work"); return false; } // Are these headers connected to each other? if (!CheckHeadersAreContinuous(headers)) { - Misbehaving(peer, 20, "non-continuous headers sequence"); + Misbehaving(peer, "non-continuous headers sequence"); return false; } return true; @@ -2680,37 +2692,24 @@ arith_uint256 PeerManagerImpl::GetAntiDoSWorkThreshold() * announcement. * * We'll send a getheaders message in response to try to connect the chain. - * - * The peer can send up to MAX_NUM_UNCONNECTING_HEADERS_MSGS in a row that - * don't connect before given DoS points. - * - * Once a headers message is received that is valid and does connect, - * m_num_unconnecting_headers_msgs gets reset back to 0. */ -void PeerManagerImpl::HandleFewUnconnectingHeaders(CNode& pfrom, Peer& peer, +void PeerManagerImpl::HandleUnconnectingHeaders(CNode& pfrom, Peer& peer, const std::vector<CBlockHeader>& headers) { - peer.m_num_unconnecting_headers_msgs++; // Try to fill in the missing headers. const CBlockIndex* best_header{WITH_LOCK(cs_main, return m_chainman.m_best_header)}; if (MaybeSendGetHeaders(pfrom, GetLocator(best_header), peer)) { - LogPrint(BCLog::NET, "received header %s: missing prev block %s, sending getheaders (%d) to end (peer=%d, m_num_unconnecting_headers_msgs=%d)\n", + LogPrint(BCLog::NET, "received header %s: missing prev block %s, sending getheaders (%d) to end (peer=%d)\n", headers[0].GetHash().ToString(), headers[0].hashPrevBlock.ToString(), best_header->nHeight, - pfrom.GetId(), peer.m_num_unconnecting_headers_msgs); + pfrom.GetId()); } // Set hashLastUnknownBlock for this peer, so that if we // eventually get the headers - even from a different peer - // we can use this peer to download. WITH_LOCK(cs_main, UpdateBlockAvailability(pfrom.GetId(), headers.back().GetHash())); - - // The peer may just be broken, so periodically assign DoS points if this - // condition persists. - if (peer.m_num_unconnecting_headers_msgs % MAX_NUM_UNCONNECTING_HEADERS_MSGS == 0) { - Misbehaving(peer, 20, strprintf("%d non-connecting headers", peer.m_num_unconnecting_headers_msgs)); - } } bool PeerManagerImpl::CheckHeadersAreContinuous(const std::vector<CBlockHeader>& headers) const @@ -2729,25 +2728,21 @@ bool PeerManagerImpl::IsContinuationOfLowWorkHeadersSync(Peer& peer, CNode& pfro { if (peer.m_headers_sync) { auto result = peer.m_headers_sync->ProcessNextHeaders(headers, headers.size() == MAX_HEADERS_RESULTS); + // If it is a valid continuation, we should treat the existing getheaders request as responded to. + if (result.success) peer.m_last_getheaders_timestamp = {}; if (result.request_more) { auto locator = peer.m_headers_sync->NextHeadersRequestLocator(); // If we were instructed to ask for a locator, it should not be empty. Assume(!locator.vHave.empty()); + // We can only be instructed to request more if processing was successful. + Assume(result.success); if (!locator.vHave.empty()) { // It should be impossible for the getheaders request to fail, - // because we should have cleared the last getheaders timestamp - // when processing the headers that triggered this call. But - // it may be possible to bypass this via compactblock - // processing, so check the result before logging just to be - // safe. + // because we just cleared the last getheaders timestamp. bool sent_getheaders = MaybeSendGetHeaders(pfrom, locator, peer); - if (sent_getheaders) { - LogPrint(BCLog::NET, "more getheaders (from %s) to peer=%d\n", - locator.vHave.front().ToString(), pfrom.GetId()); - } else { - LogPrint(BCLog::NET, "error sending next getheaders (from %s) to continue sync with peer=%d\n", - locator.vHave.front().ToString(), pfrom.GetId()); - } + Assume(sent_getheaders); + LogPrint(BCLog::NET, "more getheaders (from %s) to peer=%d\n", + locator.vHave.front().ToString(), pfrom.GetId()); } } @@ -2956,11 +2951,6 @@ void PeerManagerImpl::HeadersDirectFetchBlocks(CNode& pfrom, const Peer& peer, c void PeerManagerImpl::UpdatePeerStateForReceivedHeaders(CNode& pfrom, Peer& peer, const CBlockIndex& last_header, bool received_new_header, bool may_have_more_headers) { - if (peer.m_num_unconnecting_headers_msgs > 0) { - LogPrint(BCLog::NET, "peer=%d: resetting m_num_unconnecting_headers_msgs (%d -> 0)\n", pfrom.GetId(), peer.m_num_unconnecting_headers_msgs); - } - peer.m_num_unconnecting_headers_msgs = 0; - LOCK(cs_main); CNodeState *nodestate = State(pfrom.GetId()); @@ -3026,6 +3016,9 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, Peer& peer, LOCK(m_headers_presync_mutex); m_headers_presync_stats.erase(pfrom.GetId()); } + // A headers message with no headers cannot be an announcement, so assume + // it is a response to our last getheaders request, if there is one. + peer.m_last_getheaders_timestamp = {}; return; } @@ -3079,17 +3072,18 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, Peer& peer, bool headers_connect_blockindex{chain_start_header != nullptr}; if (!headers_connect_blockindex) { - if (nCount <= MAX_BLOCKS_TO_ANNOUNCE) { - // If this looks like it could be a BIP 130 block announcement, use - // special logic for handling headers that don't connect, as this - // could be benign. - HandleFewUnconnectingHeaders(pfrom, peer, headers); - } else { - Misbehaving(peer, 10, "invalid header received"); - } + // This could be a BIP 130 block announcement, use + // special logic for handling headers that don't connect, as this + // could be benign. + HandleUnconnectingHeaders(pfrom, peer, headers); return; } + // If headers connect, assume that this is in response to any outstanding getheaders + // request we may have sent, and clear out the time of our last request. Non-connecting + // headers cannot be a response to a getheaders request. + peer.m_last_getheaders_timestamp = {}; + // If the headers we received are already in memory and an ancestor of // m_best_header or our tip, skip anti-DoS checks. These headers will not // use any more memory (and we are not leaking information that could be @@ -3216,7 +3210,7 @@ void PeerManagerImpl::ProcessInvalidTx(NodeId nodeid, const CTransactionRef& ptx // If the tx failed in ProcessOrphanTx, it should be removed from the orphanage unless the // tx was still missing inputs. If the tx was not in the orphanage, EraseTx does nothing and returns 0. - if (Assume(state.GetResult() != TxValidationResult::TX_MISSING_INPUTS) && m_orphanage.EraseTx(ptx->GetHash()) > 0) { + if (Assume(state.GetResult() != TxValidationResult::TX_MISSING_INPUTS) && m_orphanage.EraseTx(ptx->GetWitnessHash()) > 0) { LogDebug(BCLog::TXPACKAGES, " removed orphan tx %s (wtxid=%s)\n", ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString()); } } @@ -3234,7 +3228,7 @@ void PeerManagerImpl::ProcessValidTx(NodeId nodeid, const CTransactionRef& tx, c m_orphanage.AddChildrenToWorkSet(*tx); // If it came from the orphanage, remove it. No-op if the tx is not in txorphanage. - m_orphanage.EraseTx(tx->GetHash()); + m_orphanage.EraseTx(tx->GetWitnessHash()); LogDebug(BCLog::MEMPOOL, "AcceptToMemoryPool: peer=%d: accepted %s (wtxid=%s) (poolsz %u txn, %u kB)\n", nodeid, @@ -3607,7 +3601,7 @@ void PeerManagerImpl::ProcessCompactBlockTxns(CNode& pfrom, Peer& peer, const Bl ReadStatus status = partialBlock.FillBlock(*pblock, block_transactions.txn); if (status == READ_STATUS_INVALID) { RemoveBlockRequest(block_transactions.blockhash, pfrom.GetId()); // Reset in-flight state in case Misbehaving does not result in a disconnect - Misbehaving(peer, 100, "invalid compact block/non-matching block transactions"); + Misbehaving(peer, "invalid compact block/non-matching block transactions"); return; } else if (status == READ_STATUS_FAILED) { if (first_in_flight) { @@ -4091,7 +4085,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type, if (vAddr.size() > MAX_ADDR_TO_SEND) { - Misbehaving(*peer, 20, strprintf("%s message size = %u", msg_type, vAddr.size())); + Misbehaving(*peer, strprintf("%s message size = %u", msg_type, vAddr.size())); return; } @@ -4173,7 +4167,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type, vRecv >> vInv; if (vInv.size() > MAX_INV_SZ) { - Misbehaving(*peer, 20, strprintf("inv message size = %u", vInv.size())); + Misbehaving(*peer, strprintf("inv message size = %u", vInv.size())); return; } @@ -4265,7 +4259,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type, vRecv >> vInv; if (vInv.size() > MAX_INV_SZ) { - Misbehaving(*peer, 20, strprintf("getdata message size = %u", vInv.size())); + Misbehaving(*peer, strprintf("getdata message size = %u", vInv.size())); return; } @@ -4366,6 +4360,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type, return; } + FlatFilePos block_pos{}; { LOCK(cs_main); @@ -4376,15 +4371,21 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type, } if (pindex->nHeight >= m_chainman.ActiveChain().Height() - MAX_BLOCKTXN_DEPTH) { - CBlock block; - const bool ret{m_chainman.m_blockman.ReadBlockFromDisk(block, *pindex)}; - assert(ret); - - SendBlockTransactions(pfrom, *peer, block, req); - return; + block_pos = pindex->GetBlockPos(); } } + if (!block_pos.IsNull()) { + CBlock block; + const bool ret{m_chainman.m_blockman.ReadBlockFromDisk(block, block_pos)}; + // If height is above MAX_BLOCKTXN_DEPTH then this block cannot get + // pruned after we release cs_main above, so this read should never fail. + assert(ret); + + SendBlockTransactions(pfrom, *peer, block, req); + return; + } + // If an older block is requested (should never happen in practice, // but can happen in tests) send a block response instead of a // blocktxn response. Sending a full block response instead of a @@ -4798,7 +4799,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type, ReadStatus status = partialBlock.InitData(cmpctblock, vExtraTxnForCompact); if (status == READ_STATUS_INVALID) { RemoveBlockRequest(pindex->GetBlockHash(), pfrom.GetId()); // Reset in-flight state in case Misbehaving does not result in a disconnect - Misbehaving(*peer, 100, "invalid compact block"); + Misbehaving(*peer, "invalid compact block"); return; } else if (status == READ_STATUS_FAILED) { if (first_in_flight) { @@ -4938,16 +4939,12 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type, return; } - // Assume that this is in response to any outstanding getheaders - // request we may have sent, and clear out the time of our last request - peer->m_last_getheaders_timestamp = {}; - std::vector<CBlockHeader> headers; // Bypass the normal CBlock deserialization, as we don't want to risk deserializing 2000 full blocks. unsigned int nCount = ReadCompactSize(vRecv); if (nCount > MAX_HEADERS_RESULTS) { - Misbehaving(*peer, 20, strprintf("headers message size = %u", nCount)); + Misbehaving(*peer, strprintf("headers message size = %u", nCount)); return; } headers.resize(nCount); @@ -4994,7 +4991,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type, if (prev_block && IsBlockMutated(/*block=*/*pblock, /*check_witness_root=*/DeploymentActiveAfter(prev_block, m_chainman, Consensus::DEPLOYMENT_SEGWIT))) { LogDebug(BCLog::NET, "Received mutated block from peer=%d\n", peer->m_id); - Misbehaving(*peer, 100, "mutated block"); + Misbehaving(*peer, "mutated block"); WITH_LOCK(cs_main, RemoveBlockRequest(pblock->GetHash(), peer->m_id)); return; } @@ -5175,7 +5172,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type, if (!filter.IsWithinSizeConstraints()) { // There is no excuse for sending a too-large filter - Misbehaving(*peer, 100, "too-large bloom filter"); + Misbehaving(*peer, "too-large bloom filter"); } else if (auto tx_relay = peer->GetTxRelay(); tx_relay != nullptr) { { LOCK(tx_relay->m_bloom_filter_mutex); @@ -5211,7 +5208,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type, } } if (bad) { - Misbehaving(*peer, 100, "bad filteradd message"); + Misbehaving(*peer, "bad filteradd message"); } return; } @@ -5411,16 +5408,19 @@ void PeerManagerImpl::ConsiderEviction(CNode& pto, Peer& peer, std::chrono::seco // unless it's invalid, in which case we should find that out and // disconnect from them elsewhere). if (state.pindexBestKnownBlock != nullptr && state.pindexBestKnownBlock->nChainWork >= m_chainman.ActiveChain().Tip()->nChainWork) { + // The outbound peer has sent us a block with at least as much work as our current tip, so reset the timeout if it was set if (state.m_chain_sync.m_timeout != 0s) { state.m_chain_sync.m_timeout = 0s; state.m_chain_sync.m_work_header = nullptr; state.m_chain_sync.m_sent_getheaders = false; } } else if (state.m_chain_sync.m_timeout == 0s || (state.m_chain_sync.m_work_header != nullptr && state.pindexBestKnownBlock != nullptr && state.pindexBestKnownBlock->nChainWork >= state.m_chain_sync.m_work_header->nChainWork)) { - // Our best block known by this peer is behind our tip, and we're either noticing - // that for the first time, OR this peer was able to catch up to some earlier point - // where we checked against our tip. - // Either way, set a new timeout based on current tip. + // At this point we know that the outbound peer has either never sent us a block/header or they have, but its tip is behind ours + // AND + // we are noticing this for the first time (m_timeout is 0) + // OR we noticed this at some point within the last CHAIN_SYNC_TIMEOUT + HEADERS_RESPONSE_TIME seconds and set a timeout + // for them, they caught up to our tip at the time of setting the timer but not to our current one (we've also advanced). + // Either way, set a new timeout based on our current tip. state.m_chain_sync.m_timeout = time_in_seconds + CHAIN_SYNC_TIMEOUT; state.m_chain_sync.m_work_header = m_chainman.ActiveChain().Tip(); state.m_chain_sync.m_sent_getheaders = false; @@ -5742,7 +5742,7 @@ void PeerManagerImpl::MaybeSendFeefilter(CNode& pto, Peer& peer, std::chrono::mi if (current_time > peer.m_next_send_feefilter) { CAmount filterToSend = m_fee_filter_rounder.round(currentFilter); // We always have a fee filter of at least the min relay fee - filterToSend = std::max(filterToSend, m_mempool.m_min_relay_feerate.GetFeePerK()); + filterToSend = std::max(filterToSend, m_mempool.m_opts.min_relay_feerate.GetFeePerK()); if (filterToSend != peer.m_fee_filter_sent) { MakeAndPushMessage(pto, NetMsgType::FEEFILTER, filterToSend); peer.m_fee_filter_sent = filterToSend; diff --git a/src/net_processing.h b/src/net_processing.h index 85e399d948..bf9698ee02 100644 --- a/src/net_processing.h +++ b/src/net_processing.h @@ -16,6 +16,10 @@ class CChainParams; class CTxMemPool; class ChainstateManager; +namespace node { +class Warnings; +} // namespace node + /** Whether transaction reconciliation protocol should be enabled by default. */ static constexpr bool DEFAULT_TXRECONCILIATION_ENABLE{false}; /** Default for -maxorphantx, maximum number of orphan transactions kept in memory */ @@ -25,8 +29,6 @@ static const uint32_t DEFAULT_MAX_ORPHAN_TRANSACTIONS{100}; static const uint32_t DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN{100}; static const bool DEFAULT_PEERBLOOMFILTERS = false; static const bool DEFAULT_PEERBLOCKFILTERS = false; -/** Threshold for marking a node to be discouraged, e.g. disconnected and added to the discouragement filter. */ -static const int DISCOURAGEMENT_THRESHOLD{100}; /** Maximum number of outstanding CMPCTBLOCK requests for the same block. */ static const unsigned int MAX_CMPCTBLOCKS_INFLIGHT_PER_BLOCK = 3; @@ -73,7 +75,7 @@ public: static std::unique_ptr<PeerManager> make(CConnman& connman, AddrMan& addrman, BanMan* banman, ChainstateManager& chainman, - CTxMemPool& pool, Options opts); + CTxMemPool& pool, node::Warnings& warnings, Options opts); virtual ~PeerManager() { } /** @@ -104,7 +106,7 @@ public: virtual void SetBestBlock(int height, std::chrono::seconds time) = 0; /* Public for unit testing. */ - virtual void UnitTestMisbehaving(NodeId peer_id, int howmuch) = 0; + virtual void UnitTestMisbehaving(NodeId peer_id) = 0; /** * Evict extra outbound peers. If we think our tip may be stale, connect to an extra outbound. diff --git a/src/net_types.cpp b/src/net_types.cpp index fd6ad80404..fb6ad59599 100644 --- a/src/net_types.cpp +++ b/src/net_types.cpp @@ -43,7 +43,7 @@ UniValue BanMapToJson(const banmap_t& bans) const auto& ban_entry = it.second; UniValue j = ban_entry.ToJson(); j.pushKV(BANMAN_JSON_ADDR_KEY, address.ToString()); - bans_json.push_back(j); + bans_json.push_back(std::move(j)); } return bans_json; } diff --git a/src/netaddress.cpp b/src/netaddress.cpp index 74ab6dd8d8..0053464822 100644 --- a/src/netaddress.cpp +++ b/src/netaddress.cpp @@ -20,6 +20,9 @@ #include <iterator> #include <tuple> +using util::ContainsNoNUL; +using util::HasPrefix; + CNetAddr::BIP155Network CNetAddr::GetBIP155Network() const { switch (m_net) { diff --git a/src/netaddress.h b/src/netaddress.h index c63bd4b4e5..52fecada1c 100644 --- a/src/netaddress.h +++ b/src/netaddress.h @@ -237,7 +237,7 @@ public: template <typename Stream> void Serialize(Stream& s) const { - if (s.GetParams().enc == Encoding::V2) { + if (s.template GetParams<SerParams>().enc == Encoding::V2) { SerializeV2Stream(s); } else { SerializeV1Stream(s); @@ -250,7 +250,7 @@ public: template <typename Stream> void Unserialize(Stream& s) { - if (s.GetParams().enc == Encoding::V2) { + if (s.template GetParams<SerParams>().enc == Encoding::V2) { UnserializeV2Stream(s); } else { UnserializeV1Stream(s); @@ -448,7 +448,7 @@ private: // Recognize NET_INTERNAL embedded in IPv6, such addresses are not // gossiped but could be coming from addrman, when unserializing from // disk. - if (HasPrefix(m_addr, INTERNAL_IN_IPV6_PREFIX)) { + if (util::HasPrefix(m_addr, INTERNAL_IN_IPV6_PREFIX)) { m_net = NET_INTERNAL; memmove(m_addr.data(), m_addr.data() + INTERNAL_IN_IPV6_PREFIX.size(), ADDR_INTERNAL_SIZE); @@ -456,8 +456,8 @@ private: return; } - if (!HasPrefix(m_addr, IPV4_IN_IPV6_PREFIX) && - !HasPrefix(m_addr, TORV2_IN_IPV6_PREFIX)) { + if (!util::HasPrefix(m_addr, IPV4_IN_IPV6_PREFIX) && + !util::HasPrefix(m_addr, TORV2_IN_IPV6_PREFIX)) { return; } diff --git a/src/netbase.cpp b/src/netbase.cpp index e231766487..f5f0997ba6 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -23,10 +23,12 @@ #include <limits> #include <memory> -#if HAVE_SOCKADDR_UN +#ifdef HAVE_SOCKADDR_UN #include <sys/un.h> #endif +using util::ContainsNoNUL; + // Settings static GlobalMutex g_proxyinfo_mutex; static Proxy proxyInfo[NET_MAX] GUARDED_BY(g_proxyinfo_mutex); @@ -216,7 +218,7 @@ CService LookupNumeric(const std::string& name, uint16_t portDefault, DNSLookupF bool IsUnixSocketPath(const std::string& name) { -#if HAVE_SOCKADDR_UN +#ifdef HAVE_SOCKADDR_UN if (name.find(ADDR_PREFIX_UNIX) != 0) return false; // Split off "unix:" prefix @@ -485,24 +487,23 @@ bool Socks5(const std::string& strDest, uint16_t port, const ProxyCredentials* a } } -std::unique_ptr<Sock> CreateSockOS(sa_family_t address_family) +std::unique_ptr<Sock> CreateSockOS(int domain, int type, int protocol) { // Not IPv4, IPv6 or UNIX - if (address_family == AF_UNSPEC) return nullptr; - - int protocol{IPPROTO_TCP}; -#if HAVE_SOCKADDR_UN - if (address_family == AF_UNIX) protocol = 0; -#endif + if (domain == AF_UNSPEC) return nullptr; // Create a socket in the specified address family. - SOCKET hSocket = socket(address_family, SOCK_STREAM, protocol); + SOCKET hSocket = socket(domain, type, protocol); if (hSocket == INVALID_SOCKET) { return nullptr; } auto sock = std::make_unique<Sock>(hSocket); + if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNIX) { + return sock; + } + // Ensure that waiting for I/O on this socket won't result in undefined // behavior. if (!sock->IsSelectable()) { @@ -526,19 +527,22 @@ std::unique_ptr<Sock> CreateSockOS(sa_family_t address_family) return nullptr; } -#if HAVE_SOCKADDR_UN - if (address_family == AF_UNIX) return sock; +#ifdef HAVE_SOCKADDR_UN + if (domain == AF_UNIX) return sock; #endif - // Set the no-delay option (disable Nagle's algorithm) on the TCP socket. - const int on{1}; - if (sock->SetSockOpt(IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) == SOCKET_ERROR) { - LogPrint(BCLog::NET, "Unable to set TCP_NODELAY on a newly created socket, continuing anyway\n"); + if (protocol == IPPROTO_TCP) { + // Set the no-delay option (disable Nagle's algorithm) on the TCP socket. + const int on{1}; + if (sock->SetSockOpt(IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) == SOCKET_ERROR) { + LogPrint(BCLog::NET, "Unable to set TCP_NODELAY on a newly created socket, continuing anyway\n"); + } } + return sock; } -std::function<std::unique_ptr<Sock>(const sa_family_t&)> CreateSock = CreateSockOS; +std::function<std::unique_ptr<Sock>(int, int, int)> CreateSock = CreateSockOS; template<typename... Args> static void LogConnectFailure(bool manual_connection, const char* fmt, const Args&... args) { @@ -607,7 +611,7 @@ static bool ConnectToSocket(const Sock& sock, struct sockaddr* sockaddr, socklen std::unique_ptr<Sock> ConnectDirectly(const CService& dest, bool manual_connection) { - auto sock = CreateSock(dest.GetSAFamily()); + auto sock = CreateSock(dest.GetSAFamily(), SOCK_STREAM, IPPROTO_TCP); if (!sock) { LogPrintLevel(BCLog::NET, BCLog::Level::Error, "Cannot create a socket for connecting to %s\n", dest.ToStringAddrPort()); return {}; @@ -634,8 +638,8 @@ std::unique_ptr<Sock> Proxy::Connect() const if (!m_is_unix_socket) return ConnectDirectly(proxy, /*manual_connection=*/true); -#if HAVE_SOCKADDR_UN - auto sock = CreateSock(AF_UNIX); +#ifdef HAVE_SOCKADDR_UN + auto sock = CreateSock(AF_UNIX, SOCK_STREAM, 0); if (!sock) { LogPrintLevel(BCLog::NET, BCLog::Level::Error, "Cannot create a socket for connecting to %s\n", m_unix_socket_path); return {}; diff --git a/src/netbase.h b/src/netbase.h index 321c288f67..8ef6c28996 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -262,16 +262,18 @@ CService LookupNumeric(const std::string& name, uint16_t portDefault = 0, DNSLoo CSubNet LookupSubNet(const std::string& subnet_str); /** - * Create a TCP or UNIX socket in the given address family. - * @param[in] address_family to use for the socket. + * Create a real socket from the operating system. + * @param[in] domain Communications domain, first argument to the socket(2) syscall. + * @param[in] type Type of the socket, second argument to the socket(2) syscall. + * @param[in] protocol The particular protocol to be used with the socket, third argument to the socket(2) syscall. * @return pointer to the created Sock object or unique_ptr that owns nothing in case of failure */ -std::unique_ptr<Sock> CreateSockOS(sa_family_t address_family); +std::unique_ptr<Sock> CreateSockOS(int domain, int type, int protocol); /** * Socket factory. Defaults to `CreateSockOS()`, but can be overridden by unit tests. */ -extern std::function<std::unique_ptr<Sock>(const sa_family_t&)> CreateSock; +extern std::function<std::unique_ptr<Sock>(int, int, int)> CreateSock; /** * Create a socket and try to connect to the specified service. diff --git a/src/node/abort.cpp b/src/node/abort.cpp index b727608384..8a17c41fd2 100644 --- a/src/node/abort.cpp +++ b/src/node/abort.cpp @@ -6,19 +6,18 @@ #include <logging.h> #include <node/interface_ui.h> +#include <node/warnings.h> #include <util/signalinterrupt.h> #include <util/translation.h> -#include <warnings.h> #include <atomic> #include <cstdlib> -#include <string> namespace node { -void AbortNode(util::SignalInterrupt* shutdown, std::atomic<int>& exit_status, const bilingual_str& message) +void AbortNode(util::SignalInterrupt* shutdown, std::atomic<int>& exit_status, const bilingual_str& message, node::Warnings* warnings) { - SetMiscWarning(message); + if (warnings) warnings->Set(Warning::FATAL_INTERNAL_ERROR, message); InitError(_("A fatal internal error occurred, see debug.log for details: ") + message); exit_status.store(EXIT_FAILURE); if (shutdown && !(*shutdown)()) { diff --git a/src/node/abort.h b/src/node/abort.h index 1092279142..c881af4634 100644 --- a/src/node/abort.h +++ b/src/node/abort.h @@ -14,7 +14,8 @@ class SignalInterrupt; } // namespace util namespace node { -void AbortNode(util::SignalInterrupt* shutdown, std::atomic<int>& exit_status, const bilingual_str& message); +class Warnings; +void AbortNode(util::SignalInterrupt* shutdown, std::atomic<int>& exit_status, const bilingual_str& message, node::Warnings* warnings); } // namespace node #endif // BITCOIN_NODE_ABORT_H diff --git a/src/node/blockstorage.cpp b/src/node/blockstorage.cpp index 576c07a833..fb62e78138 100644 --- a/src/node/blockstorage.cpp +++ b/src/node/blockstorage.cpp @@ -150,7 +150,6 @@ bool BlockTreeDB::LoadBlockIndexGuts(const Consensus::Params& consensusParams, s } // namespace kernel namespace node { -std::atomic_bool fReindex(false); bool CBlockIndexWorkComparator::operator()(const CBlockIndex* pa, const CBlockIndex* pb) const { @@ -552,7 +551,7 @@ bool BlockManager::LoadBlockIndexDB(const std::optional<uint256>& snapshot_block // Check whether we need to continue reindexing bool fReindexing = false; m_block_tree_db->ReadReindexing(fReindexing); - if (fReindexing) fReindex = true; + if (fReindexing) m_blockfiles_indexed = false; return true; } @@ -848,7 +847,7 @@ fs::path BlockManager::GetBlockPosFilename(const FlatFilePos& pos) const return BlockFileSeq().FileName(pos); } -bool BlockManager::FindBlockPos(FlatFilePos& pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown) +FlatFilePos BlockManager::FindNextBlockPos(unsigned int nAddSize, unsigned int nHeight, uint64_t nTime) { LOCK(cs_LastBlockFile); @@ -863,88 +862,101 @@ bool BlockManager::FindBlockPos(FlatFilePos& pos, unsigned int nAddSize, unsigne } const int last_blockfile = m_blockfile_cursors[chain_type]->file_num; - int nFile = fKnown ? pos.nFile : last_blockfile; + int nFile = last_blockfile; if (static_cast<int>(m_blockfile_info.size()) <= nFile) { m_blockfile_info.resize(nFile + 1); } bool finalize_undo = false; - if (!fKnown) { - unsigned int max_blockfile_size{MAX_BLOCKFILE_SIZE}; - // Use smaller blockfiles in test-only -fastprune mode - but avoid - // the possibility of having a block not fit into the block file. - if (m_opts.fast_prune) { - max_blockfile_size = 0x10000; // 64kiB - if (nAddSize >= max_blockfile_size) { - // dynamically adjust the blockfile size to be larger than the added size - max_blockfile_size = nAddSize + 1; - } + unsigned int max_blockfile_size{MAX_BLOCKFILE_SIZE}; + // Use smaller blockfiles in test-only -fastprune mode - but avoid + // the possibility of having a block not fit into the block file. + if (m_opts.fast_prune) { + max_blockfile_size = 0x10000; // 64kiB + if (nAddSize >= max_blockfile_size) { + // dynamically adjust the blockfile size to be larger than the added size + max_blockfile_size = nAddSize + 1; } - assert(nAddSize < max_blockfile_size); - - while (m_blockfile_info[nFile].nSize + nAddSize >= max_blockfile_size) { - // when the undo file is keeping up with the block file, we want to flush it explicitly - // when it is lagging behind (more blocks arrive than are being connected), we let the - // undo block write case handle it - finalize_undo = (static_cast<int>(m_blockfile_info[nFile].nHeightLast) == - Assert(m_blockfile_cursors[chain_type])->undo_height); - - // Try the next unclaimed blockfile number - nFile = this->MaxBlockfileNum() + 1; - // Set to increment MaxBlockfileNum() for next iteration - m_blockfile_cursors[chain_type] = BlockfileCursor{nFile}; - - if (static_cast<int>(m_blockfile_info.size()) <= nFile) { - m_blockfile_info.resize(nFile + 1); - } + } + assert(nAddSize < max_blockfile_size); + + while (m_blockfile_info[nFile].nSize + nAddSize >= max_blockfile_size) { + // when the undo file is keeping up with the block file, we want to flush it explicitly + // when it is lagging behind (more blocks arrive than are being connected), we let the + // undo block write case handle it + finalize_undo = (static_cast<int>(m_blockfile_info[nFile].nHeightLast) == + Assert(m_blockfile_cursors[chain_type])->undo_height); + + // Try the next unclaimed blockfile number + nFile = this->MaxBlockfileNum() + 1; + // Set to increment MaxBlockfileNum() for next iteration + m_blockfile_cursors[chain_type] = BlockfileCursor{nFile}; + + if (static_cast<int>(m_blockfile_info.size()) <= nFile) { + m_blockfile_info.resize(nFile + 1); } - pos.nFile = nFile; - pos.nPos = m_blockfile_info[nFile].nSize; } + FlatFilePos pos; + pos.nFile = nFile; + pos.nPos = m_blockfile_info[nFile].nSize; if (nFile != last_blockfile) { - if (!fKnown) { - LogPrint(BCLog::BLOCKSTORAGE, "Leaving block file %i: %s (onto %i) (height %i)\n", - last_blockfile, m_blockfile_info[last_blockfile].ToString(), nFile, nHeight); - - // Do not propagate the return code. The flush concerns a previous block - // and undo file that has already been written to. If a flush fails - // here, and we crash, there is no expected additional block data - // inconsistency arising from the flush failure here. However, the undo - // data may be inconsistent after a crash if the flush is called during - // a reindex. A flush error might also leave some of the data files - // untrimmed. - if (!FlushBlockFile(last_blockfile, !fKnown, finalize_undo)) { - LogPrintLevel(BCLog::BLOCKSTORAGE, BCLog::Level::Warning, - "Failed to flush previous block file %05i (finalize=%i, finalize_undo=%i) before opening new block file %05i\n", - last_blockfile, !fKnown, finalize_undo, nFile); - } + LogPrint(BCLog::BLOCKSTORAGE, "Leaving block file %i: %s (onto %i) (height %i)\n", + last_blockfile, m_blockfile_info[last_blockfile].ToString(), nFile, nHeight); + + // Do not propagate the return code. The flush concerns a previous block + // and undo file that has already been written to. If a flush fails + // here, and we crash, there is no expected additional block data + // inconsistency arising from the flush failure here. However, the undo + // data may be inconsistent after a crash if the flush is called during + // a reindex. A flush error might also leave some of the data files + // untrimmed. + if (!FlushBlockFile(last_blockfile, /*fFinalize=*/true, finalize_undo)) { + LogPrintLevel(BCLog::BLOCKSTORAGE, BCLog::Level::Warning, + "Failed to flush previous block file %05i (finalize=1, finalize_undo=%i) before opening new block file %05i\n", + last_blockfile, finalize_undo, nFile); } // No undo data yet in the new file, so reset our undo-height tracking. m_blockfile_cursors[chain_type] = BlockfileCursor{nFile}; } m_blockfile_info[nFile].AddBlock(nHeight, nTime); - if (fKnown) { - m_blockfile_info[nFile].nSize = std::max(pos.nPos + nAddSize, m_blockfile_info[nFile].nSize); - } else { - m_blockfile_info[nFile].nSize += nAddSize; + m_blockfile_info[nFile].nSize += nAddSize; + + bool out_of_space; + size_t bytes_allocated = BlockFileSeq().Allocate(pos, nAddSize, out_of_space); + if (out_of_space) { + m_opts.notifications.fatalError(_("Disk space is too low!")); + return {}; + } + if (bytes_allocated != 0 && IsPruneMode()) { + m_check_for_pruning = true; } - if (!fKnown) { - bool out_of_space; - size_t bytes_allocated = BlockFileSeq().Allocate(pos, nAddSize, out_of_space); - if (out_of_space) { - m_opts.notifications.fatalError(_("Disk space is too low!")); - return false; - } - if (bytes_allocated != 0 && IsPruneMode()) { - m_check_for_pruning = true; - } + m_dirty_fileinfo.insert(nFile); + return pos; +} + +void BlockManager::UpdateBlockInfo(const CBlock& block, unsigned int nHeight, const FlatFilePos& pos) +{ + LOCK(cs_LastBlockFile); + + // Update the cursor so it points to the last file. + const BlockfileType chain_type{BlockfileTypeForHeight(nHeight)}; + auto& cursor{m_blockfile_cursors[chain_type]}; + if (!cursor || cursor->file_num < pos.nFile) { + m_blockfile_cursors[chain_type] = BlockfileCursor{pos.nFile}; } + // Update the file information with the current block. + const unsigned int added_size = ::GetSerializeSize(TX_WITH_WITNESS(block)); + const int nFile = pos.nFile; + if (static_cast<int>(m_blockfile_info.size()) <= nFile) { + m_blockfile_info.resize(nFile + 1); + } + m_blockfile_info[nFile].AddBlock(nHeight, block.GetBlockTime()); + m_blockfile_info[nFile].nSize = std::max(pos.nPos + added_size, m_blockfile_info[nFile].nSize); m_dirty_fileinfo.insert(nFile); - return true; } bool BlockManager::FindUndoPos(BlockValidationState& state, int nFile, FlatFilePos& pos, unsigned int nAddSize) @@ -1014,7 +1026,7 @@ bool BlockManager::WriteUndoDataForBlock(const CBlockUndo& blockundo, BlockValid // we want to flush the rev (undo) file once we've written the last block, which is indicated by the last height // in the block file info as below; note that this does not catch the case where the undo writes are keeping up // with the block writes (usually when a synced up node is getting newly mined blocks) -- this case is caught in - // the FindBlockPos function + // the FindNextBlockPos function if (_pos.nFile < cursor.file_num && static_cast<uint32_t>(block.nHeight) == m_blockfile_info[_pos.nFile].nHeightLast) { // Do not propagate the return code, a failed flush here should not // be an indication for a failed write. If it were propagated here, @@ -1130,28 +1142,20 @@ bool BlockManager::ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatF return true; } -FlatFilePos BlockManager::SaveBlockToDisk(const CBlock& block, int nHeight, const FlatFilePos* dbp) +FlatFilePos BlockManager::SaveBlockToDisk(const CBlock& block, int nHeight) { unsigned int nBlockSize = ::GetSerializeSize(TX_WITH_WITNESS(block)); - FlatFilePos blockPos; - const auto position_known {dbp != nullptr}; - if (position_known) { - blockPos = *dbp; - } else { - // when known, blockPos.nPos points at the offset of the block data in the blk file. that already accounts for - // the serialization header present in the file (the 4 magic message start bytes + the 4 length bytes = 8 bytes = BLOCK_SERIALIZATION_HEADER_SIZE). - // we add BLOCK_SERIALIZATION_HEADER_SIZE only for new blocks since they will have the serialization header added when written to disk. - nBlockSize += static_cast<unsigned int>(BLOCK_SERIALIZATION_HEADER_SIZE); - } - if (!FindBlockPos(blockPos, nBlockSize, nHeight, block.GetBlockTime(), position_known)) { - LogError("%s: FindBlockPos failed\n", __func__); + // Account for the 4 magic message start bytes + the 4 length bytes (8 bytes total, + // defined as BLOCK_SERIALIZATION_HEADER_SIZE) + nBlockSize += static_cast<unsigned int>(BLOCK_SERIALIZATION_HEADER_SIZE); + FlatFilePos blockPos{FindNextBlockPos(nBlockSize, nHeight, block.GetBlockTime())}; + if (blockPos.IsNull()) { + LogError("%s: FindNextBlockPos failed\n", __func__); return FlatFilePos(); } - if (!position_known) { - if (!WriteBlockToDisk(block, blockPos)) { - m_opts.notifications.fatalError(_("Failed to write block.")); - return FlatFilePos(); - } + if (!WriteBlockToDisk(block, blockPos)) { + m_opts.notifications.fatalError(_("Failed to write block.")); + return FlatFilePos(); } return blockPos; } @@ -1175,69 +1179,66 @@ public: void ImportBlocks(ChainstateManager& chainman, std::vector<fs::path> vImportFiles) { - ScheduleBatchPriority(); - - { - ImportingNow imp{chainman.m_blockman.m_importing}; - - // -reindex - if (fReindex) { - int nFile = 0; - // Map of disk positions for blocks with unknown parent (only used for reindex); - // parent hash -> child disk position, multiple children can have the same parent. - std::multimap<uint256, FlatFilePos> blocks_with_unknown_parent; - while (true) { - FlatFilePos pos(nFile, 0); - if (!fs::exists(chainman.m_blockman.GetBlockPosFilename(pos))) { - break; // No block files left to reindex - } - AutoFile file{chainman.m_blockman.OpenBlockFile(pos, true)}; - if (file.IsNull()) { - break; // This error is logged in OpenBlockFile - } - LogPrintf("Reindexing block file blk%05u.dat...\n", (unsigned int)nFile); - chainman.LoadExternalBlockFile(file, &pos, &blocks_with_unknown_parent); - if (chainman.m_interrupt) { - LogPrintf("Interrupt requested. Exit %s\n", __func__); - return; - } - nFile++; + ImportingNow imp{chainman.m_blockman.m_importing}; + + // -reindex + if (!chainman.m_blockman.m_blockfiles_indexed) { + int nFile = 0; + // Map of disk positions for blocks with unknown parent (only used for reindex); + // parent hash -> child disk position, multiple children can have the same parent. + std::multimap<uint256, FlatFilePos> blocks_with_unknown_parent; + while (true) { + FlatFilePos pos(nFile, 0); + if (!fs::exists(chainman.m_blockman.GetBlockPosFilename(pos))) { + break; // No block files left to reindex } - WITH_LOCK(::cs_main, chainman.m_blockman.m_block_tree_db->WriteReindexing(false)); - fReindex = false; - LogPrintf("Reindexing finished\n"); - // To avoid ending up in a situation without genesis block, re-try initializing (no-op if reindexing worked): - chainman.ActiveChainstate().LoadGenesisBlock(); + AutoFile file{chainman.m_blockman.OpenBlockFile(pos, true)}; + if (file.IsNull()) { + break; // This error is logged in OpenBlockFile + } + LogPrintf("Reindexing block file blk%05u.dat...\n", (unsigned int)nFile); + chainman.LoadExternalBlockFile(file, &pos, &blocks_with_unknown_parent); + if (chainman.m_interrupt) { + LogPrintf("Interrupt requested. Exit %s\n", __func__); + return; + } + nFile++; } - - // -loadblock= - for (const fs::path& path : vImportFiles) { - AutoFile file{fsbridge::fopen(path, "rb")}; - if (!file.IsNull()) { - LogPrintf("Importing blocks file %s...\n", fs::PathToString(path)); - chainman.LoadExternalBlockFile(file); - if (chainman.m_interrupt) { - LogPrintf("Interrupt requested. Exit %s\n", __func__); - return; - } - } else { - LogPrintf("Warning: Could not open blocks file %s\n", fs::PathToString(path)); + WITH_LOCK(::cs_main, chainman.m_blockman.m_block_tree_db->WriteReindexing(false)); + chainman.m_blockman.m_blockfiles_indexed = true; + LogPrintf("Reindexing finished\n"); + // To avoid ending up in a situation without genesis block, re-try initializing (no-op if reindexing worked): + chainman.ActiveChainstate().LoadGenesisBlock(); + } + + // -loadblock= + for (const fs::path& path : vImportFiles) { + AutoFile file{fsbridge::fopen(path, "rb")}; + if (!file.IsNull()) { + LogPrintf("Importing blocks file %s...\n", fs::PathToString(path)); + chainman.LoadExternalBlockFile(file); + if (chainman.m_interrupt) { + LogPrintf("Interrupt requested. Exit %s\n", __func__); + return; } + } else { + LogPrintf("Warning: Could not open blocks file %s\n", fs::PathToString(path)); } + } - // scan for better chains in the block chain database, that are not yet connected in the active best chain + // scan for better chains in the block chain database, that are not yet connected in the active best chain - // We can't hold cs_main during ActivateBestChain even though we're accessing - // the chainman unique_ptrs since ABC requires us not to be holding cs_main, so retrieve - // the relevant pointers before the ABC call. - for (Chainstate* chainstate : WITH_LOCK(::cs_main, return chainman.GetAll())) { - BlockValidationState state; - if (!chainstate->ActivateBestChain(state, nullptr)) { - chainman.GetNotifications().fatalError(strprintf(_("Failed to connect best block (%s)."), state.ToString())); - return; - } + // We can't hold cs_main during ActivateBestChain even though we're accessing + // the chainman unique_ptrs since ABC requires us not to be holding cs_main, so retrieve + // the relevant pointers before the ABC call. + for (Chainstate* chainstate : WITH_LOCK(::cs_main, return chainman.GetAll())) { + BlockValidationState state; + if (!chainstate->ActivateBestChain(state, nullptr)) { + chainman.GetNotifications().fatalError(strprintf(_("Failed to connect best block (%s)."), state.ToString())); + return; } - } // End scope of ImportingNow + } + // End scope of ImportingNow } std::ostream& operator<<(std::ostream& os, const BlockfileType& type) { diff --git a/src/node/blockstorage.h b/src/node/blockstorage.h index ce514cc645..108a08a72b 100644 --- a/src/node/blockstorage.h +++ b/src/node/blockstorage.h @@ -76,8 +76,6 @@ static const unsigned int MAX_BLOCKFILE_SIZE = 0x8000000; // 128 MiB /** Size of header written by WriteBlockToDisk before a serialized CBlock */ static constexpr size_t BLOCK_SERIALIZATION_HEADER_SIZE = std::tuple_size_v<MessageStartChars> + sizeof(unsigned int); -extern std::atomic_bool fReindex; - // Because validation code takes pointers to the map's CBlockIndex objects, if // we ever switch to another associative container, we need to either use a // container that has stable addressing (true of all std associative @@ -155,7 +153,16 @@ private: /** Return false if undo file flushing fails. */ [[nodiscard]] bool FlushUndoFile(int block_file, bool finalize = false); - [[nodiscard]] bool FindBlockPos(FlatFilePos& pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown); + /** + * Helper function performing various preparations before a block can be saved to disk: + * Returns the correct position for the block to be saved, which may be in the current or a new + * block file depending on nAddSize. May flush the previous blockfile to disk if full, updates + * blockfile info, and checks if there is enough disk space to save the block. + * + * The nAddSize argument passed to this function should include not just the size of the serialized CBlock, but also the size of + * separator fields which are written before it by WriteBlockToDisk (BLOCK_SERIALIZATION_HEADER_SIZE). + */ + [[nodiscard]] FlatFilePos FindNextBlockPos(unsigned int nAddSize, unsigned int nHeight, uint64_t nTime); [[nodiscard]] bool FlushChainstateBlockFile(int tip_height); bool FindUndoPos(BlockValidationState& state, int nFile, FlatFilePos& pos, unsigned int nAddSize); @@ -164,6 +171,12 @@ private: AutoFile OpenUndoFile(const FlatFilePos& pos, bool fReadOnly = false) const; + /** + * Write a block to disk. The pos argument passed to this function is modified by this call. Before this call, it should + * point to an unused file location where separator fields will be written, followed by the serialized CBlock data. + * After this call, it will point to the beginning of the serialized CBlock data, after the separator fields + * (BLOCK_SERIALIZATION_HEADER_SIZE) + */ bool WriteBlockToDisk(const CBlock& block, FlatFilePos& pos) const; bool UndoWriteToDisk(const CBlockUndo& blockundo, FlatFilePos& pos, const uint256& hashBlock) const; @@ -206,7 +219,7 @@ private: //! effectively. //! //! This data structure maintains separate blockfile number cursors for each - //! BlockfileType. The ASSUMED state is initialized, when necessary, in FindBlockPos(). + //! BlockfileType. The ASSUMED state is initialized, when necessary, in FindNextBlockPos(). //! //! The first element is the NORMAL cursor, second is ASSUMED. std::array<std::optional<BlockfileCursor>, BlockfileType::NUM_TYPES> @@ -254,11 +267,19 @@ public: explicit BlockManager(const util::SignalInterrupt& interrupt, Options opts) : m_prune_mode{opts.prune_target > 0}, m_opts{std::move(opts)}, - m_interrupt{interrupt} {}; + m_interrupt{interrupt} {} const util::SignalInterrupt& m_interrupt; std::atomic<bool> m_importing{false}; + /** + * Whether all blockfiles have been added to the block tree database. + * Normally true, but set to false when a reindex is requested and the + * database is wiped. The value is persisted in the database across restarts + * and will be false until reindexing completes. + */ + std::atomic_bool m_blockfiles_indexed{true}; + BlockMap m_block_index GUARDED_BY(cs_main); /** @@ -312,8 +333,24 @@ public: bool WriteUndoDataForBlock(const CBlockUndo& blockundo, BlockValidationState& state, CBlockIndex& block) EXCLUSIVE_LOCKS_REQUIRED(::cs_main); - /** Store block on disk. If dbp is not nullptr, then it provides the known position of the block within a block file on disk. */ - FlatFilePos SaveBlockToDisk(const CBlock& block, int nHeight, const FlatFilePos* dbp); + /** Store block on disk and update block file statistics. + * + * @param[in] block the block to be stored + * @param[in] nHeight the height of the block + * + * @returns in case of success, the position to which the block was written to + * in case of an error, an empty FlatFilePos + */ + FlatFilePos SaveBlockToDisk(const CBlock& block, int nHeight); + + /** Update blockfile info while processing a block during reindex. The block must be available on disk. + * + * @param[in] block the block being processed + * @param[in] nHeight the height of the block + * @param[in] pos the position of the serialized CBlock on disk. This is the position returned + * by WriteBlockToDisk pointing at the CBlock, not the separator fields before it + */ + void UpdateBlockInfo(const CBlock& block, unsigned int nHeight, const FlatFilePos& pos); /** Whether running in -prune mode. */ [[nodiscard]] bool IsPruneMode() const { return m_prune_mode; } @@ -322,7 +359,7 @@ public: [[nodiscard]] uint64_t GetPruneTarget() const { return m_opts.prune_target; } static constexpr auto PRUNE_TARGET_MANUAL{std::numeric_limits<uint64_t>::max()}; - [[nodiscard]] bool LoadingBlocks() const { return m_importing || fReindex; } + [[nodiscard]] bool LoadingBlocks() const { return m_importing || !m_blockfiles_indexed; } /** Calculate the amount of disk space the block & undo files currently use */ uint64_t CalculateCurrentUsage(); diff --git a/src/node/chainstate.cpp b/src/node/chainstate.cpp index bf1fc06b0b..d7e6176be1 100644 --- a/src/node/chainstate.cpp +++ b/src/node/chainstate.cpp @@ -45,11 +45,12 @@ static ChainstateLoadResult CompleteChainstateInitialization( .path = chainman.m_options.datadir / "blocks" / "index", .cache_bytes = static_cast<size_t>(cache_sizes.block_tree_db), .memory_only = options.block_tree_db_in_memory, - .wipe_data = options.reindex, + .wipe_data = options.wipe_block_tree_db, .options = chainman.m_options.block_tree_db}); - if (options.reindex) { + if (options.wipe_block_tree_db) { pblocktree->WriteReindexing(true); + chainman.m_blockman.m_blockfiles_indexed = false; //If we're reindexing in prune mode, wipe away unusable block files and all undo data files if (options.prune) { chainman.m_blockman.CleanupBlockRevFiles(); @@ -60,8 +61,7 @@ static ChainstateLoadResult CompleteChainstateInitialization( // LoadBlockIndex will load m_have_pruned if we've ever removed a // block file from disk. - // Note that it also sets fReindex global based on the disk flag! - // From here on, fReindex and options.reindex values may be different! + // Note that it also sets m_blockfiles_indexed based on the disk flag! if (!chainman.LoadBlockIndex()) { if (chainman.m_interrupt) return {ChainstateLoadStatus::INTERRUPTED, {}}; return {ChainstateLoadStatus::FAILURE, _("Error loading block database")}; @@ -84,12 +84,12 @@ static ChainstateLoadResult CompleteChainstateInitialization( // If we're not mid-reindex (based on disk + args), add a genesis block on disk // (otherwise we use the one already on disk). // This is called again in ImportBlocks after the reindex completes. - if (!fReindex && !chainman.ActiveChainstate().LoadGenesisBlock()) { + if (chainman.m_blockman.m_blockfiles_indexed && !chainman.ActiveChainstate().LoadGenesisBlock()) { return {ChainstateLoadStatus::FAILURE, _("Error initializing block database")}; } auto is_coinsview_empty = [&](Chainstate* chainstate) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) { - return options.reindex || options.reindex_chainstate || chainstate->CoinsTip().GetBestBlock().IsNull(); + return options.wipe_chainstate_db || chainstate->CoinsTip().GetBestBlock().IsNull(); }; assert(chainman.m_total_coinstip_cache > 0); @@ -110,7 +110,7 @@ static ChainstateLoadResult CompleteChainstateInitialization( chainstate->InitCoinsDB( /*cache_size_bytes=*/chainman.m_total_coinsdb_cache * init_cache_fraction, /*in_memory=*/options.coins_db_in_memory, - /*should_wipe=*/options.reindex || options.reindex_chainstate); + /*should_wipe=*/options.wipe_chainstate_db); if (options.coins_error_cb) { chainstate->CoinsErrorCatcher().AddReadErrCallback(options.coins_error_cb); @@ -142,7 +142,7 @@ static ChainstateLoadResult CompleteChainstateInitialization( } } - if (!options.reindex) { + if (!options.wipe_block_tree_db) { auto chainstates{chainman.GetAll()}; if (std::any_of(chainstates.begin(), chainstates.end(), [](const Chainstate* cs) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { return cs->NeedsRedownload(); })) { @@ -188,7 +188,7 @@ ChainstateLoadResult LoadChainstate(ChainstateManager& chainman, const CacheSize // Load a chain created from a UTXO snapshot, if any exist. bool has_snapshot = chainman.DetectSnapshotChainstate(); - if (has_snapshot && (options.reindex || options.reindex_chainstate)) { + if (has_snapshot && options.wipe_chainstate_db) { LogPrintf("[snapshot] deleting snapshot chainstate due to reindexing\n"); if (!chainman.DeleteSnapshotChainstate()) { return {ChainstateLoadStatus::FAILURE_FATAL, Untranslated("Couldn't remove snapshot chainstate.")}; @@ -247,7 +247,7 @@ ChainstateLoadResult LoadChainstate(ChainstateManager& chainman, const CacheSize ChainstateLoadResult VerifyLoadedChainstate(ChainstateManager& chainman, const ChainstateLoadOptions& options) { auto is_coinsview_empty = [&](Chainstate* chainstate) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) { - return options.reindex || options.reindex_chainstate || chainstate->CoinsTip().GetBestBlock().IsNull(); + return options.wipe_chainstate_db || chainstate->CoinsTip().GetBestBlock().IsNull(); }; LOCK(cs_main); diff --git a/src/node/chainstate.h b/src/node/chainstate.h index a6e9a0331b..bb0c4f2b87 100644 --- a/src/node/chainstate.h +++ b/src/node/chainstate.h @@ -22,8 +22,13 @@ struct ChainstateLoadOptions { CTxMemPool* mempool{nullptr}; bool block_tree_db_in_memory{false}; bool coins_db_in_memory{false}; - bool reindex{false}; - bool reindex_chainstate{false}; + // Whether to wipe the block tree database when loading it. If set, this + // will also set a reindexing flag so any existing block data files will be + // scanned and added to the database. + bool wipe_block_tree_db{false}; + // Whether to wipe the chainstate database when loading it. If set, this + // will cause the chainstate database to be rebuilt starting from genesis. + bool wipe_chainstate_db{false}; bool prune{false}; //! Setting require_full_verification to true will require all checks at //! check_level (below) to succeed for loading to succeed. Setting it to diff --git a/src/node/chainstatemanager_args.cpp b/src/node/chainstatemanager_args.cpp index 1cc126cb05..bc4a815a3e 100644 --- a/src/node/chainstatemanager_args.cpp +++ b/src/node/chainstatemanager_args.cpp @@ -24,7 +24,10 @@ namespace node { util::Result<void> ApplyArgsManOptions(const ArgsManager& args, ChainstateManager::Options& opts) { - if (auto value{args.GetBoolArg("-checkblockindex")}) opts.check_block_index = *value; + if (auto value{args.GetIntArg("-checkblockindex")}) { + // Interpret bare -checkblockindex argument as 1 instead of 0. + opts.check_block_index = args.GetArg("-checkblockindex")->empty() ? 1 : *value; + } if (auto value{args.GetBoolArg("-checkpoints")}) opts.checkpoints_enabled = *value; diff --git a/src/node/context.cpp b/src/node/context.cpp index ca56fa0b86..75dfaee866 100644 --- a/src/node/context.cpp +++ b/src/node/context.cpp @@ -7,15 +7,19 @@ #include <addrman.h> #include <banman.h> #include <interfaces/chain.h> +#include <interfaces/mining.h> #include <kernel/context.h> +#include <key.h> #include <net.h> #include <net_processing.h> #include <netgroup.h> #include <node/kernel_notifications.h> +#include <node/warnings.h> #include <policy/fees.h> #include <scheduler.h> #include <txmempool.h> #include <validation.h> +#include <validationinterface.h> namespace node { NodeContext::NodeContext() = default; diff --git a/src/node/context.h b/src/node/context.h index 245f230aec..a664fad80b 100644 --- a/src/node/context.h +++ b/src/node/context.h @@ -5,10 +5,7 @@ #ifndef BITCOIN_NODE_CONTEXT_H #define BITCOIN_NODE_CONTEXT_H -#include <kernel/context.h> - #include <atomic> -#include <cassert> #include <cstdlib> #include <functional> #include <memory> @@ -24,17 +21,26 @@ class ValidationSignals; class CScheduler; class CTxMemPool; class ChainstateManager; +class ECC_Context; class NetGroupManager; class PeerManager; namespace interfaces { class Chain; class ChainClient; +class Mining; class Init; class WalletLoader; } // namespace interfaces +namespace kernel { +struct Context; +} +namespace util { +class SignalInterrupt; +} namespace node { class KernelNotifications; +class Warnings; //! NodeContext struct containing references to chain state and connection //! state. @@ -49,6 +55,7 @@ class KernelNotifications; struct NodeContext { //! libbitcoin_kernel context std::unique_ptr<kernel::Context> kernel; + std::unique_ptr<ECC_Context> ecc_context; //! Init interface for initializing current process and connecting to other processes. interfaces::Init* init{nullptr}; //! Interrupt object used to track whether node shutdown was requested. @@ -68,6 +75,7 @@ struct NodeContext { std::vector<std::unique_ptr<interfaces::ChainClient>> chain_clients; //! Reference to chain client that should used to load or create wallets //! opened by the gui. + std::unique_ptr<interfaces::Mining> mining; interfaces::WalletLoader* wallet_loader{nullptr}; std::unique_ptr<CScheduler> scheduler; std::function<void()> rpc_interruption_point = [] {}; @@ -76,6 +84,8 @@ struct NodeContext { //! Issues calls about blocks and transactions std::unique_ptr<ValidationSignals> validation_signals; std::atomic<int> exit_status{EXIT_SUCCESS}; + //! Manages all the node warnings + std::unique_ptr<node::Warnings> warnings; //! Declare default constructor and destructor that are not inline, so code //! instantiating the NodeContext struct doesn't need to #include class diff --git a/src/node/interface_ui.cpp b/src/node/interface_ui.cpp index 9dd1e7d9cf..4f4d240d1b 100644 --- a/src/node/interface_ui.cpp +++ b/src/node/interface_ui.cpp @@ -10,6 +10,8 @@ #include <boost/signals2/optional_last_value.hpp> #include <boost/signals2/signal.hpp> +using util::MakeUnorderedList; + CClientUIInterface uiInterface; struct UISignals { diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp index 84fc92e69d..e0bab6e22e 100644 --- a/src/node/interfaces.cpp +++ b/src/node/interfaces.cpp @@ -8,15 +8,18 @@ #include <chain.h> #include <chainparams.h> #include <common/args.h> +#include <consensus/validation.h> #include <deploymentstatus.h> #include <external_signer.h> #include <index/blockfilterindex.h> #include <init.h> #include <interfaces/chain.h> #include <interfaces/handler.h> +#include <interfaces/mining.h> #include <interfaces/node.h> #include <interfaces/wallet.h> #include <kernel/chain.h> +#include <kernel/context.h> #include <kernel/mempool_entry.h> #include <logging.h> #include <mapport.h> @@ -29,7 +32,10 @@ #include <node/context.h> #include <node/interface_ui.h> #include <node/mini_miner.h> +#include <node/miner.h> #include <node/transaction.h> +#include <node/types.h> +#include <node/warnings.h> #include <policy/feerate.h> #include <policy/fees.h> #include <policy/policy.h> @@ -51,7 +57,6 @@ #include <util/translation.h> #include <validation.h> #include <validationinterface.h> -#include <warnings.h> #include <config/bitcoin-config.h> // IWYU pragma: keep @@ -67,8 +72,11 @@ using interfaces::Chain; using interfaces::FoundBlock; using interfaces::Handler; using interfaces::MakeSignalHandler; +using interfaces::Mining; using interfaces::Node; using interfaces::WalletLoader; +using node::BlockAssembler; +using util::Join; namespace node { // All members of the classes in this namespace are intentionally public, as the @@ -90,7 +98,7 @@ public: explicit NodeImpl(NodeContext& context) { setContext(&context); } void initLogging() override { InitLogging(args()); } void initParameterInteraction() override { InitParameterInteraction(args()); } - bilingual_str getWarnings() override { return Join(GetWarnings(), Untranslated("<hr />")); } + bilingual_str getWarnings() override { return Join(Assert(m_context->warnings)->GetMessages(), Untranslated("<hr />")); } int getExitStatus() override { return Assert(m_context)->exit_status.load(); } uint32_t getLogCategories() override { return LogInstance().GetCategoryMask(); } bool baseInitialize() override @@ -98,7 +106,9 @@ public: if (!AppInitBasicSetup(args(), Assert(context())->exit_status)) return false; if (!AppInitParameterInteraction(args())) return false; + m_context->warnings = std::make_unique<node::Warnings>(); m_context->kernel = std::make_unique<kernel::Context>(); + m_context->ecc_context = std::make_unique<ECC_Context>(); if (!AppInitSanityChecks(*m_context->kernel)) return false; if (!AppInitLockDataDirectory()) return false; @@ -121,7 +131,7 @@ public: void startShutdown() override { if (!(*Assert(Assert(m_context)->shutdown))()) { - LogPrintf("Error: failed to send shutdown signal\n"); + LogError("Failed to send shutdown signal\n"); } // Stop RPC for clean shutdown if any of waitfor* commands is executed. if (args().GetBoolArg("-server", false)) { @@ -316,7 +326,7 @@ public: CFeeRate getDustRelayFee() override { if (!m_context->mempool) return CFeeRate{DUST_RELAY_TX_FEE}; - return m_context->mempool->m_dust_relay_feerate; + return m_context->mempool->m_opts.dust_relay_feerate; } UniValue executeRpc(const std::string& command, const UniValue& params, const std::string& uri) override { @@ -699,7 +709,7 @@ public: { const CTxMemPool::Limits default_limits{}; - const CTxMemPool::Limits& limits{m_node.mempool ? m_node.mempool->m_limits : default_limits}; + const CTxMemPool::Limits& limits{m_node.mempool ? m_node.mempool->m_opts.limits : default_limits}; limit_ancestor_count = limits.ancestor_count; limit_descendant_count = limits.descendant_count; @@ -730,17 +740,17 @@ public: CFeeRate relayMinFee() override { if (!m_node.mempool) return CFeeRate{DEFAULT_MIN_RELAY_TX_FEE}; - return m_node.mempool->m_min_relay_feerate; + return m_node.mempool->m_opts.min_relay_feerate; } CFeeRate relayIncrementalFee() override { if (!m_node.mempool) return CFeeRate{DEFAULT_INCREMENTAL_RELAY_FEE}; - return m_node.mempool->m_incremental_relay_feerate; + return m_node.mempool->m_opts.incremental_relay_feerate; } CFeeRate relayDustFee() override { if (!m_node.mempool) return CFeeRate{DUST_RELAY_TX_FEE}; - return m_node.mempool->m_dust_relay_feerate; + return m_node.mempool->m_opts.dust_relay_feerate; } bool havePruned() override { @@ -826,10 +836,64 @@ public: ValidationSignals& validation_signals() { return *Assert(m_node.validation_signals); } NodeContext& m_node; }; + +class MinerImpl : public Mining +{ +public: + explicit MinerImpl(NodeContext& node) : m_node(node) {} + + bool isTestChain() override + { + return chainman().GetParams().IsTestChain(); + } + + bool isInitialBlockDownload() override + { + return chainman().IsInitialBlockDownload(); + } + + std::optional<uint256> getTipHash() override + { + LOCK(::cs_main); + CBlockIndex* tip{chainman().ActiveChain().Tip()}; + if (!tip) return {}; + return tip->GetBlockHash(); + } + + bool processNewBlock(const std::shared_ptr<const CBlock>& block, bool* new_block) override + { + return chainman().ProcessNewBlock(block, /*force_processing=*/true, /*min_pow_checked=*/true, /*new_block=*/new_block); + } + + unsigned int getTransactionsUpdated() override + { + return context()->mempool->GetTransactionsUpdated(); + } + + bool testBlockValidity(BlockValidationState& state, const CBlock& block, bool check_merkle_root) override + { + LOCK(::cs_main); + return TestBlockValidity(state, chainman().GetParams(), chainman().ActiveChainstate(), block, chainman().ActiveChain().Tip(), /*fCheckPOW=*/false, check_merkle_root); + } + + std::unique_ptr<CBlockTemplate> createNewBlock(const CScript& script_pub_key, bool use_mempool) override + { + BlockAssembler::Options options; + ApplyArgsManOptions(gArgs, options); + + LOCK(::cs_main); + return BlockAssembler{chainman().ActiveChainstate(), use_mempool ? context()->mempool.get() : nullptr, options}.CreateNewBlock(script_pub_key); + } + + NodeContext* context() override { return &m_node; } + ChainstateManager& chainman() { return *Assert(m_node.chainman); } + NodeContext& m_node; +}; } // namespace } // namespace node namespace interfaces { std::unique_ptr<Node> MakeNode(node::NodeContext& context) { return std::make_unique<node::NodeImpl>(context); } std::unique_ptr<Chain> MakeChain(node::NodeContext& context) { return std::make_unique<node::ChainImpl>(context); } +std::unique_ptr<Mining> MakeMining(node::NodeContext& context) { return std::make_unique<node::MinerImpl>(context); } } // namespace interfaces diff --git a/src/node/kernel_notifications.cpp b/src/node/kernel_notifications.cpp index 6578b383f7..9894052a3a 100644 --- a/src/node/kernel_notifications.cpp +++ b/src/node/kernel_notifications.cpp @@ -10,22 +10,25 @@ #include <common/args.h> #include <common/system.h> #include <kernel/context.h> +#include <kernel/warning.h> #include <logging.h> #include <node/abort.h> #include <node/interface_ui.h> +#include <node/warnings.h> #include <util/check.h> +#include <util/signalinterrupt.h> #include <util/strencodings.h> #include <util/string.h> #include <util/translation.h> -#include <warnings.h> #include <cstdint> #include <string> #include <thread> +using util::ReplaceAll; + static void AlertNotify(const std::string& strMessage) { - uiInterface.NotifyAlertChanged(); #if HAVE_SYSTEM std::string strCmd = gArgs.GetArg("-alertnotify", ""); if (strCmd.empty()) return; @@ -43,16 +46,6 @@ static void AlertNotify(const std::string& strMessage) #endif } -static void DoWarning(const bilingual_str& warning) -{ - static bool fWarned = false; - SetMiscWarning(warning); - if (!fWarned) { - AlertNotify(warning.original); - fWarned = true; - } -} - namespace node { kernel::InterruptResult KernelNotifications::blockTip(SynchronizationState state, CBlockIndex& index) @@ -60,7 +53,7 @@ kernel::InterruptResult KernelNotifications::blockTip(SynchronizationState state uiInterface.NotifyBlockTip(state, &index); if (m_stop_at_height && index.nHeight >= m_stop_at_height) { if (!m_shutdown()) { - LogPrintf("Error: failed to send shutdown signal after reaching stop height\n"); + LogError("Failed to send shutdown signal after reaching stop height\n"); } return kernel::Interrupted{}; } @@ -77,20 +70,27 @@ void KernelNotifications::progress(const bilingual_str& title, int progress_perc uiInterface.ShowProgress(title.translated, progress_percent, resume_possible); } -void KernelNotifications::warning(const bilingual_str& warning) +void KernelNotifications::warningSet(kernel::Warning id, const bilingual_str& message) +{ + if (m_warnings.Set(id, message)) { + AlertNotify(message.original); + } +} + +void KernelNotifications::warningUnset(kernel::Warning id) { - DoWarning(warning); + m_warnings.Unset(id); } void KernelNotifications::flushError(const bilingual_str& message) { - AbortNode(&m_shutdown, m_exit_status, message); + AbortNode(&m_shutdown, m_exit_status, message, &m_warnings); } void KernelNotifications::fatalError(const bilingual_str& message) { node::AbortNode(m_shutdown_on_fatal_error ? &m_shutdown : nullptr, - m_exit_status, message); + m_exit_status, message, &m_warnings); } void ReadNotificationArgs(const ArgsManager& args, KernelNotifications& notifications) diff --git a/src/node/kernel_notifications.h b/src/node/kernel_notifications.h index f4d97a0fff..e37f4d4e1e 100644 --- a/src/node/kernel_notifications.h +++ b/src/node/kernel_notifications.h @@ -15,18 +15,24 @@ class CBlockIndex; enum class SynchronizationState; struct bilingual_str; +namespace kernel { +enum class Warning; +} // namespace kernel + namespace util { class SignalInterrupt; } // namespace util namespace node { +class Warnings; static constexpr int DEFAULT_STOPATHEIGHT{0}; class KernelNotifications : public kernel::Notifications { public: - KernelNotifications(util::SignalInterrupt& shutdown, std::atomic<int>& exit_status) : m_shutdown(shutdown), m_exit_status{exit_status} {} + KernelNotifications(util::SignalInterrupt& shutdown, std::atomic<int>& exit_status, node::Warnings& warnings) + : m_shutdown(shutdown), m_exit_status{exit_status}, m_warnings{warnings} {} [[nodiscard]] kernel::InterruptResult blockTip(SynchronizationState state, CBlockIndex& index) override; @@ -34,7 +40,9 @@ public: void progress(const bilingual_str& title, int progress_percent, bool resume_possible) override; - void warning(const bilingual_str& warning) override; + void warningSet(kernel::Warning id, const bilingual_str& message) override; + + void warningUnset(kernel::Warning id) override; void flushError(const bilingual_str& message) override; @@ -47,6 +55,7 @@ public: private: util::SignalInterrupt& m_shutdown; std::atomic<int>& m_exit_status; + node::Warnings& m_warnings; }; void ReadNotificationArgs(const ArgsManager& args, KernelNotifications& notifications); diff --git a/src/node/mempool_args.cpp b/src/node/mempool_args.cpp index ac26600919..f329affb1d 100644 --- a/src/node/mempool_args.cpp +++ b/src/node/mempool_args.cpp @@ -8,19 +8,20 @@ #include <kernel/mempool_options.h> #include <common/args.h> +#include <common/messages.h> #include <consensus/amount.h> #include <kernel/chainparams.h> #include <logging.h> #include <policy/feerate.h> #include <policy/policy.h> #include <tinyformat.h> -#include <util/error.h> #include <util/moneystr.h> #include <util/translation.h> #include <chrono> #include <memory> +using common::AmountErrMsg; using kernel::MemPoolLimits; using kernel::MemPoolOptions; diff --git a/src/node/miner.cpp b/src/node/miner.cpp index 87f40e993f..03c6d74deb 100644 --- a/src/node/miner.cpp +++ b/src/node/miner.cpp @@ -80,15 +80,6 @@ void ApplyArgsManOptions(const ArgsManager& args, BlockAssembler::Options& optio if (const auto parsed{ParseMoney(*blockmintxfee)}) options.blockMinFeeRate = CFeeRate{*parsed}; } } -static BlockAssembler::Options ConfiguredOptions() -{ - BlockAssembler::Options options; - ApplyArgsManOptions(gArgs, options); - return options; -} - -BlockAssembler::BlockAssembler(Chainstate& chainstate, const CTxMemPool* mempool) - : BlockAssembler(chainstate, mempool, ConfiguredOptions()) {} void BlockAssembler::resetBlock() { diff --git a/src/node/miner.h b/src/node/miner.h index 06a917228d..c3178a7532 100644 --- a/src/node/miner.h +++ b/src/node/miner.h @@ -161,7 +161,6 @@ public: bool test_block_validity{true}; }; - explicit BlockAssembler(Chainstate& chainstate, const CTxMemPool* mempool); explicit BlockAssembler(Chainstate& chainstate, const CTxMemPool* mempool, const Options& options); /** Construct a new block template with coinbase to scriptPubKeyIn */ diff --git a/src/node/timeoffsets.cpp b/src/node/timeoffsets.cpp index 62f527be8a..002c00d245 100644 --- a/src/node/timeoffsets.cpp +++ b/src/node/timeoffsets.cpp @@ -3,13 +3,12 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <logging.h> -#include <node/interface_ui.h> #include <node/timeoffsets.h> +#include <node/warnings.h> #include <sync.h> #include <tinyformat.h> #include <util/time.h> #include <util/translation.h> -#include <warnings.h> #include <algorithm> #include <chrono> @@ -49,8 +48,7 @@ bool TimeOffsets::WarnIfOutOfSync() const // when median == std::numeric_limits<int64_t>::min(), calling std::chrono::abs is UB auto median{std::max(Median(), std::chrono::seconds(std::numeric_limits<int64_t>::min() + 1))}; if (std::chrono::abs(median) <= WARN_THRESHOLD) { - SetMedianTimeOffsetWarning(std::nullopt); - uiInterface.NotifyAlertChanged(); + m_warnings.Unset(node::Warning::CLOCK_OUT_OF_SYNC); return false; } @@ -63,7 +61,6 @@ bool TimeOffsets::WarnIfOutOfSync() const "RPC methods to get more info." ), Ticks<std::chrono::minutes>(WARN_THRESHOLD))}; LogWarning("%s\n", msg.original); - SetMedianTimeOffsetWarning(msg); - uiInterface.NotifyAlertChanged(); + m_warnings.Set(node::Warning::CLOCK_OUT_OF_SYNC, msg); return true; } diff --git a/src/node/timeoffsets.h b/src/node/timeoffsets.h index 2b12584e12..eba706ac1e 100644 --- a/src/node/timeoffsets.h +++ b/src/node/timeoffsets.h @@ -11,8 +11,16 @@ #include <cstddef> #include <deque> +namespace node { +class Warnings; +} // namespace node + class TimeOffsets { +public: + TimeOffsets(node::Warnings& warnings) : m_warnings{warnings} {} + +private: //! Maximum number of timeoffsets stored. static constexpr size_t MAX_SIZE{50}; //! Minimum difference between system and network time for a warning to be raised. @@ -23,6 +31,8 @@ class TimeOffsets * positive offset means our peer's clock is ahead of our local clock. */ std::deque<std::chrono::seconds> m_offsets GUARDED_BY(m_mutex){}; + node::Warnings& m_warnings; + public: /** Add a new time offset sample. */ void Add(std::chrono::seconds offset) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex); diff --git a/src/node/transaction.cpp b/src/node/transaction.cpp index b66a4f2f39..591dcd698d 100644 --- a/src/node/transaction.cpp +++ b/src/node/transaction.cpp @@ -9,6 +9,7 @@ #include <net_processing.h> #include <node/blockstorage.h> #include <node/context.h> +#include <node/types.h> #include <txmempool.h> #include <validation.h> #include <validationinterface.h> diff --git a/src/node/transaction.h b/src/node/transaction.h index 6782536ace..5f524f4e28 100644 --- a/src/node/transaction.h +++ b/src/node/transaction.h @@ -5,9 +5,9 @@ #ifndef BITCOIN_NODE_TRANSACTION_H #define BITCOIN_NODE_TRANSACTION_H +#include <common/messages.h> #include <policy/feerate.h> #include <primitives/transaction.h> -#include <util/error.h> class CBlockIndex; class CTxMemPool; diff --git a/src/node/types.h b/src/node/types.h new file mode 100644 index 0000000000..0461e85f43 --- /dev/null +++ b/src/node/types.h @@ -0,0 +1,29 @@ +// Copyright (c) 2010-2021 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +//! @file node/types.h is a home for public enum and struct type definitions +//! that are used by internally by node code, but also used externally by wallet +//! or GUI code. +//! +//! This file is intended to define only simple types that do not have external +//! dependencies. More complicated types should be defined in dedicated header +//! files. + +#ifndef BITCOIN_NODE_TYPES_H +#define BITCOIN_NODE_TYPES_H + +namespace node { +enum class TransactionError { + OK, //!< No error + MISSING_INPUTS, + ALREADY_IN_CHAIN, + MEMPOOL_REJECTED, + MEMPOOL_ERROR, + MAX_FEE_EXCEEDED, + MAX_BURN_EXCEEDED, + INVALID_PACKAGE, +}; +} // namespace node + +#endif // BITCOIN_NODE_TYPES_H diff --git a/src/node/utxo_snapshot.h b/src/node/utxo_snapshot.h index 1160bb55f0..a7c4135787 100644 --- a/src/node/utxo_snapshot.h +++ b/src/node/utxo_snapshot.h @@ -6,16 +6,23 @@ #ifndef BITCOIN_NODE_UTXO_SNAPSHOT_H #define BITCOIN_NODE_UTXO_SNAPSHOT_H +#include <chainparams.h> +#include <kernel/chainparams.h> #include <kernel/cs_main.h> #include <serialize.h> #include <sync.h> #include <uint256.h> +#include <util/chaintype.h> +#include <util/check.h> #include <util/fs.h> #include <cstdint> #include <optional> #include <string_view> +// UTXO set snapshot magic bytes +static constexpr std::array<uint8_t, 5> SNAPSHOT_MAGIC_BYTES = {'u', 't', 'x', 'o', 0xff}; + class Chainstate; namespace node { @@ -23,23 +30,78 @@ namespace node { //! assumeutxo Chainstate can be constructed. class SnapshotMetadata { + const uint16_t m_version{1}; + const std::set<uint16_t> m_supported_versions{1}; + const MessageStartChars m_network_magic; public: //! The hash of the block that reflects the tip of the chain for the //! UTXO set contained in this snapshot. uint256 m_base_blockhash; + uint32_t m_base_blockheight; + //! The number of coins in the UTXO set contained in this snapshot. Used //! during snapshot load to estimate progress of UTXO set reconstruction. uint64_t m_coins_count = 0; - SnapshotMetadata() { } SnapshotMetadata( + const MessageStartChars network_magic) : + m_network_magic(network_magic) { } + SnapshotMetadata( + const MessageStartChars network_magic, const uint256& base_blockhash, + const int base_blockheight, uint64_t coins_count) : + m_network_magic(network_magic), m_base_blockhash(base_blockhash), + m_base_blockheight(base_blockheight), m_coins_count(coins_count) { } - SERIALIZE_METHODS(SnapshotMetadata, obj) { READWRITE(obj.m_base_blockhash, obj.m_coins_count); } + template <typename Stream> + inline void Serialize(Stream& s) const { + s << SNAPSHOT_MAGIC_BYTES; + s << m_version; + s << m_network_magic; + s << m_base_blockheight; + s << m_base_blockhash; + s << m_coins_count; + } + + template <typename Stream> + inline void Unserialize(Stream& s) { + // Read the snapshot magic bytes + std::array<uint8_t, SNAPSHOT_MAGIC_BYTES.size()> snapshot_magic; + s >> snapshot_magic; + if (snapshot_magic != SNAPSHOT_MAGIC_BYTES) { + throw std::ios_base::failure("Invalid UTXO set snapshot magic bytes. Please check if this is indeed a snapshot file or if you are using an outdated snapshot format."); + } + + // Read the version + uint16_t version; + s >> version; + if (m_supported_versions.find(version) == m_supported_versions.end()) { + throw std::ios_base::failure(strprintf("Version of snapshot %s does not match any of the supported versions.", version)); + } + + // Read the network magic (pchMessageStart) + MessageStartChars message; + s >> message; + if (!std::equal(message.begin(), message.end(), m_network_magic.data())) { + auto metadata_network{GetNetworkForMagic(message)}; + if (metadata_network) { + std::string network_string{ChainTypeToString(metadata_network.value())}; + auto node_network{GetNetworkForMagic(m_network_magic)}; + std::string node_network_string{ChainTypeToString(node_network.value())}; + throw std::ios_base::failure(strprintf("The network of the snapshot (%s) does not match the network of this node (%s).", network_string, node_network_string)); + } else { + throw std::ios_base::failure("This snapshot has been created for an unrecognized network. This could be a custom signet, a new testnet or possibly caused by data corruption."); + } + } + + s >> m_base_blockheight; + s >> m_base_blockhash; + s >> m_coins_count; + } }; //! The file in the snapshot chainstate dir which stores the base blockhash. This is diff --git a/src/node/warnings.cpp b/src/node/warnings.cpp new file mode 100644 index 0000000000..b99c845900 --- /dev/null +++ b/src/node/warnings.cpp @@ -0,0 +1,68 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2022 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <config/bitcoin-config.h> // IWYU pragma: keep + +#include <node/warnings.h> + +#include <common/system.h> +#include <node/interface_ui.h> +#include <sync.h> +#include <univalue.h> +#include <util/translation.h> + +#include <utility> +#include <vector> + +namespace node { +Warnings::Warnings() +{ + // Pre-release build warning + if (!CLIENT_VERSION_IS_RELEASE) { + m_warnings.insert( + {Warning::PRE_RELEASE_TEST_BUILD, + _("This is a pre-release test build - use at your own risk - do not use for mining or merchant applications")}); + } +} +bool Warnings::Set(warning_type id, bilingual_str message) +{ + LOCK(m_mutex); + const auto& [_, inserted]{m_warnings.insert({id, std::move(message)})}; + if (inserted) uiInterface.NotifyAlertChanged(); + return inserted; +} + +bool Warnings::Unset(warning_type id) +{ + auto success{WITH_LOCK(m_mutex, return m_warnings.erase(id))}; + if (success) uiInterface.NotifyAlertChanged(); + return success; +} + +std::vector<bilingual_str> Warnings::GetMessages() const +{ + LOCK(m_mutex); + std::vector<bilingual_str> messages; + messages.reserve(m_warnings.size()); + for (const auto& [id, msg] : m_warnings) { + messages.push_back(msg); + } + return messages; +} + +UniValue GetWarningsForRpc(const Warnings& warnings, bool use_deprecated) +{ + if (use_deprecated) { + const auto all_messages{warnings.GetMessages()}; + return all_messages.empty() ? "" : all_messages.back().original; + } + + UniValue messages{UniValue::VARR}; + for (auto&& message : warnings.GetMessages()) { + messages.push_back(std::move(message.original)); + } + return messages; +} +} // namespace node diff --git a/src/node/warnings.h b/src/node/warnings.h new file mode 100644 index 0000000000..24aeb8a922 --- /dev/null +++ b/src/node/warnings.h @@ -0,0 +1,90 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2021 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_NODE_WARNINGS_H +#define BITCOIN_NODE_WARNINGS_H + +#include <sync.h> +#include <util/translation.h> + +#include <map> +#include <variant> +#include <vector> + +class UniValue; + +namespace kernel { +enum class Warning; +} // namespace kernel + +namespace node { +enum class Warning { + CLOCK_OUT_OF_SYNC, + PRE_RELEASE_TEST_BUILD, + FATAL_INTERNAL_ERROR, +}; + +/** + * @class Warnings + * @brief Manages warning messages within a node. + * + * The Warnings class provides mechanisms to set, unset, and retrieve + * warning messages. It updates the GUI when warnings are changed. + * + * This class is designed to be non-copyable to ensure warnings + * are managed centrally. + */ +class Warnings +{ + typedef std::variant<kernel::Warning, node::Warning> warning_type; + + mutable Mutex m_mutex; + std::map<warning_type, bilingual_str> m_warnings GUARDED_BY(m_mutex); + +public: + Warnings(); + //! A warnings instance should always be passed by reference, never copied. + Warnings(const Warnings&) = delete; + Warnings& operator=(const Warnings&) = delete; + /** + * @brief Set a warning message. If a warning with the specified + * `id` is already active, false is returned and the new + * warning is ignored. If `id` does not yet exist, the + * warning is set, the UI is updated, and true is returned. + * + * @param[in] id Unique identifier of the warning. + * @param[in] message Warning message to be shown. + * + * @returns true if the warning was indeed set (i.e. there is no + * active warning with this `id`), otherwise false. + */ + bool Set(warning_type id, bilingual_str message) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex); + /** + * @brief Unset a warning message. If a warning with the specified + * `id` is active, it is unset, the UI is updated, and true + * is returned. Otherwise, no warning is unset and false is + * returned. + * + * @param[in] id Unique identifier of the warning. + * + * @returns true if the warning was indeed unset (i.e. there is an + * active warning with this `id`), otherwise false. + */ + bool Unset(warning_type id) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex); + /** Return potential problems detected by the node, sorted by the + * warning_type id */ + std::vector<bilingual_str> GetMessages() const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex); +}; + +/** + * RPC helper function that wraps warnings.GetMessages(). + * + * Returns a UniValue::VSTR with the latest warning if use_deprecated is + * set to true, or a UniValue::VARR with all warnings otherwise. + */ +UniValue GetWarningsForRpc(const Warnings& warnings, bool use_deprecated); +} // namespace node + +#endif // BITCOIN_NODE_WARNINGS_H diff --git a/src/outputtype.cpp b/src/outputtype.cpp index c72d9deacb..8c2b76494b 100644 --- a/src/outputtype.cpp +++ b/src/outputtype.cpp @@ -81,11 +81,11 @@ std::vector<CTxDestination> GetAllDestinationsForKey(const CPubKey& key) } } -CTxDestination AddAndGetDestinationForScript(FillableSigningProvider& keystore, const CScript& script, OutputType type) +CTxDestination AddAndGetDestinationForScript(FlatSigningProvider& keystore, const CScript& script, OutputType type) { // Add script to keystore - keystore.AddCScript(script); - // Note that scripts over MAX_SCRIPT_ELEMENT_SIZE bytes are not yet supported. + keystore.scripts.emplace(CScriptID(script), script); + switch (type) { case OutputType::LEGACY: return ScriptHash(script); @@ -94,7 +94,7 @@ CTxDestination AddAndGetDestinationForScript(FillableSigningProvider& keystore, CTxDestination witdest = WitnessV0ScriptHash(script); CScript witprog = GetScriptForDestination(witdest); // Add the redeemscript, so that P2WSH and P2SH-P2WSH outputs are recognized as ours. - keystore.AddCScript(witprog); + keystore.scripts.emplace(CScriptID(witprog), witprog); if (type == OutputType::BECH32) { return witdest; } else { diff --git a/src/outputtype.h b/src/outputtype.h index a2d5942320..feef7991a6 100644 --- a/src/outputtype.h +++ b/src/outputtype.h @@ -46,7 +46,7 @@ std::vector<CTxDestination> GetAllDestinationsForKey(const CPubKey& key); * This function will automatically add the script (and any other * necessary scripts) to the keystore. */ -CTxDestination AddAndGetDestinationForScript(FillableSigningProvider& keystore, const CScript& script, OutputType); +CTxDestination AddAndGetDestinationForScript(FlatSigningProvider& keystore, const CScript& script, OutputType); /** Get the OutputType for a CTxDestination */ std::optional<OutputType> OutputTypeFromDestination(const CTxDestination& dest); diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index d8b4b907e4..e84a8428bf 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -93,7 +93,7 @@ bool IsStandard(const CScript& scriptPubKey, const std::optional<unsigned>& max_ bool IsStandardTx(const CTransaction& tx, const std::optional<unsigned>& max_datacarrier_bytes, bool permit_bare_multisig, const CFeeRate& dust_relay_fee, std::string& reason) { - if (tx.nVersion > TX_MAX_STANDARD_VERSION || tx.nVersion < 1) { + if (tx.version > TX_MAX_STANDARD_VERSION || tx.version < 1) { reason = "version"; return false; } diff --git a/src/policy/policy.h b/src/policy/policy.h index 6a7980c312..a82488a28c 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -131,7 +131,7 @@ bool IsStandard(const CScript& scriptPubKey, const std::optional<unsigned>& max_ // Changing the default transaction version requires a two step process: first // adapting relay policy by bumping TX_MAX_STANDARD_VERSION, and then later // allowing the new transaction version in the wallet/RPC. -static constexpr decltype(CTransaction::nVersion) TX_MAX_STANDARD_VERSION{2}; +static constexpr decltype(CTransaction::version) TX_MAX_STANDARD_VERSION{3}; /** * Check for standard transaction types diff --git a/src/policy/v3_policy.cpp b/src/policy/v3_policy.cpp index 3c3942d707..6bd043b8e3 100644 --- a/src/policy/v3_policy.cpp +++ b/src/policy/v3_policy.cpp @@ -43,13 +43,13 @@ struct ParentInfo { const Txid& m_txid; /** Wtxid used for debug string */ const Wtxid& m_wtxid; - /** nVersion used to check inheritance of v3 and non-v3 */ - decltype(CTransaction::nVersion) m_version; + /** version used to check inheritance of v3 and non-v3 */ + decltype(CTransaction::version) m_version; /** If parent is in mempool, whether it has any descendants in mempool. */ bool m_has_mempool_descendant; ParentInfo() = delete; - ParentInfo(const Txid& txid, const Wtxid& wtxid, decltype(CTransaction::nVersion) version, bool has_mempool_descendant) : + ParentInfo(const Txid& txid, const Wtxid& wtxid, decltype(CTransaction::version) version, bool has_mempool_descendant) : m_txid{txid}, m_wtxid{wtxid}, m_version{version}, m_has_mempool_descendant{has_mempool_descendant} {} @@ -66,7 +66,13 @@ std::optional<std::string> PackageV3Checks(const CTransactionRef& ptx, int64_t v const auto in_package_parents{FindInPackageParents(package, ptx)}; // Now we have all ancestors, so we can start checking v3 rules. - if (ptx->nVersion == 3) { + if (ptx->version == TRUC_VERSION) { + // SingleV3Checks should have checked this already. + if (!Assume(vsize <= V3_MAX_VSIZE)) { + return strprintf("v3 tx %s (wtxid=%s) is too big: %u > %u virtual bytes", + ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString(), vsize, V3_MAX_VSIZE); + } + if (mempool_ancestors.size() + in_package_parents.size() + 1 > V3_ANCESTOR_LIMIT) { return strprintf("tx %s (wtxid=%s) would have too many ancestors", ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString()); @@ -85,23 +91,22 @@ std::optional<std::string> PackageV3Checks(const CTransactionRef& ptx, int64_t v const auto parent_info = [&] { if (mempool_ancestors.size() > 0) { auto& mempool_parent = *mempool_ancestors.begin(); - Assume(mempool_parent->GetCountWithDescendants() == 1); return ParentInfo{mempool_parent->GetTx().GetHash(), mempool_parent->GetTx().GetWitnessHash(), - mempool_parent->GetTx().nVersion, + mempool_parent->GetTx().version, /*has_mempool_descendant=*/mempool_parent->GetCountWithDescendants() > 1}; } else { auto& parent_index = in_package_parents.front(); auto& package_parent = package.at(parent_index); return ParentInfo{package_parent->GetHash(), package_parent->GetWitnessHash(), - package_parent->nVersion, + package_parent->version, /*has_mempool_descendant=*/false}; } }(); // If there is a parent, it must have the right version. - if (parent_info.m_version != 3) { + if (parent_info.m_version != TRUC_VERSION) { return strprintf("v3 tx %s (wtxid=%s) cannot spend from non-v3 tx %s (wtxid=%s)", ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString(), parent_info.m_txid.ToString(), parent_info.m_wtxid.ToString()); @@ -129,10 +134,7 @@ std::optional<std::string> PackageV3Checks(const CTransactionRef& ptx, int64_t v } } - // It shouldn't be possible to have any mempool siblings at this point. SingleV3Checks - // catches mempool siblings and sibling eviction is not extended to packages. Also, if the package consists of connected transactions, - // any tx having a mempool ancestor would mean the package exceeds ancestor limits. - if (!Assume(!parent_info.m_has_mempool_descendant)) { + if (parent_info.m_has_mempool_descendant) { return strprintf("tx %s (wtxid=%s) would exceed descendant count limit", parent_info.m_txid.ToString(), parent_info.m_wtxid.ToString()); } @@ -140,14 +142,14 @@ std::optional<std::string> PackageV3Checks(const CTransactionRef& ptx, int64_t v } else { // Non-v3 transactions cannot have v3 parents. for (auto it : mempool_ancestors) { - if (it->GetTx().nVersion == 3) { + if (it->GetTx().version == TRUC_VERSION) { return strprintf("non-v3 tx %s (wtxid=%s) cannot spend from v3 tx %s (wtxid=%s)", ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString(), it->GetSharedTx()->GetHash().ToString(), it->GetSharedTx()->GetWitnessHash().ToString()); } } for (const auto& index: in_package_parents) { - if (package.at(index)->nVersion == 3) { + if (package.at(index)->version == TRUC_VERSION) { return strprintf("non-v3 tx %s (wtxid=%s) cannot spend from v3 tx %s (wtxid=%s)", ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString(), @@ -166,12 +168,12 @@ std::optional<std::pair<std::string, CTransactionRef>> SingleV3Checks(const CTra { // Check v3 and non-v3 inheritance. for (const auto& entry : mempool_ancestors) { - if (ptx->nVersion != 3 && entry->GetTx().nVersion == 3) { + if (ptx->version != TRUC_VERSION && entry->GetTx().version == TRUC_VERSION) { return std::make_pair(strprintf("non-v3 tx %s (wtxid=%s) cannot spend from v3 tx %s (wtxid=%s)", ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString(), entry->GetSharedTx()->GetHash().ToString(), entry->GetSharedTx()->GetWitnessHash().ToString()), nullptr); - } else if (ptx->nVersion == 3 && entry->GetTx().nVersion != 3) { + } else if (ptx->version == TRUC_VERSION && entry->GetTx().version != TRUC_VERSION) { return std::make_pair(strprintf("v3 tx %s (wtxid=%s) cannot spend from non-v3 tx %s (wtxid=%s)", ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString(), entry->GetSharedTx()->GetHash().ToString(), entry->GetSharedTx()->GetWitnessHash().ToString()), @@ -183,8 +185,14 @@ std::optional<std::pair<std::string, CTransactionRef>> SingleV3Checks(const CTra static_assert(V3_ANCESTOR_LIMIT == 2); static_assert(V3_DESCENDANT_LIMIT == 2); - // The rest of the rules only apply to transactions with nVersion=3. - if (ptx->nVersion != 3) return std::nullopt; + // The rest of the rules only apply to transactions with version=3. + if (ptx->version != TRUC_VERSION) return std::nullopt; + + if (vsize > V3_MAX_VSIZE) { + return std::make_pair(strprintf("v3 tx %s (wtxid=%s) is too big: %u > %u virtual bytes", + ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString(), vsize, V3_MAX_VSIZE), + nullptr); + } // Check that V3_ANCESTOR_LIMIT would not be violated. if (mempool_ancestors.size() + 1 > V3_ANCESTOR_LIMIT) { diff --git a/src/policy/v3_policy.h b/src/policy/v3_policy.h index 2e56f8822b..90eaeda46f 100644 --- a/src/policy/v3_policy.h +++ b/src/policy/v3_policy.h @@ -15,8 +15,9 @@ #include <set> #include <string> -// This module enforces rules for transactions with nVersion=3 ("v3 transactions") which help make +// This module enforces rules for BIP 431 TRUC transactions (with version=3) which help make // RBF abilities more robust. +static constexpr decltype(CTransaction::version) TRUC_VERSION{3}; // v3 only allows 1 parent and 1 child when unconfirmed. /** Maximum number of transactions including an unconfirmed tx and its descendants. */ @@ -24,11 +25,13 @@ static constexpr unsigned int V3_DESCENDANT_LIMIT{2}; /** Maximum number of transactions including a V3 tx and all its mempool ancestors. */ static constexpr unsigned int V3_ANCESTOR_LIMIT{2}; +/** Maximum sigop-adjusted virtual size of all v3 transactions. */ +static constexpr int64_t V3_MAX_VSIZE{10000}; /** Maximum sigop-adjusted virtual size of a tx which spends from an unconfirmed v3 transaction. */ static constexpr int64_t V3_CHILD_MAX_VSIZE{1000}; // These limits are within the default ancestor/descendant limits. -static_assert(V3_CHILD_MAX_VSIZE + MAX_STANDARD_TX_WEIGHT / WITNESS_SCALE_FACTOR <= DEFAULT_ANCESTOR_SIZE_LIMIT_KVB * 1000); -static_assert(V3_CHILD_MAX_VSIZE + MAX_STANDARD_TX_WEIGHT / WITNESS_SCALE_FACTOR <= DEFAULT_DESCENDANT_SIZE_LIMIT_KVB * 1000); +static_assert(V3_MAX_VSIZE + V3_CHILD_MAX_VSIZE <= DEFAULT_ANCESTOR_SIZE_LIMIT_KVB * 1000); +static_assert(V3_MAX_VSIZE + V3_CHILD_MAX_VSIZE <= DEFAULT_DESCENDANT_SIZE_LIMIT_KVB * 1000); /** Must be called for every transaction, even if not v3. Not strictly necessary for transactions * accepted through AcceptMultipleTransactions. @@ -40,6 +43,7 @@ static_assert(V3_CHILD_MAX_VSIZE + MAX_STANDARD_TX_WEIGHT / WITNESS_SCALE_FACTOR * 4. A v3's descendant set, including itself, must be within V3_DESCENDANT_LIMIT. * 5. If a v3 tx has any unconfirmed ancestors, the tx's sigop-adjusted vsize must be within * V3_CHILD_MAX_VSIZE. + * 6. A v3 tx must be within V3_MAX_VSIZE. * * * @param[in] mempool_ancestors The in-mempool ancestors of ptx. diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index b4a860dd9e..fab5c40765 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -6,12 +6,12 @@ #include <primitives/transaction.h> #include <consensus/amount.h> +#include <crypto/hex_base.h> #include <hash.h> #include <script/script.h> #include <serialize.h> #include <tinyformat.h> #include <uint256.h> -#include <util/strencodings.h> #include <util/transaction_identifier.h> #include <algorithm> @@ -63,8 +63,8 @@ std::string CTxOut::ToString() const return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, HexStr(scriptPubKey).substr(0, 30)); } -CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::CURRENT_VERSION), nLockTime(0) {} -CMutableTransaction::CMutableTransaction(const CTransaction& tx) : vin(tx.vin), vout(tx.vout), nVersion(tx.nVersion), nLockTime(tx.nLockTime) {} +CMutableTransaction::CMutableTransaction() : version{CTransaction::CURRENT_VERSION}, nLockTime{0} {} +CMutableTransaction::CMutableTransaction(const CTransaction& tx) : vin(tx.vin), vout(tx.vout), version{tx.version}, nLockTime{tx.nLockTime} {} Txid CMutableTransaction::GetHash() const { @@ -92,8 +92,8 @@ Wtxid CTransaction::ComputeWitnessHash() const return Wtxid::FromUint256((HashWriter{} << TX_WITH_WITNESS(*this)).GetHash()); } -CTransaction::CTransaction(const CMutableTransaction& tx) : vin(tx.vin), vout(tx.vout), nVersion(tx.nVersion), nLockTime(tx.nLockTime), m_has_witness{ComputeHasWitness()}, hash{ComputeHash()}, m_witness_hash{ComputeWitnessHash()} {} -CTransaction::CTransaction(CMutableTransaction&& tx) : vin(std::move(tx.vin)), vout(std::move(tx.vout)), nVersion(tx.nVersion), nLockTime(tx.nLockTime), m_has_witness{ComputeHasWitness()}, hash{ComputeHash()}, m_witness_hash{ComputeWitnessHash()} {} +CTransaction::CTransaction(const CMutableTransaction& tx) : vin(tx.vin), vout(tx.vout), version{tx.version}, nLockTime{tx.nLockTime}, m_has_witness{ComputeHasWitness()}, hash{ComputeHash()}, m_witness_hash{ComputeWitnessHash()} {} +CTransaction::CTransaction(CMutableTransaction&& tx) : vin(std::move(tx.vin)), vout(std::move(tx.vout)), version{tx.version}, nLockTime{tx.nLockTime}, m_has_witness{ComputeHasWitness()}, hash{ComputeHash()}, m_witness_hash{ComputeWitnessHash()} {} CAmount CTransaction::GetValueOut() const { @@ -115,9 +115,9 @@ unsigned int CTransaction::GetTotalSize() const std::string CTransaction::ToString() const { std::string str; - str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%u, vout.size=%u, nLockTime=%u)\n", + str += strprintf("CTransaction(hash=%s, ver=%u, vin.size=%u, vout.size=%u, nLockTime=%u)\n", GetHash().ToString().substr(0,10), - nVersion, + version, vin.size(), vout.size(), nLockTime); diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index ccbeb3ec49..bf86562886 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -197,13 +197,13 @@ static constexpr TransactionSerParams TX_NO_WITNESS{.allow_witness = false}; /** * Basic transaction serialization format: - * - int32_t nVersion + * - uint32_t version * - std::vector<CTxIn> vin * - std::vector<CTxOut> vout * - uint32_t nLockTime * * Extended transaction serialization format: - * - int32_t nVersion + * - uint32_t version * - unsigned char dummy = 0x00 * - unsigned char flags (!= 0) * - std::vector<CTxIn> vin @@ -217,7 +217,7 @@ void UnserializeTransaction(TxType& tx, Stream& s, const TransactionSerParams& p { const bool fAllowWitness = params.allow_witness; - s >> tx.nVersion; + s >> tx.version; unsigned char flags = 0; tx.vin.clear(); tx.vout.clear(); @@ -257,7 +257,7 @@ void SerializeTransaction(const TxType& tx, Stream& s, const TransactionSerParam { const bool fAllowWitness = params.allow_witness; - s << tx.nVersion; + s << tx.version; unsigned char flags = 0; // Consistency check if (fAllowWitness) { @@ -296,7 +296,7 @@ class CTransaction { public: // Default transaction version. - static const int32_t CURRENT_VERSION=2; + static const uint32_t CURRENT_VERSION{2}; // The local variables are made const to prevent unintended modification // without updating the cached hash value. However, CTransaction is not @@ -305,7 +305,7 @@ public: // structure, including the hash. const std::vector<CTxIn> vin; const std::vector<CTxOut> vout; - const int32_t nVersion; + const uint32_t version; const uint32_t nLockTime; private: @@ -326,7 +326,7 @@ public: template <typename Stream> inline void Serialize(Stream& s) const { - SerializeTransaction(*this, s, s.GetParams()); + SerializeTransaction(*this, s, s.template GetParams<TransactionSerParams>()); } /** This deserializing constructor is provided instead of an Unserialize method. @@ -334,7 +334,7 @@ public: template <typename Stream> CTransaction(deserialize_type, const TransactionSerParams& params, Stream& s) : CTransaction(CMutableTransaction(deserialize, params, s)) {} template <typename Stream> - CTransaction(deserialize_type, ParamsStream<TransactionSerParams,Stream>& s) : CTransaction(CMutableTransaction(deserialize, s)) {} + CTransaction(deserialize_type, Stream& s) : CTransaction(CMutableTransaction(deserialize, s)) {} bool IsNull() const { return vin.empty() && vout.empty(); @@ -378,7 +378,7 @@ struct CMutableTransaction { std::vector<CTxIn> vin; std::vector<CTxOut> vout; - int32_t nVersion; + uint32_t version; uint32_t nLockTime; explicit CMutableTransaction(); @@ -386,12 +386,12 @@ struct CMutableTransaction template <typename Stream> inline void Serialize(Stream& s) const { - SerializeTransaction(*this, s, s.GetParams()); + SerializeTransaction(*this, s, s.template GetParams<TransactionSerParams>()); } template <typename Stream> inline void Unserialize(Stream& s) { - UnserializeTransaction(*this, s, s.GetParams()); + UnserializeTransaction(*this, s, s.template GetParams<TransactionSerParams>()); } template <typename Stream> @@ -400,7 +400,7 @@ struct CMutableTransaction } template <typename Stream> - CMutableTransaction(deserialize_type, ParamsStream<TransactionSerParams,Stream>& s) { + CMutableTransaction(deserialize_type, Stream& s) { Unserialize(s); } diff --git a/src/protocol.cpp b/src/protocol.cpp index 0da160768d..0439d398c7 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -7,87 +7,6 @@ #include <common/system.h> -#include <atomic> - -namespace NetMsgType { -const char* VERSION = "version"; -const char* VERACK = "verack"; -const char* ADDR = "addr"; -const char* ADDRV2 = "addrv2"; -const char* SENDADDRV2 = "sendaddrv2"; -const char* INV = "inv"; -const char* GETDATA = "getdata"; -const char* MERKLEBLOCK = "merkleblock"; -const char* GETBLOCKS = "getblocks"; -const char* GETHEADERS = "getheaders"; -const char* TX = "tx"; -const char* HEADERS = "headers"; -const char* BLOCK = "block"; -const char* GETADDR = "getaddr"; -const char* MEMPOOL = "mempool"; -const char* PING = "ping"; -const char* PONG = "pong"; -const char* NOTFOUND = "notfound"; -const char* FILTERLOAD = "filterload"; -const char* FILTERADD = "filteradd"; -const char* FILTERCLEAR = "filterclear"; -const char* SENDHEADERS = "sendheaders"; -const char* FEEFILTER = "feefilter"; -const char* SENDCMPCT = "sendcmpct"; -const char* CMPCTBLOCK = "cmpctblock"; -const char* GETBLOCKTXN = "getblocktxn"; -const char* BLOCKTXN = "blocktxn"; -const char* GETCFILTERS = "getcfilters"; -const char* CFILTER = "cfilter"; -const char* GETCFHEADERS = "getcfheaders"; -const char* CFHEADERS = "cfheaders"; -const char* GETCFCHECKPT = "getcfcheckpt"; -const char* CFCHECKPT = "cfcheckpt"; -const char* WTXIDRELAY = "wtxidrelay"; -const char* SENDTXRCNCL = "sendtxrcncl"; -} // namespace NetMsgType - -/** All known message types. Keep this in the same order as the list of - * messages above and in protocol.h. - */ -const static std::vector<std::string> g_all_net_message_types{ - NetMsgType::VERSION, - NetMsgType::VERACK, - NetMsgType::ADDR, - NetMsgType::ADDRV2, - NetMsgType::SENDADDRV2, - NetMsgType::INV, - NetMsgType::GETDATA, - NetMsgType::MERKLEBLOCK, - NetMsgType::GETBLOCKS, - NetMsgType::GETHEADERS, - NetMsgType::TX, - NetMsgType::HEADERS, - NetMsgType::BLOCK, - NetMsgType::GETADDR, - NetMsgType::MEMPOOL, - NetMsgType::PING, - NetMsgType::PONG, - NetMsgType::NOTFOUND, - NetMsgType::FILTERLOAD, - NetMsgType::FILTERADD, - NetMsgType::FILTERCLEAR, - NetMsgType::SENDHEADERS, - NetMsgType::FEEFILTER, - NetMsgType::SENDCMPCT, - NetMsgType::CMPCTBLOCK, - NetMsgType::GETBLOCKTXN, - NetMsgType::BLOCKTXN, - NetMsgType::GETCFILTERS, - NetMsgType::CFILTER, - NetMsgType::GETCFHEADERS, - NetMsgType::CFHEADERS, - NetMsgType::GETCFCHECKPT, - NetMsgType::CFCHECKPT, - NetMsgType::WTXIDRELAY, - NetMsgType::SENDTXRCNCL, -}; - CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn) : pchMessageStart{pchMessageStartIn} { @@ -164,11 +83,6 @@ std::string CInv::ToString() const } } -const std::vector<std::string> &getAllNetMessageTypes() -{ - return g_all_net_message_types; -} - /** * Convert a service flag (NODE_*) to a human readable string. * It supports unknown service flags which will be returned as "UNKNOWN[...]". diff --git a/src/protocol.h b/src/protocol.h index 243cd23e6e..fd7cfddf3b 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -55,106 +55,105 @@ public: /** * Bitcoin protocol message types. When adding new message types, don't forget - * to update allNetMessageTypes in protocol.cpp. + * to update ALL_NET_MESSAGE_TYPES below. */ namespace NetMsgType { - /** * The version message provides information about the transmitting node to the * receiving node at the beginning of a connection. */ -extern const char* VERSION; +inline constexpr const char* VERSION{"version"}; /** * The verack message acknowledges a previously-received version message, * informing the connecting node that it can begin to send other messages. */ -extern const char* VERACK; +inline constexpr const char* VERACK{"verack"}; /** * The addr (IP address) message relays connection information for peers on the * network. */ -extern const char* ADDR; +inline constexpr const char* ADDR{"addr"}; /** * The addrv2 message relays connection information for peers on the network just * like the addr message, but is extended to allow gossiping of longer node * addresses (see BIP155). */ -extern const char *ADDRV2; +inline constexpr const char* ADDRV2{"addrv2"}; /** * The sendaddrv2 message signals support for receiving ADDRV2 messages (BIP155). * It also implies that its sender can encode as ADDRV2 and would send ADDRV2 * instead of ADDR to a peer that has signaled ADDRV2 support by sending SENDADDRV2. */ -extern const char *SENDADDRV2; +inline constexpr const char* SENDADDRV2{"sendaddrv2"}; /** * The inv message (inventory message) transmits one or more inventories of * objects known to the transmitting peer. */ -extern const char* INV; +inline constexpr const char* INV{"inv"}; /** * The getdata message requests one or more data objects from another node. */ -extern const char* GETDATA; +inline constexpr const char* GETDATA{"getdata"}; /** * The merkleblock message is a reply to a getdata message which requested a * block using the inventory type MSG_MERKLEBLOCK. * @since protocol version 70001 as described by BIP37. */ -extern const char* MERKLEBLOCK; +inline constexpr const char* MERKLEBLOCK{"merkleblock"}; /** * The getblocks message requests an inv message that provides block header * hashes starting from a particular point in the block chain. */ -extern const char* GETBLOCKS; +inline constexpr const char* GETBLOCKS{"getblocks"}; /** * The getheaders message requests a headers message that provides block * headers starting from a particular point in the block chain. * @since protocol version 31800. */ -extern const char* GETHEADERS; +inline constexpr const char* GETHEADERS{"getheaders"}; /** * The tx message transmits a single transaction. */ -extern const char* TX; +inline constexpr const char* TX{"tx"}; /** * The headers message sends one or more block headers to a node which * previously requested certain headers with a getheaders message. * @since protocol version 31800. */ -extern const char* HEADERS; +inline constexpr const char* HEADERS{"headers"}; /** * The block message transmits a single serialized block. */ -extern const char* BLOCK; +inline constexpr const char* BLOCK{"block"}; /** * The getaddr message requests an addr message from the receiving node, * preferably one with lots of IP addresses of other receiving nodes. */ -extern const char* GETADDR; +inline constexpr const char* GETADDR{"getaddr"}; /** * The mempool message requests the TXIDs of transactions that the receiving * node has verified as valid but which have not yet appeared in a block. * @since protocol version 60002 as described by BIP35. * Only available with service bit NODE_BLOOM, see also BIP111. */ -extern const char* MEMPOOL; +inline constexpr const char* MEMPOOL{"mempool"}; /** * The ping message is sent periodically to help confirm that the receiving * peer is still connected. */ -extern const char* PING; +inline constexpr const char* PING{"ping"}; /** * The pong message replies to a ping message, proving to the pinging node that * the ponging node is still alive. * @since protocol version 60001 as described by BIP31. */ -extern const char* PONG; +inline constexpr const char* PONG{"pong"}; /** * The notfound message is a reply to a getdata message which requested an * object the receiving node does not have available for relay. * @since protocol version 70001. */ -extern const char* NOTFOUND; +inline constexpr const char* NOTFOUND{"notfound"}; /** * The filterload message tells the receiving peer to filter all relayed * transactions and requested merkle blocks through the provided filter. @@ -162,7 +161,7 @@ extern const char* NOTFOUND; * Only available with service bit NODE_BLOOM since protocol version * 70011 as described by BIP111. */ -extern const char* FILTERLOAD; +inline constexpr const char* FILTERLOAD{"filterload"}; /** * The filteradd message tells the receiving peer to add a single element to a * previously-set bloom filter, such as a new public key. @@ -170,7 +169,7 @@ extern const char* FILTERLOAD; * Only available with service bit NODE_BLOOM since protocol version * 70011 as described by BIP111. */ -extern const char* FILTERADD; +inline constexpr const char* FILTERADD{"filteradd"}; /** * The filterclear message tells the receiving peer to remove a previously-set * bloom filter. @@ -178,19 +177,19 @@ extern const char* FILTERADD; * Only available with service bit NODE_BLOOM since protocol version * 70011 as described by BIP111. */ -extern const char* FILTERCLEAR; +inline constexpr const char* FILTERCLEAR{"filterclear"}; /** * Indicates that a node prefers to receive new block announcements via a * "headers" message rather than an "inv". * @since protocol version 70012 as described by BIP130. */ -extern const char* SENDHEADERS; +inline constexpr const char* SENDHEADERS{"sendheaders"}; /** * The feefilter message tells the receiving peer not to inv us any txs * which do not meet the specified min fee rate. * @since protocol version 70013 as described by BIP133 */ -extern const char* FEEFILTER; +inline constexpr const char* FEEFILTER{"feefilter"}; /** * Contains a 1-byte bool and 8-byte LE version number. * Indicates that a node is willing to provide blocks via "cmpctblock" messages. @@ -198,36 +197,36 @@ extern const char* FEEFILTER; * "cmpctblock" message rather than an "inv", depending on message contents. * @since protocol version 70014 as described by BIP 152 */ -extern const char* SENDCMPCT; +inline constexpr const char* SENDCMPCT{"sendcmpct"}; /** * Contains a CBlockHeaderAndShortTxIDs object - providing a header and * list of "short txids". * @since protocol version 70014 as described by BIP 152 */ -extern const char* CMPCTBLOCK; +inline constexpr const char* CMPCTBLOCK{"cmpctblock"}; /** * Contains a BlockTransactionsRequest * Peer should respond with "blocktxn" message. * @since protocol version 70014 as described by BIP 152 */ -extern const char* GETBLOCKTXN; +inline constexpr const char* GETBLOCKTXN{"getblocktxn"}; /** * Contains a BlockTransactions. * Sent in response to a "getblocktxn" message. * @since protocol version 70014 as described by BIP 152 */ -extern const char* BLOCKTXN; +inline constexpr const char* BLOCKTXN{"blocktxn"}; /** * getcfilters requests compact filters for a range of blocks. * Only available with service bit NODE_COMPACT_FILTERS as described by * BIP 157 & 158. */ -extern const char* GETCFILTERS; +inline constexpr const char* GETCFILTERS{"getcfilters"}; /** * cfilter is a response to a getcfilters request containing a single compact * filter. */ -extern const char* CFILTER; +inline constexpr const char* CFILTER{"cfilter"}; /** * getcfheaders requests a compact filter header and the filter hashes for a * range of blocks, which can then be used to reconstruct the filter headers @@ -235,40 +234,76 @@ extern const char* CFILTER; * Only available with service bit NODE_COMPACT_FILTERS as described by * BIP 157 & 158. */ -extern const char* GETCFHEADERS; +inline constexpr const char* GETCFHEADERS{"getcfheaders"}; /** * cfheaders is a response to a getcfheaders request containing a filter header * and a vector of filter hashes for each subsequent block in the requested range. */ -extern const char* CFHEADERS; +inline constexpr const char* CFHEADERS{"cfheaders"}; /** * getcfcheckpt requests evenly spaced compact filter headers, enabling * parallelized download and validation of the headers between them. * Only available with service bit NODE_COMPACT_FILTERS as described by * BIP 157 & 158. */ -extern const char* GETCFCHECKPT; +inline constexpr const char* GETCFCHECKPT{"getcfcheckpt"}; /** * cfcheckpt is a response to a getcfcheckpt request containing a vector of * evenly spaced filter headers for blocks on the requested chain. */ -extern const char* CFCHECKPT; +inline constexpr const char* CFCHECKPT{"cfcheckpt"}; /** * Indicates that a node prefers to relay transactions via wtxid, rather than * txid. * @since protocol version 70016 as described by BIP 339. */ -extern const char* WTXIDRELAY; +inline constexpr const char* WTXIDRELAY{"wtxidrelay"}; /** * Contains a 4-byte version number and an 8-byte salt. * The salt is used to compute short txids needed for efficient * txreconciliation, as described by BIP 330. */ -extern const char* SENDTXRCNCL; +inline constexpr const char* SENDTXRCNCL{"sendtxrcncl"}; }; // namespace NetMsgType -/* Get a vector of all valid message types (see above) */ -const std::vector<std::string>& getAllNetMessageTypes(); +/** All known message types (see above). Keep this in the same order as the list of messages above. */ +inline const std::array ALL_NET_MESSAGE_TYPES{std::to_array<std::string>({ + NetMsgType::VERSION, + NetMsgType::VERACK, + NetMsgType::ADDR, + NetMsgType::ADDRV2, + NetMsgType::SENDADDRV2, + NetMsgType::INV, + NetMsgType::GETDATA, + NetMsgType::MERKLEBLOCK, + NetMsgType::GETBLOCKS, + NetMsgType::GETHEADERS, + NetMsgType::TX, + NetMsgType::HEADERS, + NetMsgType::BLOCK, + NetMsgType::GETADDR, + NetMsgType::MEMPOOL, + NetMsgType::PING, + NetMsgType::PONG, + NetMsgType::NOTFOUND, + NetMsgType::FILTERLOAD, + NetMsgType::FILTERADD, + NetMsgType::FILTERCLEAR, + NetMsgType::SENDHEADERS, + NetMsgType::FEEFILTER, + NetMsgType::SENDCMPCT, + NetMsgType::CMPCTBLOCK, + NetMsgType::GETBLOCKTXN, + NetMsgType::BLOCKTXN, + NetMsgType::GETCFILTERS, + NetMsgType::CFILTER, + NetMsgType::GETCFHEADERS, + NetMsgType::CFHEADERS, + NetMsgType::GETCFCHECKPT, + NetMsgType::CFCHECKPT, + NetMsgType::WTXIDRELAY, + NetMsgType::SENDTXRCNCL, +})}; /** nServices flags */ enum ServiceFlags : uint64_t { @@ -375,9 +410,10 @@ public: static constexpr SerParams V1_DISK{{CNetAddr::Encoding::V1}, Format::Disk}; static constexpr SerParams V2_DISK{{CNetAddr::Encoding::V2}, Format::Disk}; - SERIALIZE_METHODS_PARAMS(CAddress, obj, SerParams, params) + SERIALIZE_METHODS(CAddress, obj) { bool use_v2; + auto& params = SER_PARAMS(SerParams); if (params.fmt == Format::Disk) { // In the disk serialization format, the encoding (v1 or v2) is determined by a flag version // that's part of the serialization itself. ADDRV2_FORMAT in the stream version only determines diff --git a/src/psbt.cpp b/src/psbt.cpp index b2ee3ce7a5..19d855e4c7 100644 --- a/src/psbt.cpp +++ b/src/psbt.cpp @@ -4,12 +4,12 @@ #include <psbt.h> +#include <node/types.h> #include <policy/policy.h> #include <script/signingprovider.h> #include <util/check.h> #include <util/strencodings.h> - PartiallySignedTransaction::PartiallySignedTransaction(const CMutableTransaction& tx) : tx(tx) { inputs.resize(tx.vin.size()); @@ -508,17 +508,17 @@ bool FinalizeAndExtractPSBT(PartiallySignedTransaction& psbtx, CMutableTransacti return true; } -TransactionError CombinePSBTs(PartiallySignedTransaction& out, const std::vector<PartiallySignedTransaction>& psbtxs) +bool CombinePSBTs(PartiallySignedTransaction& out, const std::vector<PartiallySignedTransaction>& psbtxs) { out = psbtxs[0]; // Copy the first one // Merge for (auto it = std::next(psbtxs.begin()); it != psbtxs.end(); ++it) { if (!out.Merge(*it)) { - return TransactionError::PSBT_MISMATCH; + return false; } } - return TransactionError::OK; + return true; } std::string PSBTRoleName(PSBTRole role) { diff --git a/src/psbt.h b/src/psbt.h index 3f74083717..4607304046 100644 --- a/src/psbt.h +++ b/src/psbt.h @@ -17,6 +17,10 @@ #include <optional> +namespace node { +enum class TransactionError; +} // namespace node + // Magic bytes static constexpr uint8_t PSBT_MAGIC_BYTES[5] = {'p', 's', 'b', 't', 0xff}; @@ -237,7 +241,7 @@ struct PSBTInput if (final_script_sig.empty() && final_script_witness.IsNull()) { // Write any partial signatures - for (auto sig_pair : partial_sigs) { + for (const auto& sig_pair : partial_sigs) { SerializeToVector(s, CompactSizeWriter(PSBT_IN_PARTIAL_SIG), Span{sig_pair.second.first}); s << sig_pair.second.second; } @@ -1263,9 +1267,9 @@ bool FinalizeAndExtractPSBT(PartiallySignedTransaction& psbtx, CMutableTransacti * * @param[out] out the combined PSBT, if successful * @param[in] psbtxs the PSBTs to combine - * @return error (OK if we successfully combined the transactions, other error if they were not compatible) + * @return True if we successfully combined the transactions, false if they were not compatible */ -[[nodiscard]] TransactionError CombinePSBTs(PartiallySignedTransaction& out, const std::vector<PartiallySignedTransaction>& psbtxs); +[[nodiscard]] bool CombinePSBTs(PartiallySignedTransaction& out, const std::vector<PartiallySignedTransaction>& psbtxs); //! Decode a base64ed PSBT into a PartiallySignedTransaction [[nodiscard]] bool DecodeBase64PSBT(PartiallySignedTransaction& decoded_psbt, const std::string& base64_psbt, std::string& error); diff --git a/src/pubkey.cpp b/src/pubkey.cpp index 11e1b4abb5..13e3c2dbe0 100644 --- a/src/pubkey.cpp +++ b/src/pubkey.cpp @@ -13,6 +13,7 @@ #include <secp256k1_schnorrsig.h> #include <span.h> #include <uint256.h> +#include <util/strencodings.h> #include <algorithm> #include <cassert> @@ -181,6 +182,17 @@ int ecdsa_signature_parse_der_lax(secp256k1_ecdsa_signature* sig, const unsigned return 1; } +/** Nothing Up My Sleeve (NUMS) point + * + * NUMS_H is a point with an unknown discrete logarithm, constructed by taking the sha256 of 'g' + * (uncompressed encoding), which happens to be a point on the curve. + * + * For an example script for calculating H, refer to the unit tests in + * ./test/functional/test_framework/crypto/secp256k1.py + */ +static const std::vector<unsigned char> NUMS_H_DATA{ParseHex("50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0")}; +const XOnlyPubKey XOnlyPubKey::NUMS_H{NUMS_H_DATA}; + XOnlyPubKey::XOnlyPubKey(Span<const unsigned char> bytes) { assert(bytes.size() == 32); diff --git a/src/pubkey.h b/src/pubkey.h index 15d7e7bc07..ae34ddd0af 100644 --- a/src/pubkey.h +++ b/src/pubkey.h @@ -233,6 +233,11 @@ private: uint256 m_keydata; public: + /** Nothing Up My Sleeve point H + * Used as an internal key for provably disabling the key path spend + * see BIP341 for more details */ + static const XOnlyPubKey NUMS_H; + /** Construct an empty x-only pubkey. */ XOnlyPubKey() = default; diff --git a/src/qt/android/.gitignore b/src/qt/android/.gitignore deleted file mode 100644 index c090a2e98e..0000000000 --- a/src/qt/android/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -/.gradle -/build -/gradle -/gradlew* -/libs -/src/org/kde -/src/org/qtproject diff --git a/src/qt/android/AndroidManifest.xml b/src/qt/android/AndroidManifest.xml deleted file mode 100644 index 41615294e0..0000000000 --- a/src/qt/android/AndroidManifest.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version='1.0' encoding='utf-8'?> -<manifest package="org.bitcoincore.qt" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0" android:versionCode="1" android:installLocation="auto"> - <uses-sdk android:targetSdkVersion="24"/> - - <uses-permission android:name="android.permission.INTERNET" /> - <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> - <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> - - <uses-feature android:glEsVersion="0x00020000" android:required="true" /> - - <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/> - - <application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="Bitcoin Core"> - <activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density" - android:name="org.bitcoincore.qt.BitcoinQtActivity" - android:label="Bitcoin Core" - android:icon="@drawable/bitcoin" - android:screenOrientation="unspecified" - android:launchMode="singleTop"> - <intent-filter> - <action android:name="android.intent.action.MAIN"/> - <category android:name="android.intent.category.LAUNCHER"/> - </intent-filter> - - <meta-data android:name="android.app.arguments" android:value="-testnet"/> - <meta-data android:name="android.app.lib_name" android:value="bitcoin-qt"/> - <meta-data android:name="android.app.repository" android:value="default"/> - <meta-data android:name="android.app.bundle_local_qt_libs" android:value="1"/> - <meta-data android:name="android.app.use_local_qt_libs" android:value="1"/> - <meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/> - <meta-data android:name="android.app.system_libs_prefix" android:value="/system/lib/"/> - <meta-data android:name="android.app.background_running" android:value="true"/> - <meta-data android:name="android.app.auto_screen_scale_factor" android:value="true"/> - <meta-data android:name="android.app.extract_android_style" android:value="default"/> - <meta-data android:name="android.app.load_local_libs_resource_id" android:resource="@array/load_local_libs"/> - </activity> - - </application> -</manifest> diff --git a/src/qt/android/build.gradle b/src/qt/android/build.gradle deleted file mode 100644 index 4c36e79db8..0000000000 --- a/src/qt/android/build.gradle +++ /dev/null @@ -1,52 +0,0 @@ -buildscript { - repositories { - google() - jcenter() - } - - dependencies { - classpath 'com.android.tools.build:gradle:3.1.0' - } -} - -repositories { - google() - jcenter() -} - -apply plugin: 'com.android.application' - -dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) -} - -android { - compileSdkVersion androidCompileSdkVersion.toInteger() - - buildToolsVersion androidBuildToolsVersion - - sourceSets { - main { - manifest.srcFile 'AndroidManifest.xml' - java.srcDirs = [qt5AndroidDir + '/src', 'src', 'java'] - aidl.srcDirs = [qt5AndroidDir + '/src', 'src', 'aidl'] - res.srcDirs = [qt5AndroidDir + '/res', 'res'] - resources.srcDirs = ['src'] - renderscript.srcDirs = ['src'] - assets.srcDirs = ['assets'] - jniLibs.srcDirs = ['libs'] - } - } - - lintOptions { - abortOnError false - } - - dexOptions { - javaMaxHeapSize '4g' - } - - defaultConfig { - minSdkVersion 24 - } -} diff --git a/src/qt/android/gradle.properties b/src/qt/android/gradle.properties deleted file mode 100644 index 468f4757c0..0000000000 --- a/src/qt/android/gradle.properties +++ /dev/null @@ -1,4 +0,0 @@ -androidBuildToolsVersion=30.0.3 -androidCompileSdkVersion=30 -qt5AndroidDir=new File(".").absolutePath -org.gradle.jvmargs=-Xmx4608M diff --git a/src/qt/android/res/drawable-hdpi/bitcoin.png b/src/qt/android/res/drawable-hdpi/bitcoin.png Binary files differdeleted file mode 100644 index 31a556a35f..0000000000 --- a/src/qt/android/res/drawable-hdpi/bitcoin.png +++ /dev/null diff --git a/src/qt/android/res/drawable-ldpi/bitcoin.png b/src/qt/android/res/drawable-ldpi/bitcoin.png Binary files differdeleted file mode 100644 index 76d80d4196..0000000000 --- a/src/qt/android/res/drawable-ldpi/bitcoin.png +++ /dev/null diff --git a/src/qt/android/res/drawable-mdpi/bitcoin.png b/src/qt/android/res/drawable-mdpi/bitcoin.png Binary files differdeleted file mode 100644 index c2aeab851a..0000000000 --- a/src/qt/android/res/drawable-mdpi/bitcoin.png +++ /dev/null diff --git a/src/qt/android/res/drawable-xhdpi/bitcoin.png b/src/qt/android/res/drawable-xhdpi/bitcoin.png Binary files differdeleted file mode 100644 index 2bd5e3defc..0000000000 --- a/src/qt/android/res/drawable-xhdpi/bitcoin.png +++ /dev/null diff --git a/src/qt/android/res/drawable-xxhdpi/bitcoin.png b/src/qt/android/res/drawable-xxhdpi/bitcoin.png Binary files differdeleted file mode 100644 index d236cf2132..0000000000 --- a/src/qt/android/res/drawable-xxhdpi/bitcoin.png +++ /dev/null diff --git a/src/qt/android/res/drawable-xxxhdpi/bitcoin.png b/src/qt/android/res/drawable-xxxhdpi/bitcoin.png Binary files differdeleted file mode 100644 index bb1dbc3554..0000000000 --- a/src/qt/android/res/drawable-xxxhdpi/bitcoin.png +++ /dev/null diff --git a/src/qt/android/res/values/libs.xml b/src/qt/android/res/values/libs.xml deleted file mode 100644 index b4b77b1c7b..0000000000 --- a/src/qt/android/res/values/libs.xml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <array name="load_local_libs"> - <item> - arm64-v8a;libbitcoin-qt_arm64-v8a.so - </item> - <item> - armeabi-v7a;libbitcoin-qt_armeabi-v7a.so - </item> - <item> - x86_64;libbitcoin-qt_x86_64.so - </item> - </array> -</resources> diff --git a/src/qt/android/src/org/bitcoincore/qt/BitcoinQtActivity.java b/src/qt/android/src/org/bitcoincore/qt/BitcoinQtActivity.java deleted file mode 100644 index 2cba489242..0000000000 --- a/src/qt/android/src/org/bitcoincore/qt/BitcoinQtActivity.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.bitcoincore.qt; - -import android.os.Bundle; -import android.system.ErrnoException; -import android.system.Os; - -import org.qtproject.qt5.android.bindings.QtActivity; - -import java.io.File; - -public class BitcoinQtActivity extends QtActivity -{ - @Override - public void onCreate(Bundle savedInstanceState) - { - final File bitcoinDir = new File(getFilesDir().getAbsolutePath() + "/.bitcoin"); - if (!bitcoinDir.exists()) { - bitcoinDir.mkdir(); - } - - super.onCreate(savedInstanceState); - } -} diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index a4771bbb82..70ed40b2a1 100644 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -100,10 +100,14 @@ void AskPassphraseDialog::accept() // Cannot encrypt with empty passphrase break; } - QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm wallet encryption"), - tr("Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>!") + "<br><br>" + tr("Are you sure you wish to encrypt your wallet?"), - QMessageBox::Yes|QMessageBox::Cancel, - QMessageBox::Cancel); + QMessageBox msgBoxConfirm(QMessageBox::Question, + tr("Confirm wallet encryption"), + tr("Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>!") + "<br><br>" + tr("Are you sure you wish to encrypt your wallet?"), + QMessageBox::Cancel | QMessageBox::Yes, this); + msgBoxConfirm.button(QMessageBox::Yes)->setText(tr("Continue")); + msgBoxConfirm.button(QMessageBox::Cancel)->setText(tr("Back")); + msgBoxConfirm.setDefaultButton(QMessageBox::Cancel); + QMessageBox::StandardButton retval = (QMessageBox::StandardButton)msgBoxConfirm.exec(); if(retval == QMessageBox::Yes) { if(newpass1 == newpass2) @@ -112,10 +116,19 @@ void AskPassphraseDialog::accept() "your bitcoins from being stolen by malware infecting your computer."); if (m_passphrase_out) { m_passphrase_out->assign(newpass1); - QMessageBox::warning(this, tr("Wallet to be encrypted"), - "<qt>" + - tr("Your wallet is about to be encrypted. ") + encryption_reminder + - "</b></qt>"); + QMessageBox msgBoxWarning(QMessageBox::Warning, + tr("Wallet to be encrypted"), + "<qt>" + + tr("Your wallet is about to be encrypted. ") + encryption_reminder + " " + + tr("Are you sure you wish to encrypt your wallet?") + + "</b></qt>", + QMessageBox::Cancel | QMessageBox::Yes, this); + msgBoxWarning.setDefaultButton(QMessageBox::Cancel); + QMessageBox::StandardButton retval = (QMessageBox::StandardButton)msgBoxWarning.exec(); + if (retval == QMessageBox::Cancel) { + QDialog::reject(); + return; + } } else { assert(model != nullptr); if (model->setWalletEncrypted(newpass1)) { @@ -141,11 +154,7 @@ void AskPassphraseDialog::accept() tr("The supplied passphrases do not match.")); } } - else - { - QDialog::reject(); // Cancelled - } - } break; + } break; case Unlock: try { if (!model->setWalletLocked(false, oldpass)) { diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 44a858c16b..6c5725533b 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -85,6 +85,8 @@ Q_DECLARE_METATYPE(uint256) Q_DECLARE_METATYPE(wallet::AddressPurpose) #endif // ENABLE_WALLET +using util::MakeUnorderedList; + static void RegisterMetaTypes() { // Register meta types used for QMetaObject::invokeMethod and Qt::QueuedConnection diff --git a/src/qt/forms/debugwindow.ui b/src/qt/forms/debugwindow.ui index 60e9bcde33..eeea53864a 100644 --- a/src/qt/forms/debugwindow.ui +++ b/src/qt/forms/debugwindow.ui @@ -1113,7 +1113,7 @@ <item row="3" column="0"> <widget class="QLabel" name="peerSessionIdLabel"> <property name="toolTip"> - <string>The BIP324 session ID string in hex, if any.</string> + <string>The BIP324 session ID string in hex.</string> </property> <property name="text"> <string>Session ID</string> diff --git a/src/qt/forms/signverifymessagedialog.ui b/src/qt/forms/signverifymessagedialog.ui index f42d19093b..b72360b586 100644 --- a/src/qt/forms/signverifymessagedialog.ui +++ b/src/qt/forms/signverifymessagedialog.ui @@ -30,7 +30,7 @@ <item> <widget class="QLabel" name="infoLabel_SM"> <property name="text"> - <string>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</string> + <string>You can sign messages/agreements with your legacy (P2PKH) addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</string> </property> <property name="textFormat"> <enum>Qt::PlainText</enum> diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 15103baf59..ee53a59bb5 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -18,6 +18,7 @@ #include <node/chainstatemanager_args.h> #include <netbase.h> #include <txdb.h> +#include <util/strencodings.h> #include <chrono> @@ -480,7 +481,10 @@ QValidator(parent) QValidator::State ProxyAddressValidator::validate(QString &input, int &pos) const { Q_UNUSED(pos); - // Validate the proxy + uint16_t port{0}; + std::string hostname; + if (!SplitHostPort(input.toStdString(), port, hostname) || port != 0) return QValidator::Invalid; + CService serv(LookupNumeric(input.toStdString(), DEFAULT_GUI_PROXY_PORT)); Proxy addrProxy = Proxy(serv, true); if (addrProxy.IsValid()) diff --git a/src/qt/psbtoperationsdialog.cpp b/src/qt/psbtoperationsdialog.cpp index 353709c7f5..5a4b4442f3 100644 --- a/src/qt/psbtoperationsdialog.cpp +++ b/src/qt/psbtoperationsdialog.cpp @@ -4,10 +4,12 @@ #include <qt/psbtoperationsdialog.h> +#include <common/messages.h> #include <core_io.h> #include <interfaces/node.h> #include <key_io.h> #include <node/psbt.h> +#include <node/types.h> #include <policy/policy.h> #include <qt/bitcoinunits.h> #include <qt/forms/ui_psbtoperationsdialog.h> @@ -20,9 +22,11 @@ #include <iostream> #include <string> +using common::TransactionErrorString; using node::AnalyzePSBT; using node::DEFAULT_MAX_RAW_TX_FEE_RATE; using node::PSBTAnalysis; +using node::TransactionError; PSBTOperationsDialog::PSBTOperationsDialog( QWidget* parent, WalletModel* wallet_model, ClientModel* client_model) : QDialog(parent, GUIUtil::dialog_flags), @@ -55,10 +59,10 @@ void PSBTOperationsDialog::openWithPSBT(PartiallySignedTransaction psbtx) bool complete = FinalizePSBT(psbtx); // Make sure all existing signatures are fully combined before checking for completeness. if (m_wallet_model) { size_t n_could_sign; - TransactionError err = m_wallet_model->wallet().fillPSBT(SIGHASH_ALL, /*sign=*/false, /*bip32derivs=*/true, &n_could_sign, m_transaction_data, complete); - if (err != TransactionError::OK) { + const auto err{m_wallet_model->wallet().fillPSBT(SIGHASH_ALL, /*sign=*/false, /*bip32derivs=*/true, &n_could_sign, m_transaction_data, complete)}; + if (err) { showStatus(tr("Failed to load transaction: %1") - .arg(QString::fromStdString(TransactionErrorString(err).translated)), + .arg(QString::fromStdString(PSBTErrorString(*err).translated)), StatusLevel::ERR); return; } @@ -79,11 +83,11 @@ void PSBTOperationsDialog::signTransaction() WalletModel::UnlockContext ctx(m_wallet_model->requestUnlock()); - TransactionError err = m_wallet_model->wallet().fillPSBT(SIGHASH_ALL, /*sign=*/true, /*bip32derivs=*/true, &n_signed, m_transaction_data, complete); + const auto err{m_wallet_model->wallet().fillPSBT(SIGHASH_ALL, /*sign=*/true, /*bip32derivs=*/true, &n_signed, m_transaction_data, complete)}; - if (err != TransactionError::OK) { + if (err) { showStatus(tr("Failed to sign transaction: %1") - .arg(QString::fromStdString(TransactionErrorString(err).translated)), StatusLevel::ERR); + .arg(QString::fromStdString(PSBTErrorString(*err).translated)), StatusLevel::ERR); return; } @@ -247,9 +251,9 @@ size_t PSBTOperationsDialog::couldSignInputs(const PartiallySignedTransaction &p size_t n_signed; bool complete; - TransactionError err = m_wallet_model->wallet().fillPSBT(SIGHASH_ALL, /*sign=*/false, /*bip32derivs=*/false, &n_signed, m_transaction_data, complete); + const auto err{m_wallet_model->wallet().fillPSBT(SIGHASH_ALL, /*sign=*/false, /*bip32derivs=*/false, &n_signed, m_transaction_data, complete)}; - if (err != TransactionError::OK) { + if (err) { return 0; } return n_signed; diff --git a/src/qt/recentrequeststablemodel.cpp b/src/qt/recentrequeststablemodel.cpp index 52d4e45d49..a8d54cdc0c 100644 --- a/src/qt/recentrequeststablemodel.cpp +++ b/src/qt/recentrequeststablemodel.cpp @@ -20,6 +20,8 @@ #include <QLatin1Char> #include <QLatin1String> +using util::ToString; + RecentRequestsTableModel::RecentRequestsTableModel(WalletModel *parent) : QAbstractTableModel(parent), walletModel(parent) { diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 702ca44395..edf417a7cb 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -48,6 +48,8 @@ #include <chrono> +using util::Join; + const int CONSOLE_HISTORY = 50; const int INITIAL_TRAFFIC_GRAPH_MINS = 30; const QSize FONT_RANGE(4, 40); diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 0d8c0f7a63..03173ec80e 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -20,6 +20,7 @@ #include <interfaces/node.h> #include <key_io.h> #include <node/interface_ui.h> +#include <node/types.h> #include <policy/fees.h> #include <txmempool.h> #include <validation.h> @@ -37,6 +38,7 @@ #include <QSettings> #include <QTextDocument> +using common::PSBTError; using wallet::CCoinControl; using wallet::DEFAULT_PAY_TX_FEE; @@ -442,26 +444,26 @@ void SendCoinsDialog::presentPSBT(PartiallySignedTransaction& psbtx) } bool SendCoinsDialog::signWithExternalSigner(PartiallySignedTransaction& psbtx, CMutableTransaction& mtx, bool& complete) { - TransactionError err; + std::optional<PSBTError> err; try { err = model->wallet().fillPSBT(SIGHASH_ALL, /*sign=*/true, /*bip32derivs=*/true, /*n_signed=*/nullptr, psbtx, complete); } catch (const std::runtime_error& e) { QMessageBox::critical(nullptr, tr("Sign failed"), e.what()); return false; } - if (err == TransactionError::EXTERNAL_SIGNER_NOT_FOUND) { + if (err == PSBTError::EXTERNAL_SIGNER_NOT_FOUND) { //: "External signer" means using devices such as hardware wallets. const QString msg = tr("External signer not found"); QMessageBox::critical(nullptr, msg, msg); return false; } - if (err == TransactionError::EXTERNAL_SIGNER_FAILED) { + if (err == PSBTError::EXTERNAL_SIGNER_FAILED) { //: "External signer" means using devices such as hardware wallets. const QString msg = tr("External signer failure"); QMessageBox::critical(nullptr, msg, msg); return false; } - if (err != TransactionError::OK) { + if (err) { tfm::format(std::cerr, "Failed to sign PSBT"); processSendCoinsReturn(WalletModel::TransactionCreationFailed); return false; @@ -501,9 +503,9 @@ void SendCoinsDialog::sendButtonClicked([[maybe_unused]] bool checked) PartiallySignedTransaction psbtx(mtx); bool complete = false; // Fill without signing - TransactionError err = model->wallet().fillPSBT(SIGHASH_ALL, /*sign=*/false, /*bip32derivs=*/true, /*n_signed=*/nullptr, psbtx, complete); + const auto err{model->wallet().fillPSBT(SIGHASH_ALL, /*sign=*/false, /*bip32derivs=*/true, /*n_signed=*/nullptr, psbtx, complete)}; assert(!complete); - assert(err == TransactionError::OK); + assert(!err); // Copy PSBT to clipboard and offer to save presentPSBT(psbtx); @@ -517,9 +519,9 @@ void SendCoinsDialog::sendButtonClicked([[maybe_unused]] bool checked) bool complete = false; // Always fill without signing first. This prevents an external signer // from being called prematurely and is not expensive. - TransactionError err = model->wallet().fillPSBT(SIGHASH_ALL, /*sign=*/false, /*bip32derivs=*/true, /*n_signed=*/nullptr, psbtx, complete); + const auto err{model->wallet().fillPSBT(SIGHASH_ALL, /*sign=*/false, /*bip32derivs=*/true, /*n_signed=*/nullptr, psbtx, complete)}; assert(!complete); - assert(err == TransactionError::OK); + assert(!err); send_failure = !signWithExternalSigner(psbtx, mtx, complete); // Don't broadcast when user rejects it on the device or there's a failure: broadcast = complete && !send_failure; diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp index 0e725acb33..012186ee4d 100644 --- a/src/qt/signverifymessagedialog.cpp +++ b/src/qt/signverifymessagedialog.cpp @@ -10,8 +10,9 @@ #include <qt/platformstyle.h> #include <qt/walletmodel.h> +#include <common/signmessage.h> // For MessageSign(), MessageVerify() +#include <config/bitcoin-config.h> // IWYU pragma: keep #include <key_io.h> -#include <util/message.h> // For MessageSign(), MessageVerify() #include <wallet/wallet.h> #include <vector> @@ -123,7 +124,7 @@ void SignVerifyMessageDialog::on_signMessageButton_SM_clicked() if (!pkhash) { ui->addressIn_SM->setValid(false); ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); - ui->statusLabel_SM->setText(tr("The entered address does not refer to a key.") + QString(" ") + tr("Please check the address and try again.")); + ui->statusLabel_SM->setText(tr("The entered address does not refer to a legacy (P2PKH) key. Message signing for SegWit and other non-P2PKH address types is not supported in this version of %1. Please check the address and try again.").arg(PACKAGE_NAME)); return; } @@ -221,10 +222,7 @@ void SignVerifyMessageDialog::on_verifyMessageButton_VM_clicked() return; case MessageVerificationResult::ERR_ADDRESS_NO_KEY: ui->addressIn_VM->setValid(false); - ui->statusLabel_VM->setText( - tr("The entered address does not refer to a key.") + QString(" ") + - tr("Please check the address and try again.") - ); + ui->statusLabel_VM->setText(tr("The entered address does not refer to a legacy (P2PKH) key. Message signing for SegWit and other non-P2PKH address types is not supported in this version of %1. Please check the address and try again.").arg(PACKAGE_NAME)); return; case MessageVerificationResult::ERR_MALFORMED_SIGNATURE: ui->signatureIn_VM->setValid(false); diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index b55b4cbe64..f261c6409d 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -115,7 +115,7 @@ HelpMessageDialog::~HelpMessageDialog() void HelpMessageDialog::printToConsole() { // On other operating systems, the expected action is to print the message to the console. - tfm::format(std::cout, "%s\n", qPrintable(text)); + tfm::format(std::cout, "%s", qPrintable(text)); } void HelpMessageDialog::showOrPrint() diff --git a/src/qt/walletcontroller.cpp b/src/qt/walletcontroller.cpp index c7fe62f4e9..34b47c90a3 100644 --- a/src/qt/walletcontroller.cpp +++ b/src/qt/walletcontroller.cpp @@ -30,6 +30,7 @@ #include <QTimer> #include <QWindow> +using util::Join; using wallet::WALLET_FLAG_BLANK_WALLET; using wallet::WALLET_FLAG_DESCRIPTORS; using wallet::WALLET_FLAG_DISABLE_PRIVATE_KEYS; diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index fe000bcbb8..f8ce068e12 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -19,6 +19,7 @@ #include <interfaces/node.h> #include <key_io.h> #include <node/interface_ui.h> +#include <node/types.h> #include <psbt.h> #include <util/translation.h> #include <wallet/coincontrol.h> @@ -529,19 +530,13 @@ bool WalletModel::bumpFee(uint256 hash, uint256& new_hash) return false; } - WalletModel::UnlockContext ctx(requestUnlock()); - if(!ctx.isValid()) - { - return false; - } - // Short-circuit if we are returning a bumped transaction PSBT to clipboard if (retval == QMessageBox::Save) { // "Create Unsigned" clicked PartiallySignedTransaction psbtx(mtx); bool complete = false; - const TransactionError err = wallet().fillPSBT(SIGHASH_ALL, /*sign=*/false, /*bip32derivs=*/true, nullptr, psbtx, complete); - if (err != TransactionError::OK || complete) { + const auto err{wallet().fillPSBT(SIGHASH_ALL, /*sign=*/false, /*bip32derivs=*/true, nullptr, psbtx, complete)}; + if (err || complete) { QMessageBox::critical(nullptr, tr("Fee bump error"), tr("Can't draft transaction.")); return false; } @@ -549,10 +544,15 @@ bool WalletModel::bumpFee(uint256 hash, uint256& new_hash) DataStream ssTx{}; ssTx << psbtx; GUIUtil::setClipboard(EncodeBase64(ssTx.str()).c_str()); - Q_EMIT message(tr("PSBT copied"), tr("Copied to clipboard", "Fee-bump PSBT saved"), CClientUIInterface::MSG_INFORMATION); + Q_EMIT message(tr("PSBT copied"), tr("Fee-bump PSBT copied to clipboard"), CClientUIInterface::MSG_INFORMATION | CClientUIInterface::MODAL); return true; } + WalletModel::UnlockContext ctx(requestUnlock()); + if (!ctx.isValid()) { + return false; + } + assert(!m_wallet->privateKeysDisabled() || wallet().hasExternalSigner()); // sign bumped transaction diff --git a/src/randomenv.cpp b/src/randomenv.cpp index aeec959c28..49033deef2 100644 --- a/src/randomenv.cpp +++ b/src/randomenv.cpp @@ -42,15 +42,15 @@ #if HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS #include <ifaddrs.h> #endif -#if HAVE_SYSCTL +#ifdef HAVE_SYSCTL #include <sys/sysctl.h> -#if HAVE_VM_VM_PARAM_H +#ifdef HAVE_VM_VM_PARAM_H #include <vm/vm_param.h> #endif -#if HAVE_SYS_RESOURCES_H +#ifdef HAVE_SYS_RESOURCES_H #include <sys/resources.h> #endif -#if HAVE_SYS_VMMETER_H +#ifdef HAVE_SYS_VMMETER_H #include <sys/vmmeter.h> #endif #endif @@ -162,7 +162,7 @@ void AddPath(CSHA512& hasher, const char *path) } #endif -#if HAVE_SYSCTL +#ifdef HAVE_SYSCTL template<int... S> void AddSysctl(CSHA512& hasher) { @@ -274,7 +274,7 @@ void RandAddDynamicEnv(CSHA512& hasher) AddFile(hasher, "/proc/self/status"); #endif -#if HAVE_SYSCTL +#ifdef HAVE_SYSCTL # ifdef CTL_KERN # if defined(KERN_PROC) && defined(KERN_PROC_ALL) AddSysctl<CTL_KERN, KERN_PROC, KERN_PROC_ALL>(hasher); @@ -419,7 +419,7 @@ void RandAddStaticEnv(CSHA512& hasher) // For MacOS/BSDs, gather data through sysctl instead of /proc. Not all of these // will exist on every system. -#if HAVE_SYSCTL +#ifdef HAVE_SYSCTL # ifdef CTL_HW # ifdef HW_MACHINE AddSysctl<CTL_HW, HW_MACHINE>(hasher); diff --git a/src/rest.cpp b/src/rest.cpp index 9fc5d4af04..4abbc4d2ca 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -39,6 +39,7 @@ using node::GetTransaction; using node::NodeContext; +using util::SplitString; static const size_t MAX_GETUTXOS_OUTPOINTS = 15; //allow a max of 15 outpoints to be queried at once static constexpr unsigned int MAX_REST_HEADERS_RESULTS = 2000; @@ -247,9 +248,8 @@ static bool rest_headers(const std::any& context, ssHeader << pindex->GetBlockHeader(); } - std::string binaryHeader = ssHeader.str(); req->WriteHeader("Content-Type", "application/octet-stream"); - req->WriteReply(HTTP_OK, binaryHeader); + req->WriteReply(HTTP_OK, ssHeader); return true; } @@ -320,9 +320,8 @@ static bool rest_block(const std::any& context, switch (rf) { case RESTResponseFormat::BINARY: { - const std::string binaryBlock{block_data.begin(), block_data.end()}; req->WriteHeader("Content-Type", "application/octet-stream"); - req->WriteReply(HTTP_OK, binaryBlock); + req->WriteReply(HTTP_OK, std::as_bytes(std::span{block_data})); return true; } @@ -450,9 +449,8 @@ static bool rest_filter_header(const std::any& context, HTTPRequest* req, const ssHeader << header; } - std::string binaryHeader = ssHeader.str(); req->WriteHeader("Content-Type", "application/octet-stream"); - req->WriteReply(HTTP_OK, binaryHeader); + req->WriteReply(HTTP_OK, ssHeader); return true; } case RESTResponseFormat::HEX: { @@ -547,9 +545,8 @@ static bool rest_block_filter(const std::any& context, HTTPRequest* req, const s DataStream ssResp{}; ssResp << filter; - std::string binaryResp = ssResp.str(); req->WriteHeader("Content-Type", "application/octet-stream"); - req->WriteReply(HTTP_OK, binaryResp); + req->WriteReply(HTTP_OK, ssResp); return true; } case RESTResponseFormat::HEX: { @@ -728,9 +725,8 @@ static bool rest_tx(const std::any& context, HTTPRequest* req, const std::string DataStream ssTx; ssTx << TX_WITH_WITNESS(tx); - std::string binaryTx = ssTx.str(); req->WriteHeader("Content-Type", "application/octet-stream"); - req->WriteReply(HTTP_OK, binaryTx); + req->WriteReply(HTTP_OK, ssTx); return true; } @@ -899,10 +895,9 @@ static bool rest_getutxos(const std::any& context, HTTPRequest* req, const std:: // use exact same output as mentioned in Bip64 DataStream ssGetUTXOResponse{}; ssGetUTXOResponse << active_height << active_hash << bitmap << outs; - std::string ssGetUTXOResponseString = ssGetUTXOResponse.str(); req->WriteHeader("Content-Type", "application/octet-stream"); - req->WriteReply(HTTP_OK, ssGetUTXOResponseString); + req->WriteReply(HTTP_OK, ssGetUTXOResponse); return true; } @@ -934,10 +929,10 @@ static bool rest_getutxos(const std::any& context, HTTPRequest* req, const std:: // include the script in a json output UniValue o(UniValue::VOBJ); ScriptToUniv(coin.out.scriptPubKey, /*out=*/o, /*include_hex=*/true, /*include_address=*/true); - utxo.pushKV("scriptPubKey", o); - utxos.push_back(utxo); + utxo.pushKV("scriptPubKey", std::move(o)); + utxos.push_back(std::move(utxo)); } - objGetUTXOResponse.pushKV("utxos", utxos); + objGetUTXOResponse.pushKV("utxos", std::move(utxos)); // return json string std::string strJSON = objGetUTXOResponse.write() + "\n"; @@ -980,7 +975,7 @@ static bool rest_blockhash_by_height(const std::any& context, HTTPRequest* req, DataStream ss_blockhash{}; ss_blockhash << pblockindex->GetBlockHash(); req->WriteHeader("Content-Type", "application/octet-stream"); - req->WriteReply(HTTP_OK, ss_blockhash.str()); + req->WriteReply(HTTP_OK, ss_blockhash); return true; } case RESTResponseFormat::HEX: { diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index c9997ae063..e785678614 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -29,11 +29,13 @@ #include <node/context.h> #include <node/transaction.h> #include <node/utxo_snapshot.h> +#include <node/warnings.h> #include <primitives/transaction.h> #include <rpc/server.h> #include <rpc/server_util.h> #include <rpc/util.h> #include <script/descriptor.h> +#include <serialize.h> #include <streams.h> #include <sync.h> #include <txdb.h> @@ -60,6 +62,9 @@ using kernel::CoinStatsHashType; using node::BlockManager; using node::NodeContext; using node::SnapshotMetadata; +using util::Join; +using util::MakeUnorderedList; +using util::ToString; struct CUpdatedBlock { @@ -188,12 +193,12 @@ UniValue blockToJSON(BlockManager& blockman, const CBlock& block, const CBlockIn const CTxUndo* txundo = (have_undo && i > 0) ? &blockUndo.vtxundo.at(i - 1) : nullptr; UniValue objTx(UniValue::VOBJ); TxToUniv(*tx, /*block_hash=*/uint256(), /*entry=*/objTx, /*include_hex=*/true, txundo, verbosity); - txs.push_back(objTx); + txs.push_back(std::move(objTx)); } break; } - result.pushKV("tx", txs); + result.pushKV("tx", std::move(txs)); return result; } @@ -1025,9 +1030,9 @@ static RPCHelpMan gettxoutsetinfo() unspendables.pushKV("bip30", ValueFromAmount(stats.total_unspendables_bip30 - prev_stats.total_unspendables_bip30)); unspendables.pushKV("scripts", ValueFromAmount(stats.total_unspendables_scripts - prev_stats.total_unspendables_scripts)); unspendables.pushKV("unclaimed_rewards", ValueFromAmount(stats.total_unspendables_unclaimed_rewards - prev_stats.total_unspendables_unclaimed_rewards)); - block_info.pushKV("unspendables", unspendables); + block_info.pushKV("unspendables", std::move(unspendables)); - ret.pushKV("block_info", block_info); + ret.pushKV("block_info", std::move(block_info)); } } else { throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set"); @@ -1111,7 +1116,7 @@ static RPCHelpMan gettxout() ret.pushKV("value", ValueFromAmount(coin.out.nValue)); UniValue o(UniValue::VOBJ); ScriptToUniv(coin.out.scriptPubKey, /*out=*/o, /*include_hex=*/true, /*include_address=*/true); - ret.pushKV("scriptPubKey", o); + ret.pushKV("scriptPubKey", std::move(o)); ret.pushKV("coinbase", (bool)coin.fCoinBase); return ret; @@ -1161,7 +1166,7 @@ static void SoftForkDescPushBack(const CBlockIndex* blockindex, UniValue& softfo // one below the activation height rv.pushKV("active", DeploymentActiveAfter(blockindex, chainman, dep)); rv.pushKV("height", chainman.GetConsensus().DeploymentHeight(dep)); - softforks.pushKV(DeploymentName(dep), rv); + softforks.pushKV(DeploymentName(dep), std::move(rv)); } static void SoftForkDescPushBack(const CBlockIndex* blockindex, UniValue& softforks, const ChainstateManager& chainman, Consensus::DeploymentPos id) @@ -1214,7 +1219,7 @@ static void SoftForkDescPushBack(const CBlockIndex* blockindex, UniValue& softfo statsUV.pushKV("threshold", statsStruct.threshold); statsUV.pushKV("possible", statsStruct.possible); } - bip9.pushKV("statistics", statsUV); + bip9.pushKV("statistics", std::move(statsUV)); std::string sig; sig.reserve(signals.size()); @@ -1230,9 +1235,9 @@ static void SoftForkDescPushBack(const CBlockIndex* blockindex, UniValue& softfo rv.pushKV("height", chainman.m_versionbitscache.StateSinceHeight(blockindex, chainman.GetConsensus(), id)); } rv.pushKV("active", ThresholdState::ACTIVE == next_state); - rv.pushKV("bip9", bip9); + rv.pushKV("bip9", std::move(bip9)); - softforks.pushKV(DeploymentName(id), rv); + softforks.pushKV(DeploymentName(id), std::move(rv)); } // used by rest.cpp:rest_chaininfo, so cannot be static @@ -1304,7 +1309,8 @@ RPCHelpMan getblockchaininfo() } } - obj.pushKV("warnings", GetNodeWarnings(IsDeprecatedRPCEnabled("warnings"))); + NodeContext& node = EnsureAnyNodeContext(request.context); + obj.pushKV("warnings", node::GetWarningsForRpc(*CHECK_NONFATAL(node.warnings), IsDeprecatedRPCEnabled("warnings"))); return obj; }, }; @@ -1498,7 +1504,7 @@ static RPCHelpMan getchaintips() } obj.pushKV("status", status); - res.push_back(obj); + res.push_back(std::move(obj)); } return res; @@ -1978,7 +1984,7 @@ static RPCHelpMan getblockstats() ret_all.pushKV("avgfeerate", total_weight ? (totalfee * WITNESS_SCALE_FACTOR) / total_weight : 0); // Unit: sat/vbyte ret_all.pushKV("avgtxsize", (block.vtx.size() > 1) ? total_size / (block.vtx.size() - 1) : 0); ret_all.pushKV("blockhash", pindex.GetBlockHash().GetHex()); - ret_all.pushKV("feerate_percentiles", feerates_res); + ret_all.pushKV("feerate_percentiles", std::move(feerates_res)); ret_all.pushKV("height", (int64_t)pindex.nHeight); ret_all.pushKV("ins", inputs); ret_all.pushKV("maxfee", maxfee); @@ -2262,9 +2268,9 @@ static RPCHelpMan scantxoutset() unspent.pushKV("coinbase", coin.IsCoinBase()); unspent.pushKV("height", (int32_t)coin.nHeight); - unspents.push_back(unspent); + unspents.push_back(std::move(unspent)); } - result.pushKV("unspents", unspents); + result.pushKV("unspents", std::move(unspents)); result.pushKV("total_amount", ValueFromAmount(total_in)); } else { throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid action '%s'", action)); @@ -2504,7 +2510,7 @@ static RPCHelpMan scanblocks() ret.pushKV("from_height", start_block_height); ret.pushKV("to_height", start_index->nHeight); // start_index is always the last scanned block here - ret.pushKV("relevant_blocks", blocks); + ret.pushKV("relevant_blocks", std::move(blocks)); ret.pushKV("completed", completed); } else { @@ -2696,29 +2702,60 @@ UniValue CreateUTXOSnapshot( tip->nHeight, tip->GetBlockHash().ToString(), fs::PathToString(path), fs::PathToString(temppath))); - SnapshotMetadata metadata{tip->GetBlockHash(), maybe_stats->coins_count}; + SnapshotMetadata metadata{chainstate.m_chainman.GetParams().MessageStart(), tip->GetBlockHash(), tip->nHeight, maybe_stats->coins_count}; afile << metadata; COutPoint key; + Txid last_hash; Coin coin; unsigned int iter{0}; + size_t written_coins_count{0}; + std::vector<std::pair<uint32_t, Coin>> coins; + + // To reduce space the serialization format of the snapshot avoids + // duplication of tx hashes. The code takes advantage of the guarantee by + // leveldb that keys are lexicographically sorted. + // In the coins vector we collect all coins that belong to a certain tx hash + // (key.hash) and when we have them all (key.hash != last_hash) we write + // them to file using the below lambda function. + // See also https://github.com/bitcoin/bitcoin/issues/25675 + auto write_coins_to_file = [&](AutoFile& afile, const Txid& last_hash, const std::vector<std::pair<uint32_t, Coin>>& coins, size_t& written_coins_count) { + afile << last_hash; + WriteCompactSize(afile, coins.size()); + for (const auto& [n, coin] : coins) { + WriteCompactSize(afile, n); + afile << coin; + ++written_coins_count; + } + }; + pcursor->GetKey(key); + last_hash = key.hash; while (pcursor->Valid()) { if (iter % 5000 == 0) node.rpc_interruption_point(); ++iter; if (pcursor->GetKey(key) && pcursor->GetValue(coin)) { - afile << key; - afile << coin; + if (key.hash != last_hash) { + write_coins_to_file(afile, last_hash, coins, written_coins_count); + last_hash = key.hash; + coins.clear(); + } + coins.emplace_back(key.n, coin); } - pcursor->Next(); } + if (!coins.empty()) { + write_coins_to_file(afile, last_hash, coins, written_coins_count); + } + + CHECK_NONFATAL(written_coins_count == maybe_stats->coins_count); + afile.fclose(); UniValue result(UniValue::VOBJ); - result.pushKV("coins_written", maybe_stats->coins_count); + result.pushKV("coins_written", written_coins_count); result.pushKV("base_hash", tip->GetBlockHash().ToString()); result.pushKV("base_height", tip->nHeight); result.pushKV("path", path.utf8string()); @@ -2777,13 +2814,23 @@ static RPCHelpMan loadtxoutset() "Couldn't open file " + path.utf8string() + " for reading."); } - SnapshotMetadata metadata; - afile >> metadata; + SnapshotMetadata metadata{chainman.GetParams().MessageStart()}; + try { + afile >> metadata; + } catch (const std::ios_base::failure& e) { + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("Unable to parse metadata: %s", e.what())); + } uint256 base_blockhash = metadata.m_base_blockhash; + int base_blockheight = metadata.m_base_blockheight; if (!chainman.GetParams().AssumeutxoForBlockhash(base_blockhash).has_value()) { + auto available_heights = chainman.GetParams().GetAvailableSnapshotHeights(); + std::string heights_formatted = Join(available_heights, ", ", [&](const auto& i) { return ToString(i); }); throw JSONRPCError(RPC_INTERNAL_ERROR, strprintf("Unable to load UTXO snapshot, " - "assumeutxo block hash in snapshot metadata not recognized (%s)", base_blockhash.ToString())); + "assumeutxo block hash in snapshot metadata not recognized (hash: %s, height: %s). The following snapshot heights are available: %s.", + base_blockhash.ToString(), + base_blockheight, + heights_formatted)); } CBlockIndex* snapshot_start_block = WITH_LOCK(::cs_main, return chainman.m_blockman.LookupBlockIndex(base_blockhash)); diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index b8dc148eae..7dfe69a6c5 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -391,7 +391,7 @@ UniValue RPCConvertNamedValues(const std::string &strMethod, const std::vector<s // Use pushKVEnd instead of pushKV to avoid overwriting an explicit // "args" value with an implicit one. Let the RPC server handle the // request as given. - params.pushKVEnd("args", positional_args); + params.pushKVEnd("args", std::move(positional_args)); } return params; diff --git a/src/rpc/external_signer.cpp b/src/rpc/external_signer.cpp index 27c7394909..3ad7a940e0 100644 --- a/src/rpc/external_signer.cpp +++ b/src/rpc/external_signer.cpp @@ -53,13 +53,13 @@ static RPCHelpMan enumeratesigners() UniValue signer_res = UniValue::VOBJ; signer_res.pushKV("fingerprint", signer.m_fingerprint); signer_res.pushKV("name", signer.m_name); - signers_res.push_back(signer_res); + signers_res.push_back(std::move(signer_res)); } } catch (const std::exception& e) { throw JSONRPCError(RPC_MISC_ERROR, e.what()); } UniValue result(UniValue::VOBJ); - result.pushKV("signers", signers_res); + result.pushKV("signers", std::move(signers_res)); return result; } }; diff --git a/src/rpc/fees.cpp b/src/rpc/fees.cpp index f3345b4f1c..aefe78162b 100644 --- a/src/rpc/fees.cpp +++ b/src/rpc/fees.cpp @@ -3,6 +3,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <common/messages.h> #include <core_io.h> #include <node/context.h> #include <policy/feerate.h> @@ -14,7 +15,6 @@ #include <rpc/util.h> #include <txmempool.h> #include <univalue.h> -#include <util/fees.h> #include <validationinterface.h> #include <algorithm> @@ -22,6 +22,9 @@ #include <cmath> #include <string> +using common::FeeModeFromString; +using common::FeeModes; +using common::InvalidEstimateModeErrorMessage; using node::NodeContext; static RPCHelpMan estimatesmartfee() @@ -65,7 +68,7 @@ static RPCHelpMan estimatesmartfee() const NodeContext& node = EnsureAnyNodeContext(request.context); const CTxMemPool& mempool = EnsureMemPool(node); - CHECK_NONFATAL(mempool.m_signals)->SyncWithValidationInterfaceQueue(); + CHECK_NONFATAL(mempool.m_opts.signals)->SyncWithValidationInterfaceQueue(); unsigned int max_target = fee_estimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE); unsigned int conf_target = ParseConfirmTarget(request.params[0], max_target); bool conservative = true; @@ -83,12 +86,12 @@ static RPCHelpMan estimatesmartfee() CFeeRate feeRate{fee_estimator.estimateSmartFee(conf_target, &feeCalc, conservative)}; if (feeRate != CFeeRate(0)) { CFeeRate min_mempool_feerate{mempool.GetMinFee()}; - CFeeRate min_relay_feerate{mempool.m_min_relay_feerate}; + CFeeRate min_relay_feerate{mempool.m_opts.min_relay_feerate}; feeRate = std::max({feeRate, min_mempool_feerate, min_relay_feerate}); result.pushKV("feerate", ValueFromAmount(feeRate.GetFeePerK())); } else { errors.push_back("Insufficient data or no feerate found"); - result.pushKV("errors", errors); + result.pushKV("errors", std::move(errors)); } result.pushKV("blocks", feeCalc.returnedTarget); return result; @@ -198,18 +201,18 @@ static RPCHelpMan estimaterawfee() horizon_result.pushKV("feerate", ValueFromAmount(feeRate.GetFeePerK())); horizon_result.pushKV("decay", buckets.decay); horizon_result.pushKV("scale", (int)buckets.scale); - horizon_result.pushKV("pass", passbucket); + horizon_result.pushKV("pass", std::move(passbucket)); // buckets.fail.start == -1 indicates that all buckets passed, there is no fail bucket to output - if (buckets.fail.start != -1) horizon_result.pushKV("fail", failbucket); + if (buckets.fail.start != -1) horizon_result.pushKV("fail", std::move(failbucket)); } else { // Output only information that is still meaningful in the event of error horizon_result.pushKV("decay", buckets.decay); horizon_result.pushKV("scale", (int)buckets.scale); - horizon_result.pushKV("fail", failbucket); + horizon_result.pushKV("fail", std::move(failbucket)); errors.push_back("Insufficient data or no feerate found which meets threshold"); - horizon_result.pushKV("errors", errors); + horizon_result.pushKV("errors", std::move(errors)); } - result.pushKV(StringForFeeEstimateHorizon(horizon), horizon_result); + result.pushKV(StringForFeeEstimateHorizon(horizon), std::move(horizon_result)); } return result; }, diff --git a/src/rpc/mempool.cpp b/src/rpc/mempool.cpp index e6fe3c7ebd..fd11f6cfeb 100644 --- a/src/rpc/mempool.cpp +++ b/src/rpc/mempool.cpp @@ -11,6 +11,7 @@ #include <core_io.h> #include <kernel/mempool_entry.h> #include <node/mempool_persist_args.h> +#include <node/types.h> #include <policy/rbf.h> #include <policy/settings.h> #include <primitives/transaction.h> @@ -32,6 +33,8 @@ using node::DEFAULT_MAX_BURN_AMOUNT; using node::DEFAULT_MAX_RAW_TX_FEE_RATE; using node::MempoolPath; using node::NodeContext; +using node::TransactionError; +using util::ToString; static RPCHelpMan sendrawtransaction() { @@ -82,7 +85,7 @@ static RPCHelpMan sendrawtransaction() CTransactionRef tx(MakeTransactionRef(std::move(mtx))); - const CFeeRate max_raw_tx_fee_rate{ParseFeeRate(self.Arg<UniValue>(1))}; + const CFeeRate max_raw_tx_fee_rate{ParseFeeRate(self.Arg<UniValue>("maxfeerate"))}; int64_t virtual_size = GetVirtualTransactionSize(*tx); CAmount max_raw_tx_fee = max_raw_tx_fee_rate.GetFee(virtual_size); @@ -162,7 +165,7 @@ static RPCHelpMan testmempoolaccept() "Array must contain between 1 and " + ToString(MAX_PACKAGE_COUNT) + " transactions."); } - const CFeeRate max_raw_tx_fee_rate{ParseFeeRate(self.Arg<UniValue>(1))}; + const CFeeRate max_raw_tx_fee_rate{ParseFeeRate(self.Arg<UniValue>("maxfeerate"))}; std::vector<CTransactionRef> txns; txns.reserve(raw_transactions.size()); @@ -202,7 +205,7 @@ static RPCHelpMan testmempoolaccept() auto it = package_result.m_tx_results.find(tx->GetWitnessHash()); if (exit_early || it == package_result.m_tx_results.end()) { // Validation unfinished. Just return the txid and wtxid. - rpc_result.push_back(result_inner); + rpc_result.push_back(std::move(result_inner)); continue; } const auto& tx_result = it->second; @@ -229,8 +232,8 @@ static RPCHelpMan testmempoolaccept() for (const auto& wtxid : tx_result.m_wtxids_fee_calculations.value()) { effective_includes_res.push_back(wtxid.ToString()); } - fees.pushKV("effective-includes", effective_includes_res); - result_inner.pushKV("fees", fees); + fees.pushKV("effective-includes", std::move(effective_includes_res)); + result_inner.pushKV("fees", std::move(fees)); } } else { result_inner.pushKV("allowed", false); @@ -241,7 +244,7 @@ static RPCHelpMan testmempoolaccept() result_inner.pushKV("reject-reason", state.GetRejectReason()); } } - rpc_result.push_back(result_inner); + rpc_result.push_back(std::move(result_inner)); } return rpc_result; }, @@ -295,7 +298,7 @@ static void entryToJSON(const CTxMemPool& pool, UniValue& info, const CTxMemPool fees.pushKV("modified", ValueFromAmount(e.GetModifiedFee())); fees.pushKV("ancestor", ValueFromAmount(e.GetModFeesWithAncestors())); fees.pushKV("descendant", ValueFromAmount(e.GetModFeesWithDescendants())); - info.pushKV("fees", fees); + info.pushKV("fees", std::move(fees)); const CTransaction& tx = e.GetTx(); std::set<std::string> setDepends; @@ -311,14 +314,14 @@ static void entryToJSON(const CTxMemPool& pool, UniValue& info, const CTxMemPool depends.push_back(dep); } - info.pushKV("depends", depends); + info.pushKV("depends", std::move(depends)); UniValue spent(UniValue::VARR); for (const CTxMemPoolEntry& child : e.GetMemPoolChildrenConst()) { spent.push_back(child.GetTx().GetHash().ToString()); } - info.pushKV("spentby", spent); + info.pushKV("spentby", std::move(spent)); // Add opt-in RBF status bool rbfStatus = false; @@ -347,7 +350,7 @@ UniValue MempoolToJSON(const CTxMemPool& pool, bool verbose, bool include_mempoo // Mempool has unique entries so there is no advantage in using // UniValue::pushKV, which checks if the key already exists in O(N). // UniValue::pushKVEnd is used instead which currently is O(1). - o.pushKVEnd(e.GetTx().GetHash().ToString(), info); + o.pushKVEnd(e.GetTx().GetHash().ToString(), std::move(info)); } return o; } else { @@ -364,7 +367,7 @@ UniValue MempoolToJSON(const CTxMemPool& pool, bool verbose, bool include_mempoo return a; } else { UniValue o(UniValue::VOBJ); - o.pushKV("txids", a); + o.pushKV("txids", std::move(a)); o.pushKV("mempool_sequence", mempool_sequence); return o; } @@ -474,7 +477,7 @@ static RPCHelpMan getmempoolancestors() const uint256& _hash = e.GetTx().GetHash(); UniValue info(UniValue::VOBJ); entryToJSON(mempool, info, e); - o.pushKV(_hash.ToString(), info); + o.pushKV(_hash.ToString(), std::move(info)); } return o; } @@ -539,7 +542,7 @@ static RPCHelpMan getmempooldescendants() const uint256& _hash = e.GetTx().GetHash(); UniValue info(UniValue::VOBJ); entryToJSON(mempool, info, e); - o.pushKV(_hash.ToString(), info); + o.pushKV(_hash.ToString(), std::move(info)); } return o; } @@ -653,7 +656,7 @@ static RPCHelpMan gettxspendingprevout() o.pushKV("spendingtxid", spendingTx->GetHash().ToString()); } - result.push_back(o); + result.push_back(std::move(o)); } return result; @@ -671,12 +674,12 @@ UniValue MempoolInfoToJSON(const CTxMemPool& pool) ret.pushKV("bytes", (int64_t)pool.GetTotalTxSize()); ret.pushKV("usage", (int64_t)pool.DynamicMemoryUsage()); ret.pushKV("total_fee", ValueFromAmount(pool.GetTotalFee())); - ret.pushKV("maxmempool", pool.m_max_size_bytes); - ret.pushKV("mempoolminfee", ValueFromAmount(std::max(pool.GetMinFee(), pool.m_min_relay_feerate).GetFeePerK())); - ret.pushKV("minrelaytxfee", ValueFromAmount(pool.m_min_relay_feerate.GetFeePerK())); - ret.pushKV("incrementalrelayfee", ValueFromAmount(pool.m_incremental_relay_feerate.GetFeePerK())); + ret.pushKV("maxmempool", pool.m_opts.max_size_bytes); + ret.pushKV("mempoolminfee", ValueFromAmount(std::max(pool.GetMinFee(), pool.m_opts.min_relay_feerate).GetFeePerK())); + ret.pushKV("minrelaytxfee", ValueFromAmount(pool.m_opts.min_relay_feerate.GetFeePerK())); + ret.pushKV("incrementalrelayfee", ValueFromAmount(pool.m_opts.incremental_relay_feerate.GetFeePerK())); ret.pushKV("unbroadcastcount", uint64_t{pool.GetUnbroadcastTxs().size()}); - ret.pushKV("fullrbf", pool.m_full_rbf); + ret.pushKV("fullrbf", pool.m_opts.full_rbf); return ret; } @@ -813,13 +816,14 @@ static RPCHelpMan submitpackage() { return RPCHelpMan{"submitpackage", "Submit a package of raw transactions (serialized, hex-encoded) to local node.\n" - "The package must consist of a child with its parents, and none of the parents may depend on one another.\n" "The package will be validated according to consensus and mempool policy rules. If any transaction passes, it will be accepted to mempool.\n" "This RPC is experimental and the interface may be unstable. Refer to doc/policy/packages.md for documentation on package policies.\n" "Warning: successful submission does not mean the transactions will propagate throughout the network.\n" , { - {"package", RPCArg::Type::ARR, RPCArg::Optional::NO, "An array of raw transactions.", + {"package", RPCArg::Type::ARR, RPCArg::Optional::NO, "An array of raw transactions.\n" + "The package must solely consist of a child and its parents. None of the parents may depend on each other.\n" + "The package must be topologically sorted, with the child being the last element in the array.", { {"rawtx", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, ""}, }, @@ -860,19 +864,19 @@ static RPCHelpMan submitpackage() }, }, RPCExamples{ - HelpExampleCli("testmempoolaccept", "[rawtx1, rawtx2]") + - HelpExampleCli("submitpackage", "[rawtx1, rawtx2]") + HelpExampleRpc("submitpackage", R"(["rawtx1", "rawtx2"])") + + HelpExampleCli("submitpackage", R"('["rawtx1", "rawtx2"]')") }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { const UniValue raw_transactions = request.params[0].get_array(); - if (raw_transactions.size() < 1 || raw_transactions.size() > MAX_PACKAGE_COUNT) { + if (raw_transactions.size() < 2 || raw_transactions.size() > MAX_PACKAGE_COUNT) { throw JSONRPCError(RPC_INVALID_PARAMETER, - "Array must contain between 1 and " + ToString(MAX_PACKAGE_COUNT) + " transactions."); + "Array must contain between 2 and " + ToString(MAX_PACKAGE_COUNT) + " transactions."); } // Fee check needs to be run with chainstate and package context - const CFeeRate max_raw_tx_fee_rate = ParseFeeRate(self.Arg<UniValue>(1)); + const CFeeRate max_raw_tx_fee_rate{ParseFeeRate(self.Arg<UniValue>("maxfeerate"))}; std::optional<CFeeRate> client_maxfeerate{max_raw_tx_fee_rate}; // 0-value is special; it's mapped to no sanity check if (max_raw_tx_fee_rate == CFeeRate(0)) { @@ -991,20 +995,20 @@ static RPCHelpMan submitpackage() for (const auto& wtxid : tx_result.m_wtxids_fee_calculations.value()) { effective_includes_res.push_back(wtxid.ToString()); } - fees.pushKV("effective-includes", effective_includes_res); + fees.pushKV("effective-includes", std::move(effective_includes_res)); } - result_inner.pushKV("fees", fees); + result_inner.pushKV("fees", std::move(fees)); for (const auto& ptx : it->second.m_replaced_transactions) { replaced_txids.insert(ptx->GetHash()); } break; } - tx_result_map.pushKV(tx->GetWitnessHash().GetHex(), result_inner); + tx_result_map.pushKV(tx->GetWitnessHash().GetHex(), std::move(result_inner)); } - rpc_result.pushKV("tx-results", tx_result_map); + rpc_result.pushKV("tx-results", std::move(tx_result_map)); UniValue replaced_list(UniValue::VARR); for (const uint256& hash : replaced_txids) replaced_list.push_back(hash.ToString()); - rpc_result.pushKV("replaced-transactions", replaced_list); + rpc_result.pushKV("replaced-transactions", std::move(replaced_list)); return rpc_result; }, }; diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 73987669a5..2b93c18965 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -16,10 +16,12 @@ #include <core_io.h> #include <deploymentinfo.h> #include <deploymentstatus.h> +#include <interfaces/mining.h> #include <key_io.h> #include <net.h> #include <node/context.h> #include <node/miner.h> +#include <node/warnings.h> #include <pow.h> #include <rpc/blockchain.h> #include <rpc/mining.h> @@ -31,6 +33,7 @@ #include <script/signingprovider.h> #include <txmempool.h> #include <univalue.h> +#include <util/signalinterrupt.h> #include <util/strencodings.h> #include <util/string.h> #include <util/time.h> @@ -43,9 +46,11 @@ using node::BlockAssembler; using node::CBlockTemplate; +using interfaces::Mining; using node::NodeContext; using node::RegenerateCommitments; using node::UpdateTime; +using util::ToString; /** * Return average network hashes per second based on the last 'lookup' blocks, @@ -124,7 +129,7 @@ static RPCHelpMan getnetworkhashps() }; } -static bool GenerateBlock(ChainstateManager& chainman, CBlock& block, uint64_t& max_tries, std::shared_ptr<const CBlock>& block_out, bool process_new_block) +static bool GenerateBlock(ChainstateManager& chainman, Mining& miner, CBlock& block, uint64_t& max_tries, std::shared_ptr<const CBlock>& block_out, bool process_new_block) { block_out.reset(); block.hashMerkleRoot = BlockMerkleRoot(block); @@ -144,23 +149,23 @@ static bool GenerateBlock(ChainstateManager& chainman, CBlock& block, uint64_t& if (!process_new_block) return true; - if (!chainman.ProcessNewBlock(block_out, /*force_processing=*/true, /*min_pow_checked=*/true, nullptr)) { + if (!miner.processNewBlock(block_out, nullptr)) { throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted"); } return true; } -static UniValue generateBlocks(ChainstateManager& chainman, const CTxMemPool& mempool, const CScript& coinbase_script, int nGenerate, uint64_t nMaxTries) +static UniValue generateBlocks(ChainstateManager& chainman, Mining& miner, const CScript& coinbase_script, int nGenerate, uint64_t nMaxTries) { UniValue blockHashes(UniValue::VARR); while (nGenerate > 0 && !chainman.m_interrupt) { - std::unique_ptr<CBlockTemplate> pblocktemplate(BlockAssembler{chainman.ActiveChainstate(), &mempool}.CreateNewBlock(coinbase_script)); + std::unique_ptr<CBlockTemplate> pblocktemplate(miner.createNewBlock(coinbase_script)); if (!pblocktemplate.get()) throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block"); std::shared_ptr<const CBlock> block_out; - if (!GenerateBlock(chainman, pblocktemplate->block, nMaxTries, block_out, /*process_new_block=*/true)) { + if (!GenerateBlock(chainman, miner, pblocktemplate->block, nMaxTries, block_out, /*process_new_block=*/true)) { break; } @@ -236,10 +241,10 @@ static RPCHelpMan generatetodescriptor() } NodeContext& node = EnsureAnyNodeContext(request.context); - const CTxMemPool& mempool = EnsureMemPool(node); + Mining& miner = EnsureMining(node); ChainstateManager& chainman = EnsureChainman(node); - return generateBlocks(chainman, mempool, coinbase_script, num_blocks, max_tries); + return generateBlocks(chainman, miner, coinbase_script, num_blocks, max_tries); }, }; } @@ -282,12 +287,12 @@ static RPCHelpMan generatetoaddress() } NodeContext& node = EnsureAnyNodeContext(request.context); - const CTxMemPool& mempool = EnsureMemPool(node); + Mining& miner = EnsureMining(node); ChainstateManager& chainman = EnsureChainman(node); CScript coinbase_script = GetScriptForDestination(destination); - return generateBlocks(chainman, mempool, coinbase_script, num_blocks, max_tries); + return generateBlocks(chainman, miner, coinbase_script, num_blocks, max_tries); }, }; } @@ -334,6 +339,7 @@ static RPCHelpMan generateblock() } NodeContext& node = EnsureAnyNodeContext(request.context); + Mining& miner = EnsureMining(node); const CTxMemPool& mempool = EnsureMemPool(node); std::vector<CTransactionRef> txs; @@ -367,7 +373,7 @@ static RPCHelpMan generateblock() { LOCK(cs_main); - std::unique_ptr<CBlockTemplate> blocktemplate(BlockAssembler{chainman.ActiveChainstate(), nullptr}.CreateNewBlock(coinbase_script)); + std::unique_ptr<CBlockTemplate> blocktemplate{miner.createNewBlock(coinbase_script, /*use_mempool=*/false)}; if (!blocktemplate) { throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block"); } @@ -384,15 +390,15 @@ static RPCHelpMan generateblock() LOCK(cs_main); BlockValidationState state; - if (!TestBlockValidity(state, chainman.GetParams(), chainman.ActiveChainstate(), block, chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock), false, false)) { - throw JSONRPCError(RPC_VERIFY_ERROR, strprintf("TestBlockValidity failed: %s", state.ToString())); + if (!miner.testBlockValidity(state, block, /*check_merkle_root=*/false)) { + throw JSONRPCError(RPC_VERIFY_ERROR, strprintf("testBlockValidity failed: %s", state.ToString())); } } std::shared_ptr<const CBlock> block_out; uint64_t max_tries{DEFAULT_MAX_TRIES}; - if (!GenerateBlock(chainman, block, max_tries, block_out, process_new_block) || !block_out) { + if (!GenerateBlock(chainman, miner, block, max_tries, block_out, process_new_block) || !block_out) { throw JSONRPCError(RPC_MISC_ERROR, "Failed to make block."); } @@ -452,7 +458,7 @@ static RPCHelpMan getmininginfo() obj.pushKV("networkhashps", getnetworkhashps().HandleRequest(request)); obj.pushKV("pooledtx", (uint64_t)mempool.size()); obj.pushKV("chain", chainman.GetParams().GetChainTypeString()); - obj.pushKV("warnings", GetNodeWarnings(IsDeprecatedRPCEnabled("warnings"))); + obj.pushKV("warnings", node::GetWarningsForRpc(*CHECK_NONFATAL(node.warnings), IsDeprecatedRPCEnabled("warnings"))); return obj; }, }; @@ -484,7 +490,7 @@ static RPCHelpMan prioritisetransaction() LOCK(cs_main); uint256 hash(ParseHashV(request.params[0], "txid")); - const auto dummy{self.MaybeArg<double>(1)}; + const auto dummy{self.MaybeArg<double>("dummy")}; CAmount nAmount = request.params[2].getInt<int64_t>(); if (dummy && *dummy != 0) { @@ -528,7 +534,7 @@ static RPCHelpMan getprioritisedtransactions() if (delta_info.in_mempool) { result_inner.pushKV("modified_fee", *delta_info.modified_fee); } - rpc_result.pushKV(delta_info.txid.GetHex(), result_inner); + rpc_result.pushKV(delta_info.txid.GetHex(), std::move(result_inner)); } return rpc_result; }, @@ -659,13 +665,15 @@ static RPCHelpMan getblocktemplate() { NodeContext& node = EnsureAnyNodeContext(request.context); ChainstateManager& chainman = EnsureChainman(node); + Mining& miner = EnsureMining(node); LOCK(cs_main); + std::optional<uint256> maybe_tip{miner.getTipHash()}; + CHECK_NONFATAL(maybe_tip); + uint256 tip{maybe_tip.value()}; std::string strMode = "template"; UniValue lpval = NullUniValue; std::set<std::string> setClientRules; - Chainstate& active_chainstate = chainman.ActiveChainstate(); - CChain& active_chain = active_chainstate.m_chain; if (!request.params[0].isNull()) { const UniValue& oparam = request.params[0].get_obj(); @@ -700,12 +708,12 @@ static RPCHelpMan getblocktemplate() return "duplicate-inconclusive"; } - CBlockIndex* const pindexPrev = active_chain.Tip(); - // TestBlockValidity only supports blocks built on the current Tip - if (block.hashPrevBlock != pindexPrev->GetBlockHash()) + // testBlockValidity only supports blocks built on the current Tip + if (block.hashPrevBlock != tip) { return "inconclusive-not-best-prevblk"; + } BlockValidationState state; - TestBlockValidity(state, chainman.GetParams(), active_chainstate, block, pindexPrev, false, true); + miner.testBlockValidity(state, block); return BIP22ValidationResult(state); } @@ -721,19 +729,18 @@ static RPCHelpMan getblocktemplate() if (strMode != "template") throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode"); - if (!chainman.GetParams().IsTestChain()) { + if (!miner.isTestChain()) { const CConnman& connman = EnsureConnman(node); if (connman.GetNodeCount(ConnectionDirection::Both) == 0) { throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, PACKAGE_NAME " is not connected!"); } - if (chainman.IsInitialBlockDownload()) { + if (miner.isInitialBlockDownload()) { throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, PACKAGE_NAME " is in initial sync and waiting for blocks..."); } } static unsigned int nTransactionsUpdatedLast; - const CTxMemPool& mempool = EnsureMemPool(node); if (!lpval.isNull()) { @@ -753,7 +760,7 @@ static RPCHelpMan getblocktemplate() else { // NOTE: Spec does not specify behaviour for non-string longpollid, but this makes testing easier - hashWatchedChain = active_chain.Tip()->GetBlockHash(); + hashWatchedChain = tip; nTransactionsUpdatedLastLP = nTransactionsUpdatedLast; } @@ -769,7 +776,7 @@ static RPCHelpMan getblocktemplate() { // Timeout: Check transactions for update // without holding the mempool lock to avoid deadlocks - if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLastLP) + if (miner.getTransactionsUpdated() != nTransactionsUpdatedLastLP) break; checktxtime += std::chrono::seconds(10); } @@ -777,6 +784,10 @@ static RPCHelpMan getblocktemplate() } ENTER_CRITICAL_SECTION(cs_main); + std::optional<uint256> maybe_tip{miner.getTipHash()}; + CHECK_NONFATAL(maybe_tip); + tip = maybe_tip.value(); + if (!IsRPCRunning()) throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Shutting down"); // TODO: Maybe recheck connections/IBD and (if something wrong) send an expires-immediately template to stop miners? @@ -798,24 +809,25 @@ static RPCHelpMan getblocktemplate() static CBlockIndex* pindexPrev; static int64_t time_start; static std::unique_ptr<CBlockTemplate> pblocktemplate; - if (pindexPrev != active_chain.Tip() || - (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - time_start > 5)) + if (!pindexPrev || pindexPrev->GetBlockHash() != tip || + (miner.getTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - time_start > 5)) { // Clear pindexPrev so future calls make a new block, despite any failures from here on pindexPrev = nullptr; - // Store the pindexBest used before CreateNewBlock, to avoid races - nTransactionsUpdatedLast = mempool.GetTransactionsUpdated(); - CBlockIndex* pindexPrevNew = active_chain.Tip(); + // Store the pindexBest used before createNewBlock, to avoid races + nTransactionsUpdatedLast = miner.getTransactionsUpdated(); + CBlockIndex* pindexPrevNew = chainman.m_blockman.LookupBlockIndex(tip); time_start = GetTime(); // Create new block CScript scriptDummy = CScript() << OP_TRUE; - pblocktemplate = BlockAssembler{active_chainstate, &mempool}.CreateNewBlock(scriptDummy); - if (!pblocktemplate) + pblocktemplate = miner.createNewBlock(scriptDummy); + if (!pblocktemplate) { throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); + } - // Need to update only after we know CreateNewBlock succeeded + // Need to update only after we know createNewBlock succeeded pindexPrev = pindexPrevNew; } CHECK_NONFATAL(pindexPrev); @@ -853,7 +865,7 @@ static RPCHelpMan getblocktemplate() if (setTxIndex.count(in.prevout.hash)) deps.push_back(setTxIndex[in.prevout.hash]); } - entry.pushKV("depends", deps); + entry.pushKV("depends", std::move(deps)); int index_in_template = i - 1; entry.pushKV("fee", pblocktemplate->vTxFees[index_in_template]); @@ -865,7 +877,7 @@ static RPCHelpMan getblocktemplate() entry.pushKV("sigops", nTxSigOps); entry.pushKV("weight", GetTransactionWeight(tx)); - transactions.push_back(entry); + transactions.push_back(std::move(entry)); } UniValue aux(UniValue::VOBJ); @@ -878,7 +890,7 @@ static RPCHelpMan getblocktemplate() aMutable.push_back("prevblock"); UniValue result(UniValue::VOBJ); - result.pushKV("capabilities", aCaps); + result.pushKV("capabilities", std::move(aCaps)); UniValue aRules(UniValue::VARR); aRules.push_back("csv"); @@ -930,18 +942,18 @@ static RPCHelpMan getblocktemplate() } } result.pushKV("version", pblock->nVersion); - result.pushKV("rules", aRules); - result.pushKV("vbavailable", vbavailable); + result.pushKV("rules", std::move(aRules)); + result.pushKV("vbavailable", std::move(vbavailable)); result.pushKV("vbrequired", int(0)); result.pushKV("previousblockhash", pblock->hashPrevBlock.GetHex()); - result.pushKV("transactions", transactions); - result.pushKV("coinbaseaux", aux); + result.pushKV("transactions", std::move(transactions)); + result.pushKV("coinbaseaux", std::move(aux)); result.pushKV("coinbasevalue", (int64_t)pblock->vtx[0]->vout[0].nValue); - result.pushKV("longpollid", active_chain.Tip()->GetBlockHash().GetHex() + ToString(nTransactionsUpdatedLast)); + result.pushKV("longpollid", tip.GetHex() + ToString(nTransactionsUpdatedLast)); result.pushKV("target", hashTarget.GetHex()); result.pushKV("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1); - result.pushKV("mutable", aMutable); + result.pushKV("mutable", std::move(aMutable)); result.pushKV("noncerange", "00000000ffffffff"); int64_t nSigOpLimit = MAX_BLOCK_SIGOPS_COST; int64_t nSizeLimit = MAX_BLOCK_SERIALIZED_SIZE; @@ -1044,10 +1056,13 @@ static RPCHelpMan submitblock() } } + NodeContext& node = EnsureAnyNodeContext(request.context); + Mining& miner = EnsureMining(node); + bool new_block; auto sc = std::make_shared<submitblock_StateCatcher>(block.GetHash()); CHECK_NONFATAL(chainman.m_options.signals)->RegisterSharedValidationInterface(sc); - bool accepted = chainman.ProcessNewBlock(blockptr, /*force_processing=*/true, /*min_pow_checked=*/true, /*new_block=*/&new_block); + bool accepted = miner.processNewBlock(blockptr, /*new_block=*/&new_block); CHECK_NONFATAL(chainman.m_options.signals)->UnregisterSharedValidationInterface(sc); if (!new_block && accepted) { return "duplicate"; diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 04f9410b32..1119a3e668 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -16,6 +16,7 @@ #include <netbase.h> #include <node/context.h> #include <node/protocol_version.h> +#include <node/warnings.h> #include <policy/settings.h> #include <protocol.h> #include <rpc/blockchain.h> @@ -35,6 +36,8 @@ #include <univalue.h> using node::NodeContext; +using util::Join; +using util::TrimString; const std::vector<std::string> CONNECTION_TYPE_DOC{ "outbound-full-relay (default automatic connections)", @@ -263,7 +266,7 @@ static RPCHelpMan getpeerinfo() for (const int height : statestats.vHeightInFlight) { heights.push_back(height); } - obj.pushKV("inflight", heights); + obj.pushKV("inflight", std::move(heights)); obj.pushKV("addr_relay_enabled", statestats.m_addr_relay_enabled); obj.pushKV("addr_processed", statestats.m_addr_processed); obj.pushKV("addr_rate_limited", statestats.m_addr_rate_limited); @@ -271,7 +274,7 @@ static RPCHelpMan getpeerinfo() for (const auto& permission : NetPermissions::ToStrings(stats.m_permission_flags)) { permissions.push_back(permission); } - obj.pushKV("permissions", permissions); + obj.pushKV("permissions", std::move(permissions)); obj.pushKV("minfeefilter", ValueFromAmount(statestats.m_fee_filter_received)); UniValue sendPerMsgType(UniValue::VOBJ); @@ -279,19 +282,19 @@ static RPCHelpMan getpeerinfo() if (i.second > 0) sendPerMsgType.pushKV(i.first, i.second); } - obj.pushKV("bytessent_per_msg", sendPerMsgType); + obj.pushKV("bytessent_per_msg", std::move(sendPerMsgType)); UniValue recvPerMsgType(UniValue::VOBJ); for (const auto& i : stats.mapRecvBytesPerMsgType) { if (i.second > 0) recvPerMsgType.pushKV(i.first, i.second); } - obj.pushKV("bytesrecv_per_msg", recvPerMsgType); + obj.pushKV("bytesrecv_per_msg", std::move(recvPerMsgType)); obj.pushKV("connection_type", ConnectionTypeAsString(stats.m_conn_type)); obj.pushKV("transport_protocol_type", TransportTypeAsString(stats.m_transport_type)); obj.pushKV("session_id", stats.m_session_id); - ret.push_back(obj); + ret.push_back(std::move(obj)); } return ret; @@ -401,7 +404,7 @@ static RPCHelpMan addconnection() } else { throw JSONRPCError(RPC_INVALID_PARAMETER, self.ToString()); } - bool use_v2transport = self.Arg<bool>(2); + bool use_v2transport{self.Arg<bool>("v2transport")}; NodeContext& node = EnsureAnyNodeContext(request.context); CConnman& connman = EnsureConnman(node); @@ -532,10 +535,10 @@ static RPCHelpMan getaddednodeinfo() UniValue address(UniValue::VOBJ); address.pushKV("address", info.resolvedAddress.ToStringAddrPort()); address.pushKV("connected", info.fInbound ? "inbound" : "outbound"); - addresses.push_back(address); + addresses.push_back(std::move(address)); } - obj.pushKV("addresses", addresses); - ret.push_back(obj); + obj.pushKV("addresses", std::move(addresses)); + ret.push_back(std::move(obj)); } return ret; @@ -587,7 +590,7 @@ static RPCHelpMan getnettotals() outboundLimit.pushKV("serve_historical_blocks", !connman.OutboundTargetReached(true)); outboundLimit.pushKV("bytes_left_in_cycle", connman.GetOutboundTargetBytesLeft()); outboundLimit.pushKV("time_left_in_cycle", count_seconds(connman.GetMaxOutboundTimeLeftInCycle())); - obj.pushKV("uploadtarget", outboundLimit); + obj.pushKV("uploadtarget", std::move(outboundLimit)); return obj; }, }; @@ -607,7 +610,7 @@ static UniValue GetNetworksInfo() obj.pushKV("reachable", g_reachable_nets.Contains(network)); obj.pushKV("proxy", proxy.IsValid() ? proxy.ToString() : std::string()); obj.pushKV("proxy_randomize_credentials", proxy.m_randomize_credentials); - networks.push_back(obj); + networks.push_back(std::move(obj)); } return networks; } @@ -697,8 +700,8 @@ static RPCHelpMan getnetworkinfo() obj.pushKV("networks", GetNetworksInfo()); if (node.mempool) { // Those fields can be deprecated, to be replaced by the getmempoolinfo fields - obj.pushKV("relayfee", ValueFromAmount(node.mempool->m_min_relay_feerate.GetFeePerK())); - obj.pushKV("incrementalfee", ValueFromAmount(node.mempool->m_incremental_relay_feerate.GetFeePerK())); + obj.pushKV("relayfee", ValueFromAmount(node.mempool->m_opts.min_relay_feerate.GetFeePerK())); + obj.pushKV("incrementalfee", ValueFromAmount(node.mempool->m_opts.incremental_relay_feerate.GetFeePerK())); } UniValue localAddresses(UniValue::VARR); { @@ -709,11 +712,11 @@ static RPCHelpMan getnetworkinfo() rec.pushKV("address", item.first.ToStringAddr()); rec.pushKV("port", item.second.nPort); rec.pushKV("score", item.second.nScore); - localAddresses.push_back(rec); + localAddresses.push_back(std::move(rec)); } } - obj.pushKV("localaddresses", localAddresses); - obj.pushKV("warnings", GetNodeWarnings(IsDeprecatedRPCEnabled("warnings"))); + obj.pushKV("localaddresses", std::move(localAddresses)); + obj.pushKV("warnings", node::GetWarningsForRpc(*CHECK_NONFATAL(node.warnings), IsDeprecatedRPCEnabled("warnings"))); return obj; }, }; @@ -843,7 +846,7 @@ static RPCHelpMan listbanned() rec.pushKV("ban_duration", (banEntry.nBanUntil - banEntry.nCreateTime)); rec.pushKV("time_remaining", (banEntry.nBanUntil - current_time)); - bannedAddresses.push_back(rec); + bannedAddresses.push_back(std::move(rec)); } return bannedAddresses; @@ -947,7 +950,7 @@ static RPCHelpMan getnodeaddresses() obj.pushKV("address", addr.ToStringAddr()); obj.pushKV("port", addr.GetPort()); obj.pushKV("network", GetNetworkName(addr.GetNetClass())); - ret.push_back(obj); + ret.push_back(std::move(obj)); } return ret; }, @@ -1087,32 +1090,40 @@ static RPCHelpMan getaddrmaninfo() obj.pushKV("new", addrman.Size(network, true)); obj.pushKV("tried", addrman.Size(network, false)); obj.pushKV("total", addrman.Size(network)); - ret.pushKV(GetNetworkName(network), obj); + ret.pushKV(GetNetworkName(network), std::move(obj)); } UniValue obj(UniValue::VOBJ); obj.pushKV("new", addrman.Size(std::nullopt, true)); obj.pushKV("tried", addrman.Size(std::nullopt, false)); obj.pushKV("total", addrman.Size()); - ret.pushKV("all_networks", obj); + ret.pushKV("all_networks", std::move(obj)); return ret; }, }; } -UniValue AddrmanEntryToJSON(const AddrInfo& info) +UniValue AddrmanEntryToJSON(const AddrInfo& info, CConnman& connman) { UniValue ret(UniValue::VOBJ); ret.pushKV("address", info.ToStringAddr()); + const auto mapped_as{connman.GetMappedAS(info)}; + if (mapped_as != 0) { + ret.pushKV("mapped_as", mapped_as); + } ret.pushKV("port", info.GetPort()); ret.pushKV("services", (uint64_t)info.nServices); ret.pushKV("time", int64_t{TicksSinceEpoch<std::chrono::seconds>(info.nTime)}); ret.pushKV("network", GetNetworkName(info.GetNetClass())); ret.pushKV("source", info.source.ToStringAddr()); ret.pushKV("source_network", GetNetworkName(info.source.GetNetClass())); + const auto source_mapped_as{connman.GetMappedAS(info.source)}; + if (source_mapped_as != 0) { + ret.pushKV("source_mapped_as", source_mapped_as); + } return ret; } -UniValue AddrmanTableToJSON(const std::vector<std::pair<AddrInfo, AddressPosition>>& tableInfos) +UniValue AddrmanTableToJSON(const std::vector<std::pair<AddrInfo, AddressPosition>>& tableInfos, CConnman& connman) { UniValue table(UniValue::VOBJ); for (const auto& e : tableInfos) { @@ -1123,7 +1134,7 @@ UniValue AddrmanTableToJSON(const std::vector<std::pair<AddrInfo, AddressPositio // Address manager tables have unique entries so there is no advantage // in using UniValue::pushKV, which checks if the key already exists // in O(N). UniValue::pushKVEnd is used instead which currently is O(1). - table.pushKVEnd(key.str(), AddrmanEntryToJSON(info)); + table.pushKVEnd(key.str(), AddrmanEntryToJSON(info, connman)); } return table; } @@ -1139,12 +1150,14 @@ static RPCHelpMan getrawaddrman() {RPCResult::Type::OBJ_DYN, "table", "buckets with addresses in the address manager table ( new, tried )", { {RPCResult::Type::OBJ, "bucket/position", "the location in the address manager table (<bucket>/<position>)", { {RPCResult::Type::STR, "address", "The address of the node"}, + {RPCResult::Type::NUM, "mapped_as", /*optional=*/true, "The ASN mapped to the IP of this peer per our current ASMap"}, {RPCResult::Type::NUM, "port", "The port number of the node"}, {RPCResult::Type::STR, "network", "The network (" + Join(GetNetworkNames(), ", ") + ") of the address"}, {RPCResult::Type::NUM, "services", "The services offered by the node"}, {RPCResult::Type::NUM_TIME, "time", "The " + UNIX_EPOCH_TIME + " when the node was last seen"}, {RPCResult::Type::STR, "source", "The address that relayed the address to us"}, {RPCResult::Type::STR, "source_network", "The network (" + Join(GetNetworkNames(), ", ") + ") of the source address"}, + {RPCResult::Type::NUM, "source_mapped_as", /*optional=*/true, "The ASN mapped to the IP of this peer's source per our current ASMap"} }} }} } @@ -1155,10 +1168,12 @@ static RPCHelpMan getrawaddrman() }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { AddrMan& addrman = EnsureAnyAddrman(request.context); + NodeContext& node_context = EnsureAnyNodeContext(request.context); + CConnman& connman = EnsureConnman(node_context); UniValue ret(UniValue::VOBJ); - ret.pushKV("new", AddrmanTableToJSON(addrman.GetEntries(false))); - ret.pushKV("tried", AddrmanTableToJSON(addrman.GetEntries(true))); + ret.pushKV("new", AddrmanTableToJSON(addrman.GetEntries(false), connman)); + ret.pushKV("tried", AddrmanTableToJSON(addrman.GetEntries(true), connman)); return ret; }, }; diff --git a/src/rpc/node.cpp b/src/rpc/node.cpp index 447be2cf64..65b0a93cdd 100644 --- a/src/rpc/node.cpp +++ b/src/rpc/node.cpp @@ -351,7 +351,7 @@ static UniValue SummaryToJSON(const IndexSummary&& summary, std::string index_na UniValue entry(UniValue::VOBJ); entry.pushKV("synced", summary.synced); entry.pushKV("best_block_height", summary.best_block_height); - ret_summary.pushKV(summary.name, entry); + ret_summary.pushKV(summary.name, std::move(entry)); return ret_summary; } diff --git a/src/rpc/output_script.cpp b/src/rpc/output_script.cpp index f9343f48a8..65a9be2762 100644 --- a/src/rpc/output_script.cpp +++ b/src/rpc/output_script.cpp @@ -72,11 +72,11 @@ static RPCHelpMan validateaddress() ret.pushKV("scriptPubKey", HexStr(scriptPubKey)); UniValue detail = DescribeAddress(dest); - ret.pushKVs(detail); + ret.pushKVs(std::move(detail)); } else { UniValue error_indices(UniValue::VARR); for (int i : error_locations) error_indices.push_back(i); - ret.pushKV("error_locations", error_indices); + ret.pushKV("error_locations", std::move(error_indices)); ret.pushKV("error", error_msg); } @@ -124,11 +124,7 @@ static RPCHelpMan createmultisig() const UniValue& keys = request.params[1].get_array(); std::vector<CPubKey> pubkeys; for (unsigned int i = 0; i < keys.size(); ++i) { - if (IsHex(keys[i].get_str()) && (keys[i].get_str().length() == 66 || keys[i].get_str().length() == 130)) { - pubkeys.push_back(HexToPubKey(keys[i].get_str())); - } else { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Invalid public key: %s\n.", keys[i].get_str())); - } + pubkeys.push_back(HexToPubKey(keys[i].get_str())); } // Get the output type @@ -143,8 +139,7 @@ static RPCHelpMan createmultisig() output_type = parsed.value(); } - // Construct using pay-to-script-hash: - FillableSigningProvider keystore; + FlatSigningProvider keystore; CScript inner; const CTxDestination dest = AddAndGetMultisigDestination(required, pubkeys, output_type, keystore, inner); diff --git a/src/rpc/protocol.h b/src/rpc/protocol.h index 75e42e4c88..83a9010681 100644 --- a/src/rpc/protocol.h +++ b/src/rpc/protocol.h @@ -10,6 +10,7 @@ enum HTTPStatusCode { HTTP_OK = 200, + HTTP_NO_CONTENT = 204, HTTP_BAD_REQUEST = 400, HTTP_UNAUTHORIZED = 401, HTTP_FORBIDDEN = 403, diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 634be2f7fb..75b538061d 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -16,6 +16,7 @@ #include <node/context.h> #include <node/psbt.h> #include <node/transaction.h> +#include <node/types.h> #include <policy/packages.h> #include <policy/policy.h> #include <policy/rbf.h> @@ -618,7 +619,7 @@ static RPCHelpMan decodescript() } ScriptToUniv(segwitScr, /*out=*/sr, /*include_hex=*/true, /*include_address=*/true, /*provider=*/&provider); sr.pushKV("p2sh-segwit", EncodeDestination(ScriptHash(segwitScr))); - r.pushKV("segwit", sr); + r.pushKV("segwit", std::move(sr)); } } @@ -785,7 +786,7 @@ static RPCHelpMan signrawtransactionwithkey() throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed. Make sure the tx has at least one input."); } - FillableSigningProvider keystore; + FlatSigningProvider keystore; const UniValue& keys = request.params[1].get_array(); for (unsigned int idx = 0; idx < keys.size(); ++idx) { UniValue k = keys[idx]; @@ -793,7 +794,11 @@ static RPCHelpMan signrawtransactionwithkey() if (!key.IsValid()) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key"); } - keystore.AddKey(key); + + CPubKey pubkey = key.GetPubKey(); + CKeyID key_id = pubkey.GetID(); + keystore.pubkeys.emplace(key_id, pubkey); + keystore.keys.emplace(key_id, key); } // Fetch previous transactions (inputs): @@ -1069,7 +1074,7 @@ static RPCHelpMan decodepsbt() // Add the decoded tx UniValue tx_univ(UniValue::VOBJ); TxToUniv(CTransaction(*psbtx.tx), /*block_hash=*/uint256(), /*entry=*/tx_univ, /*include_hex=*/false); - result.pushKV("tx", tx_univ); + result.pushKV("tx", std::move(tx_univ)); // Add the global xpubs UniValue global_xpubs(UniValue::VARR); @@ -1083,10 +1088,10 @@ static RPCHelpMan decodepsbt() keypath.pushKV("xpub", EncodeBase58Check(ser_xpub)); keypath.pushKV("master_fingerprint", HexStr(Span<unsigned char>(xpub_pair.first.fingerprint, xpub_pair.first.fingerprint + 4))); keypath.pushKV("path", WriteHDKeypath(xpub_pair.first.path)); - global_xpubs.push_back(keypath); + global_xpubs.push_back(std::move(keypath)); } } - result.pushKV("global_xpubs", global_xpubs); + result.pushKV("global_xpubs", std::move(global_xpubs)); // PSBT version result.pushKV("psbt_version", static_cast<uint64_t>(psbtx.GetVersion())); @@ -1099,16 +1104,16 @@ static RPCHelpMan decodepsbt() this_prop.pushKV("subtype", entry.subtype); this_prop.pushKV("key", HexStr(entry.key)); this_prop.pushKV("value", HexStr(entry.value)); - proprietary.push_back(this_prop); + proprietary.push_back(std::move(this_prop)); } - result.pushKV("proprietary", proprietary); + result.pushKV("proprietary", std::move(proprietary)); // Unknown data UniValue unknowns(UniValue::VOBJ); for (auto entry : psbtx.unknown) { unknowns.pushKV(HexStr(entry.first), HexStr(entry.second)); } - result.pushKV("unknown", unknowns); + result.pushKV("unknown", std::move(unknowns)); // inputs CAmount total_in = 0; @@ -1128,9 +1133,9 @@ static RPCHelpMan decodepsbt() UniValue out(UniValue::VOBJ); out.pushKV("amount", ValueFromAmount(txout.nValue)); - out.pushKV("scriptPubKey", o); + out.pushKV("scriptPubKey", std::move(o)); - in.pushKV("witness_utxo", out); + in.pushKV("witness_utxo", std::move(out)); have_a_utxo = true; } @@ -1139,7 +1144,7 @@ static RPCHelpMan decodepsbt() UniValue non_wit(UniValue::VOBJ); TxToUniv(*input.non_witness_utxo, /*block_hash=*/uint256(), /*entry=*/non_wit, /*include_hex=*/false); - in.pushKV("non_witness_utxo", non_wit); + in.pushKV("non_witness_utxo", std::move(non_wit)); have_a_utxo = true; } @@ -1160,7 +1165,7 @@ static RPCHelpMan decodepsbt() for (const auto& sig : input.partial_sigs) { partial_sigs.pushKV(HexStr(sig.second.first), HexStr(sig.second.second)); } - in.pushKV("partial_signatures", partial_sigs); + in.pushKV("partial_signatures", std::move(partial_sigs)); } // Sighash @@ -1172,12 +1177,12 @@ static RPCHelpMan decodepsbt() if (!input.redeem_script.empty()) { UniValue r(UniValue::VOBJ); ScriptToUniv(input.redeem_script, /*out=*/r); - in.pushKV("redeem_script", r); + in.pushKV("redeem_script", std::move(r)); } if (!input.witness_script.empty()) { UniValue r(UniValue::VOBJ); ScriptToUniv(input.witness_script, /*out=*/r); - in.pushKV("witness_script", r); + in.pushKV("witness_script", std::move(r)); } // keypaths @@ -1189,9 +1194,9 @@ static RPCHelpMan decodepsbt() keypath.pushKV("master_fingerprint", strprintf("%08x", ReadBE32(entry.second.fingerprint))); keypath.pushKV("path", WriteHDKeypath(entry.second.path)); - keypaths.push_back(keypath); + keypaths.push_back(std::move(keypath)); } - in.pushKV("bip32_derivs", keypaths); + in.pushKV("bip32_derivs", std::move(keypaths)); } // Final scriptSig and scriptwitness @@ -1199,14 +1204,14 @@ static RPCHelpMan decodepsbt() UniValue scriptsig(UniValue::VOBJ); scriptsig.pushKV("asm", ScriptToAsmStr(input.final_script_sig, true)); scriptsig.pushKV("hex", HexStr(input.final_script_sig)); - in.pushKV("final_scriptSig", scriptsig); + in.pushKV("final_scriptSig", std::move(scriptsig)); } if (!input.final_script_witness.IsNull()) { UniValue txinwitness(UniValue::VARR); for (const auto& item : input.final_script_witness.stack) { txinwitness.push_back(HexStr(item)); } - in.pushKV("final_scriptwitness", txinwitness); + in.pushKV("final_scriptwitness", std::move(txinwitness)); } // Ripemd160 hash preimages @@ -1215,7 +1220,7 @@ static RPCHelpMan decodepsbt() for (const auto& [hash, preimage] : input.ripemd160_preimages) { ripemd160_preimages.pushKV(HexStr(hash), HexStr(preimage)); } - in.pushKV("ripemd160_preimages", ripemd160_preimages); + in.pushKV("ripemd160_preimages", std::move(ripemd160_preimages)); } // Sha256 hash preimages @@ -1224,7 +1229,7 @@ static RPCHelpMan decodepsbt() for (const auto& [hash, preimage] : input.sha256_preimages) { sha256_preimages.pushKV(HexStr(hash), HexStr(preimage)); } - in.pushKV("sha256_preimages", sha256_preimages); + in.pushKV("sha256_preimages", std::move(sha256_preimages)); } // Hash160 hash preimages @@ -1233,7 +1238,7 @@ static RPCHelpMan decodepsbt() for (const auto& [hash, preimage] : input.hash160_preimages) { hash160_preimages.pushKV(HexStr(hash), HexStr(preimage)); } - in.pushKV("hash160_preimages", hash160_preimages); + in.pushKV("hash160_preimages", std::move(hash160_preimages)); } // Hash256 hash preimages @@ -1242,7 +1247,7 @@ static RPCHelpMan decodepsbt() for (const auto& [hash, preimage] : input.hash256_preimages) { hash256_preimages.pushKV(HexStr(hash), HexStr(preimage)); } - in.pushKV("hash256_preimages", hash256_preimages); + in.pushKV("hash256_preimages", std::move(hash256_preimages)); } // Taproot key path signature @@ -1259,9 +1264,9 @@ static RPCHelpMan decodepsbt() sigobj.pushKV("pubkey", HexStr(xonly)); sigobj.pushKV("leaf_hash", HexStr(leaf_hash)); sigobj.pushKV("sig", HexStr(sig)); - script_sigs.push_back(sigobj); + script_sigs.push_back(std::move(sigobj)); } - in.pushKV("taproot_script_path_sigs", script_sigs); + in.pushKV("taproot_script_path_sigs", std::move(script_sigs)); } // Taproot leaf scripts @@ -1276,10 +1281,10 @@ static RPCHelpMan decodepsbt() for (const auto& control_block : control_blocks) { control_blocks_univ.push_back(HexStr(control_block)); } - script_info.pushKV("control_blocks", control_blocks_univ); - tap_scripts.push_back(script_info); + script_info.pushKV("control_blocks", std::move(control_blocks_univ)); + tap_scripts.push_back(std::move(script_info)); } - in.pushKV("taproot_scripts", tap_scripts); + in.pushKV("taproot_scripts", std::move(tap_scripts)); } // Taproot bip32 keypaths @@ -1295,10 +1300,10 @@ static RPCHelpMan decodepsbt() for (const auto& leaf_hash : leaf_hashes) { leaf_hashes_arr.push_back(HexStr(leaf_hash)); } - path_obj.pushKV("leaf_hashes", leaf_hashes_arr); - keypaths.push_back(path_obj); + path_obj.pushKV("leaf_hashes", std::move(leaf_hashes_arr)); + keypaths.push_back(std::move(path_obj)); } - in.pushKV("taproot_bip32_derivs", keypaths); + in.pushKV("taproot_bip32_derivs", std::move(keypaths)); } // Taproot internal key @@ -1320,9 +1325,9 @@ static RPCHelpMan decodepsbt() this_prop.pushKV("subtype", entry.subtype); this_prop.pushKV("key", HexStr(entry.key)); this_prop.pushKV("value", HexStr(entry.value)); - proprietary.push_back(this_prop); + proprietary.push_back(std::move(this_prop)); } - in.pushKV("proprietary", proprietary); + in.pushKV("proprietary", std::move(proprietary)); } // Unknown data @@ -1331,12 +1336,12 @@ static RPCHelpMan decodepsbt() for (auto entry : input.unknown) { unknowns.pushKV(HexStr(entry.first), HexStr(entry.second)); } - in.pushKV("unknown", unknowns); + in.pushKV("unknown", std::move(unknowns)); } - inputs.push_back(in); + inputs.push_back(std::move(in)); } - result.pushKV("inputs", inputs); + result.pushKV("inputs", std::move(inputs)); // outputs CAmount output_value = 0; @@ -1348,12 +1353,12 @@ static RPCHelpMan decodepsbt() if (!output.redeem_script.empty()) { UniValue r(UniValue::VOBJ); ScriptToUniv(output.redeem_script, /*out=*/r); - out.pushKV("redeem_script", r); + out.pushKV("redeem_script", std::move(r)); } if (!output.witness_script.empty()) { UniValue r(UniValue::VOBJ); ScriptToUniv(output.witness_script, /*out=*/r); - out.pushKV("witness_script", r); + out.pushKV("witness_script", std::move(r)); } // keypaths @@ -1364,9 +1369,9 @@ static RPCHelpMan decodepsbt() keypath.pushKV("pubkey", HexStr(entry.first)); keypath.pushKV("master_fingerprint", strprintf("%08x", ReadBE32(entry.second.fingerprint))); keypath.pushKV("path", WriteHDKeypath(entry.second.path)); - keypaths.push_back(keypath); + keypaths.push_back(std::move(keypath)); } - out.pushKV("bip32_derivs", keypaths); + out.pushKV("bip32_derivs", std::move(keypaths)); } // Taproot internal key @@ -1382,9 +1387,9 @@ static RPCHelpMan decodepsbt() elem.pushKV("depth", (int)depth); elem.pushKV("leaf_ver", (int)leaf_ver); elem.pushKV("script", HexStr(script)); - tree.push_back(elem); + tree.push_back(std::move(elem)); } - out.pushKV("taproot_tree", tree); + out.pushKV("taproot_tree", std::move(tree)); } // Taproot bip32 keypaths @@ -1400,10 +1405,10 @@ static RPCHelpMan decodepsbt() for (const auto& leaf_hash : leaf_hashes) { leaf_hashes_arr.push_back(HexStr(leaf_hash)); } - path_obj.pushKV("leaf_hashes", leaf_hashes_arr); - keypaths.push_back(path_obj); + path_obj.pushKV("leaf_hashes", std::move(leaf_hashes_arr)); + keypaths.push_back(std::move(path_obj)); } - out.pushKV("taproot_bip32_derivs", keypaths); + out.pushKV("taproot_bip32_derivs", std::move(keypaths)); } // Proprietary @@ -1415,9 +1420,9 @@ static RPCHelpMan decodepsbt() this_prop.pushKV("subtype", entry.subtype); this_prop.pushKV("key", HexStr(entry.key)); this_prop.pushKV("value", HexStr(entry.value)); - proprietary.push_back(this_prop); + proprietary.push_back(std::move(this_prop)); } - out.pushKV("proprietary", proprietary); + out.pushKV("proprietary", std::move(proprietary)); } // Unknown data @@ -1426,10 +1431,10 @@ static RPCHelpMan decodepsbt() for (auto entry : output.unknown) { unknowns.pushKV(HexStr(entry.first), HexStr(entry.second)); } - out.pushKV("unknown", unknowns); + out.pushKV("unknown", std::move(unknowns)); } - outputs.push_back(out); + outputs.push_back(std::move(out)); // Fee calculation if (MoneyRange(psbtx.tx->vout[i].nValue) && MoneyRange(output_value + psbtx.tx->vout[i].nValue)) { @@ -1439,7 +1444,7 @@ static RPCHelpMan decodepsbt() have_all_utxos = false; } } - result.pushKV("outputs", outputs); + result.pushKV("outputs", std::move(outputs)); if (have_all_utxos) { result.pushKV("fee", ValueFromAmount(total_in - output_value)); } @@ -1485,9 +1490,8 @@ static RPCHelpMan combinepsbt() } PartiallySignedTransaction merged_psbt; - const TransactionError error = CombinePSBTs(merged_psbt, psbtxs); - if (error != TransactionError::OK) { - throw JSONRPCTransactionError(error); + if (!CombinePSBTs(merged_psbt, psbtxs)) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "PSBTs not compatible (different transactions)"); } DataStream ssTx{}; @@ -1744,8 +1748,8 @@ static RPCHelpMan joinpsbts() } psbtxs.push_back(psbtx); // Choose the highest version number - if (static_cast<uint32_t>(psbtx.tx->nVersion) > best_version) { - best_version = static_cast<uint32_t>(psbtx.tx->nVersion); + if (psbtx.tx->version > best_version) { + best_version = psbtx.tx->version; } // Choose the lowest lock time if (psbtx.tx->nLockTime < best_locktime) { @@ -1756,7 +1760,7 @@ static RPCHelpMan joinpsbts() // Create a blank psbt where everything will be added PartiallySignedTransaction merged_psbt; merged_psbt.tx = CMutableTransaction(); - merged_psbt.tx->nVersion = static_cast<int32_t>(best_version); + merged_psbt.tx->version = best_version; merged_psbt.tx->nLockTime = best_locktime; // Merge @@ -1791,7 +1795,7 @@ static RPCHelpMan joinpsbts() PartiallySignedTransaction shuffled_psbt; shuffled_psbt.tx = CMutableTransaction(); - shuffled_psbt.tx->nVersion = merged_psbt.tx->nVersion; + shuffled_psbt.tx->version = merged_psbt.tx->version; shuffled_psbt.tx->nLockTime = merged_psbt.tx->nLockTime; for (int i : input_indices) { shuffled_psbt.AddInput(merged_psbt.tx->vin[i], merged_psbt.inputs[i]); @@ -1876,7 +1880,7 @@ static RPCHelpMan analyzepsbt() for (const CKeyID& pubkey : input.missing_pubkeys) { missing_pubkeys_univ.push_back(HexStr(pubkey)); } - missing.pushKV("pubkeys", missing_pubkeys_univ); + missing.pushKV("pubkeys", std::move(missing_pubkeys_univ)); } if (!input.missing_redeem_script.IsNull()) { missing.pushKV("redeemscript", HexStr(input.missing_redeem_script)); @@ -1889,14 +1893,14 @@ static RPCHelpMan analyzepsbt() for (const CKeyID& pubkey : input.missing_sigs) { missing_sigs_univ.push_back(HexStr(pubkey)); } - missing.pushKV("signatures", missing_sigs_univ); + missing.pushKV("signatures", std::move(missing_sigs_univ)); } if (!missing.getKeys().empty()) { - input_univ.pushKV("missing", missing); + input_univ.pushKV("missing", std::move(missing)); } - inputs_result.push_back(input_univ); + inputs_result.push_back(std::move(input_univ)); } - if (!inputs_result.empty()) result.pushKV("inputs", inputs_result); + if (!inputs_result.empty()) result.pushKV("inputs", std::move(inputs_result)); if (psbta.estimated_vsize != std::nullopt) { result.pushKV("estimated_vsize", (int)*psbta.estimated_vsize); diff --git a/src/rpc/rawtransaction_util.cpp b/src/rpc/rawtransaction_util.cpp index a9e11622a7..53f943bb9e 100644 --- a/src/rpc/rawtransaction_util.cpp +++ b/src/rpc/rawtransaction_util.cpp @@ -174,14 +174,14 @@ static void TxInErrorToJSON(const CTxIn& txin, UniValue& vErrorsRet, const std:: for (unsigned int i = 0; i < txin.scriptWitness.stack.size(); i++) { witness.push_back(HexStr(txin.scriptWitness.stack[i])); } - entry.pushKV("witness", witness); + entry.pushKV("witness", std::move(witness)); entry.pushKV("scriptSig", HexStr(txin.scriptSig)); entry.pushKV("sequence", (uint64_t)txin.nSequence); entry.pushKV("error", strMessage); - vErrorsRet.push_back(entry); + vErrorsRet.push_back(std::move(entry)); } -void ParsePrevouts(const UniValue& prevTxsUnival, FillableSigningProvider* keystore, std::map<COutPoint, Coin>& coins) +void ParsePrevouts(const UniValue& prevTxsUnival, FlatSigningProvider* keystore, std::map<COutPoint, Coin>& coins) { if (!prevTxsUnival.isNull()) { const UniValue& prevTxs = prevTxsUnival.get_array(); @@ -247,11 +247,11 @@ void ParsePrevouts(const UniValue& prevTxsUnival, FillableSigningProvider* keyst // work from witnessScript when possible std::vector<unsigned char> scriptData(!ws.isNull() ? ParseHexV(ws, "witnessScript") : ParseHexV(rs, "redeemScript")); CScript script(scriptData.begin(), scriptData.end()); - keystore->AddCScript(script); + keystore->scripts.emplace(CScriptID(script), script); // Automatically also add the P2WSH wrapped version of the script (to deal with P2SH-P2WSH). // This is done for redeemScript only for compatibility, it is encouraged to use the explicit witnessScript field instead. CScript witness_output_script{GetScriptForDestination(WitnessV0ScriptHash(script))}; - keystore->AddCScript(witness_output_script); + keystore->scripts.emplace(CScriptID(witness_output_script), witness_output_script); if (!ws.isNull() && !rs.isNull()) { // if both witnessScript and redeemScript are provided, @@ -331,6 +331,6 @@ void SignTransactionResultToJSON(CMutableTransaction& mtx, bool complete, const if (result.exists("errors")) { vErrors.push_backV(result["errors"].getValues()); } - result.pushKV("errors", vErrors); + result.pushKV("errors", std::move(vErrors)); } } diff --git a/src/rpc/rawtransaction_util.h b/src/rpc/rawtransaction_util.h index 964d0b095b..40d6bbba87 100644 --- a/src/rpc/rawtransaction_util.h +++ b/src/rpc/rawtransaction_util.h @@ -12,7 +12,7 @@ #include <optional> struct bilingual_str; -class FillableSigningProvider; +struct FlatSigningProvider; class UniValue; struct CMutableTransaction; class Coin; @@ -38,7 +38,7 @@ void SignTransactionResultToJSON(CMutableTransaction& mtx, bool complete, const * @param keystore A pointer to the temporary keystore if there is one * @param coins Map of unspent outputs - coins in mempool and current chain UTXO set, may be extended by previous txns outputs after call */ -void ParsePrevouts(const UniValue& prevTxsUnival, FillableSigningProvider* keystore, std::map<COutPoint, Coin>& coins); +void ParsePrevouts(const UniValue& prevTxsUnival, FlatSigningProvider* keystore, std::map<COutPoint, Coin>& coins); /** Normalize univalue-represented inputs and add them to the transaction */ void AddInputs(CMutableTransaction& rawTx, const UniValue& inputs_in, bool rbf); diff --git a/src/rpc/request.cpp b/src/rpc/request.cpp index eae7c4ba18..083d1be44f 100644 --- a/src/rpc/request.cpp +++ b/src/rpc/request.cpp @@ -25,6 +25,17 @@ * * 1.0 spec: http://json-rpc.org/wiki/specification * 1.2 spec: http://jsonrpc.org/historical/json-rpc-over-http.html + * + * If the server receives a request with the JSON-RPC 2.0 marker `{"jsonrpc": "2.0"}` + * then Bitcoin will respond with a strictly specified response. + * It will only return an HTTP error code if an actual HTTP error is encountered + * such as the endpoint is not found (404) or the request is not formatted correctly (500). + * Otherwise the HTTP code is always OK (200) and RPC errors will be included in the + * response body. + * + * 2.0 spec: https://www.jsonrpc.org/specification + * + * Also see http://www.simple-is-better.org/rpc/#differences-between-1-0-and-2-0 */ UniValue JSONRPCRequestObj(const std::string& strMethod, const UniValue& params, const UniValue& id) @@ -33,27 +44,29 @@ UniValue JSONRPCRequestObj(const std::string& strMethod, const UniValue& params, request.pushKV("method", strMethod); request.pushKV("params", params); request.pushKV("id", id); + request.pushKV("jsonrpc", "2.0"); return request; } -UniValue JSONRPCReplyObj(const UniValue& result, const UniValue& error, const UniValue& id) +UniValue JSONRPCReplyObj(UniValue result, UniValue error, std::optional<UniValue> id, JSONRPCVersion jsonrpc_version) { UniValue reply(UniValue::VOBJ); - if (!error.isNull()) - reply.pushKV("result", NullUniValue); - else - reply.pushKV("result", result); - reply.pushKV("error", error); - reply.pushKV("id", id); + // Add JSON-RPC version number field in v2 only. + if (jsonrpc_version == JSONRPCVersion::V2) reply.pushKV("jsonrpc", "2.0"); + + // Add both result and error fields in v1, even though one will be null. + // Omit the null field in v2. + if (error.isNull()) { + reply.pushKV("result", std::move(result)); + if (jsonrpc_version == JSONRPCVersion::V1_LEGACY) reply.pushKV("error", NullUniValue); + } else { + if (jsonrpc_version == JSONRPCVersion::V1_LEGACY) reply.pushKV("result", NullUniValue); + reply.pushKV("error", std::move(error)); + } + if (id.has_value()) reply.pushKV("id", std::move(id.value())); return reply; } -std::string JSONRPCReply(const UniValue& result, const UniValue& error, const UniValue& id) -{ - UniValue reply = JSONRPCReplyObj(result, error, id); - return reply.write() + "\n"; -} - UniValue JSONRPCError(int code, const std::string& message) { UniValue error(UniValue::VOBJ); @@ -180,7 +193,30 @@ void JSONRPCRequest::parse(const UniValue& valRequest) const UniValue& request = valRequest.get_obj(); // Parse id now so errors from here on will have the id - id = request.find_value("id"); + if (request.exists("id")) { + id = request.find_value("id"); + } else { + id = std::nullopt; + } + + // Check for JSON-RPC 2.0 (default 1.1) + m_json_version = JSONRPCVersion::V1_LEGACY; + const UniValue& jsonrpc_version = request.find_value("jsonrpc"); + if (!jsonrpc_version.isNull()) { + if (!jsonrpc_version.isStr()) { + throw JSONRPCError(RPC_INVALID_REQUEST, "jsonrpc field must be a string"); + } + // The "jsonrpc" key was added in the 2.0 spec, but some older documentation + // incorrectly included {"jsonrpc":"1.0"} in a request object, so we + // maintain that for backwards compatibility. + if (jsonrpc_version.get_str() == "1.0") { + m_json_version = JSONRPCVersion::V1_LEGACY; + } else if (jsonrpc_version.get_str() == "2.0") { + m_json_version = JSONRPCVersion::V2; + } else { + throw JSONRPCError(RPC_INVALID_REQUEST, "JSON-RPC version not supported"); + } + } // Parse method const UniValue& valMethod{request.find_value("method")}; diff --git a/src/rpc/request.h b/src/rpc/request.h index c7e723d962..24887e8691 100644 --- a/src/rpc/request.h +++ b/src/rpc/request.h @@ -13,9 +13,14 @@ #include <univalue.h> #include <util/fs.h> +enum class JSONRPCVersion { + V1_LEGACY, + V2 +}; + +/** JSON-RPC 2.0 request, only used in bitcoin-cli **/ UniValue JSONRPCRequestObj(const std::string& strMethod, const UniValue& params, const UniValue& id); -UniValue JSONRPCReplyObj(const UniValue& result, const UniValue& error, const UniValue& id); -std::string JSONRPCReply(const UniValue& result, const UniValue& error, const UniValue& id); +UniValue JSONRPCReplyObj(UniValue result, UniValue error, std::optional<UniValue> id, JSONRPCVersion jsonrpc_version); UniValue JSONRPCError(int code, const std::string& message); /** Generate a new RPC authentication cookie and write it to disk */ @@ -30,7 +35,7 @@ std::vector<UniValue> JSONRPCProcessBatchReply(const UniValue& in); class JSONRPCRequest { public: - UniValue id; + std::optional<UniValue> id = UniValue::VNULL; std::string strMethod; UniValue params; enum Mode { EXECUTE, GET_HELP, GET_ARGS } mode = EXECUTE; @@ -38,8 +43,10 @@ public: std::string authUser; std::string peerAddr; std::any context; + JSONRPCVersion m_json_version = JSONRPCVersion::V1_LEGACY; void parse(const UniValue& valRequest); + [[nodiscard]] bool IsNotification() const { return !id.has_value() && m_json_version == JSONRPCVersion::V2; }; }; #endif // BITCOIN_RPC_REQUEST_H diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index a800451f4a..19063fa5be 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -27,6 +27,8 @@ #include <mutex> #include <unordered_map> +using util::SplitString; + static GlobalMutex g_rpc_warmup_mutex; static std::atomic<bool> g_rpc_running{false}; static bool fRPCInWarmup GUARDED_BY(g_rpc_warmup_mutex) = true; @@ -241,15 +243,15 @@ static RPCHelpMan getrpcinfo() UniValue entry(UniValue::VOBJ); entry.pushKV("method", info.method); entry.pushKV("duration", int64_t{Ticks<std::chrono::microseconds>(SteadyClock::now() - info.start)}); - active_commands.push_back(entry); + active_commands.push_back(std::move(entry)); } UniValue result(UniValue::VOBJ); - result.pushKV("active_commands", active_commands); + result.pushKV("active_commands", std::move(active_commands)); const std::string path = LogInstance().m_file_path.utf8string(); UniValue log_path(UniValue::VSTR, path); - result.pushKV("logpath", log_path); + result.pushKV("logpath", std::move(log_path)); return result; } @@ -360,36 +362,22 @@ bool IsDeprecatedRPCEnabled(const std::string& method) return find(enabled_methods.begin(), enabled_methods.end(), method) != enabled_methods.end(); } -static UniValue JSONRPCExecOne(JSONRPCRequest jreq, const UniValue& req) +UniValue JSONRPCExec(const JSONRPCRequest& jreq, bool catch_errors) { - UniValue rpc_result(UniValue::VOBJ); - - try { - jreq.parse(req); - - UniValue result = tableRPC.execute(jreq); - rpc_result = JSONRPCReplyObj(result, NullUniValue, jreq.id); - } - catch (const UniValue& objError) - { - rpc_result = JSONRPCReplyObj(NullUniValue, objError, jreq.id); - } - catch (const std::exception& e) - { - rpc_result = JSONRPCReplyObj(NullUniValue, - JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id); + UniValue result; + if (catch_errors) { + try { + result = tableRPC.execute(jreq); + } catch (UniValue& e) { + return JSONRPCReplyObj(NullUniValue, std::move(e), jreq.id, jreq.m_json_version); + } catch (const std::exception& e) { + return JSONRPCReplyObj(NullUniValue, JSONRPCError(RPC_MISC_ERROR, e.what()), jreq.id, jreq.m_json_version); + } + } else { + result = tableRPC.execute(jreq); } - return rpc_result; -} - -std::string JSONRPCExecBatch(const JSONRPCRequest& jreq, const UniValue& vReq) -{ - UniValue ret(UniValue::VARR); - for (unsigned int reqIdx = 0; reqIdx < vReq.size(); reqIdx++) - ret.push_back(JSONRPCExecOne(jreq, vReq[reqIdx])); - - return ret.write() + "\n"; + return JSONRPCReplyObj(std::move(result), NullUniValue, jreq.id, jreq.m_json_version); } /** diff --git a/src/rpc/server.h b/src/rpc/server.h index b8348e4aa6..5735aff821 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -179,6 +179,6 @@ extern CRPCTable tableRPC; void StartRPC(); void InterruptRPC(); void StopRPC(); -std::string JSONRPCExecBatch(const JSONRPCRequest& jreq, const UniValue& vReq); +UniValue JSONRPCExec(const JSONRPCRequest& jreq, bool catch_errors); #endif // BITCOIN_RPC_SERVER_H diff --git a/src/rpc/server_util.cpp b/src/rpc/server_util.cpp index efd4a43c28..0387cbb8e2 100644 --- a/src/rpc/server_util.cpp +++ b/src/rpc/server_util.cpp @@ -101,6 +101,14 @@ CConnman& EnsureConnman(const NodeContext& node) return *node.connman; } +interfaces::Mining& EnsureMining(const NodeContext& node) +{ + if (!node.mining) { + throw JSONRPCError(RPC_INTERNAL_ERROR, "Node miner not found"); + } + return *node.mining; +} + PeerManager& EnsurePeerman(const NodeContext& node) { if (!node.peerman) { diff --git a/src/rpc/server_util.h b/src/rpc/server_util.h index a4a53166b4..1e6fb7e6a6 100644 --- a/src/rpc/server_util.h +++ b/src/rpc/server_util.h @@ -18,6 +18,9 @@ class BanMan; namespace node { struct NodeContext; } // namespace node +namespace interfaces { +class Mining; +} // namespace interfaces node::NodeContext& EnsureAnyNodeContext(const std::any& context); CTxMemPool& EnsureMemPool(const node::NodeContext& node); @@ -31,6 +34,7 @@ ChainstateManager& EnsureAnyChainman(const std::any& context); CBlockPolicyEstimator& EnsureFeeEstimator(const node::NodeContext& node); CBlockPolicyEstimator& EnsureAnyFeeEstimator(const std::any& context); CConnman& EnsureConnman(const node::NodeContext& node); +interfaces::Mining& EnsureMining(const node::NodeContext& node); PeerManager& EnsurePeerman(const node::NodeContext& node); AddrMan& EnsureAddrman(const node::NodeContext& node); AddrMan& EnsureAnyAddrman(const std::any& context); diff --git a/src/rpc/signmessage.cpp b/src/rpc/signmessage.cpp index 9f3c24efcf..83462738c5 100644 --- a/src/rpc/signmessage.cpp +++ b/src/rpc/signmessage.cpp @@ -3,6 +3,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <common/signmessage.h> #include <key.h> #include <key_io.h> #include <rpc/protocol.h> @@ -10,7 +11,6 @@ #include <rpc/server.h> #include <rpc/util.h> #include <univalue.h> -#include <util/message.h> #include <string> diff --git a/src/rpc/util.cpp b/src/rpc/util.cpp index 22ec4e6967..4df4466c49 100644 --- a/src/rpc/util.cpp +++ b/src/rpc/util.cpp @@ -5,14 +5,17 @@ #include <config/bitcoin-config.h> // IWYU pragma: keep #include <clientversion.h> -#include <core_io.h> #include <common/args.h> +#include <common/messages.h> +#include <common/types.h> #include <consensus/amount.h> -#include <script/interpreter.h> +#include <core_io.h> #include <key_io.h> +#include <node/types.h> #include <outputtype.h> #include <rpc/util.h> #include <script/descriptor.h> +#include <script/interpreter.h> #include <script/signingprovider.h> #include <script/solver.h> #include <tinyformat.h> @@ -22,7 +25,6 @@ #include <util/strencodings.h> #include <util/string.h> #include <util/translation.h> -#include <warnings.h> #include <algorithm> #include <iterator> @@ -30,6 +32,14 @@ #include <tuple> #include <utility> +using common::PSBTError; +using common::PSBTErrorString; +using common::TransactionErrorString; +using node::TransactionError; +using util::Join; +using util::SplitString; +using util::TrimString; + const std::string UNIX_EPOCH_TIME = "UNIX epoch time"; const std::string EXAMPLE_ADDRESS[2] = {"bc1q09vm5lfy0j5reeulh4x5752q25uqqvz34hufdl", "bc1q02ad21edsxd23d32dfgqqsz4vv4nmtfzuklhy3"}; @@ -175,8 +185,8 @@ std::string HelpExampleCliNamed(const std::string& methodname, const RPCArgList& std::string HelpExampleRpc(const std::string& methodname, const std::string& args) { - return "> curl --user myusername --data-binary '{\"jsonrpc\": \"1.0\", \"id\": \"curltest\", " - "\"method\": \"" + methodname + "\", \"params\": [" + args + "]}' -H 'content-type: text/plain;' http://127.0.0.1:8332/\n"; + return "> curl --user myusername --data-binary '{\"jsonrpc\": \"2.0\", \"id\": \"curltest\", " + "\"method\": \"" + methodname + "\", \"params\": [" + args + "]}' -H 'content-type: application/json' http://127.0.0.1:8332/\n"; } std::string HelpExampleRpcNamed(const std::string& methodname, const RPCArgList& args) @@ -186,19 +196,22 @@ std::string HelpExampleRpcNamed(const std::string& methodname, const RPCArgList& params.pushKV(param.first, param.second); } - return "> curl --user myusername --data-binary '{\"jsonrpc\": \"1.0\", \"id\": \"curltest\", " - "\"method\": \"" + methodname + "\", \"params\": " + params.write() + "}' -H 'content-type: text/plain;' http://127.0.0.1:8332/\n"; + return "> curl --user myusername --data-binary '{\"jsonrpc\": \"2.0\", \"id\": \"curltest\", " + "\"method\": \"" + methodname + "\", \"params\": " + params.write() + "}' -H 'content-type: application/json' http://127.0.0.1:8332/\n"; } // Converts a hex string to a public key if possible CPubKey HexToPubKey(const std::string& hex_in) { if (!IsHex(hex_in)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid public key: " + hex_in); + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey \"" + hex_in + "\" must be a hex string"); + } + if (hex_in.length() != 66 && hex_in.length() != 130) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey \"" + hex_in + "\" must have a length of either 33 or 65 bytes"); } CPubKey vchPubKey(ParseHex(hex_in)); if (!vchPubKey.IsFullyValid()) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid public key: " + hex_in); + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey \"" + hex_in + "\" must be cryptographically valid."); } return vchPubKey; } @@ -225,7 +238,7 @@ CPubKey AddrToPubKey(const FillableSigningProvider& keystore, const std::string& } // Creates a multisig address from a given list of public keys, number of signatures required, and the address type -CTxDestination AddAndGetMultisigDestination(const int required, const std::vector<CPubKey>& pubkeys, OutputType type, FillableSigningProvider& keystore, CScript& script_out) +CTxDestination AddAndGetMultisigDestination(const int required, const std::vector<CPubKey>& pubkeys, OutputType type, FlatSigningProvider& keystore, CScript& script_out) { // Gather public keys if (required < 1) { @@ -361,6 +374,18 @@ unsigned int ParseConfirmTarget(const UniValue& value, unsigned int max_target) return unsigned_target; } +RPCErrorCode RPCErrorFromPSBTError(PSBTError err) +{ + switch (err) { + case PSBTError::UNSUPPORTED: + return RPC_INVALID_PARAMETER; + case PSBTError::SIGHASH_MISMATCH: + return RPC_DESERIALIZATION_ERROR; + default: break; + } + return RPC_TRANSACTION_ERROR; +} + RPCErrorCode RPCErrorFromTransactionError(TransactionError terr) { switch (terr) { @@ -368,18 +393,16 @@ RPCErrorCode RPCErrorFromTransactionError(TransactionError terr) return RPC_TRANSACTION_REJECTED; case TransactionError::ALREADY_IN_CHAIN: return RPC_TRANSACTION_ALREADY_IN_CHAIN; - case TransactionError::P2P_DISABLED: - return RPC_CLIENT_P2P_DISABLED; - case TransactionError::INVALID_PSBT: - case TransactionError::PSBT_MISMATCH: - return RPC_INVALID_PARAMETER; - case TransactionError::SIGHASH_MISMATCH: - return RPC_DESERIALIZATION_ERROR; default: break; } return RPC_TRANSACTION_ERROR; } +UniValue JSONRPCPSBTError(PSBTError err) +{ + return JSONRPCError(RPCErrorFromPSBTError(err), PSBTErrorString(err).original); +} + UniValue JSONRPCTransactionError(TransactionError terr, const std::string& err_string) { if (err_string.length() > 0) { @@ -642,7 +665,7 @@ UniValue RPCHelpMan::HandleRequest(const JSONRPCRequest& request) const mismatch.setNull(); break; } - mismatch.push_back(match); + mismatch.push_back(std::move(match)); } if (!mismatch.isNull()) { std::string explain{ @@ -674,7 +697,7 @@ static const UniValue* DetailMaybeArg(CheckFn* check, const std::vector<RPCArg>& static void CheckRequiredOrDefault(const RPCArg& param) { - // Must use `Arg<Type>(i)` to get the argument or its default value. + // Must use `Arg<Type>(key)` to get the argument or its default value. const bool required{ std::holds_alternative<RPCArg::Optional>(param.m_fallback) && RPCArg::Optional::NO == std::get<RPCArg::Optional>(param.m_fallback), }; @@ -775,7 +798,7 @@ std::string RPCHelpMan::ToString() const if (arg.m_opts.hidden) break; // Any arg that follows is also hidden // Push named argument name and description - sections.m_sections.emplace_back(::ToString(i + 1) + ". " + arg.GetFirstName(), arg.ToDescriptionString(/*is_named_arg=*/true)); + sections.m_sections.emplace_back(util::ToString(i + 1) + ". " + arg.GetFirstName(), arg.ToDescriptionString(/*is_named_arg=*/true)); sections.m_max_pad = std::max(sections.m_max_pad, sections.m_sections.back().m_left.size()); // Recursively push nested args @@ -815,7 +838,7 @@ UniValue RPCHelpMan::GetArgMap() const map.push_back(arg_name); map.push_back(type == RPCArg::Type::STR || type == RPCArg::Type::STR_HEX); - arr.push_back(map); + arr.push_back(std::move(map)); }; for (int i{0}; i < int(m_args.size()); ++i) { @@ -1121,7 +1144,7 @@ UniValue RPCResult::MatchesType(const UniValue& result) const // If there are more results than documented, reuse the last doc_inner. const RPCResult& doc_inner{m_inner.at(std::min(m_inner.size() - 1, i))}; UniValue match{doc_inner.MatchesType(result.get_array()[i])}; - if (!match.isTrue()) errors.pushKV(strprintf("%d", i), match); + if (!match.isTrue()) errors.pushKV(strprintf("%d", i), std::move(match)); } if (errors.empty()) return true; // empty result array is valid return errors; @@ -1134,7 +1157,7 @@ UniValue RPCResult::MatchesType(const UniValue& result) const const RPCResult& doc_inner{m_inner.at(0)}; // Assume all types are the same, randomly pick the first for (size_t i{0}; i < result.get_obj().size(); ++i) { UniValue match{doc_inner.MatchesType(result.get_obj()[i])}; - if (!match.isTrue()) errors.pushKV(result.getKeys()[i], match); + if (!match.isTrue()) errors.pushKV(result.getKeys()[i], std::move(match)); } if (errors.empty()) return true; // empty result obj is valid return errors; @@ -1160,7 +1183,7 @@ UniValue RPCResult::MatchesType(const UniValue& result) const continue; } UniValue match{doc_entry.MatchesType(result_it->second)}; - if (!match.isTrue()) errors.pushKV(doc_entry.m_key_name, match); + if (!match.isTrue()) errors.pushKV(doc_entry.m_key_name, std::move(match)); } if (errors.empty()) return true; return errors; @@ -1358,17 +1381,3 @@ void PushWarnings(const std::vector<bilingual_str>& warnings, UniValue& obj) if (warnings.empty()) return; obj.pushKV("warnings", BilingualStringsToUniValue(warnings)); } - -UniValue GetNodeWarnings(bool use_deprecated) -{ - if (use_deprecated) { - const auto all_warnings{GetWarnings()}; - return all_warnings.empty() ? "" : all_warnings.back().original; - } - - UniValue warnings{UniValue::VARR}; - for (auto&& warning : GetWarnings()) { - warnings.push_back(std::move(warning.original)); - } - return warnings; -} diff --git a/src/rpc/util.h b/src/rpc/util.h index 0e4dcc27b5..23024376e0 100644 --- a/src/rpc/util.h +++ b/src/rpc/util.h @@ -34,9 +34,14 @@ class JSONRPCRequest; enum ServiceFlags : uint64_t; enum class OutputType; -enum class TransactionError; struct FlatSigningProvider; struct bilingual_str; +namespace common { +enum class PSBTError; +} // namespace common +namespace node { +enum class TransactionError; +} // namespace node static constexpr bool DEFAULT_RPC_DOC_CHECK{ #ifdef RPC_DOC_CHECK @@ -117,7 +122,7 @@ std::string HelpExampleRpcNamed(const std::string& methodname, const RPCArgList& CPubKey HexToPubKey(const std::string& hex_in); CPubKey AddrToPubKey(const FillableSigningProvider& keystore, const std::string& addr_in); -CTxDestination AddAndGetMultisigDestination(const int required, const std::vector<CPubKey>& pubkeys, OutputType type, FillableSigningProvider& keystore, CScript& script_out); +CTxDestination AddAndGetMultisigDestination(const int required, const std::vector<CPubKey>& pubkeys, OutputType type, FlatSigningProvider& keystore, CScript& script_out); UniValue DescribeAddress(const CTxDestination& dest); @@ -127,8 +132,9 @@ int ParseSighashString(const UniValue& sighash); //! Parse a confirm target option and raise an RPC error if it is invalid. unsigned int ParseConfirmTarget(const UniValue& value, unsigned int max_target); -RPCErrorCode RPCErrorFromTransactionError(TransactionError terr); -UniValue JSONRPCTransactionError(TransactionError terr, const std::string& err_string = ""); +RPCErrorCode RPCErrorFromTransactionError(node::TransactionError terr); +UniValue JSONRPCPSBTError(common::PSBTError err); +UniValue JSONRPCTransactionError(node::TransactionError terr, const std::string& err_string = ""); //! Parse a JSON range specified as int64, or [int64, int64] std::pair<int64_t, int64_t> ParseDescriptorRange(const UniValue& value); @@ -414,19 +420,16 @@ public: * argument isNull() and parses (from JSON) and returns the user-passed argument, * or the default value derived from the RPCArg documentation. * - * There are two overloads of this function: - * - Use Arg<Type>(size_t i) to get the argument (or the default value) by index. - * - Use Arg<Type>(const std::string& key) to get the argument (or the default value) by key. - * - * The Type passed to this helper must match the corresponding RPCArg::Type. + * The instantiation of this helper for type R must match the corresponding RPCArg::Type. * - * @return The value of the RPC argument (or the default value) cast to type Type. + * @return The value of the RPC argument (or the default value) cast to type R. * * @see MaybeArg for handling optional arguments without default values. */ template <typename R> - auto Arg(size_t i) const + auto Arg(std::string_view key) const { + auto i{GetParamIndex(key)}; // Return argument (required or with default value). if constexpr (std::is_integral_v<R> || std::is_floating_point_v<R>) { // Return numbers by value. @@ -436,11 +439,6 @@ public: return ArgValue<const R&>(i); } } - template<typename R> - auto Arg(std::string_view key) const - { - return Arg<R>(GetParamIndex(key)); - } /** * @brief Helper to get an optional request argument. * @@ -452,21 +450,18 @@ public: * argument isNull() and parses (from JSON) and returns the user-passed argument, * or a falsy value if no argument was passed. * - * There are two overloads of this function: - * - Use MaybeArg<Type>(size_t i) to get the optional argument by index. - * - Use MaybeArg<Type>(const std::string& key) to get the optional argument by key. + * The instantiation of this helper for type R must match the corresponding RPCArg::Type. * - * The Type passed to this helper must match the corresponding RPCArg::Type. + * @return For integral and floating-point types, a std::optional<R> is returned. + * For other types, a R* pointer to the argument is returned. If the + * argument is not provided, std::nullopt or a null pointer is returned. * - * @return For integral and floating-point types, a std::optional<Type> is returned. - * For other types, a Type* pointer to the argument is returned. If the - * argument is not provided, std::nullopt or a null pointer is returned. - * * @see Arg for handling arguments that are required or have a default value. */ template <typename R> - auto MaybeArg(size_t i) const + auto MaybeArg(std::string_view key) const { + auto i{GetParamIndex(key)}; // Return optional argument (without default). if constexpr (std::is_integral_v<R> || std::is_floating_point_v<R>) { // Return numbers by value, wrapped in optional. @@ -476,11 +471,6 @@ public: return ArgValue<const R*>(i); } } - template<typename R> - auto MaybeArg(std::string_view key) const - { - return MaybeArg<R>(GetParamIndex(key)); - } std::string ToString() const; /** Return the named args that need to be converted from string to another JSON type */ UniValue GetArgMap() const; @@ -513,6 +503,4 @@ private: void PushWarnings(const UniValue& warnings, UniValue& obj); void PushWarnings(const std::vector<bilingual_str>& warnings, UniValue& obj); -UniValue GetNodeWarnings(bool use_deprecated); - #endif // BITCOIN_RPC_UTIL_H diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp index a11d4dcbd5..0987db194c 100644 --- a/src/script/descriptor.cpp +++ b/src/script/descriptor.cpp @@ -8,6 +8,7 @@ #include <key_io.h> #include <pubkey.h> #include <script/miniscript.h> +#include <script/parsing.h> #include <script/script.h> #include <script/signingprovider.h> #include <script/solver.h> @@ -17,7 +18,6 @@ #include <span.h> #include <util/bip32.h> #include <util/check.h> -#include <util/spanparsing.h> #include <util/strencodings.h> #include <util/vector.h> @@ -27,6 +27,8 @@ #include <string> #include <vector> +using util::Split; + namespace { //////////////////////////////////////////////////////////////////////////// @@ -1350,8 +1352,6 @@ enum class ParseScriptContext { /** Parse a public key that excludes origin information. */ std::unique_ptr<PubkeyProvider> ParsePubkeyInner(uint32_t key_exp_index, const Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, bool& apostrophe, std::string& error) { - using namespace spanparsing; - bool permit_uncompressed = ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH; auto split = Split(sp, '/'); std::string str(split[0].begin(), split[0].end()); @@ -1424,8 +1424,6 @@ std::unique_ptr<PubkeyProvider> ParsePubkeyInner(uint32_t key_exp_index, const S /** Parse a public key including origin information (if enabled). */ std::unique_ptr<PubkeyProvider> ParsePubkey(uint32_t key_exp_index, const Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error) { - using namespace spanparsing; - auto origin_split = Split(sp, ']'); if (origin_split.size() > 2) { error = "Multiple ']' characters found for a single pubkey"; @@ -1589,7 +1587,7 @@ struct KeyParser { // NOLINTNEXTLINE(misc-no-recursion) std::unique_ptr<DescriptorImpl> ParseScript(uint32_t& key_exp_index, Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error) { - using namespace spanparsing; + using namespace script; auto expr = Expr(sp); if (Func("pk", expr)) { @@ -2038,8 +2036,6 @@ std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptCo /** Check a descriptor checksum, and update desc to be the checksum-less part. */ bool CheckChecksum(Span<const char>& sp, bool require_checksum, std::string& error, std::string* out_checksum = nullptr) { - using namespace spanparsing; - auto check_split = Split(sp, '#'); if (check_split.size() > 2) { error = "Multiple '#' symbols"; diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index c969ce45f1..20a9830d0e 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1321,8 +1321,8 @@ public: /** Serialize txTo */ template<typename S> void Serialize(S &s) const { - // Serialize nVersion - ::Serialize(s, txTo.nVersion); + // Serialize version + ::Serialize(s, txTo.version); // Serialize vin unsigned int nInputs = fAnyoneCanPay ? 1 : txTo.vin.size(); ::WriteCompactSize(s, nInputs); @@ -1512,7 +1512,7 @@ bool SignatureHashSchnorr(uint256& hash_out, ScriptExecutionData& execdata, cons ss << hash_type; // Transaction level data - ss << tx_to.nVersion; + ss << tx_to.version; ss << tx_to.nLockTime; if (input_type != SIGHASH_ANYONECANPAY) { ss << cache.m_prevouts_single_hash; @@ -1594,7 +1594,7 @@ uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn HashWriter ss{}; // Version - ss << txTo.nVersion; + ss << txTo.version; // Input prevouts/nSequence (none/all, depending on flags) ss << hashPrevouts; ss << hashSequence; @@ -1743,7 +1743,7 @@ bool GenericTransactionSignatureChecker<T>::CheckSequence(const CScriptNum& nSeq // Fail if the transaction's version number is not set high // enough to trigger BIP 68 rules. - if (static_cast<uint32_t>(txTo->nVersion) < 2) + if (txTo->version < 2) return false; // Sequence numbers with their most significant bit set are not diff --git a/src/script/miniscript.h b/src/script/miniscript.h index 4880f32410..a269709e72 100644 --- a/src/script/miniscript.h +++ b/src/script/miniscript.h @@ -18,10 +18,10 @@ #include <policy/policy.h> #include <primitives/transaction.h> +#include <script/parsing.h> #include <script/script.h> #include <span.h> #include <util/check.h> -#include <util/spanparsing.h> #include <util/strencodings.h> #include <util/string.h> #include <util/vector.h> @@ -251,7 +251,7 @@ namespace internal { //! The maximum size of a witness item for a Miniscript under Tapscript context. (A BIP340 signature with a sighash type byte.) static constexpr uint32_t MAX_TAPMINISCRIPT_STACK_ELEM_SIZE{65}; -//! nVersion + nLockTime +//! version + nLockTime constexpr uint32_t TX_OVERHEAD{4 + 4}; //! prevout + nSequence + scriptSig constexpr uint32_t TXIN_BYTES_NO_WITNESS{36 + 4 + 1}; @@ -863,8 +863,8 @@ public: if (!key_str) return {}; return std::move(ret) + "pk_h(" + std::move(*key_str) + ")"; } - case Fragment::AFTER: return std::move(ret) + "after(" + ::ToString(node.k) + ")"; - case Fragment::OLDER: return std::move(ret) + "older(" + ::ToString(node.k) + ")"; + case Fragment::AFTER: return std::move(ret) + "after(" + util::ToString(node.k) + ")"; + case Fragment::OLDER: return std::move(ret) + "older(" + util::ToString(node.k) + ")"; case Fragment::HASH256: return std::move(ret) + "hash256(" + HexStr(node.data) + ")"; case Fragment::HASH160: return std::move(ret) + "hash160(" + HexStr(node.data) + ")"; case Fragment::SHA256: return std::move(ret) + "sha256(" + HexStr(node.data) + ")"; @@ -883,7 +883,7 @@ public: return std::move(ret) + "andor(" + std::move(subs[0]) + "," + std::move(subs[1]) + "," + std::move(subs[2]) + ")"; case Fragment::MULTI: { CHECK_NONFATAL(!is_tapscript); - auto str = std::move(ret) + "multi(" + ::ToString(node.k); + auto str = std::move(ret) + "multi(" + util::ToString(node.k); for (const auto& key : node.keys) { auto key_str = ctx.ToString(key); if (!key_str) return {}; @@ -893,7 +893,7 @@ public: } case Fragment::MULTI_A: { CHECK_NONFATAL(is_tapscript); - auto str = std::move(ret) + "multi_a(" + ::ToString(node.k); + auto str = std::move(ret) + "multi_a(" + util::ToString(node.k); for (const auto& key : node.keys) { auto key_str = ctx.ToString(key); if (!key_str) return {}; @@ -902,7 +902,7 @@ public: return std::move(str) + ")"; } case Fragment::THRESH: { - auto str = std::move(ret) + "thresh(" + ::ToString(node.k); + auto str = std::move(ret) + "thresh(" + util::ToString(node.k); for (auto& sub : subs) { str += "," + std::move(sub); } @@ -1764,7 +1764,7 @@ void BuildBack(const MiniscriptContext script_ctx, Fragment nt, std::vector<Node template<typename Key, typename Ctx> inline NodeRef<Key> Parse(Span<const char> in, const Ctx& ctx) { - using namespace spanparsing; + using namespace script; // Account for the minimum script size for all parsed fragments so far. It "borrows" 1 // script byte from all leaf nodes, counting it instead whenever a space for a recursive diff --git a/src/util/spanparsing.cpp b/src/script/parsing.cpp index c464fc2b87..3528ac9bfa 100644 --- a/src/util/spanparsing.cpp +++ b/src/script/parsing.cpp @@ -2,7 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include <util/spanparsing.h> +#include <script/parsing.h> #include <span.h> @@ -10,7 +10,7 @@ #include <cstddef> #include <string> -namespace spanparsing { +namespace script { bool Const(const std::string& str, Span<const char>& sp) { @@ -49,4 +49,4 @@ Span<const char> Expr(Span<const char>& sp) return ret; } -} // namespace spanparsing +} // namespace script diff --git a/src/script/parsing.h b/src/script/parsing.h new file mode 100644 index 0000000000..850faea041 --- /dev/null +++ b/src/script/parsing.h @@ -0,0 +1,40 @@ +// Copyright (c) 2018-2022 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_SCRIPT_PARSING_H +#define BITCOIN_SCRIPT_PARSING_H + +#include <span.h> + +#include <string> + +namespace script { + +/** Parse a constant. + * + * If sp's initial part matches str, sp is updated to skip that part, and true is returned. + * Otherwise sp is unmodified and false is returned. + */ +bool Const(const std::string& str, Span<const char>& sp); + +/** Parse a function call. + * + * If sp's initial part matches str + "(", and sp ends with ")", sp is updated to be the + * section between the braces, and true is returned. Otherwise sp is unmodified and false + * is returned. + */ +bool Func(const std::string& str, Span<const char>& sp); + +/** Extract the expression that sp begins with. + * + * This function will return the initial part of sp, up to (but not including) the first + * comma or closing brace, skipping ones that are surrounded by braces. So for example, + * for "foo(bar(1),2),3" the initial part "foo(bar(1),2)" will be returned. sp will be + * updated to skip the initial part that is returned. + */ +Span<const char> Expr(Span<const char>& sp); + +} // namespace script + +#endif // BITCOIN_SCRIPT_PARSING_H diff --git a/src/script/script.cpp b/src/script/script.cpp index 80e8d26bcf..73ea336c4f 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -6,10 +6,10 @@ #include <script/script.h> #include <crypto/common.h> +#include <crypto/hex_base.h> #include <hash.h> #include <uint256.h> #include <util/hash_type.h> -#include <util/strencodings.h> #include <string> diff --git a/src/secp256k1/.cirrus.yml b/src/secp256k1/.cirrus.yml index 04aa8f2409..4bd15511a4 100644 --- a/src/secp256k1/.cirrus.yml +++ b/src/secp256k1/.cirrus.yml @@ -10,8 +10,8 @@ env: MAKEFLAGS: -j4 BUILD: check ### secp256k1 config - ECMULTWINDOW: auto - ECMULTGENPRECISION: auto + ECMULTWINDOW: 15 + ECMULTGENKB: 22 ASM: no WIDEMUL: auto WITH_VALGRIND: yes diff --git a/src/secp256k1/.github/workflows/ci.yml b/src/secp256k1/.github/workflows/ci.yml index 4ad905af52..ade94e1eec 100644 --- a/src/secp256k1/.github/workflows/ci.yml +++ b/src/secp256k1/.github/workflows/ci.yml @@ -21,8 +21,8 @@ env: MAKEFLAGS: '-j4' BUILD: 'check' ### secp256k1 config - ECMULTWINDOW: 'auto' - ECMULTGENPRECISION: 'auto' + ECMULTWINDOW: 15 + ECMULTGENKB: 22 ASM: 'no' WIDEMUL: 'auto' WITH_VALGRIND: 'yes' @@ -83,8 +83,8 @@ jobs: - env_vars: { CPPFLAGS: '-DDETERMINISTIC' } - env_vars: { CFLAGS: '-O0', CTIMETESTS: 'no' } - env_vars: { CFLAGS: '-O1', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes' } - - env_vars: { ECMULTGENPRECISION: 2, ECMULTWINDOW: 2 } - - env_vars: { ECMULTGENPRECISION: 8, ECMULTWINDOW: 4 } + - env_vars: { ECMULTGENKB: 2, ECMULTWINDOW: 2 } + - env_vars: { ECMULTGENKB: 86, ECMULTWINDOW: 4 } cc: - 'gcc' - 'clang' @@ -377,8 +377,8 @@ jobs: configuration: - env_vars: { CC: 'clang', ASM: 'auto' } - env_vars: { CC: 'i686-linux-gnu-gcc', HOST: 'i686-linux-gnu', ASM: 'auto' } - - env_vars: { CC: 'clang', ASM: 'no', ECMULTGENPRECISION: 2, ECMULTWINDOW: 2 } - - env_vars: { CC: 'i686-linux-gnu-gcc', HOST: 'i686-linux-gnu', ASM: 'no', ECMULTGENPRECISION: 2, ECMULTWINDOW: 2 } + - env_vars: { CC: 'clang', ASM: 'no', ECMULTGENKB: 2, ECMULTWINDOW: 2 } + - env_vars: { CC: 'i686-linux-gnu-gcc', HOST: 'i686-linux-gnu', ASM: 'no', ECMULTGENKB: 2, ECMULTWINDOW: 2 } env: # The `--error-exitcode` is required to make the test fail if valgrind found errors, @@ -431,8 +431,8 @@ jobs: configuration: - env_vars: { CC: 'clang', ASM: 'auto' } - env_vars: { CC: 'i686-linux-gnu-gcc', HOST: 'i686-linux-gnu', ASM: 'auto' } - - env_vars: { CC: 'clang', ASM: 'no', ECMULTGENPRECISION: 2, ECMULTWINDOW: 2 } - - env_vars: { CC: 'i686-linux-gnu-gcc', HOST: 'i686-linux-gnu', ASM: 'no', ECMULTGENPRECISION: 2, ECMULTWINDOW: 2 } + - env_vars: { CC: 'clang', ASM: 'no', ECMULTGENKB: 2, ECMULTWINDOW: 2 } + - env_vars: { CC: 'i686-linux-gnu-gcc', HOST: 'i686-linux-gnu', ASM: 'no', ECMULTGENKB: 2, ECMULTWINDOW: 2 } env: ECDH: 'yes' @@ -485,18 +485,24 @@ jobs: matrix: configuration: - env_vars: + CTIMETESTS: 'yes' CFLAGS: '-fsanitize=memory -fsanitize-recover=memory -g' - env_vars: - ECMULTGENPRECISION: 2 + ECMULTGENKB: 2 ECMULTWINDOW: 2 + CTIMETESTS: 'yes' CFLAGS: '-fsanitize=memory -fsanitize-recover=memory -g -O3' + - env_vars: + # -fsanitize-memory-param-retval is clang's default, but our build system disables it + # when ctime_tests when enabled. + CFLAGS: '-fsanitize=memory -fsanitize-recover=memory -fsanitize-memory-param-retval -g' + CTIMETESTS: 'no' env: ECDH: 'yes' RECOVERY: 'yes' SCHNORRSIG: 'yes' ELLSWIFT: 'yes' - CTIMETESTS: 'yes' CC: 'clang' SECP256K1_TEST_ITERS: 32 ASM: 'no' @@ -585,10 +591,10 @@ jobs: run: env if: ${{ always() }} - macos-native: - name: "x86_64: macOS Monterey" + x86_64-macos-native: + name: "x86_64: macOS Monterey, Valgrind" # See: https://github.com/actions/runner-images#available-images. - runs-on: macos-12 # Use M1 once available https://github.com/github/roadmap/issues/528 + runs-on: macos-12 env: CC: 'clang' @@ -600,7 +606,7 @@ jobs: matrix: env_vars: - { WIDEMUL: 'int64', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes' } - - { WIDEMUL: 'int128_struct', ECMULTGENPRECISION: 2, ECMULTWINDOW: 4 } + - { WIDEMUL: 'int128_struct', ECMULTGENKB: 2, ECMULTWINDOW: 4 } - { WIDEMUL: 'int128', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes' } - { WIDEMUL: 'int128', RECOVERY: 'yes' } - { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes' } @@ -644,6 +650,62 @@ jobs: run: env if: ${{ always() }} + arm64-macos-native: + name: "ARM64: macOS Sonoma" + # See: https://github.com/actions/runner-images#available-images. + runs-on: macos-14 + + env: + CC: 'clang' + HOMEBREW_NO_AUTO_UPDATE: 1 + HOMEBREW_NO_INSTALL_CLEANUP: 1 + WITH_VALGRIND: 'no' + CTIMETESTS: 'no' + + strategy: + fail-fast: false + matrix: + env_vars: + - { WIDEMUL: 'int64', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes' } + - { WIDEMUL: 'int128_struct', ECMULTGENPRECISION: 2, ECMULTWINDOW: 4 } + - { WIDEMUL: 'int128', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes' } + - { WIDEMUL: 'int128', RECOVERY: 'yes' } + - { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes' } + - { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', CC: 'gcc' } + - { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', CPPFLAGS: '-DVERIFY' } + - BUILD: 'distcheck' + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Homebrew packages + run: | + brew install automake libtool gcc + ln -s $(brew --prefix gcc)/bin/gcc-?? /usr/local/bin/gcc + + - name: CI script + env: ${{ matrix.env_vars }} + run: ./ci/ci.sh + + - run: cat tests.log || true + if: ${{ always() }} + - run: cat noverify_tests.log || true + if: ${{ always() }} + - run: cat exhaustive_tests.log || true + if: ${{ always() }} + - run: cat ctime_tests.log || true + if: ${{ always() }} + - run: cat bench.log || true + if: ${{ always() }} + - run: cat config.log || true + if: ${{ always() }} + - run: cat test_env.log || true + if: ${{ always() }} + - name: CI env + run: env + if: ${{ always() }} + win64-native: name: ${{ matrix.configuration.job_name }} # See: https://github.com/actions/runner-images#available-images. diff --git a/src/secp256k1/CHANGELOG.md b/src/secp256k1/CHANGELOG.md index 04ac9b7e5a..a2855912fd 100644 --- a/src/secp256k1/CHANGELOG.md +++ b/src/secp256k1/CHANGELOG.md @@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.5.0] - 2024-05-06 + +#### Added + - New function `secp256k1_ec_pubkey_sort` that sorts public keys using lexicographic (of compressed serialization) order. + +#### Changed + - The implementation of the point multiplication algorithm used for signing and public key generation was changed, resulting in improved performance for those operations. + - The related configure option `--ecmult-gen-precision` was replaced with `--ecmult-gen-kb` (`ECMULT_GEN_KB` for CMake). + - This changes the supported precomputed table sizes for these operations. The new supported sizes are 2 KiB, 22 KiB, or 86 KiB (while the old supported sizes were 32 KiB, 64 KiB, or 512 KiB). + +#### ABI Compatibility +The ABI is backward compatible with versions 0.4.x and 0.3.x. + ## [0.4.1] - 2023-12-21 #### Changed @@ -115,7 +128,8 @@ This version was in fact never released. The number was given by the build system since the introduction of autotools in Jan 2014 (ea0fe5a5bf0c04f9cc955b2966b614f5f378c6f6). Therefore, this version number does not uniquely identify a set of source files. -[unreleased]: https://github.com/bitcoin-core/secp256k1/compare/v0.4.1...HEAD +[unreleased]: https://github.com/bitcoin-core/secp256k1/compare/v0.5.0...HEAD +[0.5.0]: https://github.com/bitcoin-core/secp256k1/compare/v0.4.1...v0.5.0 [0.4.1]: https://github.com/bitcoin-core/secp256k1/compare/v0.4.0...v0.4.1 [0.4.0]: https://github.com/bitcoin-core/secp256k1/compare/v0.3.2...v0.4.0 [0.3.2]: https://github.com/bitcoin-core/secp256k1/compare/v0.3.1...v0.3.2 diff --git a/src/secp256k1/CMakeLists.txt b/src/secp256k1/CMakeLists.txt index 9ef7defe51..7e3465a75b 100644 --- a/src/secp256k1/CMakeLists.txt +++ b/src/secp256k1/CMakeLists.txt @@ -11,22 +11,21 @@ project(libsecp256k1 # The package (a.k.a. release) version is based on semantic versioning 2.0.0 of # the API. All changes in experimental modules are treated as # backwards-compatible and therefore at most increase the minor version. - VERSION 0.4.2 + VERSION 0.5.1 DESCRIPTION "Optimized C library for ECDSA signatures and secret/public key operations on curve secp256k1." HOMEPAGE_URL "https://github.com/bitcoin-core/secp256k1" LANGUAGES C ) if(CMAKE_VERSION VERSION_LESS 3.21) - get_directory_property(parent_directory PARENT_DIRECTORY) - if(parent_directory) - set(PROJECT_IS_TOP_LEVEL OFF CACHE INTERNAL "Emulates CMake 3.21+ behavior.") - set(${PROJECT_NAME}_IS_TOP_LEVEL OFF CACHE INTERNAL "Emulates CMake 3.21+ behavior.") + # Emulates CMake 3.21+ behavior. + if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + set(PROJECT_IS_TOP_LEVEL ON) + set(${PROJECT_NAME}_IS_TOP_LEVEL ON) else() - set(PROJECT_IS_TOP_LEVEL ON CACHE INTERNAL "Emulates CMake 3.21+ behavior.") - set(${PROJECT_NAME}_IS_TOP_LEVEL ON CACHE INTERNAL "Emulates CMake 3.21+ behavior.") + set(PROJECT_IS_TOP_LEVEL OFF) + set(${PROJECT_NAME}_IS_TOP_LEVEL OFF) endif() - unset(parent_directory) endif() # The library version is based on libtool versioning of the ABI. The set of @@ -34,9 +33,9 @@ endif() # https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html # All changes in experimental modules are treated as if they don't affect the # interface and therefore only increase the revision. -set(${PROJECT_NAME}_LIB_VERSION_CURRENT 3) -set(${PROJECT_NAME}_LIB_VERSION_REVISION 2) -set(${PROJECT_NAME}_LIB_VERSION_AGE 1) +set(${PROJECT_NAME}_LIB_VERSION_CURRENT 4) +set(${PROJECT_NAME}_LIB_VERSION_REVISION 1) +set(${PROJECT_NAME}_LIB_VERSION_AGE 2) set(CMAKE_C_STANDARD 90) set(CMAKE_C_EXTENSIONS OFF) @@ -92,22 +91,25 @@ if(SECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS) add_compile_definitions(USE_EXTERNAL_DEFAULT_CALLBACKS=1) endif() -set(SECP256K1_ECMULT_WINDOW_SIZE "AUTO" CACHE STRING "Window size for ecmult precomputation for verification, specified as integer in range [2..24]. \"AUTO\" is a reasonable setting for desktop machines (currently 15). [default=AUTO]") -set_property(CACHE SECP256K1_ECMULT_WINDOW_SIZE PROPERTY STRINGS "AUTO" 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24) +set(SECP256K1_ECMULT_WINDOW_SIZE 15 CACHE STRING "Window size for ecmult precomputation for verification, specified as integer in range [2..24]. The default value is a reasonable setting for desktop machines (currently 15). [default=15]") +set_property(CACHE SECP256K1_ECMULT_WINDOW_SIZE PROPERTY STRINGS 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24) include(CheckStringOptionValue) check_string_option_value(SECP256K1_ECMULT_WINDOW_SIZE) -if(SECP256K1_ECMULT_WINDOW_SIZE STREQUAL "AUTO") - set(SECP256K1_ECMULT_WINDOW_SIZE 15) -endif() add_compile_definitions(ECMULT_WINDOW_SIZE=${SECP256K1_ECMULT_WINDOW_SIZE}) -set(SECP256K1_ECMULT_GEN_PREC_BITS "AUTO" CACHE STRING "Precision bits to tune the precomputed table size for signing, specified as integer 2, 4 or 8. \"AUTO\" is a reasonable setting for desktop machines (currently 4). [default=AUTO]") -set_property(CACHE SECP256K1_ECMULT_GEN_PREC_BITS PROPERTY STRINGS "AUTO" 2 4 8) -check_string_option_value(SECP256K1_ECMULT_GEN_PREC_BITS) -if(SECP256K1_ECMULT_GEN_PREC_BITS STREQUAL "AUTO") - set(SECP256K1_ECMULT_GEN_PREC_BITS 4) +set(SECP256K1_ECMULT_GEN_KB 22 CACHE STRING "The size of the precomputed table for signing in multiples of 1024 bytes (on typical platforms). Larger values result in possibly better signing or key generation performance at the cost of a larger table. Valid choices are 2, 22, 86. The default value is a reasonable setting for desktop machines (currently 22). [default=22]") +set_property(CACHE SECP256K1_ECMULT_GEN_KB PROPERTY STRINGS 2 22 86) +check_string_option_value(SECP256K1_ECMULT_GEN_KB) +if(SECP256K1_ECMULT_GEN_KB EQUAL 2) + add_compile_definitions(COMB_BLOCKS=2) + add_compile_definitions(COMB_TEETH=5) +elseif(SECP256K1_ECMULT_GEN_KB EQUAL 22) + add_compile_definitions(COMB_BLOCKS=11) + add_compile_definitions(COMB_TEETH=6) +elseif(SECP256K1_ECMULT_GEN_KB EQUAL 86) + add_compile_definitions(COMB_BLOCKS=43) + add_compile_definitions(COMB_TEETH=6) endif() -add_compile_definitions(ECMULT_GEN_PREC_BITS=${SECP256K1_ECMULT_GEN_PREC_BITS}) set(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY "OFF" CACHE STRING "Test-only override of the (autodetected by the C code) \"widemul\" setting. Legal values are: \"OFF\", \"int128_struct\", \"int128\" or \"int64\". [default=OFF]") set_property(CACHE SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY PROPERTY STRINGS "OFF" "int128_struct" "int128" "int64") @@ -205,23 +207,25 @@ mark_as_advanced( CMAKE_SHARED_LINKER_FLAGS_COVERAGE ) -get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) -set(default_build_type "RelWithDebInfo") -if(is_multi_config) - set(CMAKE_CONFIGURATION_TYPES "${default_build_type}" "Release" "Debug" "MinSizeRel" "Coverage" CACHE STRING - "Supported configuration types." - FORCE - ) -else() - set_property(CACHE CMAKE_BUILD_TYPE PROPERTY - STRINGS "${default_build_type}" "Release" "Debug" "MinSizeRel" "Coverage" - ) - if(NOT CMAKE_BUILD_TYPE) - message(STATUS "Setting build type to \"${default_build_type}\" as none was specified") - set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE STRING - "Choose the type of build." +if(PROJECT_IS_TOP_LEVEL) + get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + set(default_build_type "RelWithDebInfo") + if(is_multi_config) + set(CMAKE_CONFIGURATION_TYPES "${default_build_type}" "Release" "Debug" "MinSizeRel" "Coverage" CACHE STRING + "Supported configuration types." FORCE ) + else() + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY + STRINGS "${default_build_type}" "Release" "Debug" "MinSizeRel" "Coverage" + ) + if(NOT CMAKE_BUILD_TYPE) + message(STATUS "Setting build type to \"${default_build_type}\" as none was specified") + set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE STRING + "Choose the type of build." + FORCE + ) + endif() endif() endif() @@ -254,10 +258,17 @@ endif() set(CMAKE_C_VISIBILITY_PRESET hidden) -# Ask CTest to create a "check" target (e.g., make check) as alias for the "test" target. -# CTEST_TEST_TARGET_ALIAS is not documented but supposed to be user-facing. -# See: https://gitlab.kitware.com/cmake/cmake/-/commit/816c9d1aa1f2b42d40c81a991b68c96eb12b6d2 -set(CTEST_TEST_TARGET_ALIAS check) +set(print_msan_notice) +if(SECP256K1_BUILD_CTIME_TESTS) + include(CheckMemorySanitizer) + check_memory_sanitizer(msan_enabled) + if(msan_enabled) + try_append_c_flags(-fno-sanitize-memory-param-retval) + set(print_msan_notice YES) + endif() + unset(msan_enabled) +endif() + include(CTest) # We do not use CTest's BUILD_TESTING because a single toggle for all tests is too coarse for our needs. mark_as_advanced(BUILD_TESTING) @@ -265,14 +276,16 @@ if(SECP256K1_BUILD_BENCHMARK OR SECP256K1_BUILD_TESTS OR SECP256K1_BUILD_EXHAUST enable_testing() endif() -set(SECP256K1_LATE_CFLAGS "" CACHE STRING "Compiler flags that are added to the command line after all other flags added by the build system.") -include(AllTargetsCompileOptions) +set(SECP256K1_APPEND_CFLAGS "" CACHE STRING "Compiler flags that are appended to the command line after all other flags added by the build system. This variable is intended for debugging and special builds.") +if(SECP256K1_APPEND_CFLAGS) + # Appending to this low-level rule variable is the only way to + # guarantee that the flags appear at the end of the command line. + string(APPEND CMAKE_C_COMPILE_OBJECT " ${SECP256K1_APPEND_CFLAGS}") +endif() add_subdirectory(src) -all_targets_compile_options(src "${SECP256K1_LATE_CFLAGS}") if(SECP256K1_BUILD_EXAMPLES) add_subdirectory(examples) - all_targets_compile_options(examples "${SECP256K1_LATE_CFLAGS}") endif() message("\n") @@ -294,7 +307,7 @@ message(" schnorrsig .......................... ${SECP256K1_ENABLE_MODULE_SCHNO message(" ElligatorSwift ...................... ${SECP256K1_ENABLE_MODULE_ELLSWIFT}") message("Parameters:") message(" ecmult window size .................. ${SECP256K1_ECMULT_WINDOW_SIZE}") -message(" ecmult gen precision bits ........... ${SECP256K1_ECMULT_GEN_PREC_BITS}") +message(" ecmult gen table size ............... ${SECP256K1_ECMULT_GEN_KB} KiB") message("Optional features:") message(" assembly ............................ ${SECP256K1_ASM}") message(" external callbacks .................. ${SECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS}") @@ -323,7 +336,7 @@ message("Valgrind .............................. ${SECP256K1_VALGRIND}") get_directory_property(definitions COMPILE_DEFINITIONS) string(REPLACE ";" " " definitions "${definitions}") message("Preprocessor defined macros ........... ${definitions}") -message("C compiler ............................ ${CMAKE_C_COMPILER}") +message("C compiler ............................ ${CMAKE_C_COMPILER_ID} ${CMAKE_C_COMPILER_VERSION}, ${CMAKE_C_COMPILER}") message("CFLAGS ................................ ${CMAKE_C_FLAGS}") get_directory_property(compile_options COMPILE_OPTIONS) string(REPLACE ";" " " compile_options "${compile_options}") @@ -346,10 +359,17 @@ else() message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_DEBUG}") message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_DEBUG}") endif() -if(SECP256K1_LATE_CFLAGS) - message("SECP256K1_LATE_CFLAGS ................. ${SECP256K1_LATE_CFLAGS}") +if(SECP256K1_APPEND_CFLAGS) + message("SECP256K1_APPEND_CFLAGS ............... ${SECP256K1_APPEND_CFLAGS}") +endif() +message("") +if(print_msan_notice) + message( + "Note:\n" + " MemorySanitizer detected, tried to add -fno-sanitize-memory-param-retval to compile options\n" + " to avoid false positives in ctime_tests. Pass -DSECP256K1_BUILD_CTIME_TESTS=OFF to avoid this.\n" + ) endif() -message("\n") if(SECP256K1_EXPERIMENTAL) message( " ******\n" diff --git a/src/secp256k1/Makefile.am b/src/secp256k1/Makefile.am index 5498617915..322e44eaab 100644 --- a/src/secp256k1/Makefile.am +++ b/src/secp256k1/Makefile.am @@ -64,6 +64,8 @@ noinst_HEADERS += src/field.h noinst_HEADERS += src/field_impl.h noinst_HEADERS += src/bench.h noinst_HEADERS += src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h +noinst_HEADERS += src/hsort.h +noinst_HEADERS += src/hsort_impl.h noinst_HEADERS += contrib/lax_der_parsing.h noinst_HEADERS += contrib/lax_der_parsing.c noinst_HEADERS += contrib/lax_der_privatekey_parsing.h diff --git a/src/secp256k1/README.md b/src/secp256k1/README.md index 6e88eb4ecb..e8d4123ab9 100644 --- a/src/secp256k1/README.md +++ b/src/secp256k1/README.md @@ -20,6 +20,7 @@ Features: * Optional module for public key recovery. * Optional module for ECDH key exchange. * Optional module for Schnorr signatures according to [BIP-340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki). +* Optional module for ElligatorSwift key exchange according to [BIP-324](https://github.com/bitcoin/bips/blob/master/bip-0324.mediawiki). Implementation details ---------------------- diff --git a/src/secp256k1/build-aux/m4/bitcoin_secp.m4 b/src/secp256k1/build-aux/m4/bitcoin_secp.m4 index 11adef4f22..048267fa6e 100644 --- a/src/secp256k1/build-aux/m4/bitcoin_secp.m4 +++ b/src/secp256k1/build-aux/m4/bitcoin_secp.m4 @@ -45,6 +45,22 @@ fi AC_MSG_RESULT($has_valgrind) ]) +AC_DEFUN([SECP_MSAN_CHECK], [ +AC_MSG_CHECKING(whether MemorySanitizer is enabled) +AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ + #if defined(__has_feature) + # if __has_feature(memory_sanitizer) + /* MemorySanitizer is enabled. */ + # elif + # error "MemorySanitizer is disabled." + # endif + #else + # error "__has_feature is not defined." + #endif + ]])], [msan_enabled=yes], [msan_enabled=no]) +AC_MSG_RESULT([$msan_enabled]) +]) + dnl SECP_TRY_APPEND_CFLAGS(flags, VAR) dnl Append flags to VAR if CC accepts them. AC_DEFUN([SECP_TRY_APPEND_CFLAGS], [ diff --git a/src/secp256k1/ci/ci.sh b/src/secp256k1/ci/ci.sh index 3999af4f1c..c7d2e9e4ea 100755 --- a/src/secp256k1/ci/ci.sh +++ b/src/secp256k1/ci/ci.sh @@ -12,7 +12,7 @@ print_environment() { # There are many ways to print variable names and their content. This one # does not rely on bash. for var in WERROR_CFLAGS MAKEFLAGS BUILD \ - ECMULTWINDOW ECMULTGENPRECISION ASM WIDEMUL WITH_VALGRIND EXTRAFLAGS \ + ECMULTWINDOW ECMULTGENKB ASM WIDEMUL WITH_VALGRIND EXTRAFLAGS \ EXPERIMENTAL ECDH RECOVERY SCHNORRSIG ELLSWIFT \ SECP256K1_TEST_ITERS BENCH SECP256K1_BENCH_ITERS CTIMETESTS\ EXAMPLES \ @@ -74,7 +74,7 @@ esac --enable-experimental="$EXPERIMENTAL" \ --with-test-override-wide-multiply="$WIDEMUL" --with-asm="$ASM" \ --with-ecmult-window="$ECMULTWINDOW" \ - --with-ecmult-gen-precision="$ECMULTGENPRECISION" \ + --with-ecmult-gen-kb="$ECMULTGENKB" \ --enable-module-ecdh="$ECDH" --enable-module-recovery="$RECOVERY" \ --enable-module-ellswift="$ELLSWIFT" \ --enable-module-schnorrsig="$SCHNORRSIG" \ diff --git a/src/secp256k1/cmake/AllTargetsCompileOptions.cmake b/src/secp256k1/cmake/AllTargetsCompileOptions.cmake deleted file mode 100644 index 6e420e0fde..0000000000 --- a/src/secp256k1/cmake/AllTargetsCompileOptions.cmake +++ /dev/null @@ -1,12 +0,0 @@ -# Add compile options to all targets added in the subdirectory. -function(all_targets_compile_options dir options) - get_directory_property(targets DIRECTORY ${dir} BUILDSYSTEM_TARGETS) - separate_arguments(options) - set(compiled_target_types STATIC_LIBRARY SHARED_LIBRARY OBJECT_LIBRARY EXECUTABLE) - foreach(target ${targets}) - get_target_property(type ${target} TYPE) - if(type IN_LIST compiled_target_types) - target_compile_options(${target} PRIVATE ${options}) - endif() - endforeach() -endfunction() diff --git a/src/secp256k1/cmake/CheckArm32Assembly.cmake b/src/secp256k1/cmake/CheckArm32Assembly.cmake index 15c44b24b0..baeeff0292 100644 --- a/src/secp256k1/cmake/CheckArm32Assembly.cmake +++ b/src/secp256k1/cmake/CheckArm32Assembly.cmake @@ -1,6 +1,6 @@ function(check_arm32_assembly) try_compile(HAVE_ARM32_ASM - ${CMAKE_BINARY_DIR}/check_arm32_assembly - SOURCES ${CMAKE_SOURCE_DIR}/cmake/source_arm32.s + ${PROJECT_BINARY_DIR}/check_arm32_assembly + SOURCES ${PROJECT_SOURCE_DIR}/cmake/source_arm32.s ) endfunction() diff --git a/src/secp256k1/cmake/CheckMemorySanitizer.cmake b/src/secp256k1/cmake/CheckMemorySanitizer.cmake new file mode 100644 index 0000000000..d9ef681e65 --- /dev/null +++ b/src/secp256k1/cmake/CheckMemorySanitizer.cmake @@ -0,0 +1,18 @@ +include_guard(GLOBAL) +include(CheckCSourceCompiles) + +function(check_memory_sanitizer output) + set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + check_c_source_compiles(" + #if defined(__has_feature) + # if __has_feature(memory_sanitizer) + /* MemorySanitizer is enabled. */ + # elif + # error \"MemorySanitizer is disabled.\" + # endif + #else + # error \"__has_feature is not defined.\" + #endif + " HAVE_MSAN) + set(${output} ${HAVE_MSAN} PARENT_SCOPE) +endfunction() diff --git a/src/secp256k1/configure.ac b/src/secp256k1/configure.ac index 158ed5d769..adae189787 100644 --- a/src/secp256k1/configure.ac +++ b/src/secp256k1/configure.ac @@ -4,8 +4,8 @@ AC_PREREQ([2.60]) # the API. All changes in experimental modules are treated as # backwards-compatible and therefore at most increase the minor version. define(_PKG_VERSION_MAJOR, 0) -define(_PKG_VERSION_MINOR, 4) -define(_PKG_VERSION_PATCH, 2) +define(_PKG_VERSION_MINOR, 5) +define(_PKG_VERSION_PATCH, 1) define(_PKG_VERSION_IS_RELEASE, false) # The library version is based on libtool versioning of the ABI. The set of @@ -13,9 +13,9 @@ define(_PKG_VERSION_IS_RELEASE, false) # https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html # All changes in experimental modules are treated as if they don't affect the # interface and therefore only increase the revision. -define(_LIB_VERSION_CURRENT, 3) -define(_LIB_VERSION_REVISION, 2) -define(_LIB_VERSION_AGE, 1) +define(_LIB_VERSION_CURRENT, 4) +define(_LIB_VERSION_REVISION, 1) +define(_LIB_VERSION_AGE, 2) AC_INIT([libsecp256k1],m4_join([.], _PKG_VERSION_MAJOR, _PKG_VERSION_MINOR, _PKG_VERSION_PATCH)m4_if(_PKG_VERSION_IS_RELEASE, [true], [], [-dev]),[https://github.com/bitcoin-core/secp256k1/issues],[libsecp256k1],[https://github.com/bitcoin-core/secp256k1]) @@ -203,23 +203,22 @@ AC_ARG_WITH([test-override-wide-multiply], [] ,[set_widemul=$withval], [set_wide AC_ARG_WITH([asm], [AS_HELP_STRING([--with-asm=x86_64|arm32|no|auto], [assembly to use (experimental: arm32) [default=auto]])],[req_asm=$withval], [req_asm=auto]) -AC_ARG_WITH([ecmult-window], [AS_HELP_STRING([--with-ecmult-window=SIZE|auto], +AC_ARG_WITH([ecmult-window], [AS_HELP_STRING([--with-ecmult-window=SIZE], [window size for ecmult precomputation for verification, specified as integer in range [2..24].] [Larger values result in possibly better performance at the cost of an exponentially larger precomputed table.] [The table will store 2^(SIZE-1) * 64 bytes of data but can be larger in memory due to platform-specific padding and alignment.] [A window size larger than 15 will require you delete the prebuilt precomputed_ecmult.c file so that it can be rebuilt.] [For very large window sizes, use "make -j 1" to reduce memory use during compilation.] -["auto" is a reasonable setting for desktop machines (currently 15). [default=auto]] +[The default value is a reasonable setting for desktop machines (currently 15). [default=15]] )], -[req_ecmult_window=$withval], [req_ecmult_window=auto]) +[set_ecmult_window=$withval], [set_ecmult_window=15]) -AC_ARG_WITH([ecmult-gen-precision], [AS_HELP_STRING([--with-ecmult-gen-precision=2|4|8|auto], -[Precision bits to tune the precomputed table size for signing.] -[The size of the table is 32kB for 2 bits, 64kB for 4 bits, 512kB for 8 bits of precision.] -[A larger table size usually results in possible faster signing.] -["auto" is a reasonable setting for desktop machines (currently 4). [default=auto]] +AC_ARG_WITH([ecmult-gen-kb], [AS_HELP_STRING([--with-ecmult-gen-kb=2|22|86], +[The size of the precomputed table for signing in multiples of 1024 bytes (on typical platforms).] +[Larger values result in possibly better signing/keygeneration performance at the cost of a larger table.] +[The default value is a reasonable setting for desktop machines (currently 22). [default=22]] )], -[req_ecmult_gen_precision=$withval], [req_ecmult_gen_precision=auto]) +[set_ecmult_gen_kb=$withval], [set_ecmult_gen_kb=22]) AC_ARG_WITH([valgrind], [AS_HELP_STRING([--with-valgrind=yes|no|auto], [Build with extra checks for running inside Valgrind [default=auto]] @@ -248,6 +247,20 @@ if test x"$enable_ctime_tests" = x"auto"; then enable_ctime_tests=$enable_valgrind fi +print_msan_notice=no +if test x"$enable_ctime_tests" = x"yes"; then + SECP_MSAN_CHECK + # MSan on Clang >=16 reports unitialized memory in function parameters and return values, even if + # the uninitalized variable is never actually "used". This is called "eager" checking, and it's + # sounds like good idea for normal use of MSan. However, it yields many false positives in the + # ctime_tests because many return values depend on secret (i.e., "uninitialized") values, and + # we're only interested in detecting branches (which count as "uses") on secret data. + if test x"$msan_enabled" = x"yes"; then + SECP_TRY_APPEND_CFLAGS([-fno-sanitize-memory-param-retval], SECP_CFLAGS) + print_msan_notice=yes + fi +fi + if test x"$enable_coverage" = x"yes"; then SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DCOVERAGE=1" SECP_CFLAGS="-O0 --coverage $SECP_CFLAGS" @@ -336,14 +349,7 @@ auto) ;; esac -# Set ecmult window size -if test x"$req_ecmult_window" = x"auto"; then - set_ecmult_window=15 -else - set_ecmult_window=$req_ecmult_window -fi - -error_window_size=['window size for ecmult precomputation not an integer in range [2..24] or "auto"'] +error_window_size=['window size for ecmult precomputation not an integer in range [2..24]'] case $set_ecmult_window in ''|*[[!0-9]]*) # no valid integer @@ -358,19 +364,18 @@ case $set_ecmult_window in ;; esac -# Set ecmult gen precision -if test x"$req_ecmult_gen_precision" = x"auto"; then - set_ecmult_gen_precision=4 -else - set_ecmult_gen_precision=$req_ecmult_gen_precision -fi - -case $set_ecmult_gen_precision in -2|4|8) - SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DECMULT_GEN_PREC_BITS=$set_ecmult_gen_precision" +case $set_ecmult_gen_kb in +2) + SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DCOMB_BLOCKS=2 -DCOMB_TEETH=5" + ;; +22) + SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DCOMB_BLOCKS=11 -DCOMB_TEETH=6" + ;; +86) + SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DCOMB_BLOCKS=43 -DCOMB_TEETH=6" ;; *) - AC_MSG_ERROR(['ecmult gen precision not 2, 4, 8 or "auto"']) + AC_MSG_ERROR(['ecmult gen table size not 2, 22 or 86']) ;; esac @@ -421,12 +426,7 @@ fi ### Check for --enable-experimental if necessary ### -if test x"$enable_experimental" = x"yes"; then - AC_MSG_NOTICE([******]) - AC_MSG_NOTICE([WARNING: experimental build]) - AC_MSG_NOTICE([Experimental features do not have stable APIs or properties, and may not be safe for production use.]) - AC_MSG_NOTICE([******]) -else +if test x"$enable_experimental" = x"no"; then if test x"$set_asm" = x"arm32"; then AC_MSG_ERROR([ARM32 assembly is experimental. Use --enable-experimental to allow.]) fi @@ -475,7 +475,7 @@ echo " module ellswift = $enable_module_ellswift" echo echo " asm = $set_asm" echo " ecmult window size = $set_ecmult_window" -echo " ecmult gen prec. bits = $set_ecmult_gen_precision" +echo " ecmult gen table size = $set_ecmult_gen_kb KiB" # Hide test-only options unless they're used. if test x"$set_widemul" != xauto; then echo " wide multiplication = $set_widemul" @@ -487,3 +487,17 @@ echo " CPPFLAGS = $CPPFLAGS" echo " SECP_CFLAGS = $SECP_CFLAGS" echo " CFLAGS = $CFLAGS" echo " LDFLAGS = $LDFLAGS" + +if test x"$print_msan_notice" = x"yes"; then + echo + echo "Note:" + echo " MemorySanitizer detected, tried to add -fno-sanitize-memory-param-retval to SECP_CFLAGS" + echo " to avoid false positives in ctime_tests. Pass --disable-ctime-tests to avoid this." +fi + +if test x"$enable_experimental" = x"yes"; then + echo + echo "WARNING: Experimental build" + echo " Experimental features do not have stable APIs or properties, and may not be safe for" + echo " production use." +fi diff --git a/src/secp256k1/include/secp256k1.h b/src/secp256k1/include/secp256k1.h index f4053f2a93..cfbdd528c2 100644 --- a/src/secp256k1/include/secp256k1.h +++ b/src/secp256k1/include/secp256k1.h @@ -474,6 +474,20 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_cmp( const secp256k1_pubkey *pubkey2 ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); +/** Sort public keys using lexicographic (of compressed serialization) order + * + * Returns: 0 if the arguments are invalid. 1 otherwise. + * + * Args: ctx: pointer to a context object + * In: pubkeys: array of pointers to pubkeys to sort + * n_pubkeys: number of elements in the pubkeys array + */ +SECP256K1_API int secp256k1_ec_pubkey_sort( + const secp256k1_context *ctx, + const secp256k1_pubkey **pubkeys, + size_t n_pubkeys +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); + /** Parse an ECDSA signature in compact (64 bytes) format. * * Returns: 1 when the signature could be parsed, 0 otherwise. diff --git a/src/secp256k1/src/ecmult_const_impl.h b/src/secp256k1/src/ecmult_const_impl.h index 7dc4aac25d..0d78f7c3ce 100644 --- a/src/secp256k1/src/ecmult_const_impl.h +++ b/src/secp256k1/src/ecmult_const_impl.h @@ -214,8 +214,8 @@ static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, cons #ifdef VERIFY /* Verify that v1 and v2 are in range [0, 2^129-1]. */ for (i = 129; i < 256; ++i) { - VERIFY_CHECK(secp256k1_scalar_get_bits(&v1, i, 1) == 0); - VERIFY_CHECK(secp256k1_scalar_get_bits(&v2, i, 1) == 0); + VERIFY_CHECK(secp256k1_scalar_get_bits_limb32(&v1, i, 1) == 0); + VERIFY_CHECK(secp256k1_scalar_get_bits_limb32(&v2, i, 1) == 0); } #endif diff --git a/src/secp256k1/src/ecmult_gen.h b/src/secp256k1/src/ecmult_gen.h index a430e8d5d9..43dd10c38d 100644 --- a/src/secp256k1/src/ecmult_gen.h +++ b/src/secp256k1/src/ecmult_gen.h @@ -1,5 +1,5 @@ /*********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * + * Copyright (c) Pieter Wuille, Peter Dettman * * Distributed under the MIT software license, see the accompanying * * file COPYING or https://www.opensource.org/licenses/mit-license.php.* ***********************************************************************/ @@ -10,31 +10,126 @@ #include "scalar.h" #include "group.h" -#ifndef ECMULT_GEN_PREC_BITS -# define ECMULT_GEN_PREC_BITS 4 + +/* Configuration parameters for the signed-digit multi-comb algorithm: + * + * - COMB_BLOCKS is the number of blocks the input is split into. Each + * has a corresponding table. + * - COMB_TEETH is the number of bits simultaneously covered by one table. + * - COMB_RANGE is the number of bits in supported scalars. For production + * purposes, only 256 is reasonable, but smaller numbers are supported for + * exhaustive test mode. + * + * The comb's spacing (COMB_SPACING), or the distance between the teeth, + * is defined as ceil(COMB_RANGE / (COMB_BLOCKS * COMB_TEETH)). Each block covers + * COMB_SPACING * COMB_TEETH consecutive bits in the input. + * + * The size of the precomputed table is COMB_BLOCKS * (1 << (COMB_TEETH - 1)) + * secp256k1_ge_storages. + * + * The number of point additions equals COMB_BLOCKS * COMB_SPACING. Each point + * addition involves a cmov from (1 << (COMB_TEETH - 1)) table entries and a + * conditional negation. + * + * The number of point doublings is COMB_SPACING - 1. */ + +#if defined(EXHAUSTIVE_TEST_ORDER) +/* We need to control these values for exhaustive tests because + * the table cannot have infinities in them (secp256k1_ge_storage + * doesn't support infinities) */ +# undef COMB_BLOCKS +# undef COMB_TEETH +# if EXHAUSTIVE_TEST_ORDER == 7 +# define COMB_RANGE 3 +# define COMB_BLOCKS 1 +# define COMB_TEETH 2 +# elif EXHAUSTIVE_TEST_ORDER == 13 +# define COMB_RANGE 4 +# define COMB_BLOCKS 1 +# define COMB_TEETH 2 +# elif EXHAUSTIVE_TEST_ORDER == 199 +# define COMB_RANGE 8 +# define COMB_BLOCKS 2 +# define COMB_TEETH 3 +# else +# error "Unknown exhaustive test order" +# endif +# if (COMB_RANGE >= 32) || ((EXHAUSTIVE_TEST_ORDER >> (COMB_RANGE - 1)) != 1) +# error "COMB_RANGE != ceil(log2(EXHAUSTIVE_TEST_ORDER+1))" +# endif +#else /* !defined(EXHAUSTIVE_TEST_ORDER) */ +# define COMB_RANGE 256 +#endif /* defined(EXHAUSTIVE_TEST_ORDER) */ + +/* Use (11, 6) as default configuration, which results in a 22 kB table. */ +#ifndef COMB_BLOCKS +# define COMB_BLOCKS 11 # ifdef DEBUG_CONFIG -# pragma message DEBUG_CONFIG_MSG("ECMULT_GEN_PREC_BITS undefined, assuming default value") +# pragma message DEBUG_CONFIG_MSG("COMB_BLOCKS undefined, assuming default value") # endif #endif +#ifndef COMB_TEETH +# define COMB_TEETH 6 +# ifdef DEBUG_CONFIG +# pragma message DEBUG_CONFIG_MSG("COMB_TEETH undefined, assuming default value") +# endif +#endif +/* Use ceil(COMB_RANGE / (COMB_BLOCKS * COMB_TEETH)) as COMB_SPACING. */ +#define COMB_SPACING CEIL_DIV(COMB_RANGE, COMB_BLOCKS * COMB_TEETH) -#ifdef DEBUG_CONFIG -# pragma message DEBUG_CONFIG_DEF(ECMULT_GEN_PREC_BITS) +/* Range checks on the parameters. */ + +/* The remaining COMB_* parameters are derived values, don't modify these. */ +/* - The number of bits covered by all the blocks; must be at least COMB_RANGE. */ +#define COMB_BITS (COMB_BLOCKS * COMB_TEETH * COMB_SPACING) +/* - The number of entries per table. */ +#define COMB_POINTS (1 << (COMB_TEETH - 1)) + +/* Sanity checks. */ +#if !(1 <= COMB_BLOCKS && COMB_BLOCKS <= 256) +# error "COMB_BLOCKS must be in the range [1, 256]" +#endif +#if !(1 <= COMB_TEETH && COMB_TEETH <= 8) +# error "COMB_TEETH must be in the range [1, 8]" +#endif +#if COMB_BITS < COMB_RANGE +# error "COMB_BLOCKS * COMB_TEETH * COMB_SPACING is too low" #endif -#if ECMULT_GEN_PREC_BITS != 2 && ECMULT_GEN_PREC_BITS != 4 && ECMULT_GEN_PREC_BITS != 8 -# error "Set ECMULT_GEN_PREC_BITS to 2, 4 or 8." +/* These last 2 checks are not strictly required, but prevent gratuitously inefficient + * configurations. Note that they compare with 256 rather than COMB_RANGE, so they do + * permit somewhat excessive values for the exhaustive test case, where testing with + * suboptimal parameters may be desirable. */ +#if (COMB_BLOCKS - 1) * COMB_TEETH * COMB_SPACING >= 256 +# error "COMB_BLOCKS can be reduced" +#endif +#if COMB_BLOCKS * (COMB_TEETH - 1) * COMB_SPACING >= 256 +# error "COMB_TEETH can be reduced" #endif -#define ECMULT_GEN_PREC_G(bits) (1 << bits) -#define ECMULT_GEN_PREC_N(bits) (256 / bits) +#ifdef DEBUG_CONFIG +# pragma message DEBUG_CONFIG_DEF(COMB_RANGE) +# pragma message DEBUG_CONFIG_DEF(COMB_BLOCKS) +# pragma message DEBUG_CONFIG_DEF(COMB_TEETH) +# pragma message DEBUG_CONFIG_DEF(COMB_SPACING) +#endif typedef struct { /* Whether the context has been built. */ int built; - /* Blinding values used when computing (n-b)G + bG. */ - secp256k1_scalar blind; /* -b */ - secp256k1_gej initial; /* bG */ + /* Values chosen such that + * + * n*G == comb(n + scalar_offset, G/2) + ge_offset. + * + * This expression lets us use scalar blinding and optimize the comb precomputation. See + * ecmult_gen_impl.h for more details. */ + secp256k1_scalar scalar_offset; + secp256k1_ge ge_offset; + + /* Factor used for projective blinding. This value is used to rescale the Z + * coordinate of the first table lookup. */ + secp256k1_fe proj_blind; } secp256k1_ecmult_gen_context; static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context* ctx); diff --git a/src/secp256k1/src/ecmult_gen_compute_table.h b/src/secp256k1/src/ecmult_gen_compute_table.h index e577158d92..bd41803a87 100644 --- a/src/secp256k1/src/ecmult_gen_compute_table.h +++ b/src/secp256k1/src/ecmult_gen_compute_table.h @@ -1,5 +1,5 @@ /*********************************************************************** - * Copyright (c) 2013, 2014, 2015 Pieter Wuille, Gregory Maxwell * + * Copyright (c) Pieter Wuille, Gregory Maxwell * * Distributed under the MIT software license, see the accompanying * * file COPYING or https://www.opensource.org/licenses/mit-license.php.* ***********************************************************************/ @@ -9,6 +9,6 @@ #include "ecmult_gen.h" -static void secp256k1_ecmult_gen_compute_table(secp256k1_ge_storage* table, const secp256k1_ge* gen, int bits); +static void secp256k1_ecmult_gen_compute_table(secp256k1_ge_storage* table, const secp256k1_ge* gen, int blocks, int teeth, int spacing); #endif /* SECP256K1_ECMULT_GEN_COMPUTE_TABLE_H */ diff --git a/src/secp256k1/src/ecmult_gen_compute_table_impl.h b/src/secp256k1/src/ecmult_gen_compute_table_impl.h index dfbacdbfde..6aa8d84082 100644 --- a/src/secp256k1/src/ecmult_gen_compute_table_impl.h +++ b/src/secp256k1/src/ecmult_gen_compute_table_impl.h @@ -1,5 +1,5 @@ /*********************************************************************** - * Copyright (c) 2013, 2014, 2015 Pieter Wuille, Gregory Maxwell * + * Copyright (c) Pieter Wuille, Gregory Maxwell, Peter Dettman * * Distributed under the MIT software license, see the accompanying * * file COPYING or https://www.opensource.org/licenses/mit-license.php.* ***********************************************************************/ @@ -10,74 +10,98 @@ #include "ecmult_gen_compute_table.h" #include "group_impl.h" #include "field_impl.h" +#include "scalar_impl.h" #include "ecmult_gen.h" #include "util.h" -static void secp256k1_ecmult_gen_compute_table(secp256k1_ge_storage* table, const secp256k1_ge* gen, int bits) { - int g = ECMULT_GEN_PREC_G(bits); - int n = ECMULT_GEN_PREC_N(bits); +static void secp256k1_ecmult_gen_compute_table(secp256k1_ge_storage* table, const secp256k1_ge* gen, int blocks, int teeth, int spacing) { + size_t points = ((size_t)1) << (teeth - 1); + size_t points_total = points * blocks; + secp256k1_ge* prec = checked_malloc(&default_error_callback, points_total * sizeof(*prec)); + secp256k1_gej* ds = checked_malloc(&default_error_callback, teeth * sizeof(*ds)); + secp256k1_gej* vs = checked_malloc(&default_error_callback, points_total * sizeof(*vs)); + secp256k1_gej u; + size_t vs_pos = 0; + secp256k1_scalar half; + int block, i; - secp256k1_ge* prec = checked_malloc(&default_error_callback, n * g * sizeof(*prec)); - secp256k1_gej gj; - secp256k1_gej nums_gej; - int i, j; + VERIFY_CHECK(points_total > 0); - VERIFY_CHECK(g > 0); - VERIFY_CHECK(n > 0); - - /* get the generator */ - secp256k1_gej_set_ge(&gj, gen); - - /* Construct a group element with no known corresponding scalar (nothing up my sleeve). */ + /* u is the running power of two times gen we're working with, initially gen/2. */ + secp256k1_scalar_half(&half, &secp256k1_scalar_one); + secp256k1_gej_set_infinity(&u); + for (i = 255; i >= 0; --i) { + /* Use a very simple multiplication ladder to avoid dependency on ecmult. */ + secp256k1_gej_double_var(&u, &u, NULL); + if (secp256k1_scalar_get_bits_limb32(&half, i, 1)) { + secp256k1_gej_add_ge_var(&u, &u, gen, NULL); + } + } +#ifdef VERIFY { - static const unsigned char nums_b32[33] = "The scalar for this x is unknown"; - secp256k1_fe nums_x; - secp256k1_ge nums_ge; - int r; - r = secp256k1_fe_set_b32_limit(&nums_x, nums_b32); - (void)r; - VERIFY_CHECK(r); - r = secp256k1_ge_set_xo_var(&nums_ge, &nums_x, 0); - (void)r; - VERIFY_CHECK(r); - secp256k1_gej_set_ge(&nums_gej, &nums_ge); - /* Add G to make the bits in x uniformly distributed. */ - secp256k1_gej_add_ge_var(&nums_gej, &nums_gej, gen, NULL); + /* Verify that u*2 = gen. */ + secp256k1_gej double_u; + secp256k1_gej_double_var(&double_u, &u, NULL); + VERIFY_CHECK(secp256k1_gej_eq_ge_var(&double_u, gen)); } +#endif - /* compute prec. */ - { - secp256k1_gej gbase; - secp256k1_gej numsbase; - secp256k1_gej* precj = checked_malloc(&default_error_callback, n * g * sizeof(*precj)); /* Jacobian versions of prec. */ - gbase = gj; /* PREC_G^j * G */ - numsbase = nums_gej; /* 2^j * nums. */ - for (j = 0; j < n; j++) { - /* Set precj[j*PREC_G .. j*PREC_G+(PREC_G-1)] to (numsbase, numsbase + gbase, ..., numsbase + (PREC_G-1)*gbase). */ - precj[j*g] = numsbase; - for (i = 1; i < g; i++) { - secp256k1_gej_add_var(&precj[j*g + i], &precj[j*g + i - 1], &gbase, NULL); + for (block = 0; block < blocks; ++block) { + int tooth; + /* Here u = 2^(block*teeth*spacing) * gen/2. */ + secp256k1_gej sum; + secp256k1_gej_set_infinity(&sum); + for (tooth = 0; tooth < teeth; ++tooth) { + /* Here u = 2^((block*teeth + tooth)*spacing) * gen/2. */ + /* Make sum = sum(2^((block*teeth + t)*spacing), t=0..tooth) * gen/2. */ + secp256k1_gej_add_var(&sum, &sum, &u, NULL); + /* Make u = 2^((block*teeth + tooth)*spacing + 1) * gen/2. */ + secp256k1_gej_double_var(&u, &u, NULL); + /* Make ds[tooth] = u = 2^((block*teeth + tooth)*spacing + 1) * gen/2. */ + ds[tooth] = u; + /* Make u = 2^((block*teeth + tooth + 1)*spacing) * gen/2, unless at the end. */ + if (block + tooth != blocks + teeth - 2) { + int bit_off; + for (bit_off = 1; bit_off < spacing; ++bit_off) { + secp256k1_gej_double_var(&u, &u, NULL); + } } - /* Multiply gbase by PREC_G. */ - for (i = 0; i < bits; i++) { - secp256k1_gej_double_var(&gbase, &gbase, NULL); - } - /* Multiply numbase by 2. */ - secp256k1_gej_double_var(&numsbase, &numsbase, NULL); - if (j == n - 2) { - /* In the last iteration, numsbase is (1 - 2^j) * nums instead. */ - secp256k1_gej_neg(&numsbase, &numsbase); - secp256k1_gej_add_var(&numsbase, &numsbase, &nums_gej, NULL); + } + /* Now u = 2^((block*teeth + teeth)*spacing) * gen/2 + * = 2^((block+1)*teeth*spacing) * gen/2 */ + + /* Next, compute the table entries for block number block in Jacobian coordinates. + * The entries will occupy vs[block*points + i] for i=0..points-1. + * We start by computing the first (i=0) value corresponding to all summed + * powers of two times G being negative. */ + secp256k1_gej_neg(&vs[vs_pos++], &sum); + /* And then teeth-1 times "double" the range of i values for which the table + * is computed: in each iteration, double the table by taking an existing + * table entry and adding ds[tooth]. */ + for (tooth = 0; tooth < teeth - 1; ++tooth) { + size_t stride = ((size_t)1) << tooth; + size_t index; + for (index = 0; index < stride; ++index, ++vs_pos) { + secp256k1_gej_add_var(&vs[vs_pos], &vs[vs_pos - stride], &ds[tooth], NULL); } } - secp256k1_ge_set_all_gej_var(prec, precj, n * g); - free(precj); } - for (j = 0; j < n; j++) { - for (i = 0; i < g; i++) { - secp256k1_ge_to_storage(&table[j*g + i], &prec[j*g + i]); + VERIFY_CHECK(vs_pos == points_total); + + /* Convert all points simultaneously from secp256k1_gej to secp256k1_ge. */ + secp256k1_ge_set_all_gej_var(prec, vs, points_total); + /* Convert all points from secp256k1_ge to secp256k1_ge_storage output. */ + for (block = 0; block < blocks; ++block) { + size_t index; + for (index = 0; index < points; ++index) { + VERIFY_CHECK(!secp256k1_ge_is_infinity(&prec[block * points + index])); + secp256k1_ge_to_storage(&table[block * points + index], &prec[block * points + index]); } } + + /* Free memory. */ + free(vs); + free(ds); free(prec); } diff --git a/src/secp256k1/src/ecmult_gen_impl.h b/src/secp256k1/src/ecmult_gen_impl.h index af412173e9..2fbf623ca3 100644 --- a/src/secp256k1/src/ecmult_gen_impl.h +++ b/src/secp256k1/src/ecmult_gen_impl.h @@ -1,5 +1,5 @@ /*********************************************************************** - * Copyright (c) 2013, 2014, 2015 Pieter Wuille, Gregory Maxwell * + * Copyright (c) Pieter Wuille, Gregory Maxwell, Peter Dettman * * Distributed under the MIT software license, see the accompanying * * file COPYING or https://www.opensource.org/licenses/mit-license.php.* ***********************************************************************/ @@ -25,41 +25,215 @@ static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_cont static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context *ctx) { ctx->built = 0; - secp256k1_scalar_clear(&ctx->blind); - secp256k1_gej_clear(&ctx->initial); + secp256k1_scalar_clear(&ctx->scalar_offset); + secp256k1_ge_clear(&ctx->ge_offset); + secp256k1_fe_clear(&ctx->proj_blind); } -/* For accelerating the computation of a*G: - * To harden against timing attacks, use the following mechanism: - * * Break up the multiplicand into groups of PREC_BITS bits, called n_0, n_1, n_2, ..., n_(PREC_N-1). - * * Compute sum(n_i * (PREC_G)^i * G + U_i, i=0 ... PREC_N-1), where: - * * U_i = U * 2^i, for i=0 ... PREC_N-2 - * * U_i = U * (1-2^(PREC_N-1)), for i=PREC_N-1 - * where U is a point with no known corresponding scalar. Note that sum(U_i, i=0 ... PREC_N-1) = 0. - * For each i, and each of the PREC_G possible values of n_i, (n_i * (PREC_G)^i * G + U_i) is - * precomputed (call it prec(i, n_i)). The formula now becomes sum(prec(i, n_i), i=0 ... PREC_N-1). - * None of the resulting prec group elements have a known scalar, and neither do any of - * the intermediate sums while computing a*G. - * The prec values are stored in secp256k1_ecmult_gen_prec_table[i][n_i] = n_i * (PREC_G)^i * G + U_i. - */ -static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context *ctx, secp256k1_gej *r, const secp256k1_scalar *gn) { - int bits = ECMULT_GEN_PREC_BITS; - int g = ECMULT_GEN_PREC_G(bits); - int n = ECMULT_GEN_PREC_N(bits); +/* Compute the scalar (2^COMB_BITS - 1) / 2, the difference between the gn argument to + * secp256k1_ecmult_gen, and the scalar whose encoding the table lookup bits are drawn + * from (before applying blinding). */ +static void secp256k1_ecmult_gen_scalar_diff(secp256k1_scalar* diff) { + int i; + + /* Compute scalar -1/2. */ + secp256k1_scalar neghalf; + secp256k1_scalar_half(&neghalf, &secp256k1_scalar_one); + secp256k1_scalar_negate(&neghalf, &neghalf); + + /* Compute offset = 2^(COMB_BITS - 1). */ + *diff = secp256k1_scalar_one; + for (i = 0; i < COMB_BITS - 1; ++i) { + secp256k1_scalar_add(diff, diff, diff); + } + /* The result is the sum 2^(COMB_BITS - 1) + (-1/2). */ + secp256k1_scalar_add(diff, diff, &neghalf); +} + +static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context *ctx, secp256k1_gej *r, const secp256k1_scalar *gn) { + uint32_t comb_off; secp256k1_ge add; + secp256k1_fe neg; secp256k1_ge_storage adds; - secp256k1_scalar gnb; - int i, j, n_i; - + secp256k1_scalar d; + /* Array of uint32_t values large enough to store COMB_BITS bits. Only the bottom + * 8 are ever nonzero, but having the zero padding at the end if COMB_BITS>256 + * avoids the need to deal with out-of-bounds reads from a scalar. */ + uint32_t recoded[(COMB_BITS + 31) >> 5] = {0}; + int first = 1, i; + memset(&adds, 0, sizeof(adds)); - *r = ctx->initial; - /* Blind scalar/point multiplication by computing (n-b)G + bG instead of nG. */ - secp256k1_scalar_add(&gnb, gn, &ctx->blind); - add.infinity = 0; - for (i = 0; i < n; i++) { - n_i = secp256k1_scalar_get_bits(&gnb, i * bits, bits); - for (j = 0; j < g; j++) { + + /* We want to compute R = gn*G. + * + * To blind the scalar used in the computation, we rewrite this to be + * R = (gn - b)*G + b*G, with a blinding value b determined by the context. + * + * The multiplication (gn-b)*G will be performed using a signed-digit multi-comb (see Section + * 3.3 of "Fast and compact elliptic-curve cryptography" by Mike Hamburg, + * https://eprint.iacr.org/2012/309). + * + * Let comb(s, P) = sum((2*s[i]-1)*2^i*P for i=0..COMB_BITS-1), where s[i] is the i'th bit of + * the binary representation of scalar s. So the s[i] values determine whether -2^i*P (s[i]=0) + * or +2^i*P (s[i]=1) are added together. COMB_BITS is at least 256, so all bits of s are + * covered. By manipulating: + * + * comb(s, P) = sum((2*s[i]-1)*2^i*P for i=0..COMB_BITS-1) + * <=> comb(s, P) = sum((2*s[i]-1)*2^i for i=0..COMB_BITS-1) * P + * <=> comb(s, P) = (2*sum(s[i]*2^i for i=0..COMB_BITS-1) - sum(2^i for i=0..COMB_BITS-1)) * P + * <=> comb(s, P) = (2*s - (2^COMB_BITS - 1)) * P + * + * If we wanted to compute (gn-b)*G as comb(s, G), it would need to hold that + * + * (gn - b) * G = (2*s - (2^COMB_BITS - 1)) * G + * <=> s = (gn - b + (2^COMB_BITS - 1))/2 (mod order) + * + * We use an alternative here that avoids the modular division by two: instead we compute + * (gn-b)*G as comb(d, G/2). For that to hold it must be the case that + * + * (gn - b) * G = (2*d - (2^COMB_BITS - 1)) * (G/2) + * <=> d = gn - b + (2^COMB_BITS - 1)/2 (mod order) + * + * Adding precomputation, our final equations become: + * + * ctx->scalar_offset = (2^COMB_BITS - 1)/2 - b (mod order) + * ctx->ge_offset = b*G + * d = gn + ctx->scalar_offset (mod order) + * R = comb(d, G/2) + ctx->ge_offset + * + * comb(d, G/2) function is then computed by summing + or - 2^(i-1)*G, for i=0..COMB_BITS-1, + * depending on the value of the bits d[i] of the binary representation of scalar d. + */ + + /* Compute the scalar d = (gn + ctx->scalar_offset). */ + secp256k1_scalar_add(&d, &ctx->scalar_offset, gn); + /* Convert to recoded array. */ + for (i = 0; i < 8 && i < ((COMB_BITS + 31) >> 5); ++i) { + recoded[i] = secp256k1_scalar_get_bits_limb32(&d, 32 * i, 32); + } + secp256k1_scalar_clear(&d); + + /* In secp256k1_ecmult_gen_prec_table we have precomputed sums of the + * (2*d[i]-1) * 2^(i-1) * G points, for various combinations of i positions. + * We rewrite our equation in terms of these table entries. + * + * Let mask(b) = sum(2^((b*COMB_TEETH + t)*COMB_SPACING) for t=0..COMB_TEETH-1), + * with b ranging from 0 to COMB_BLOCKS-1. So for example with COMB_BLOCKS=11, + * COMB_TEETH=6, COMB_SPACING=4, we would have: + * mask(0) = 2^0 + 2^4 + 2^8 + 2^12 + 2^16 + 2^20, + * mask(1) = 2^24 + 2^28 + 2^32 + 2^36 + 2^40 + 2^44, + * mask(2) = 2^48 + 2^52 + 2^56 + 2^60 + 2^64 + 2^68, + * ... + * mask(10) = 2^240 + 2^244 + 2^248 + 2^252 + 2^256 + 2^260 + * + * We will split up the bits d[i] using these masks. Specifically, each mask is + * used COMB_SPACING times, with different shifts: + * + * d = (d & mask(0)<<0) + (d & mask(1)<<0) + ... + (d & mask(COMB_BLOCKS-1)<<0) + + * (d & mask(0)<<1) + (d & mask(1)<<1) + ... + (d & mask(COMB_BLOCKS-1)<<1) + + * ... + * (d & mask(0)<<(COMB_SPACING-1)) + ... + * + * Now define table(b, m) = (m - mask(b)/2) * G, and we will precompute these values for + * b=0..COMB_BLOCKS-1, and for all values m which (d & mask(b)) can take (so m can take on + * 2^COMB_TEETH distinct values). + * + * If m=(d & mask(b)), then table(b, m) is the sum of 2^i * (2*d[i]-1) * G/2, with i + * iterating over the set bits in mask(b). In our example, table(2, 2^48 + 2^56 + 2^68) + * would equal (2^48 - 2^52 + 2^56 - 2^60 - 2^64 + 2^68) * G/2. + * + * With that, we can rewrite comb(d, G/2) as: + * + * 2^0 * (table(0, d>>0 & mask(0)) + ... + table(COMB_BLOCKS-1, d>>0 & mask(COMP_BLOCKS-1))) + * + 2^1 * (table(0, d>>1 & mask(0)) + ... + table(COMB_BLOCKS-1, d>>1 & mask(COMP_BLOCKS-1))) + * + 2^2 * (table(0, d>>2 & mask(0)) + ... + table(COMB_BLOCKS-1, d>>2 & mask(COMP_BLOCKS-1))) + * + ... + * + 2^(COMB_SPACING-1) * (table(0, d>>(COMB_SPACING-1) & mask(0)) + ...) + * + * Or more generically as + * + * sum(2^i * sum(table(b, d>>i & mask(b)), b=0..COMB_BLOCKS-1), i=0..COMB_SPACING-1) + * + * This is implemented using an outer loop that runs in reverse order over the lines of this + * equation, which in each iteration runs an inner loop that adds the terms of that line and + * then doubles the result before proceeding to the next line. + * + * In pseudocode: + * c = infinity + * for comb_off in range(COMB_SPACING - 1, -1, -1): + * for block in range(COMB_BLOCKS): + * c += table(block, (d >> comb_off) & mask(block)) + * if comb_off > 0: + * c = 2*c + * return c + * + * This computes c = comb(d, G/2), and thus finally R = c + ctx->ge_offset. Note that it would + * be possible to apply an initial offset instead of a final offset (moving ge_offset to take + * the place of infinity above), but the chosen approach allows using (in a future improvement) + * an incomplete addition formula for most of the multiplication. + * + * The last question is how to implement the table(b, m) function. For any value of b, + * m=(d & mask(b)) can only take on at most 2^COMB_TEETH possible values (the last one may have + * fewer as there mask(b) may exceed the curve order). So we could create COMB_BLOCK tables + * which contain a value for each such m value. + * + * Now note that if m=(d & mask(b)), then flipping the relevant bits of m results in negating + * the result of table(b, m). This is because table(b,m XOR mask(b)) = table(b, mask(b) - m) = + * (mask(b) - m - mask(b)/2)*G = (-m + mask(b)/2)*G = -(m - mask(b)/2)*G = -table(b, m). + * Because of this it suffices to only store the first half of the m values for every b. If an + * entry from the second half is needed, we look up its bit-flipped version instead, and negate + * it. + * + * secp256k1_ecmult_gen_prec_table[b][index] stores the table(b, m) entries. Index + * is the relevant mask(b) bits of m packed together without gaps. */ + + /* Outer loop: iterate over comb_off from COMB_SPACING - 1 down to 0. */ + comb_off = COMB_SPACING - 1; + while (1) { + uint32_t block; + uint32_t bit_pos = comb_off; + /* Inner loop: for each block, add table entries to the result. */ + for (block = 0; block < COMB_BLOCKS; ++block) { + /* Gather the mask(block)-selected bits of d into bits. They're packed: + * bits[tooth] = d[(block*COMB_TEETH + tooth)*COMB_SPACING + comb_off]. */ + uint32_t bits = 0, sign, abs, index, tooth; + /* Instead of reading individual bits here to construct the bits variable, + * build up the result by xoring rotated reads together. In every iteration, + * one additional bit is made correct, starting at the bottom. The bits + * above that contain junk. This reduces leakage by avoiding computations + * on variables that can have only a low number of possible values (e.g., + * just two values when reading a single bit into a variable.) See: + * https://www.usenix.org/system/files/conference/usenixsecurity18/sec18-alam.pdf + */ + for (tooth = 0; tooth < COMB_TEETH; ++tooth) { + /* Construct bitdata s.t. the bottom bit is the bit we'd like to read. + * + * We could just set bitdata = recoded[bit_pos >> 5] >> (bit_pos & 0x1f) + * but this would simply discard the bits that fall off at the bottom, + * and thus, for example, bitdata could still have only two values if we + * happen to shift by exactly 31 positions. We use a rotation instead, + * which ensures that bitdata doesn't loose entropy. This relies on the + * rotation being atomic, i.e., the compiler emitting an actual rot + * instruction. */ + uint32_t bitdata = secp256k1_rotr32(recoded[bit_pos >> 5], bit_pos & 0x1f); + + /* Clear the bit at position tooth, but sssh, don't tell clang. */ + uint32_t volatile vmask = ~(1 << tooth); + bits &= vmask; + + /* Write the bit into position tooth (and junk into higher bits). */ + bits ^= bitdata << tooth; + bit_pos += COMB_SPACING; + } + + /* If the top bit of bits is 1, flip them all (corresponding to looking up + * the negated table value), and remember to negate the result in sign. */ + sign = (bits >> (COMB_TEETH - 1)) & 1; + abs = (bits ^ -sign) & (COMB_POINTS - 1); + VERIFY_CHECK(sign == 0 || sign == 1); + VERIFY_CHECK(abs < COMB_POINTS); + /** This uses a conditional move to avoid any secret data in array indexes. * _Any_ use of secret indexes has been demonstrated to result in timing * sidechannels, even when the cache-line access patterns are uniform. @@ -70,33 +244,65 @@ static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context *ctx, secp25 * by Dag Arne Osvik, Adi Shamir, and Eran Tromer * (https://www.tau.ac.il/~tromer/papers/cache.pdf) */ - secp256k1_ge_storage_cmov(&adds, &secp256k1_ecmult_gen_prec_table[i][j], j == n_i); + for (index = 0; index < COMB_POINTS; ++index) { + secp256k1_ge_storage_cmov(&adds, &secp256k1_ecmult_gen_prec_table[block][index], index == abs); + } + + /* Set add=adds or add=-adds, in constant time, based on sign. */ + secp256k1_ge_from_storage(&add, &adds); + secp256k1_fe_negate(&neg, &add.y, 1); + secp256k1_fe_cmov(&add.y, &neg, sign); + + /* Add the looked up and conditionally negated value to r. */ + if (EXPECT(first, 0)) { + /* If this is the first table lookup, we can skip addition. */ + secp256k1_gej_set_ge(r, &add); + /* Give the entry a random Z coordinate to blind intermediary results. */ + secp256k1_gej_rescale(r, &ctx->proj_blind); + first = 0; + } else { + secp256k1_gej_add_ge(r, r, &add); + } } - secp256k1_ge_from_storage(&add, &adds); - secp256k1_gej_add_ge(r, r, &add); + + /* Double the result, except in the last iteration. */ + if (comb_off-- == 0) break; + secp256k1_gej_double(r, r); } - n_i = 0; + + /* Correct for the scalar_offset added at the start (ge_offset = b*G, while b was + * subtracted from the input scalar gn). */ + secp256k1_gej_add_ge(r, r, &ctx->ge_offset); + + /* Cleanup. */ + secp256k1_fe_clear(&neg); secp256k1_ge_clear(&add); - secp256k1_scalar_clear(&gnb); + memset(&adds, 0, sizeof(adds)); + memset(&recoded, 0, sizeof(recoded)); } /* Setup blinding values for secp256k1_ecmult_gen. */ static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const unsigned char *seed32) { secp256k1_scalar b; + secp256k1_scalar diff; secp256k1_gej gb; - secp256k1_fe s; + secp256k1_fe f; unsigned char nonce32[32]; secp256k1_rfc6979_hmac_sha256 rng; unsigned char keydata[64]; + + /* Compute the (2^COMB_BITS - 1)/2 term once. */ + secp256k1_ecmult_gen_scalar_diff(&diff); + if (seed32 == NULL) { - /* When seed is NULL, reset the initial point and blinding value. */ - secp256k1_gej_set_ge(&ctx->initial, &secp256k1_ge_const_g); - secp256k1_gej_neg(&ctx->initial, &ctx->initial); - secp256k1_scalar_set_int(&ctx->blind, 1); + /* When seed is NULL, reset the final point and blinding value. */ + secp256k1_ge_neg(&ctx->ge_offset, &secp256k1_ge_const_g); + secp256k1_scalar_add(&ctx->scalar_offset, &secp256k1_scalar_one, &diff); + ctx->proj_blind = secp256k1_fe_one; return; } /* The prior blinding value (if not reset) is chained forward by including it in the hash. */ - secp256k1_scalar_get_b32(keydata, &ctx->blind); + secp256k1_scalar_get_b32(keydata, &ctx->scalar_offset); /** Using a CSPRNG allows a failure free interface, avoids needing large amounts of random data, * and guards against weak or adversarial seeds. This is a simpler and safer interface than * asking the caller for blinding values directly and expecting them to retry on failure. @@ -105,26 +311,30 @@ static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const memcpy(keydata + 32, seed32, 32); secp256k1_rfc6979_hmac_sha256_initialize(&rng, keydata, 64); memset(keydata, 0, sizeof(keydata)); + + /* Compute projective blinding factor (cannot be 0). */ secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); - secp256k1_fe_set_b32_mod(&s, nonce32); - secp256k1_fe_cmov(&s, &secp256k1_fe_one, secp256k1_fe_normalizes_to_zero(&s)); - /* Randomize the projection to defend against multiplier sidechannels. - Do this before our own call to secp256k1_ecmult_gen below. */ - secp256k1_gej_rescale(&ctx->initial, &s); - secp256k1_fe_clear(&s); + secp256k1_fe_set_b32_mod(&f, nonce32); + secp256k1_fe_cmov(&f, &secp256k1_fe_one, secp256k1_fe_normalizes_to_zero(&f)); + ctx->proj_blind = f; + + /* For a random blinding value b, set scalar_offset=diff-b, ge_offset=bG */ secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); secp256k1_scalar_set_b32(&b, nonce32, NULL); - /* A blinding value of 0 works, but would undermine the projection hardening. */ + /* The blinding value cannot be zero, as that would mean ge_offset = infinity, + * which secp256k1_gej_add_ge cannot handle. */ secp256k1_scalar_cmov(&b, &secp256k1_scalar_one, secp256k1_scalar_is_zero(&b)); secp256k1_rfc6979_hmac_sha256_finalize(&rng); memset(nonce32, 0, 32); - /* The random projection in ctx->initial ensures that gb will have a random projection. */ secp256k1_ecmult_gen(ctx, &gb, &b); secp256k1_scalar_negate(&b, &b); - ctx->blind = b; - ctx->initial = gb; + secp256k1_scalar_add(&ctx->scalar_offset, &b, &diff); + secp256k1_ge_set_gej(&ctx->ge_offset, &gb); + + /* Clean up. */ secp256k1_scalar_clear(&b); secp256k1_gej_clear(&gb); + secp256k1_fe_clear(&f); } #endif /* SECP256K1_ECMULT_GEN_IMPL_H */ diff --git a/src/secp256k1/src/ecmult_impl.h b/src/secp256k1/src/ecmult_impl.h index 6d14c7ac4b..07d8477eb0 100644 --- a/src/secp256k1/src/ecmult_impl.h +++ b/src/secp256k1/src/ecmult_impl.h @@ -42,7 +42,7 @@ #endif #define WNAF_BITS 128 -#define WNAF_SIZE_BITS(bits, w) (((bits) + (w) - 1) / (w)) +#define WNAF_SIZE_BITS(bits, w) CEIL_DIV(bits, w) #define WNAF_SIZE(w) WNAF_SIZE_BITS(WNAF_BITS, w) /* The number of objects allocated on the scratch space for ecmult_multi algorithms */ @@ -174,7 +174,7 @@ static int secp256k1_ecmult_wnaf(int *wnaf, int len, const secp256k1_scalar *a, memset(wnaf, 0, len * sizeof(wnaf[0])); s = *a; - if (secp256k1_scalar_get_bits(&s, 255, 1)) { + if (secp256k1_scalar_get_bits_limb32(&s, 255, 1)) { secp256k1_scalar_negate(&s, &s); sign = -1; } @@ -182,7 +182,7 @@ static int secp256k1_ecmult_wnaf(int *wnaf, int len, const secp256k1_scalar *a, while (bit < len) { int now; int word; - if (secp256k1_scalar_get_bits(&s, bit, 1) == (unsigned int)carry) { + if (secp256k1_scalar_get_bits_limb32(&s, bit, 1) == (unsigned int)carry) { bit++; continue; } @@ -209,7 +209,7 @@ static int secp256k1_ecmult_wnaf(int *wnaf, int len, const secp256k1_scalar *a, VERIFY_CHECK(carry == 0); while (verify_bit < 256) { - VERIFY_CHECK(secp256k1_scalar_get_bits(&s, verify_bit, 1) == 0); + VERIFY_CHECK(secp256k1_scalar_get_bits_limb32(&s, verify_bit, 1) == 0); verify_bit++; } } @@ -808,8 +808,8 @@ static int secp256k1_ecmult_multi_batch_size_helper(size_t *n_batches, size_t *n return 1; } /* Compute ceil(n/max_n_batch_points) and ceil(n/n_batches) */ - *n_batches = 1 + (n - 1) / max_n_batch_points; - *n_batch_points = 1 + (n - 1) / *n_batches; + *n_batches = CEIL_DIV(n, max_n_batch_points); + *n_batch_points = CEIL_DIV(n, *n_batches); return 1; } diff --git a/src/secp256k1/src/hsort.h b/src/secp256k1/src/hsort.h new file mode 100644 index 0000000000..d54995caad --- /dev/null +++ b/src/secp256k1/src/hsort.h @@ -0,0 +1,33 @@ +/*********************************************************************** + * Copyright (c) 2021 Russell O'Connor, Jonas Nick * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_HSORT_H +#define SECP256K1_HSORT_H + +#include <stddef.h> +#include <string.h> + +/* In-place, iterative heapsort with an interface matching glibc's qsort_r. This + * is preferred over standard library implementations because they generally + * make no guarantee about being fast for malicious inputs. + * Remember that heapsort is unstable. + * + * In/Out: ptr: pointer to the array to sort. The contents of the array are + * sorted in ascending order according to the comparison function. + * In: count: number of elements in the array. + * size: size in bytes of each element. + * cmp: pointer to a comparison function that is called with two + * arguments that point to the objects being compared. The cmp_data + * argument of secp256k1_hsort is passed as third argument. The + * function must return an integer less than, equal to, or greater + * than zero if the first argument is considered to be respectively + * less than, equal to, or greater than the second. + * cmp_data: pointer passed as third argument to cmp. + */ +static void secp256k1_hsort(void *ptr, size_t count, size_t size, + int (*cmp)(const void *, const void *, void *), + void *cmp_data); +#endif diff --git a/src/secp256k1/src/hsort_impl.h b/src/secp256k1/src/hsort_impl.h new file mode 100644 index 0000000000..1c674ff1c4 --- /dev/null +++ b/src/secp256k1/src/hsort_impl.h @@ -0,0 +1,125 @@ +/*********************************************************************** + * Copyright (c) 2021 Russell O'Connor, Jonas Nick * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_HSORT_IMPL_H +#define SECP256K1_HSORT_IMPL_H + +#include "hsort.h" + +/* An array is a heap when, for all non-zero indexes i, the element at index i + * compares as less than or equal to the element at index parent(i) = (i-1)/2. + */ + +static SECP256K1_INLINE size_t secp256k1_heap_child1(size_t i) { + VERIFY_CHECK(i <= (SIZE_MAX - 1)/2); + return 2*i + 1; +} + +static SECP256K1_INLINE size_t secp256k1_heap_child2(size_t i) { + VERIFY_CHECK(i <= SIZE_MAX/2 - 1); + return secp256k1_heap_child1(i)+1; +} + +static SECP256K1_INLINE void secp256k1_heap_swap64(unsigned char *a, unsigned char *b, size_t len) { + unsigned char tmp[64]; + VERIFY_CHECK(len <= 64); + memcpy(tmp, a, len); + memmove(a, b, len); + memcpy(b, tmp, len); +} + +static SECP256K1_INLINE void secp256k1_heap_swap(unsigned char *arr, size_t i, size_t j, size_t stride) { + unsigned char *a = arr + i*stride; + unsigned char *b = arr + j*stride; + size_t len = stride; + while (64 < len) { + secp256k1_heap_swap64(a + (len - 64), b + (len - 64), 64); + len -= 64; + } + secp256k1_heap_swap64(a, b, len); +} + +/* This function accepts an array arr containing heap_size elements, each of + * size stride. The elements in the array at indices >i satisfy the max-heap + * property, i.e., for any element at index j (where j > i), all of its children + * are smaller than the element itself. The purpose of the function is to update + * the array so that all elements at indices >=i satisfy the max-heap + * property. */ +static SECP256K1_INLINE void secp256k1_heap_down(unsigned char *arr, size_t i, size_t heap_size, size_t stride, + int (*cmp)(const void *, const void *, void *), void *cmp_data) { + while (i < heap_size/2) { + VERIFY_CHECK(i <= SIZE_MAX/2 - 1); + /* Proof: + * i < heap_size/2 + * i + 1 <= heap_size/2 + * 2*i + 2 <= heap_size <= SIZE_MAX + * 2*i <= SIZE_MAX - 2 + */ + + VERIFY_CHECK(secp256k1_heap_child1(i) < heap_size); + /* Proof: + * i < heap_size/2 + * i + 1 <= heap_size/2 + * 2*i + 2 <= heap_size + * 2*i + 1 < heap_size + * child1(i) < heap_size + */ + + /* Let [x] be notation for the contents at arr[x*stride]. + * + * If [child1(i)] > [i] and [child2(i)] > [i], + * swap [i] with the larger child to ensure the new parent is larger + * than both children. When [child1(i)] == [child2(i)], swap [i] with + * [child2(i)]. + * Else if [child1(i)] > [i], swap [i] with [child1(i)]. + * Else if [child2(i)] > [i], swap [i] with [child2(i)]. + */ + if (secp256k1_heap_child2(i) < heap_size + && 0 <= cmp(arr + secp256k1_heap_child2(i)*stride, arr + secp256k1_heap_child1(i)*stride, cmp_data)) { + if (0 < cmp(arr + secp256k1_heap_child2(i)*stride, arr + i*stride, cmp_data)) { + secp256k1_heap_swap(arr, i, secp256k1_heap_child2(i), stride); + i = secp256k1_heap_child2(i); + } else { + /* At this point we have [child2(i)] >= [child1(i)] and we have + * [child2(i)] <= [i], and thus [child1(i)] <= [i] which means + * that the next comparison can be skipped. */ + return; + } + } else if (0 < cmp(arr + secp256k1_heap_child1(i)*stride, arr + i*stride, cmp_data)) { + secp256k1_heap_swap(arr, i, secp256k1_heap_child1(i), stride); + i = secp256k1_heap_child1(i); + } else { + return; + } + } + /* heap_size/2 <= i + * heap_size/2 < i + 1 + * heap_size < 2*i + 2 + * heap_size <= 2*i + 1 + * heap_size <= child1(i) + * Thus child1(i) and child2(i) are now out of bounds and we are at a leaf. + */ +} + +/* In-place heap sort. */ +static void secp256k1_hsort(void *ptr, size_t count, size_t size, + int (*cmp)(const void *, const void *, void *), + void *cmp_data) { + size_t i; + + for (i = count/2; 0 < i; --i) { + secp256k1_heap_down(ptr, i-1, count, size, cmp, cmp_data); + } + for (i = count; 1 < i; --i) { + /* Extract the largest value from the heap */ + secp256k1_heap_swap(ptr, 0, i-1, size); + + /* Repair the heap condition */ + secp256k1_heap_down(ptr, 0, i-1, size, cmp, cmp_data); + } +} + +#endif diff --git a/src/secp256k1/src/modules/ecdh/tests_impl.h b/src/secp256k1/src/modules/ecdh/tests_impl.h index 6be96eacbe..3c3acdaf8c 100644 --- a/src/secp256k1/src/modules/ecdh/tests_impl.h +++ b/src/secp256k1/src/modules/ecdh/tests_impl.h @@ -56,7 +56,7 @@ static void test_ecdh_generator_basepoint(void) { size_t point_ser_len = sizeof(point_ser); secp256k1_scalar s; - random_scalar_order(&s); + testutil_random_scalar_order(&s); secp256k1_scalar_get_b32(s_b32, &s); CHECK(secp256k1_ec_pubkey_create(CTX, &point[0], s_one) == 1); @@ -95,7 +95,7 @@ static void test_bad_scalar(void) { secp256k1_pubkey point; /* Create random point */ - random_scalar_order(&rand); + testutil_random_scalar_order(&rand); secp256k1_scalar_get_b32(s_rand, &rand); CHECK(secp256k1_ec_pubkey_create(CTX, &point, s_rand) == 1); @@ -127,7 +127,7 @@ static void test_result_basepoint(void) { CHECK(secp256k1_ecdh(CTX, out_base, &point, s_one, NULL, NULL) == 1); for (i = 0; i < 2 * COUNT; i++) { - random_scalar_order(&rand); + testutil_random_scalar_order(&rand); secp256k1_scalar_get_b32(s, &rand); secp256k1_scalar_inverse(&rand, &rand); secp256k1_scalar_get_b32(s_inv, &rand); diff --git a/src/secp256k1/src/modules/ellswift/tests_impl.h b/src/secp256k1/src/modules/ellswift/tests_impl.h index f96e3a1268..ed5658f34c 100644 --- a/src/secp256k1/src/modules/ellswift/tests_impl.h +++ b/src/secp256k1/src/modules/ellswift/tests_impl.h @@ -229,9 +229,9 @@ void run_ellswift_tests(void) { secp256k1_ge g, g2; secp256k1_pubkey pubkey, pubkey2; /* Generate random public key and random randomizer. */ - random_group_element_test(&g); + testutil_random_ge_test(&g); secp256k1_pubkey_save(&pubkey, &g); - secp256k1_testrand256(rnd32); + testrand256(rnd32); /* Convert the public key to ElligatorSwift and back. */ secp256k1_ellswift_encode(CTX, ell64, &pubkey, rnd32); secp256k1_ellswift_decode(CTX, &pubkey2, ell64); @@ -249,8 +249,8 @@ void run_ellswift_tests(void) { unsigned char ell64[64]; int ret; /* Generate random secret key and random randomizer. */ - if (i & 1) secp256k1_testrand256_test(auxrnd32); - random_scalar_order_test(&sec); + if (i & 1) testrand256_test(auxrnd32); + testutil_random_scalar_order_test(&sec); secp256k1_scalar_get_b32(sec32, &sec); /* Construct ElligatorSwift-encoded public keys for that key. */ ret = secp256k1_ellswift_create(CTX, ell64, sec32, (i & 1) ? auxrnd32 : NULL); @@ -271,11 +271,11 @@ void run_ellswift_tests(void) { secp256k1_pubkey pub; int ret; /* Generate random secret key. */ - random_scalar_order_test(&sec); + testutil_random_scalar_order_test(&sec); secp256k1_scalar_get_b32(sec32, &sec); /* Generate random ElligatorSwift encoding for the remote key and decode it. */ - secp256k1_testrand256_test(ell64); - secp256k1_testrand256_test(ell64 + 32); + testrand256_test(ell64); + testrand256_test(ell64 + 32); secp256k1_ellswift_decode(CTX, &pub, ell64); secp256k1_pubkey_load(CTX, &dec, &pub); secp256k1_gej_set_ge(&decj, &dec); @@ -313,18 +313,18 @@ void run_ellswift_tests(void) { data = NULL; } else { hash_function = secp256k1_ellswift_xdh_hash_function_prefix; - secp256k1_testrand256_test(prefix64); - secp256k1_testrand256_test(prefix64 + 32); + testrand256_test(prefix64); + testrand256_test(prefix64 + 32); data = prefix64; } /* Generate random secret keys and random randomizers. */ - secp256k1_testrand256_test(auxrnd32a); - secp256k1_testrand256_test(auxrnd32b); - random_scalar_order_test(&seca); + testrand256_test(auxrnd32a); + testrand256_test(auxrnd32b); + testutil_random_scalar_order_test(&seca); /* Draw secb uniformly at random to make sure that the secret keys * differ */ - random_scalar_order(&secb); + testutil_random_scalar_order(&secb); secp256k1_scalar_get_b32(sec32a, &seca); secp256k1_scalar_get_b32(sec32b, &secb); @@ -349,13 +349,13 @@ void run_ellswift_tests(void) { /* Verify that the shared secret doesn't match if other side's public key is incorrect. */ /* For A (using a bad public key for B): */ memcpy(ell64b_bad, ell64b, sizeof(ell64a_bad)); - secp256k1_testrand_flip(ell64b_bad, sizeof(ell64b_bad)); + testrand_flip(ell64b_bad, sizeof(ell64b_bad)); ret = secp256k1_ellswift_xdh(CTX, share32_bad, ell64a, ell64b_bad, sec32a, 0, hash_function, data); CHECK(ret); /* Mismatching encodings don't get detected by secp256k1_ellswift_xdh. */ CHECK(secp256k1_memcmp_var(share32_bad, share32a, 32) != 0); /* For B (using a bad public key for A): */ memcpy(ell64a_bad, ell64a, sizeof(ell64a_bad)); - secp256k1_testrand_flip(ell64a_bad, sizeof(ell64a_bad)); + testrand_flip(ell64a_bad, sizeof(ell64a_bad)); ret = secp256k1_ellswift_xdh(CTX, share32_bad, ell64a_bad, ell64b, sec32b, 1, hash_function, data); CHECK(ret); CHECK(secp256k1_memcmp_var(share32_bad, share32b, 32) != 0); @@ -363,12 +363,12 @@ void run_ellswift_tests(void) { /* Verify that the shared secret doesn't match if the private key is incorrect. */ /* For A: */ memcpy(sec32a_bad, sec32a, sizeof(sec32a_bad)); - secp256k1_testrand_flip(sec32a_bad, sizeof(sec32a_bad)); + testrand_flip(sec32a_bad, sizeof(sec32a_bad)); ret = secp256k1_ellswift_xdh(CTX, share32_bad, ell64a, ell64b, sec32a_bad, 0, hash_function, data); CHECK(!ret || secp256k1_memcmp_var(share32_bad, share32a, 32) != 0); /* For B: */ memcpy(sec32b_bad, sec32b, sizeof(sec32b_bad)); - secp256k1_testrand_flip(sec32b_bad, sizeof(sec32b_bad)); + testrand_flip(sec32b_bad, sizeof(sec32b_bad)); ret = secp256k1_ellswift_xdh(CTX, share32_bad, ell64a, ell64b, sec32b_bad, 1, hash_function, data); CHECK(!ret || secp256k1_memcmp_var(share32_bad, share32b, 32) != 0); @@ -376,7 +376,7 @@ void run_ellswift_tests(void) { /* Verify that the shared secret doesn't match when a different encoding of the same public key is used. */ /* For A (changing B's public key): */ memcpy(auxrnd32b_bad, auxrnd32b, sizeof(auxrnd32b_bad)); - secp256k1_testrand_flip(auxrnd32b_bad, sizeof(auxrnd32b_bad)); + testrand_flip(auxrnd32b_bad, sizeof(auxrnd32b_bad)); ret = secp256k1_ellswift_create(CTX, ell64b_bad, sec32b, auxrnd32b_bad); CHECK(ret); ret = secp256k1_ellswift_xdh(CTX, share32_bad, ell64a, ell64b_bad, sec32a, 0, hash_function, data); @@ -384,7 +384,7 @@ void run_ellswift_tests(void) { CHECK(secp256k1_memcmp_var(share32_bad, share32a, 32) != 0); /* For B (changing A's public key): */ memcpy(auxrnd32a_bad, auxrnd32a, sizeof(auxrnd32a_bad)); - secp256k1_testrand_flip(auxrnd32a_bad, sizeof(auxrnd32a_bad)); + testrand_flip(auxrnd32a_bad, sizeof(auxrnd32a_bad)); ret = secp256k1_ellswift_create(CTX, ell64a_bad, sec32a, auxrnd32a_bad); CHECK(ret); ret = secp256k1_ellswift_xdh(CTX, share32_bad, ell64a_bad, ell64b, sec32b, 1, hash_function, data); diff --git a/src/secp256k1/src/modules/extrakeys/tests_impl.h b/src/secp256k1/src/modules/extrakeys/tests_impl.h index 45521d1742..ab4ef4a74b 100644 --- a/src/secp256k1/src/modules/extrakeys/tests_impl.h +++ b/src/secp256k1/src/modules/extrakeys/tests_impl.h @@ -23,9 +23,9 @@ static void test_xonly_pubkey(void) { int pk_parity; int i; - secp256k1_testrand256(sk); + testrand256(sk); memset(ones32, 0xFF, 32); - secp256k1_testrand256(xy_sk); + testrand256(xy_sk); CHECK(secp256k1_ec_pubkey_create(CTX, &pk, sk) == 1); CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk) == 1); @@ -95,7 +95,7 @@ static void test_xonly_pubkey(void) { * the curve) then xonly_pubkey_parse should fail as well. */ for (i = 0; i < COUNT; i++) { unsigned char rand33[33]; - secp256k1_testrand256(&rand33[1]); + testrand256(&rand33[1]); rand33[0] = SECP256K1_TAG_PUBKEY_EVEN; if (!secp256k1_ec_pubkey_parse(CTX, &pk, rand33, 33)) { memset(&xonly_pk, 1, sizeof(xonly_pk)); @@ -152,8 +152,8 @@ static void test_xonly_pubkey_tweak(void) { int i; memset(overflows, 0xff, sizeof(overflows)); - secp256k1_testrand256(tweak); - secp256k1_testrand256(sk); + testrand256(tweak); + testrand256(sk); CHECK(secp256k1_ec_pubkey_create(CTX, &internal_pk, sk) == 1); CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &internal_xonly_pk, &pk_parity, &internal_pk) == 1); @@ -190,7 +190,7 @@ static void test_xonly_pubkey_tweak(void) { /* Invalid pk with a valid tweak */ memset(&internal_xonly_pk, 0, sizeof(internal_xonly_pk)); - secp256k1_testrand256(tweak); + testrand256(tweak); CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak)); CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0); } @@ -209,8 +209,8 @@ static void test_xonly_pubkey_tweak_check(void) { unsigned char tweak[32]; memset(overflows, 0xff, sizeof(overflows)); - secp256k1_testrand256(tweak); - secp256k1_testrand256(sk); + testrand256(tweak); + testrand256(sk); CHECK(secp256k1_ec_pubkey_create(CTX, &internal_pk, sk) == 1); CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &internal_xonly_pk, &pk_parity, &internal_pk) == 1); @@ -256,7 +256,7 @@ static void test_xonly_pubkey_tweak_recursive(void) { unsigned char tweak[N_PUBKEYS - 1][32]; int i; - secp256k1_testrand256(sk); + testrand256(sk); CHECK(secp256k1_ec_pubkey_create(CTX, &pk[0], sk) == 1); /* Add tweaks */ for (i = 0; i < N_PUBKEYS - 1; i++) { @@ -292,7 +292,7 @@ static void test_keypair(void) { memset(overflows, 0xFF, sizeof(overflows)); /* Test keypair_create */ - secp256k1_testrand256(sk); + testrand256(sk); CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1); CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) != 0); CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1); @@ -311,7 +311,7 @@ static void test_keypair(void) { CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0); /* Test keypair_pub */ - secp256k1_testrand256(sk); + testrand256(sk); CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1); CHECK(secp256k1_keypair_pub(CTX, &pk, &keypair) == 1); CHECK_ILLEGAL(CTX, secp256k1_keypair_pub(CTX, NULL, &keypair)); @@ -330,7 +330,7 @@ static void test_keypair(void) { CHECK(secp256k1_memcmp_var(&pk, &pk_tmp, sizeof(pk)) == 0); /** Test keypair_xonly_pub **/ - secp256k1_testrand256(sk); + testrand256(sk); CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1); CHECK(secp256k1_keypair_xonly_pub(CTX, &xonly_pk, &pk_parity, &keypair) == 1); CHECK_ILLEGAL(CTX, secp256k1_keypair_xonly_pub(CTX, NULL, &pk_parity, &keypair)); @@ -353,7 +353,7 @@ static void test_keypair(void) { CHECK(pk_parity == pk_parity_tmp); /* Test keypair_seckey */ - secp256k1_testrand256(sk); + testrand256(sk); CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1); CHECK(secp256k1_keypair_sec(CTX, sk_tmp, &keypair) == 1); CHECK_ILLEGAL(CTX, secp256k1_keypair_sec(CTX, NULL, &keypair)); @@ -381,8 +381,8 @@ static void test_keypair_add(void) { int i; CHECK(sizeof(zeros96) == sizeof(keypair)); - secp256k1_testrand256(sk); - secp256k1_testrand256(tweak); + testrand256(sk); + testrand256(tweak); memset(overflows, 0xFF, 32); CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1); @@ -407,7 +407,7 @@ static void test_keypair_add(void) { for (i = 0; i < COUNT; i++) { secp256k1_scalar scalar_tweak; secp256k1_keypair keypair_tmp; - secp256k1_testrand256(sk); + testrand256(sk); CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1); memcpy(&keypair_tmp, &keypair, sizeof(keypair)); /* Because sk may be negated before adding, we need to try with tweak = @@ -423,7 +423,7 @@ static void test_keypair_add(void) { /* Invalid keypair with a valid tweak */ memset(&keypair, 0, sizeof(keypair)); - secp256k1_testrand256(tweak); + testrand256(tweak); CHECK_ILLEGAL(CTX, secp256k1_keypair_xonly_tweak_add(CTX, &keypair, tweak)); CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0); /* Only seckey part of keypair invalid */ @@ -446,7 +446,7 @@ static void test_keypair_add(void) { unsigned char sk32[32]; int pk_parity; - secp256k1_testrand256(tweak); + testrand256(tweak); CHECK(secp256k1_keypair_xonly_pub(CTX, &internal_pk, NULL, &keypair) == 1); CHECK(secp256k1_keypair_xonly_tweak_add(CTX, &keypair, tweak) == 1); CHECK(secp256k1_keypair_xonly_pub(CTX, &output_pk, &pk_parity, &keypair) == 1); diff --git a/src/secp256k1/src/modules/recovery/tests_impl.h b/src/secp256k1/src/modules/recovery/tests_impl.h index 728ccfed8d..7a28a3ce65 100644 --- a/src/secp256k1/src/modules/recovery/tests_impl.h +++ b/src/secp256k1/src/modules/recovery/tests_impl.h @@ -25,7 +25,7 @@ static int recovery_test_nonce_function(unsigned char *nonce32, const unsigned c } /* On the next run, return a valid nonce, but flip a coin as to whether or not to fail signing. */ memset(nonce32, 1, 32); - return secp256k1_testrand_bits(1); + return testrand_bits(1); } static void test_ecdsa_recovery_api(void) { @@ -106,8 +106,8 @@ static void test_ecdsa_recovery_end_to_end(void) { /* Generate a random key and message. */ { secp256k1_scalar msg, key; - random_scalar_order_test(&msg); - random_scalar_order_test(&key); + testutil_random_scalar_order_test(&msg); + testutil_random_scalar_order_test(&key); secp256k1_scalar_get_b32(privkey, &key); secp256k1_scalar_get_b32(message, &msg); } @@ -141,7 +141,7 @@ static void test_ecdsa_recovery_end_to_end(void) { CHECK(secp256k1_memcmp_var(&pubkey, &recpubkey, sizeof(pubkey)) == 0); /* Serialize/destroy/parse signature and verify again. */ CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(CTX, sig, &recid, &rsignature[4]) == 1); - sig[secp256k1_testrand_bits(6)] += 1 + secp256k1_testrand_int(255); + sig[testrand_bits(6)] += 1 + testrand_int(255); CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &rsignature[4], sig, recid) == 1); CHECK(secp256k1_ecdsa_recoverable_signature_convert(CTX, &signature[4], &rsignature[4]) == 1); CHECK(secp256k1_ecdsa_verify(CTX, &signature[4], message, &pubkey) == 0); diff --git a/src/secp256k1/src/modules/schnorrsig/tests_exhaustive_impl.h b/src/secp256k1/src/modules/schnorrsig/tests_exhaustive_impl.h index bc31d81107..601b54975d 100644 --- a/src/secp256k1/src/modules/schnorrsig/tests_exhaustive_impl.h +++ b/src/secp256k1/src/modules/schnorrsig/tests_exhaustive_impl.h @@ -104,7 +104,7 @@ static void test_exhaustive_schnorrsig_verify(const secp256k1_context *ctx, cons while (e_count_done < EXHAUSTIVE_TEST_ORDER) { secp256k1_scalar e; unsigned char msg32[32]; - secp256k1_testrand256(msg32); + testrand256(msg32); secp256k1_schnorrsig_challenge(&e, sig64, msg32, sizeof(msg32), pk32); /* Only do work if we hit a challenge we haven't tried before. */ if (!e_done[e]) { @@ -120,7 +120,7 @@ static void test_exhaustive_schnorrsig_verify(const secp256k1_context *ctx, cons expect_valid = actual_k != -1 && s != EXHAUSTIVE_TEST_ORDER && (s == (actual_k + actual_d * e) % EXHAUSTIVE_TEST_ORDER); } else { - secp256k1_testrand256(sig64 + 32); + testrand256(sig64 + 32); expect_valid = 0; } valid = secp256k1_schnorrsig_verify(ctx, sig64, msg32, sizeof(msg32), &pubkeys[d - 1]); @@ -161,7 +161,7 @@ static void test_exhaustive_schnorrsig_sign(const secp256k1_context *ctx, unsign /* Generate random messages until all challenges have been tried. */ while (e_count_done < EXHAUSTIVE_TEST_ORDER) { secp256k1_scalar e; - secp256k1_testrand256(msg32); + testrand256(msg32); secp256k1_schnorrsig_challenge(&e, xonly_pubkey_bytes[k - 1], msg32, sizeof(msg32), xonly_pubkey_bytes[d - 1]); /* Only do work if we hit a challenge we haven't tried before. */ if (!e_done[e]) { diff --git a/src/secp256k1/src/modules/schnorrsig/tests_impl.h b/src/secp256k1/src/modules/schnorrsig/tests_impl.h index 8ada90a87b..aa4fc38270 100644 --- a/src/secp256k1/src/modules/schnorrsig/tests_impl.h +++ b/src/secp256k1/src/modules/schnorrsig/tests_impl.h @@ -15,7 +15,7 @@ static void nonce_function_bip340_bitflip(unsigned char **args, size_t n_flip, size_t n_bytes, size_t msglen, size_t algolen) { unsigned char nonces[2][32]; CHECK(nonce_function_bip340(nonces[0], args[0], msglen, args[1], args[2], args[3], algolen, args[4]) == 1); - secp256k1_testrand_flip(args[n_flip], n_bytes); + testrand_flip(args[n_flip], n_bytes); CHECK(nonce_function_bip340(nonces[1], args[0], msglen, args[1], args[2], args[3], algolen, args[4]) == 1); CHECK(secp256k1_memcmp_var(nonces[0], nonces[1], 32) != 0); } @@ -50,10 +50,10 @@ static void run_nonce_function_bip340_tests(void) { secp256k1_nonce_function_bip340_sha256_tagged_aux(&sha_optimized); test_sha256_eq(&sha, &sha_optimized); - secp256k1_testrand256(msg); - secp256k1_testrand256(key); - secp256k1_testrand256(pk); - secp256k1_testrand256(aux_rand); + testrand256(msg); + testrand256(key); + testrand256(pk); + testrand256(aux_rand); /* Check that a bitflip in an argument results in different nonces. */ args[0] = msg; @@ -76,12 +76,12 @@ static void run_nonce_function_bip340_tests(void) { CHECK(nonce_function_bip340(nonce, msg, msglen, key, pk, NULL, 0, NULL) == 0); CHECK(nonce_function_bip340(nonce, msg, msglen, key, pk, algo, algolen, NULL) == 1); /* Other algo is fine */ - secp256k1_testrand_bytes_test(algo, algolen); + testrand_bytes_test(algo, algolen); CHECK(nonce_function_bip340(nonce, msg, msglen, key, pk, algo, algolen, NULL) == 1); for (i = 0; i < COUNT; i++) { unsigned char nonce2[32]; - uint32_t offset = secp256k1_testrand_int(msglen - 1); + uint32_t offset = testrand_int(msglen - 1); size_t msglen_tmp = (msglen + offset) % msglen; size_t algolen_tmp; @@ -90,7 +90,7 @@ static void run_nonce_function_bip340_tests(void) { CHECK(secp256k1_memcmp_var(nonce, nonce2, 32) != 0); /* Different algolen gives different nonce */ - offset = secp256k1_testrand_int(algolen - 1); + offset = testrand_int(algolen - 1); algolen_tmp = (algolen + offset) % algolen; CHECK(nonce_function_bip340(nonce2, msg, msglen, key, pk, algo, algolen_tmp, NULL) == 1); CHECK(secp256k1_memcmp_var(nonce, nonce2, 32) != 0); @@ -116,10 +116,10 @@ static void test_schnorrsig_api(void) { secp256k1_schnorrsig_extraparams extraparams = SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT; secp256k1_schnorrsig_extraparams invalid_extraparams = {{ 0 }, NULL, NULL}; - secp256k1_testrand256(sk1); - secp256k1_testrand256(sk2); - secp256k1_testrand256(sk3); - secp256k1_testrand256(msg); + testrand256(sk1); + testrand256(sk2); + testrand256(sk3); + testrand256(msg); CHECK(secp256k1_keypair_create(CTX, &keypairs[0], sk1) == 1); CHECK(secp256k1_keypair_create(CTX, &keypairs[1], sk2) == 1); CHECK(secp256k1_keypair_create(CTX, &keypairs[2], sk3) == 1); @@ -813,8 +813,8 @@ static void test_schnorrsig_sign(void) { secp256k1_schnorrsig_extraparams extraparams = SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT; unsigned char aux_rand[32]; - secp256k1_testrand256(sk); - secp256k1_testrand256(aux_rand); + testrand256(sk); + testrand256(aux_rand); CHECK(secp256k1_keypair_create(CTX, &keypair, sk)); CHECK(secp256k1_keypair_xonly_pub(CTX, &pk, NULL, &keypair)); CHECK(secp256k1_schnorrsig_sign32(CTX, sig, msg, &keypair, NULL) == 1); @@ -861,12 +861,12 @@ static void test_schnorrsig_sign_verify(void) { secp256k1_xonly_pubkey pk; secp256k1_scalar s; - secp256k1_testrand256(sk); + testrand256(sk); CHECK(secp256k1_keypair_create(CTX, &keypair, sk)); CHECK(secp256k1_keypair_xonly_pub(CTX, &pk, NULL, &keypair)); for (i = 0; i < N_SIGS; i++) { - secp256k1_testrand256(msg[i]); + testrand256(msg[i]); CHECK(secp256k1_schnorrsig_sign32(CTX, sig[i], msg[i], &keypair, NULL)); CHECK(secp256k1_schnorrsig_verify(CTX, sig[i], msg[i], sizeof(msg[i]), &pk)); } @@ -874,19 +874,19 @@ static void test_schnorrsig_sign_verify(void) { { /* Flip a few bits in the signature and in the message and check that * verify and verify_batch (TODO) fail */ - size_t sig_idx = secp256k1_testrand_int(N_SIGS); - size_t byte_idx = secp256k1_testrand_bits(5); - unsigned char xorbyte = secp256k1_testrand_int(254)+1; + size_t sig_idx = testrand_int(N_SIGS); + size_t byte_idx = testrand_bits(5); + unsigned char xorbyte = testrand_int(254)+1; sig[sig_idx][byte_idx] ^= xorbyte; CHECK(!secp256k1_schnorrsig_verify(CTX, sig[sig_idx], msg[sig_idx], sizeof(msg[sig_idx]), &pk)); sig[sig_idx][byte_idx] ^= xorbyte; - byte_idx = secp256k1_testrand_bits(5); + byte_idx = testrand_bits(5); sig[sig_idx][32+byte_idx] ^= xorbyte; CHECK(!secp256k1_schnorrsig_verify(CTX, sig[sig_idx], msg[sig_idx], sizeof(msg[sig_idx]), &pk)); sig[sig_idx][32+byte_idx] ^= xorbyte; - byte_idx = secp256k1_testrand_bits(5); + byte_idx = testrand_bits(5); msg[sig_idx][byte_idx] ^= xorbyte; CHECK(!secp256k1_schnorrsig_verify(CTX, sig[sig_idx], msg[sig_idx], sizeof(msg[sig_idx]), &pk)); msg[sig_idx][byte_idx] ^= xorbyte; @@ -916,9 +916,9 @@ static void test_schnorrsig_sign_verify(void) { { /* Test varying message lengths */ unsigned char msg_large[32 * 8]; - uint32_t msglen = secp256k1_testrand_int(sizeof(msg_large)); + uint32_t msglen = testrand_int(sizeof(msg_large)); for (i = 0; i < sizeof(msg_large); i += 32) { - secp256k1_testrand256(&msg_large[i]); + testrand256(&msg_large[i]); } CHECK(secp256k1_schnorrsig_sign_custom(CTX, sig[0], msg_large, msglen, &keypair, NULL) == 1); CHECK(secp256k1_schnorrsig_verify(CTX, sig[0], msg_large, msglen, &pk) == 1); @@ -942,7 +942,7 @@ static void test_schnorrsig_taproot(void) { unsigned char sig[64]; /* Create output key */ - secp256k1_testrand256(sk); + testrand256(sk); CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1); CHECK(secp256k1_keypair_xonly_pub(CTX, &internal_pk, NULL, &keypair) == 1); /* In actual taproot the tweak would be hash of internal_pk */ @@ -952,7 +952,7 @@ static void test_schnorrsig_taproot(void) { CHECK(secp256k1_xonly_pubkey_serialize(CTX, output_pk_bytes, &output_pk) == 1); /* Key spend */ - secp256k1_testrand256(msg); + testrand256(msg); CHECK(secp256k1_schnorrsig_sign32(CTX, sig, msg, &keypair, NULL) == 1); /* Verify key spend */ CHECK(secp256k1_xonly_pubkey_parse(CTX, &output_pk, output_pk_bytes) == 1); diff --git a/src/secp256k1/src/precompute_ecmult_gen.c b/src/secp256k1/src/precompute_ecmult_gen.c index ce648cb9b0..4d153a6574 100644 --- a/src/secp256k1/src/precompute_ecmult_gen.c +++ b/src/secp256k1/src/precompute_ecmult_gen.c @@ -17,10 +17,46 @@ #include "ecmult_gen.h" #include "ecmult_gen_compute_table_impl.h" +static const int CONFIGS[][2] = { + {2, 5}, + {11, 6}, + {43, 6} +}; + +static void print_table(FILE* fp, int blocks, int teeth) { + int spacing = CEIL_DIV(256, blocks * teeth); + size_t points = ((size_t)1) << (teeth - 1); + int outer; + size_t inner; + + secp256k1_ge_storage* table = checked_malloc(&default_error_callback, blocks * points * sizeof(secp256k1_ge_storage)); + secp256k1_ecmult_gen_compute_table(table, &secp256k1_ge_const_g, blocks, teeth, spacing); + + fprintf(fp, "#elif (COMB_BLOCKS == %d) && (COMB_TEETH == %d) && (COMB_SPACING == %d)\n", blocks, teeth, spacing); + for (outer = 0; outer != blocks; outer++) { + fprintf(fp,"{"); + for (inner = 0; inner != points; inner++) { + fprintf(fp, "S(%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32 + ",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32")", + SECP256K1_GE_STORAGE_CONST_GET(table[outer * points + inner])); + if (inner != points - 1) { + fprintf(fp,",\n"); + } + } + if (outer != blocks - 1) { + fprintf(fp,"},\n"); + } else { + fprintf(fp,"}\n"); + } + } + free(table); +} + int main(int argc, char **argv) { const char outfile[] = "src/precomputed_ecmult_gen.c"; FILE* fp; - int bits; + size_t config; + int did_current_config = 0; (void)argc; (void)argv; @@ -40,36 +76,21 @@ int main(int argc, char **argv) { fprintf(fp, "# error Cannot compile precomputed_ecmult_gen.c in exhaustive test mode\n"); fprintf(fp, "#endif /* EXHAUSTIVE_TEST_ORDER */\n"); fprintf(fp, "#define S(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) SECP256K1_GE_STORAGE_CONST(0x##a##u,0x##b##u,0x##c##u,0x##d##u,0x##e##u,0x##f##u,0x##g##u,0x##h##u,0x##i##u,0x##j##u,0x##k##u,0x##l##u,0x##m##u,0x##n##u,0x##o##u,0x##p##u)\n"); - fprintf(fp, "const secp256k1_ge_storage secp256k1_ecmult_gen_prec_table[ECMULT_GEN_PREC_N(ECMULT_GEN_PREC_BITS)][ECMULT_GEN_PREC_G(ECMULT_GEN_PREC_BITS)] = {\n"); - - for (bits = 2; bits <= 8; bits *= 2) { - int g = ECMULT_GEN_PREC_G(bits); - int n = ECMULT_GEN_PREC_N(bits); - int inner, outer; - - secp256k1_ge_storage* table = checked_malloc(&default_error_callback, n * g * sizeof(secp256k1_ge_storage)); - secp256k1_ecmult_gen_compute_table(table, &secp256k1_ge_const_g, bits); - fprintf(fp, "#if ECMULT_GEN_PREC_BITS == %d\n", bits); - for(outer = 0; outer != n; outer++) { - fprintf(fp,"{"); - for(inner = 0; inner != g; inner++) { - fprintf(fp, "S(%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32 - ",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32")", - SECP256K1_GE_STORAGE_CONST_GET(table[outer * g + inner])); - if (inner != g - 1) { - fprintf(fp,",\n"); - } - } - if (outer != n - 1) { - fprintf(fp,"},\n"); - } else { - fprintf(fp,"}\n"); - } + fprintf(fp, "const secp256k1_ge_storage secp256k1_ecmult_gen_prec_table[COMB_BLOCKS][COMB_POINTS] = {\n"); + fprintf(fp, "#if 0\n"); + for (config = 0; config < sizeof(CONFIGS) / sizeof(*CONFIGS); ++config) { + print_table(fp, CONFIGS[config][0], CONFIGS[config][1]); + if (CONFIGS[config][0] == COMB_BLOCKS && CONFIGS[config][1] == COMB_TEETH) { + did_current_config = 1; } - fprintf(fp, "#endif\n"); - free(table); } + if (!did_current_config) { + print_table(fp, COMB_BLOCKS, COMB_TEETH); + } + fprintf(fp, "#else\n"); + fprintf(fp, "# error Configuration mismatch, invalid COMB_* parameters. Try deleting precomputed_ecmult_gen.c before the build.\n"); + fprintf(fp, "#endif\n"); fprintf(fp, "};\n"); fprintf(fp, "#undef S\n"); diff --git a/src/secp256k1/src/precomputed_ecmult_gen.c b/src/secp256k1/src/precomputed_ecmult_gen.c index 75ec59c27a..248fb077e5 100644 --- a/src/secp256k1/src/precomputed_ecmult_gen.c +++ b/src/secp256k1/src/precomputed_ecmult_gen.c @@ -7,9740 +7,1773 @@ # error Cannot compile precomputed_ecmult_gen.c in exhaustive test mode #endif /* EXHAUSTIVE_TEST_ORDER */ #define S(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) SECP256K1_GE_STORAGE_CONST(0x##a##u,0x##b##u,0x##c##u,0x##d##u,0x##e##u,0x##f##u,0x##g##u,0x##h##u,0x##i##u,0x##j##u,0x##k##u,0x##l##u,0x##m##u,0x##n##u,0x##o##u,0x##p##u) -const secp256k1_ge_storage secp256k1_ecmult_gen_prec_table[ECMULT_GEN_PREC_N(ECMULT_GEN_PREC_BITS)][ECMULT_GEN_PREC_G(ECMULT_GEN_PREC_BITS)] = { -#if ECMULT_GEN_PREC_BITS == 2 -{S(3a9ed373,6eed3eec,9aeb5ac0,21b54652,56817b1f,8de6cd0,fbcee548,ba044bb5,7bcc5928,bdc9c023,dfc663b8,9e4f6969,ab751798,8e600ec1,d242010c,45c7974a), -S(e44d7675,c3cb2857,4e133c01,a74f4afc,5ce684f8,4a789711,603f7c4f,50abef58,25bcb62f,fe2e2ce2,196ad86c,a006e20,8c64d21b,b25320a3,b5574b9c,1e1bfb4b), -S(6ada98a4,8118166f,e7082591,d6cda51e,914b60b1,49696270,3350249b,ee8d4770,c234dfad,f3847877,a0a7bcda,112dba85,1cdddf00,84d0c07,df1d1a,a3ec3aeb), -S(a94ae8,63264dfb,b910ea95,4ce9ca7e,4f86f92d,9f3a95d1,ed61552a,7a3f5743,7f53f7f1,6ad2d08f,15e73314,6d80467,41557acf,19556c0f,ed7117ce,37040823)}, -{S(1b8462eb,1ccdf7b2,b8372f2f,cec1f479,ab07c09f,cb26d6c3,965ec73,4d654f81,62f6755,b4a7891d,55de6427,fbc37d33,e4eea418,a2c04392,a3d11807,ccc9025), -S(c3b55f99,9cd9113c,fcb4f29,be00c785,cc70d1c1,f1cfd0ed,593abe8d,260bd2bb,8945790b,5696225a,1c6a1f45,1d6b085e,cde2f332,df068271,f6279877,6d1015aa), -S(a4b41b41,1a255142,ee62144d,96ccfdc,a3cdf5a6,af32bdd8,d1c3d26b,d6aab0b9,3ade7f6a,299ee56c,299fcaad,72a146d2,62db1dcd,2ea1a355,d6e00294,ee34c3), -S(d4af67c6,75f97f30,4a621fe5,343dfa5b,e432d9f1,43758d4d,62df1e09,b79abfe8,d0fea700,2a851a85,33929e5f,1f41d4a9,68b9e520,6c19f3b0,35ce96a5,12b61921)}, -{S(6ae991de,18418b49,160194f,a735eb72,c299b987,1981a4f9,aa717ad2,bcdcf13,7ee8011a,40f384f2,e50add2d,97005173,2787cc7c,89dafb66,301bc94d,24b913f), -S(c28203a6,e0f93259,778bddca,10f994be,67cec8a3,109d0001,d830a8e7,b452794b,18df3a42,ec24b713,2ac4b6ec,dd7605e4,169aa07a,41d7559e,bde808d9,bbfbcb14), -S(4848adb6,b0350cd7,b745b603,cff69deb,8be10519,cc02881c,4b980157,5635aa37,7a814076,187ed7b9,84d0be65,b2f83b90,325441cf,54325183,beb01136,d626ca5c), -S(515d497f,f274da3d,9bb9e4f7,e1b77e8a,af859d52,be7c7e93,f197267,d73ce5ae,da648754,a5ed476,3fad55e1,e93f9687,2d1fe961,b448b9bf,2c42c885,b44678f0)}, -{S(64850a04,76870a44,2cfa57e0,4e4707f7,eccc5e99,12dbcb07,3b457317,717f5686,7c5facd2,91a6defb,a1837cb9,3bcbd0f5,bc37572e,68ccb2a0,c062a155,46656fcc), -S(c3ae412c,a3e5f22b,44863ab1,b5e64719,99078ac0,d5844d9,6a37899f,3e064475,e491d89e,b38b0443,50d96e01,7baceb35,fa0e247,8c982d25,5a2a332c,239e0a54), -S(e72c3804,a774f3db,42348883,297b5035,c9dd3970,7e3bc60d,1e51e41,d7d8e395,e3cb5abb,c3c259ab,2c9e5,fa059c10,fe6f633b,4f99da29,61b9117e,61fbb457), -S(6a7b9de1,8d16a0e2,1b30cb61,3586ebc6,78b60618,e2b45e2d,8c94ad09,36227f74,ac1fb735,266d34,eb995f8f,91cbc339,f63b6e6,bd4c89f0,d7607908,75a4918f)}, -{S(92133195,a4fd0c59,7e0cf65e,8ce1d939,e333f7a8,441523aa,31e339e1,2ae51e8d,556a388,7a7d579e,87de7f49,8c54bf24,2ca4b8a2,8b959e21,ceec4555,b8fabccf), -S(1b3ee78b,df5cbab,a7649125,40852351,602bb558,e4bea533,dbb08eb0,299ae994,9a0c2165,5512777f,fac5ed54,b8e5b4ce,d7a6b17d,643f8c3d,d0173a96,3a4c7aa), -S(6be3de2d,1ceb66ac,1ecd3435,3f241a89,cdaf48f4,a8d5522a,1d6f0083,3c4b2a39,88e10da0,e53b8f5a,ada0db7e,e1ce75c2,8898d5e,156e777f,7acc3ba0,9fee727f), -S(b38c82e4,3e0559db,6732e87a,7cb1e6e6,6164f6f2,258ce060,6d239836,5af9ec0d,9e0f87f4,9d240b33,dc325bd0,49e9fac5,6b7a64e8,57f27ab9,ad765604,2fe47653)}, -{S(ae5fb021,e9256cc0,6236d667,b76b9bdf,304a4683,d2916ffe,489cf019,6b4c5683,e768366b,5c8d36b6,18e45550,d57493e2,41fed17d,12627e37,b29b4b74,d3603696), -S(e4f916f1,a96dc6dd,8867a619,fef6cf67,14ec2642,12d7ba2b,14b5fbda,b584f339,b44855e3,3ddf19b4,31f109b1,daeea11c,340a9ad8,c17b78ea,c9979ecb,791c31fd), -S(4baca037,647377c6,f3146dcc,d732b21d,32449773,f55766d4,de5b239b,2ef89e6a,50b4b046,b9e3cab5,dffdefa,fa305051,7bdb2deb,9bd9fb,9d3cfca0,34a72228), -S(867d7d44,734389e9,71363522,9d4f2c3b,bfc66e57,44a5f01d,1c93c201,9dd3f363,e9b94307,b39ceb65,653f2206,ffc8c858,37654fb5,90eb8d1f,24a9c82e,d8b4d210)}, -{S(782d5c9a,d970322e,deff2e7b,57844184,c589a4da,c042fcf3,86c1a9f8,26c1babb,27bba565,405cb392,64762d97,cbaff552,1bc38b20,56afe313,556542d3,f200eb06), -S(d07eb76,bb6694dd,4d6160e7,4d4a397d,963ea132,f74d0b9,e9f35c06,830940,2b7f902,62c67203,d6f3fc8c,2d435309,7f8e80fa,c2a732a5,dfdf6dee,ab47f017), -S(36afeed4,b7507388,285fc481,beb1de1,bc8e143c,ce7b8e46,7c1e22c0,395fef48,5318e7c9,686171a8,ceefff55,3fc98e41,d9e0d789,a2e880fd,6487c2f5,54816a97), -S(cfc25614,fc96d911,24b3b74,7aed144d,8656693b,a2844934,d2ee61ab,ab794160,fa9e529b,be133fe2,835ec397,b130ff27,187aefdd,df524ed0,9fdd0486,5cf6c014)}, -{S(ebc119d3,8e794efa,85fcbd,5affac35,f73c7428,590ede0f,6365f1ea,87c65b4b,183a9992,3911b1b1,cd9b0fea,3667b6e1,52af7499,8d32beb3,d2ecb91d,af6e8a06), -S(456dfac3,c239290c,336d1b46,e9638bd2,592484bc,f76d011d,104cea57,dd0e5167,62264555,8de68f49,170a8aa4,121aa307,378984a1,76b8affc,241419e6,95500049), -S(71108a04,a50b30f8,29f1420f,b9994ba,384c2ff0,8a581672,e3464bb2,93f0f756,ff6a402c,eb50bb4f,7ae17680,458f53fe,d627b0b,dca24cb1,b033feda,f27cbff4), -S(f8261d8e,ea970b26,fb13ed01,cec553b0,a374b03e,c14763ec,13e68ff9,b219f39,3cee77fb,6e684798,68499e40,fd33fd61,e43ab21d,96a6bf78,35dad6c8,2fea2407)}, -{S(bc4bb9a6,292aa09f,5c66dc9b,667c4642,6b08211f,a9a80f5e,f3f17b,21f275de,5d0e0492,39a862ec,b9649572,6f11bc09,cebd9f29,d9407ab3,1603054d,d9b76b07), -S(ccf3d9af,434d96b9,fd9e12ee,45ea3858,5060b000,896f1de7,a73a12a1,3f635c73,7efe7415,8a3893af,d408b0c,fcd992d9,cff412f0,f77d6a9c,5d5a9235,d14f5e21), -S(18ade473,1ee3019f,ad5621f0,cfc0d6ee,ba69ab38,fdca04ae,fedddf1d,f9cad1ab,1ea6e4d3,63f1cbfb,e9d11c54,c2ab43a4,49e9610f,24b6adf4,446454c9,c3bdccf0), -S(8bc05563,1b13b451,5a99eebd,837e67e9,e80ab8d3,58ee840e,3140ac8e,131cc214,cede3aba,b11b6a91,4ef1ef36,30c12127,bb818ec9,b4d3ad38,a9e68641,a7b799a)}, -{S(c8e595d2,666f4913,1f375b67,81b9113a,d0760e5,9477ca17,8863828b,307488f0,a82cf2a9,d823af13,5c23a04b,bc12dd81,2c352a48,27e19030,8e089d9d,9c316596), -S(d194c03b,ff719a14,6bba239,fc3e1255,7637c9b1,30609ff9,1501942d,348930ee,5e9387d6,4bbc72de,39ca8141,c6c6d526,530e82,47b43161,72717b68,28d1c1c1), -S(cfe58760,54b85d2b,e1220cbc,28ba55f4,51cb3c4b,1ef1d39e,b82e8c25,7538b631,a7616b4a,f3564048,b5cdc6bd,b0250abb,ab1bdd33,a7a15857,31119d26,94ff4bea), -S(190a763e,58315639,578def37,53f4610e,5a802af9,e4873d3e,8c3186c0,e424ac42,b156da85,b8462fa6,83f85c7e,5f718ed7,34a159c2,5b18d092,185ff467,8b8840ed)}, -{S(49e7429b,e0d97bf9,3f17e9a8,53fedb6a,a9bc6edd,8e85f44b,9d2f1469,b2d3b178,ff9e5dfc,2746679e,9826039d,578bac31,c08fbaac,a075214c,73c50f,74568fff), -S(2beda894,682676e6,11bf6a,78cae329,c26b47c6,237d0e52,61a70b9c,36796207,103a18d9,a6785ad0,2129ca1b,96834d9f,f185d49c,edd1c053,96a8c9f4,dd16be16), -S(9602058a,fce0160a,70bd2a32,6cd3eb1b,e5ffbaa8,e05bc2db,fbb9c303,7b449ceb,1fa171c,682393c8,2b237910,2ba5ca8,7efa0543,b8cd65af,de324f14,cc53945b), -S(118d0b52,f418dcd2,b6864967,a49f9d88,809f2468,8bbb6c47,c68f2eb7,bbe7ab31,30ebfb30,ba0bac02,57bf568d,479b7bed,2b1512f9,33aaa040,4966b6fd,5e1678)}, -{S(9a1db7bf,53241ed1,df8d3ea0,f70c0b26,76b43ebc,bcb4622a,9704b0a,3067400a,e3638ad2,95740505,455b2e1e,d495c57a,54ed8e8f,c647a6b9,c69b7dd0,715cef52), -S(b5c353a5,c86b2d4a,9b00804e,f0439259,335d0bde,91dd2bac,a567cd5e,284be39a,5bba9f1e,877d5e0d,21e384d,52de73eb,9aefcaa5,132117d1,2dd984c9,4a0562e1), -S(337a0242,62b9fd60,28f5fcdb,c2305543,385010d6,98fb258a,d5c25b1c,4a765fed,e179c1fb,d671e158,36050d89,48fac97c,57abcae6,79e3be7f,16ed8b98,84dcb013), -S(ecc024ca,640ec936,f7e2320b,58147466,686528ed,579865d0,f61672e8,3e6b0f18,a1335b77,ddb11959,24d40e4c,81270679,270f87e4,158a745c,8d2d810c,ee7024eb)}, -{S(50cd2e16,997d7d45,98bb2d9b,61aceaff,5ad5f38c,8286a0e1,d08055ad,726c7800,dd19c3b,c08b8d97,88f9de1,5941f5fa,6402bbbb,5fdc708b,cfc08844,eb23733b), -S(34d6a7b6,733bf5e9,ae6aad06,5ee0793b,4f5e1ba9,97de99f9,8771ca57,81fb2382,22f8c6f6,dc7203a8,53e64cf1,dbf26d6d,e255f0bf,bddd9508,a759db8f,2c55cbd9), -S(8458b56c,982ccb85,8731c149,e2f38880,3958d6b7,55f38582,b9f4d95b,85d22ee3,b5b8fc5d,2da56779,a5b06b85,b5d07349,9b04cfb1,2d7b26b2,d9a4bf44,3f00cb05), -S(cdbf1327,3388dd49,c163ce36,8d451e3b,51bc7924,173efc08,376cac4d,6f73a84a,d2854757,18fa95a7,1978bb04,5e81095c,f1423d45,e533ba6e,ad91f40f,a6961d2a)}, -{S(4bd266bd,4a730879,cb06d8dc,bd8e5854,c50b6221,d83e0a10,3afcb2a9,a64cca67,a4654a1d,835a51f0,5a877200,1768c549,909212e5,78e3b1d1,df935959,93650863), -S(6666f098,c04d51a2,609c9eb6,596dc668,16735175,1458cd51,59f5bc1e,2c86722c,4ce5faca,45027cb6,85aad7de,e926be69,95b22719,d8d8fb61,260fc9d7,62a9e47b), -S(87b459b0,6e3e2750,31087f45,79e53818,fc200703,59d28147,ad79e39a,488c79ab,2656b94d,d33c0721,b90e981c,b47dda60,166839c0,1c5ca2ee,76979133,824d2488), -S(830acf28,c0a99fcd,f1d3409,ca3066fa,ef8d267a,7ae6ba4,55fceb5,7f76f83c,aa4ec098,51361d43,a339f418,a28de217,a9f464dc,26ceea5a,ae74b4f3,193a58a7)}, -{S(217de5b,a47e8de,cb9d8dc3,dc8fcfd8,203c514b,b9d7bb5e,fb03584b,aa1baaff,c77bddc0,3af15e63,912e51c7,19bd8186,67f999ed,9bd801b8,11bc289b,f12864ed), -S(e5abf144,9c4770fe,b6772067,b18dce01,efab139e,f0a4d73a,eeff868e,6425a7a4,ba62fc47,597dea8d,4bcd1a08,77730314,81ea6990,796a29b5,94bd06d7,d5330188), -S(699e20cd,3b320b24,878b6a98,4c3338d7,45f93ae1,a7aaf363,e20b18e1,8b6d0f56,6602370d,65efc133,83ee1c45,baae4a65,efce9bf8,acb0c3,cfedb5c2,94f36d2), -S(6cf56e78,d6f58bec,32184506,9f26cdbd,7f6ae28,ed310203,dfe410a4,b83449dc,4c24cc91,f78d5c14,690ae276,89a56531,34f89a09,c17e229b,3ab7379c,6da021c8)}, -{S(761cab41,3916a1f5,e131f337,e9023519,6199f789,87ef390b,3f2d8bfa,b0e9bbc6,f10272df,f7e91c40,3565da85,17fd3011,bde7b797,526d3c3,f00fb28e,f26dbd91), -S(ec45cef2,3211527f,220dd3c5,2e4b88be,8f0b0191,d9e73d7d,679fd75d,ae9dc2ae,ac07402f,c7cf8884,8f00e396,42b5e306,7749e10a,441c18b2,646b2fcf,3f76309e), -S(70234e32,61f2e099,a1525a81,9ab7c926,bd672805,ed3562,55369cec,85615e9b,785a6c93,f2673a8f,ccf3b332,35922f9,208dcaee,6932c27c,b8e40b0e,c9b06360), -S(a7c9a0cd,c3692f9a,48ba8307,de80b5d9,80593eef,9e236bf2,49c9693b,c2bb46b,d44258b3,790b9ca2,9636694,6e9ec845,3e3eacf1,a9253092,a7bc92d7,62a03d3c)}, -{S(60b01067,25cf781d,e78ba725,40508697,3f2ff6ec,1511515,6e19384,1fddda7a,624ccf87,f0ec21b9,82efbc4,6d4db878,5d20fb8e,dfe663fc,46660bb7,98c96eb), -S(5d24589d,5ebf326c,9419d539,f06b2291,42c02d0e,44556a3c,772f484,6cb78938,2fb6e6bb,759dbfb7,57257d21,43064225,beeeaf42,4c99b426,aa27d969,d459a5a0), -S(43d4db79,797f6415,93248363,38980bb4,3c90400f,a698ab3a,ba38a4a0,9bb13701,e2bacfbf,b84517da,efb0e137,678ee0b7,bbeefd64,7256628d,7edf46f8,38c65ffd), -S(eb0e5c31,d95f3325,78596f3c,8a027e48,453b5c24,4d0627f3,cffbd413,f8c53db2,29386000,7c3c97da,cc0b5a30,1a7c7c6c,8a1dbfe1,5358c72c,5fa30912,634d4a0b)}, -{S(a707efc4,89165c75,7edcea3c,ce729b44,91f04142,3fc6ea9a,704f52df,c8a0650,f2e7657c,6c618494,c01c5a90,d06b625b,c9416d63,f7b8f809,dda5076f,74fa2c92), -S(b930b8c,a68df36d,80b589ba,72dda82b,502bcee2,cb98a9e9,95c3235b,457ad4c6,7b8fff37,9970f1b4,1a12baae,f7628868,fd3f1003,bd6ea442,46559b40,3a1e8bf6), -S(a6d3233,f7e1001c,eea237bc,d4484744,aa0888b7,a2b44b82,59a542a6,c0d6b552,d2f5772,1c2cbc0,7179d252,3cc0d0e6,94551842,afbb51e4,31a6efb3,9206a70c), -S(c1dd7db5,e5dc3f50,2b08a177,98bb1cfa,afd02252,1bdec7e5,f4653e7b,3303cbaa,558676c3,e25db8,c46bd903,2e9dd122,a981fc50,cbb9e807,157ef35b,5619d3bc)}, -{S(6efd8760,aed4f239,bd97a00,63794c4,ef14acc9,f5b94862,4c7f8b51,3ff35278,74acac29,694c5307,aa221b37,f2ea068a,a269fcd3,c6d85aaf,a8c8eac1,17d7f997), -S(cdd67435,c9fd1182,88f703b1,1fb4e848,9aa2b752,3237a279,ca30a11e,d05de955,149e113c,49db4e2d,bd50dffd,bd53dcf1,a5876825,da059718,e0575d3d,f39476f3), -S(b0fdcf78,9c509ff9,8bb36db8,dbbad047,36bce756,e350373d,ba4d452,8410280d,7c8a7550,91b2cac5,ab71d820,84b335e9,b630cee7,2a277e12,dcb04605,21747c9e), -S(b5ca53ad,77f1569d,ae1c26bf,84ab8e71,98e305fe,e21545e6,f3b2c734,aaa161f2,ec96edd,82ed1d41,cc8423d3,bba6d50,4659de8c,ae5730a9,a0b54fe1,25acdb34)}, -{S(2def7e67,7906cf3f,3677e7b6,1b0a8f8,985fbd9b,23265ea7,18a5c16e,139f0a8,650a89bb,df8c8326,d364fae7,558de827,a529780c,9b7bf8f1,c6925632,7c59c74c), -S(847cecc2,f30f30d3,40ff0276,9167e2db,97b07103,821eecfe,640fe4a1,b3f5a08b,e59c450,3ea1f4db,c4b00c6,e5b912f6,7dafd112,59773c66,d478781,bb343d40), -S(4157664b,4baa043b,9cb959d6,96aa1501,5635bfc8,a20ba704,b6477aaf,a9af9ea5,3e44d11,432b4e5b,97428706,4a787681,522ffe,28eab2f1,15e5bcd6,d42f69ea), -S(675389b6,32431381,bbc0d5eb,20f356aa,31418409,ea9150b,aa7f9c83,41b1124a,999645d2,7a169a1c,de866f4b,ae713070,b9b37c9c,a393567d,8ecd04c5,85b8059d)}, -{S(9705d56f,f75c7d2c,bacc47a4,a6cf8b10,300c688c,fdbd1b1,528f41b9,652d49fa,c53f7f11,896f2edb,fc957dd7,2cc90856,c5df9d86,43e42489,70182843,84201b98), -S(ed362790,55151b78,4e6f5088,e99b7079,d2409203,c08a8791,7644a639,7a8b6199,84affa8c,62a0109c,b003196c,25296d8d,5d3e1904,c1cd10c2,1e73fad1,3a46caa1), -S(21227229,b8deca6f,c30351e1,7607ef99,23cc3f8,9aaaa48,9661487c,7b3bd0e3,a054a47,fcab568b,f8bd4234,a5d7fbec,b11d96e1,aa3ad5b4,88fbb405,a7437f21), -S(59f2227c,32afa124,999ad653,8393e47d,d64c4331,773e09ed,f0517651,3090f07d,1348ffdf,d8adad12,4370f188,cfb47fde,a8297e6f,ea00967,7061bf66,e03b0472)}, -{S(5b27aec1,c644f0a9,ba7f6486,9a960ea6,28343ab,da3feab2,4a2d6add,754866a2,3d1f365c,2aee6c1e,ab2f1879,429b6275,5d1bac85,2998ef25,8a914bfc,ca280b43), -S(27f03daf,a370763a,e2b44480,7b9e6779,9361efcf,cdd7be23,6c493392,f19253fc,eeedf887,cd8f3df0,9d1748c5,62723c56,31956880,cceb0f1f,c118052f,8c44b5ff), -S(d301d8c2,8d7413cf,3298cf95,1f7d6c3a,2e8d86ee,c5e3fbd5,e80e5358,4855e04b,6856d7f1,5e94773a,465cb69c,8b7f8961,a2988f50,fdc179d7,63a92ab5,d94b22a5), -S(8b88670b,72fd02c8,5f973403,5299ad19,484c1367,c8296c73,122d80c7,9bce8407,c98b5a2c,3b0d5c44,32975c0d,32c90794,63ade4fe,92cd4c44,4e8e64ae,7a05c5d4)}, -{S(53512a21,4a659914,82cc157f,da02880f,7c4ff9e6,47a93136,c1e55725,9ce7132f,3ccac75b,13cc40fa,5ab2e017,80f55f2e,b8e6a7e7,22b2e6b1,13a28316,b3c99d3), -S(2a1e20e6,8cfbb77a,ec1f5666,dfc1c85c,c4a07dda,4ead1722,8d7f3633,6771be47,b1f5752b,3f6650ff,261898a7,a8c61f71,48e8f54f,a39e2f4f,8e94ea2f,b332a08a), -S(560d86db,354e5f8e,e8522056,aa9d0f5f,6329fca8,2bf11ba9,fc29505f,7974662d,bfd52860,f42f9d8d,84892fda,b78aa79,9143eee7,26fbc95,b5e17856,53b13878), -S(24c3c40b,df047994,d0416339,e64d6195,276e3779,68869b66,3ecdf186,4703207d,643b0918,c8dce682,50aa3abb,db68f9cf,f8ac64a2,2c7cb77,ef8fd252,36cdf29c)}, -{S(534e9d8,bea140bb,4970b516,c42f2677,dc413f42,9b7c56de,e261f60d,ec68f9d8,e55aff90,1098b0a9,ea377acd,b62dc479,da109514,2654107a,28c68e9f,73b1cba), -S(28ecf7fd,a122550,8301ad75,6028e29e,13da7586,d8b2aaeb,f061e927,dd030db3,bc3e08d3,df4218b,88279f3d,cf75dca7,4a9f567b,75ad0a86,f9379c6e,37661962), -S(851aa3bf,37ee83d0,8318527a,5f4366ee,8ae98d29,de2254d6,2e4428fb,cb5e0f21,423393e3,937816e7,ada1df1c,ebdda887,5e114ab4,23059a35,96668a80,7820754), -S(7e6cf455,9d674d6f,a6263ffa,69cef00e,f69f50e5,4a5d6603,5efb7732,b1aec817,3c6d0cdb,c7ac0623,1c47c044,e28bba2f,105a1730,7cdce1a9,ced324c8,f770cea2)}, -{S(dd7503a2,a3e15e7,39eb9b1f,856d6e33,be4890b2,f40cfea8,1bdf516c,b942731,ca9cd04e,c3789ab4,5088b819,953e08a0,b8adb8b,b2b6f7c8,661a2d3b,83a54c77), -S(9850c031,33d251c2,9f0d64a,f7941f4c,475c6099,e6ba606,9d396ce2,772a5e53,acad3120,b2b5aff9,209bdfce,34d6e5a0,899c9de9,15083064,b84fe57f,2e1c1adb), -S(14194578,53638284,4574721,cb83660,bedd3cff,b68c7023,3f3e6a8e,1d78d797,94d7a10,f4e52fca,c855fbc0,7c977386,b11e179b,db6e6488,67ff3957,28ef2556), -S(c35a90c9,d1f6e5f0,265b7f79,ec47025f,75eda795,27a80f3d,297eb2de,9a85c603,94336bed,d5187e4,5faa0993,875e2421,b7e02eb1,c4dd9e94,b4aab892,3f63f838)}, -{S(c8116b60,1f8d72c6,24957215,46b844f6,bf6bae0b,7575a77,f1f6c6c2,5524fa2b,b7477ca6,de2004df,34882c65,3a46821b,53372f13,ed822cbf,40c20bd9,ddd1d6bd), -S(100f81d7,3b016931,1291696c,c08236f3,6100d4e,10737bd9,2b583d74,1b1903dc,80740c37,a67af622,bcfad64c,38be6968,7e780ad7,318163fe,5d2373a5,b6c90976), -S(17d3e5c8,8a7c9ec5,8a600c2b,c5d0574,491d3c19,6cca5de5,1f812975,e6fd3152,6676bbb0,9ef082b5,f8ebe69b,22c57949,43df3335,2d329621,3238f39,36bc0b9a), -S(f7ccb6af,6dd503e9,a694d721,7e0444a9,6428f277,2cf0e511,cc73bf08,590a5475,817daf4f,3a7106,f23aa303,772a35a4,92d49ce,1d4cf9b5,fde4653d,28ac6cf8)}, -{S(e7ff8d5c,83bd5846,5c967b5,37ac0f36,b9ffe9d2,fc7531e,ef183cb1,7369c066,9a9c3c4b,e482031b,f6dc69fa,843ea90e,de165479,26ba201b,5f05b00a,dbcc30a8), -S(da3b16c5,dd1f95f7,6e54297a,d6be133a,ef0df2f,45f14a55,de978a02,6b8b5fda,6712c26a,cd07740a,70573f13,f42e2b10,edbe32ab,fdb517fa,7a61af6e,aa1c6132), -S(18e515af,fe6c7273,e2acc85b,6dc345c8,f0dce23b,219abd3a,d295f686,4e02ff15,339f848e,f0b1bc1d,fa748290,f25e381e,68cebff2,f3e47caf,ff654909,63fcd515), -S(66bdebee,8c0935ef,32735526,c077cadf,bbc14003,8cbe910e,66107308,8c2edf8b,91ca5bbf,3911b59e,d6c6fe5,2fdd9a94,5ed49883,275b8cac,7fe4c63b,530c7a50)}, -{S(d8f08d18,ece61855,5b06a3b5,ac8e7cf,a6375446,cbc7c8db,ad924f78,69e7f00e,46a91d23,910957eb,db830624,73839954,2cea0570,2f67a09d,d7d19217,646606e), -S(3af65e2b,b700e873,edcf50c7,913e6fb5,534e314f,a2eda897,29fad58f,c7a49b54,dafee0e8,7d70e7b6,fb159def,92a6e5d6,cfd6b8f3,68fdec20,7719e085,94bb8e28), -S(10db17f1,8b009000,660f7dc4,d1a48fba,13926ba,67b71c34,51d2557f,a6f141ca,2f5bcc34,51445a41,d5f574e0,278845d4,805f82ab,ec84bf1c,a39b4bc8,9abdac4c), -S(ab18b6c1,55cb972d,9152c11a,36877a3a,86df3379,181c712f,7242bddf,9fd8f099,b8b8f41b,dcfc9ac0,fc112dbb,63e4cf,72906ad5,1ddaf95c,2a8ecbe5,bae0e229)}, -{S(ca3c008e,cf9efd5f,75cc1035,f9edaa7c,46b17d25,9895b0e3,b3523b6e,eee9daaf,a676aea9,3ce9bb,128ffc34,deb96b0f,72179d28,77406d04,6d0c8b5c,3572f4d2), -S(cf03f3c4,11bf7fe1,46abf004,ecc3583a,25116d55,6c6fff00,71464810,8470f0aa,aa0c0197,d57d72d7,bf336ab3,5527f42e,c7472b8f,8113a9f0,c99f129,4b39e7bf), -S(5d78371e,cb875987,c9e65356,d35240b6,c51e3897,6f884d73,c80dc0d0,839e8b26,76451b48,5c9d7468,77017dd7,412e06b6,2ccfd59d,a1800765,31bae6a5,b2a0bf73), -S(c1df0be6,6001ba2f,2a4ac3a9,466eb526,f37432e0,43688623,8fddcfd1,c1a2bacc,a8b676d5,2b3ecf46,e5849f4c,7c7c46a7,33beff28,d59285a,755509cf,5c629060)}, -{S(8a4e9691,3533875d,b8559500,65c90785,a78233ac,ef24113c,f6ed543a,e6a40024,57d9444,8d091df9,602e6c7f,c3f88934,d45a7c76,18da574b,4d4c15a6,6925bcf4), -S(2afd690,bb940709,ed1a4f85,41658f4d,254edbdb,7a64fff7,c06c904c,47d0cc7,d2177070,3bcdc50c,bc219ac4,62a6fab3,5897b550,d057f9ef,837ac04a,f6233c2f), -S(aad6646,8406b84d,38782e5a,669bddfd,c2279bd7,df486dd7,93e15f82,47bb9cfa,5c0a68b6,2065ebad,f38595e9,5f7a44fe,2bfd7ca8,4ecbaa82,ad39fbd7,b5a1afe5), -S(4a7d2720,1b508d35,a89b6406,68e99cdf,5a400d1c,cb21732b,e51fb44d,61c4cbb,d714cc9,9d59036c,4d82b668,e852cd52,d4d09ba4,f4007346,c7c1bb97,232b0fbd)}, -{S(458f8dbf,9cef8cbc,5d2046c7,42ca6297,e8fc76a,ad22fd3,af4f9a8e,2173d857,57074c8f,14a36b5f,6924517,6e3dc7b6,4d12a08d,8d00565,e70e0ca1,56f29820), -S(970222f4,b79b7b44,bc10c23,1dd6ed2b,2d3412d9,a225fb31,53e8d633,57f2c9a4,5151094a,f28c4b19,6653a42a,dd1f2270,50f0bced,e5e9339a,cea08b7f,e44f9357), -S(5efd117f,645a903,dd4d3f60,72a1f9e0,3c5a91d5,c8042267,1f791747,df32cfa0,770add6c,9b44ecc6,6b7a5fd3,3801ffc3,112bee8a,af0c02c3,fc646347,fb8483f3), -S(ffe6a8da,2abb5280,2d5b9e43,d2d0505f,f564db87,57179c55,30238353,c51c5365,4f1a00f5,4171e1,65d40719,8b913be5,fa84f018,50c40123,9aaa98dd,b303cb71)}, -{S(d2fff4de,9ecfdbd2,dd99ebae,d038415b,19b6c44c,9717926c,9e9a668,3fdfd377,a7e8ef8b,89877e3c,cca566cc,7b7dd537,d157cab,121d1623,b6880567,ac66fa8b), -S(5aaf3141,4ec3d722,75d928a1,c6a528d1,c94ce228,19eb8932,b0da11c,9e4a4574,5d496edf,c3b054ed,5b7fd57c,e731e41b,a538089e,19c11232,2e844b49,918da76b), -S(5798970,da3ee2e,d65e087e,81d9ce60,fb7ee1d4,145af16b,42a4889b,31b68258,8a8fba47,b0b2d716,6324f55b,143b3b14,9af089b0,dc9b9557,40c5df93,3067841d), -S(b482e028,f9cfe926,6d7d4072,c01d30ea,28dfaf9e,268f979d,faaf0b11,4f420d45,eddfa10b,7cba2273,4fa22208,51fc47ba,82721443,19a60d40,624d4e7d,454aff71)}, -{S(b3b5422f,1361ce5c,bf7cc061,3c78aa88,a02683ee,cddeaaf3,f5516cb,291632e0,1790cb50,cc2c760a,c7c2e97c,c44aff29,86c73be5,59a88180,8d036e7a,94347156), -S(34359647,5f3bb33f,eaac445b,5574c7b0,d2fcecf1,50a098d2,445748bd,482b5e0b,7caef8f2,4aa39495,6a36abc7,6704f7f,f7be9b22,6e3a1004,bc3dccc8,3a58cfa5), -S(5000310b,6e81394c,4f91677b,a03c5ca2,5e5c2581,bdaeb320,573febcc,4bd638fa,1c238674,6752ef6,25526d5d,1c80e106,c45a7b83,9ffd9160,bbe6bbe2,8056b532), -S(be843ac0,1b9efaac,adb5c047,49c5990,7441afda,8f33b1ad,20f6335a,5bea9c02,1d14d074,baf0a79,6c165a23,fa9ac432,c46f6576,838625ca,1d73c7f5,327808b0)}, -{S(2e01d33a,c10caa03,ab514f75,46226f67,69a08f01,56017b64,a2436a34,447bfdbe,f5bd77a1,2c61f2ef,60a8c937,cf29e1e6,882b12c0,3e7a7763,f1ea498e,9207836), -S(c8104402,70594c5b,f4e36d2f,ed9e6fb4,2d362b49,5eab7a11,2b1e1c26,aaa20cec,939741b4,db55bca3,53879f72,6362518f,98538a95,77249283,e62b98b6,b3c65c34), -S(408038a2,a79bc8cc,f1fe98f7,d7ddc784,28fd3c71,ed6be435,d76f1390,ed4e3ec0,2dbc7345,f4a358c6,f9690213,1f0418ba,2db1fd01,7e47d8a7,583d30c8,e74027ba), -S(8f0e6b51,50d752a4,86f0edad,a8c21b14,1f7a73c7,2d797233,6a45fc96,8c857683,3cd1fe18,21f1291,7d86b629,ad5aa2ea,46243c8c,398be570,f1959d4a,47b5c3cd)}, -{S(934807e3,60b79e08,d1e28924,2478db59,331c171,6366f421,eda4417b,c0699286,f7f83c26,50e7a77e,2f760e68,7f475858,b2c2d770,195c199d,33a84324,e23f02ef), -S(73c23592,7ae07afa,1cfc030f,a8c874c1,e6d876a4,7414894e,dfd993d1,208ff29d,c2158086,e6dcb078,3a602887,d5d780bc,6e620946,91260289,5244ddc2,f98bb1f5), -S(e588d73a,6eb03f3c,4700380f,17f4c36a,41415cf6,43bd12b3,7e5eedd5,13612e84,3a1cc3ed,22df4c92,96dfa9e3,3faf5035,d084a6f4,fd06c27b,e9bdfefe,bcf1753), -S(7fe24906,485a5638,42ae477b,de90b8a3,1984bf42,7f43660a,f120370d,cf6a3d3d,16bf27da,45038c52,a6051298,26039376,a6fbf802,583ee59a,9752dd09,f30a7ed5)}, -{S(accea070,aa6709bf,efd88be4,bef1d485,a0da83e7,ac9a1eb0,eda8387e,b9fe666b,93fc1c9d,fed8fff9,60ef750e,94dd2342,5fa08c3d,8eda3eee,7f51381,196080e3), -S(412c82e9,f90a302d,f404bf6f,c3581516,b23519aa,2ec26f20,9c80fca3,1f4d0698,31b2bbb8,493e0c15,796d93bb,59cf70d2,7f9c65b4,b3a74969,8612f72e,a42e572b), -S(c0ce0313,52b119b9,795635d8,5e2f5153,a3514d6c,190e2a0c,f9effdf9,bcbdd6ff,b4ef69bd,d4671af5,2be6a4be,1ab4460,71485a7f,6fde10f3,65db8bb0,91eeceb2), -S(b7a23510,abe3c77b,3720006a,9e29c6c,180e40aa,889ea103,ea2387c1,1667aa9a,863f8837,faef7267,d7e36595,a15dd7a4,b2012733,c7347dff,501017f,188ce8b1)}, -{S(a488f83,2bf3e57b,5225f748,754ba2b5,cd9657c7,175198ae,122c3d1c,ee336ef2,4e326d40,648cf269,2db42532,55391fca,5c2b48d7,44a9e39f,bd1293dc,827e9021), -S(bf6227e2,a75c717f,fb3d8d62,361b9212,45bf64e,b19554ed,11040b32,521b9e52,209826fd,41f88c85,f90b4c4b,f90caba0,9cba91aa,687cc502,23bc71cb,7f5459a3), -S(c0ecca8e,90d6979b,54b9e9aa,5a804c8e,106b8b41,a609b85d,1824d079,e2b95f70,1ce95138,2b6eff47,9660cc00,8ed77229,b11158ef,15d97809,a6253439,b88cc4ff), -S(3d4861e1,6069f0f,ddacdb17,595e59df,54a07376,4237b29c,102eba03,230dcb3a,435fa321,90e459cb,137046d7,d316fcff,6fd6c954,a8e2476f,3d38d9e8,263deb51)}, -{S(a473de46,a554667a,368fd573,168dea23,3f81153d,e1b35b26,90da8863,71e6c131,4ba0b462,92aed936,7a2bf9e9,de48a08a,874fd681,aef86a15,58b49e4f,13dbbcec), -S(435ae44e,4f062fae,72ec122d,b7cd5d5a,719c5889,a76ee171,be0e5c61,c5c2d148,d4a6c494,1fafd583,39b59229,b384a5bb,85140ed9,b8cc99b6,38f995b4,2044f380), -S(c170e94b,8fbff40c,159b8fda,ab69093,49e7ce91,1658aa2,896049cc,56b4ee31,19b45604,e602baaa,7085e27a,69d8317f,26ecb345,a558a3e1,5456c1a6,5d89e992), -S(2a043b61,f5e22943,19a38b67,b3bf2f8c,89be156e,641159ad,c94144c9,971af395,17d7c7e1,6c097256,be0cfb11,d9a3cdd7,8bca6a1a,c9514e37,3f59aa5b,c48eeb9c)}, -{S(476d7ba4,35177a71,299267f4,14ef275d,48b434e1,380c1afd,9fac4606,f8e02be0,7f1255fa,57a60447,c14d6574,1d7774b9,695e6d25,1b46912d,d33c77f3,f756edc2), -S(ac4bc955,aae3fa7c,a4ac46a3,84cc2f7f,3cf71f73,b15dd3bc,30513ca2,7da2808a,694ee4e8,6ff945c4,4a5ffd3a,19965ae5,2e15cca9,b51d4795,855eaad7,fc959809), -S(43b4f6e4,25ce5fd6,2c5d6d5,ce33c6c2,df453c6a,9fcb3b15,83faba41,69fee22d,dfda0e64,572ee74f,1fbcc406,7879fbbc,b3896243,70d4bc7a,677eedc0,a3432e4c), -S(e2c0dd25,96da70ee,2569cd83,cea9281e,e37c731c,d0112018,7966da7e,75a9cadd,f87becf8,ed20a606,f8be39ec,2baff52f,60543859,fbbf2b9d,2f8c9933,838b6507)}, -{S(4f62ab4c,b7fb0d13,12620121,9841e932,b0de312d,674cd002,315594e9,81dfb3a1,1145fdd8,c5d16653,a9129b0c,39fcbbd9,5968d22c,ff2127bf,91e89847,35e2834f), -S(ca2ca59e,ad140068,e488658a,836090a8,eba824f0,3c6a81f8,fed13956,865f1be9,f8e286f9,8e9c9003,e4701dfe,83b79be0,d475e320,8cc6fda1,84095f5c,9d0d70b3), -S(eae775d0,8d013499,5ffcba75,33a6dd91,2a07ef45,5a20f49b,8e7b7ed2,75d3c54b,aa4ba756,dd0bd16b,32e86c7e,a520ce1a,bc224d2f,822059e,3df2cd7f,d8d1f855), -S(db566c14,bcae1071,e0bd82a,7a965a72,101d4b5c,29cd7aad,c91e5e99,f4648978,78569150,59ba0432,3afd6a3b,ae5eb503,f920318f,25fc8c45,d1b0fe35,fcbab0e1)}, -{S(110f05a7,489138c6,51e48771,d505c7ce,68bd6e61,67cf4c3,3933441f,a236f263,761652d,178d0d5c,f6189501,d02d7078,2f10f835,27894d79,4f93dff6,e90a3b16), -S(7e0419aa,c31953f4,73ac26a6,80fa9996,7e8f0af6,18ba8a64,de8be81,33f48b6f,b6ef4bd6,5b82a94d,e774eb86,63ad7144,f025fc3e,d8a229cc,af59a816,5c38638f), -S(ec0cc26c,6044567d,609cf31c,c874d9a1,844f61db,37ac4e04,10497e05,c7accec8,20004878,3f7d270e,81144d48,ec839dc1,d1ecdac7,75910eec,b2942619,c8baba8e), -S(942bb265,6d6cf90a,44b1701,76fa9b2b,e366ddbe,fce1a83c,cb3ecb4c,555626cc,e07e2e36,2a835d8e,31601417,fb185a06,14aa4598,6896880b,f1df90e9,aa5c40a7)}, -{S(81f4223,6a39a14e,d2764665,22edb719,f2fb72b2,c571ed67,343e2c57,4fb60e5b,34f10ee5,6c1d5e02,51e8ba8c,9f129391,521f0601,2ebb4549,7377967a,d8347e4b), -S(f983c256,b5c49a86,6bf19c43,50083f4a,7e9cfba8,723d4740,f6909434,3b422fb0,11dd2c7f,16c588c7,d675ddd2,be80e785,50f63fb9,1f1bc016,bc29891b,f5bbd8d5), -S(37fc1499,95a90668,a871c28d,8ed84092,b928fc95,2c459c6d,cde783,28c936ed,e0b07cfb,6fc2442e,4459036d,bcd0117f,c36760ef,2f1046de,17673726,a41316df), -S(4ffc822e,916594f3,fa007cd2,682f0c5d,91b835ac,dbda2ad6,3ac3b73e,5094a175,3ff732fb,57aee90d,ad86ede4,5afa2e18,c95a0a77,d6cd008b,11c95bfc,dc927843)}, -{S(2dc8f27b,b3bdcaa9,2feace80,f2f6212f,8209477e,531e74cb,f497372e,9a2f2263,7feb63a7,96b55bee,ffa180ba,fef47776,fc4fabd4,2ccdcd97,64b4bab3,10350790), -S(c395d4c4,d877c2c8,268621d9,5fbf4f3a,bf839512,c68dc89f,82d6e757,d3938cf7,b37a444,a4e73223,204799c3,df859859,892eae5a,73844d09,9d33eac6,37779a7a), -S(d31454b8,b44e2a30,395674f8,abdc4fb4,6ac242b1,68f0fcd9,c59cbe1d,c8d2b47e,c5a4cbe4,6f8775cd,9482de12,4bcf447a,14e75b52,74f04a5f,c7912457,e31a4d82), -S(c133b76c,a0e74084,b279a464,dd7d5ab5,829e8304,ad8bd982,b2e112a2,9f452272,3bc44411,65b0b601,93bbef51,641b2569,a57aa5c9,6150ffb3,936f00c6,b6434b80)}, -{S(118d5053,fa3ef05c,810cf906,3a410f53,38a9e6bf,513b9a7f,5259112f,f84ad7e4,a371fc9b,c9182528,27d6c842,32e4e44a,9d32eafa,84f1a02d,a86039d1,6309e92), -S(29f11f0d,1457c9ef,7660a6f7,efc42e79,f58ad31c,1df3ee82,33856c30,185a4152,60cc2ceb,5a506326,657219fb,5a8bfcc8,d290f5b,1e05f73a,5f410c10,6ad99bf0), -S(ab757a3a,7af4069e,23493c2f,3978b8af,67d735ea,92382381,727ca6a0,df3082d5,335e418d,1ac2ac71,81a96a7b,7d15c55f,f8c6e342,83aa7f9d,8ae130e,dbe0fd41), -S(37e90fb6,b197550,14d0ea75,1ef33c24,a00d8cf2,5ecd8476,8adabba4,477260f7,90ce4d73,7613beaf,3e884036,5071f104,b88a58a,94c80b4a,1325694,722abbae)}, -{S(568b3e2a,2db4792e,4ef4ee66,14e201f8,a847fdca,38bb003b,adb06d74,1e4f999b,7334b395,61cbcce4,49d83eed,205a4c40,d91d2751,938ba7d0,6ed9e5a5,e1ffea7c), -S(8e37181d,e892fa67,3f26c69c,f6940204,c8f5e5b4,7a027489,ba6f02ac,b87a40ff,9c1a3ad0,bf418dd3,876388af,d45c6ab6,dfa7f7f6,94e991e3,ef0895e,7d7a51c9), -S(cf2e6330,134713f0,cfb27276,9e65e4ae,83d7a3b,84900aaa,3d32d401,55a19673,b8a0a5ca,ebbb17c3,923448a,767804ef,43bb056b,724471f2,5b089b3,ec77e453), -S(ac0df937,d2d65ab2,e6bd28ac,76551b78,bcb1f38d,81f988e9,3fe2b8ed,740ab0b9,f546faf2,120b2e92,6c4f0f18,49cc01eb,834e1406,b5ab4d54,bf3abd22,2b40ec25)}, -{S(7c32fcd7,13305cc7,44fc4ff5,2d315e2d,d4cdf7c0,31b41a64,db6ecbf9,fd4edcbb,7f002bf7,b8e1b8f4,a4a4f2b,1922983e,fb901e13,59cbe934,8a31d91b,7bc86bf4), -S(c72e640,f0401cde,93d85764,224730de,8d46477b,538528b2,53361873,c9f39dfb,571700b2,b5768244,63541839,a1a890bc,dc823e39,a7d137f,9e31e849,583b8fbe), -S(3bf6cfec,83091c9e,1c1deab8,6271526d,9d9afce3,1f052a3a,c8ebd1a9,49005470,35fbff47,bc7d13bb,197e6d7d,50596617,79a06b,e956bfca,667cf070,b80b45de), -S(3416d9d3,6c2c2c6b,77a5d647,500b145c,926cb3e7,1aeb7e83,101dc410,a72bf818,c785a0c4,7408b8b0,30b386cf,9e39f1ef,7bbc4358,f66ddc20,22b1b781,8ca175cc)}, -{S(29d70da5,92094c96,e293c115,42b9dbab,b30df8db,ac98416b,65b0b75b,b3ca446e,a8a5aa3c,c3269596,dd8a9d98,87a3b772,efa1c668,3f8a947f,ff80c662,31c70799), -S(bcaf0322,1e406be9,5df0e9d8,79d82851,2a71aa7a,7a84d8c2,ceb0a6,9d33d827,7a9ecf5c,efb0adf0,c0a2af5b,dc6c2537,b1fdbe0d,be399bf5,6e9d3612,a94f4239), -S(7a24f37d,d6a8c278,cdae5cd1,70be20e5,b9c9c028,ffd3c9fe,4dd3fc18,45a339b2,705f933a,d0dc7a14,7838c060,abba9bc1,7012ccbe,83633551,536e8aba,c8b5ee1b), -S(c35ffef3,aa4a3e9d,93dcaa91,a972172b,785d997e,dee6cf34,e181d217,a3c83d97,122638e5,b7bd05a9,1c5ad0d9,bda96767,6281434,dd0f8a92,561df9bd,96779571)}, -{S(7885bb79,25196ae6,f45b6658,f3c04f5,a3b76cb6,1d60eaf2,45cb35c2,2552267a,9839aae2,b4d9de01,1a119d3a,d269a821,dd88d287,2f031910,a2f3cc22,2e8555a7), -S(b425f805,2659b55e,4b46894e,3498c273,e1869ffb,880e9c50,20bef244,ad471ea7,b0bde647,f6422b6,a8f8fd07,a6f8c73,5b5a17bd,9d6eb57b,34142a18,93825a7e), -S(ccdc5e4c,7593b182,a70c2f97,c358db89,f5b09cf9,de3c5bdf,2a44808e,a84023df,8004b543,df7a516e,faebadfd,c2121101,1ab99b4f,c7a8cdf1,43a56afc,8aa72854), -S(d55f41a9,331ead98,db392478,aea2ce68,ae5c9f84,179caed1,aba5d60f,246f576d,43eed529,61c8bc39,8da97200,92f66f18,69be7dc2,d644f291,98be290d,adabc6a3)}, -{S(422f029,1f51c4df,af233322,7015e4c1,ec8175b1,a8ab6b2f,60a9e291,7242d940,51ae32b0,ed5d39d,e1d61437,d363d59,181a68b6,4e052bc5,9d132da0,9c1f422e), -S(3287920f,f0fc9643,9b0aff00,d6944422,297d3f52,7539f579,98fe3d29,80cc58c4,eaab3473,d562fe1,6cb86453,52228f69,f34efede,6934a587,ce62760d,5fb7869a), -S(a9ce3776,2c703adf,e36d3f6c,7a2b04b9,288bd09e,59bf6fd8,25cb0ac,84bbc641,1e9e8e03,ade9a185,d0680f80,9a9a0468,2338a1bb,4fdc129d,f6a86377,2f9da89), -S(a7480262,bab701d4,11642b23,50934791,8e393f5f,3d55ca2d,fcdf1957,f20c4e04,460875e0,a7afbd6b,ee8491df,d1e80b58,9cba5bd3,a6e4d74e,a4f5bc6c,567460d4)}, -{S(43cf2273,e372157c,2180640,594c144c,93f64fa1,75f28cd2,5e7efebb,14028a93,1f8b092d,4cabc600,33782374,10eafd04,37d6436f,6064932,6f8de6d,94059d4e), -S(e327e5fe,3d20effd,89532c73,eae90c0a,36358e5e,65cff655,b25bd325,8339599f,311932aa,8e4c3f38,cf6ba972,d9872585,14d376,460a1185,6b3a8bbb,ef050996), -S(5fe08c73,62e99994,ea0416e7,d29e1f8e,56e66baa,ef9f3cd8,47732960,c6e545ba,f9373f76,5a340816,cde0db8f,486d6453,531c0ec7,4ddea72e,280d7f42,2fd7ad80), -S(5c32f5a4,74b7f6f0,c019f7d0,a2df5c77,4017dc1a,f93b5c00,bd531eac,32488609,94ca08eb,3d86eb5d,b8f31b4d,9455a6c6,1525a0cf,b388b698,4fb286c7,188d3193)}, -{S(9f10aba7,5a7b9fa0,233bf53c,d819ba2d,919f8acf,9a5e6717,2c93229d,547a40bd,85485295,254a4456,87b065aa,dad21f32,b31735e1,96333fb8,11117a00,d0bf2361), -S(b56da700,114ee476,21540199,e77ba271,e8d578a4,5be263c6,cee2e8ad,fb3a3e48,23ec87c4,236c1299,96ba8d3f,b8cc8af0,b099042c,6623deaf,2abc10cb,c17536fd), -S(a9d94ff7,a5be0ab7,5a8563d6,b061a8a0,7e12690,4870fe3e,39c4ce98,93e96b09,8d1b1b28,a0366d25,a61b617d,9fc10194,72fb3e5e,ff5ce43c,9e1bf1ec,708be6be), -S(fb9fa3f5,381ed2f8,b8f407b2,9991fa07,a6d7a265,4dd2b3b0,cffa3814,10efe8ec,8e9b9167,bf42b7f0,6bb22bb2,3fb40e01,bfbac1a0,dac536ba,b17e7970,803ed9f4)}, -{S(b365ce49,d21ca341,c173b6d7,2238c56b,f080d218,a89e57c6,ce1664f6,5c290a44,e77935dd,75d26531,d4045f72,3b4b5dc4,6608f8b,60f58989,d2ac4002,c304cf04), -S(f512da13,dec07111,2b2cdffe,f72b2b20,aab81bc4,8c3514d2,f6f1360e,ea17e855,3934b35b,87269072,77bb171b,fa2bf260,244b1f6a,13bdba7e,a3e43b8,d86d8abe), -S(3e000708,badfe5fd,d7f708ca,92bd5784,80d0164f,d76bb0bb,4dfaf9eb,e54335a6,713915c9,7c1b1d3a,7111ea47,6c232b85,527ed32b,1e6c4584,cf36e9d8,5abb9d80), -S(c6e97208,17f00aef,4988ea97,8f7a0240,efe4a0ce,203ff10f,4dc77e2b,eb49934,d47cc2d7,f0e499b4,985048fd,fd5f14,83d1f90d,a1abc2ff,340993cb,e7ae03d4)}, -{S(38186a1d,6092b158,554f3f6d,c6de049a,2037577b,2da8db39,163fde30,b19dbf2a,a8cf045,9c7ea28a,415d01f4,47566d54,f986cab5,eb272326,442f32ef,cb6c43c8), -S(ac911a57,1f58a283,517f1ae7,7b2ec8ce,1bbb2d17,3e2dd021,bbaf352e,edca57ad,c9e985f3,f278463b,66851c70,d2a2192,299a3bb1,7ac40661,bff10ea9,29734b3a), -S(9a691204,2f6e8cf2,7189de67,f04d15c5,b80df68e,daa7dc7b,74d08053,e32d4516,a60a7abd,6448fc26,3d49e9fc,32b51f05,1578a8c6,74827059,ddfb9f93,f4621acb), -S(8e6ecfe4,e5b519fc,be7bfc37,5b0738b4,618e5586,dea95ce1,8b870424,55b8d1da,4d459953,53cf5ec3,43b38aed,c3d6bf27,83230fbb,9fc0e147,5cc5ca9,6a341ef8)}, -{S(d8e5f3ba,c152215a,8cf8ca08,40aaad6c,7d001aa0,140bb0b4,dcac726,229ee272,e59390a8,21e8608b,e53fb258,a426dfb6,ca762fd0,9d574f7c,5555cb8d,7174b381), -S(281c15f2,ff06b872,5d0b9a22,2583cbe1,f29c6bd9,7d63db8f,426bbbb7,f36dfd57,ca452a00,fd4afd88,f5369ec0,5b3a99a8,7ebc60cc,db297d6e,ad1479ce,a8c87bf1), -S(69c61933,b91a122a,36087b61,1fb86372,3cfaec6a,5e51b4de,9db83fb5,cc5a1e5c,18b17e6d,74d632da,90946919,2ea6700a,ddfb34f1,f537e5ff,581e04c1,97437d78), -S(e97b38d0,9bc65cb3,421a6ba7,9efeb127,16fc82fd,b539f94c,1c068699,2aab5eb8,43244371,2d899972,a9ebfdab,4ab8a5d3,b7b14b0e,64d82d52,50b9875d,bfc9e1a8)}, -{S(f41bd2b0,e0f49133,747e831c,af4c7a0c,22d2b55f,1cd4ca53,1115d81b,b47754b0,869485d7,26d4687b,c57a9eb6,e90e93a7,bce3b523,998d16c1,297c996a,b68c4fa3), -S(b6161665,b95062e3,aefcc0b5,1220e1d4,dc6945ec,3f73ca4c,47449592,ca977cf9,edea5f23,e6dd49be,7d718fbc,d0368be2,ab3b556c,e1c1de15,1d811c81,44bfd39e), -S(efa245d4,3743d3cd,863a6144,cae9db8a,c7b80e58,4bb31a66,1b670b3e,a17a63b1,ccb90bd2,806117e3,3781f7fd,7ec24d22,b6174aa7,1c8b0f35,bd22e95b,7f5fd96b), -S(ff59688a,fc00c3ce,15e0b2fd,d829725d,28b9d07f,9fb13e7,61ea7f8c,c271914,9779dd1f,aa487c2d,b4c4bb48,3877a848,c329fe68,52c05a8c,7c8d1c51,95a905c6)}, -{S(67c452cb,e71c61c5,8aaf68cc,b1f6208d,5646432b,86774f8f,60081179,6d5337c9,d5f859de,a125aee2,11dcc7cb,b50b4fa3,ef4f9767,7eb94f65,b6a181df,9b938c0a), -S(247c1e17,4a3fcde8,580214e6,b791ad00,59a992d9,84a80f32,640e25ea,3841b18e,1a9f638a,74228a49,e083b3c,c233022f,6943ce4,457199ca,30f230d3,42fb15c4), -S(d36e3977,66121dd6,af8676ea,155f4898,c04ad6f9,d682841a,6811c4c7,2d0a498c,61c0712d,24db9d98,dd6dcdcb,e0a57878,b5cc5a88,d42c50c7,d5f144ce,a937ebf1), -S(b0a52f1f,2cad54b6,658a07a0,dd64c7df,e227aa3f,a32329bd,cf0dba1d,b33de23,c760832f,9be22f9d,c7d17a21,46255338,25ed8afd,1468d03d,d6ae5593,71bfad31)}, -{S(56d09714,cde8f0c,f1956cf,a56bb0aa,b73507c8,bc0399f8,c0fd17de,19e48e9b,d62e1f31,b40ca6ba,71de9059,8a9fb911,6c5f0007,df0c33eb,f50db688,ef0ab90f), -S(a070b352,ecfb2a06,d450cfbf,6800d7ab,6ecd58c4,a5d66c38,a330feb7,739c7dd0,226e8d14,8b074b35,db600e7f,4bbf40f5,c957e5d2,10b757de,3796f2db,1fa4e89f), -S(acf26ed4,9c8d49fc,69d83f06,168a7ead,77a0e16b,89fcd5b9,65da0d65,5dcb7d3f,54894631,5bfd024f,cfff92f2,df2e2ce8,987c385e,6147d783,612a91bb,5411126d), -S(33b944e9,fbcac6bb,4a0a2c95,168180de,fb88eb50,7cbe354,884af02e,dbf5e0c1,a0de73f,8c3646b2,dfeb126b,100a8e6,f5adfd54,2e26b225,d096d760,90f87c62)}, -{S(31095045,658b8c85,ec0c4ddc,7cbce691,d060181d,ffa08855,f3f36722,4c026225,9a8cc527,1c231ce7,aeb6e73b,9acbc16f,4b331b01,4bd457b8,799bad40,547c210c), -S(48472fcc,ddf9b0b3,99ca4d48,254695ba,4beb02da,849833ca,fe68454e,284998c9,a08a0346,83e54fda,d2a1fe63,20b67fb1,b58a4671,b4d08172,b1b6ffc3,c3852499), -S(22cbc8e8,e2d632e7,bbff1662,4b6b971b,ae0b1c12,14c342d6,61fccc2a,af196054,1fae61c2,9843ca1c,6ec5a163,f11c5c7a,1ec4637,4406f32,67a47c4,c111ef3d), -S(5024b68f,89c9eb0,fe4e1517,726f2cef,d270ecf8,182dd81d,20d65a67,8dc81c32,952869d4,4a76c942,ac9c0516,fc16b1d7,a0de7bc7,3fb1a18d,a7253d0b,cbd9019c)}, -{S(da34375c,e38127dc,cc88a823,55d763a7,2dd5d733,d9bac216,7c3e621b,ede529df,13426579,db1353d2,8095e1f2,a007904d,5c04a725,2c621ce4,41157aef,d2e28cf2), -S(ca76f69,937d5d84,659fce11,e1dce556,f450874,5c0e003c,5e474b84,515a7ef5,d2e10042,a71e3e65,d1290d8d,7b5389ea,4156528a,2633ba15,bfe900fa,c5464939), -S(8d7a5378,92f98107,3dcfea0c,9750e22d,e42066a7,ce3b4d16,8b1e56fd,c8a9b93b,ca32aad9,b5d0b83,8eeebde1,8eb7b526,8169b0ae,912539f9,49a1981,d6065703), -S(d58ca70a,51085dee,3d1c06a6,13a5a46d,22d1ba6f,6077df3e,f67b33b9,614869c7,bd212d56,451c1609,93ab9ffe,9371c3b0,76a2c702,d7c12823,ee66a084,ee82fbdb)}, -{S(a80dd274,9cb3c40d,af91b91f,6e8b0850,27fae17,96e416fb,8a172c27,d39e8789,466161e1,e9519ac5,e1b03652,cd1ce6cd,1d7dc696,aa59ab5c,565d822f,af427896), -S(e2313561,865ab364,7118595,e7a10279,4a94ff32,48b7247f,a21d2a3c,906cfc7d,9af6a874,d22254c,f148b479,7d70947d,3065d907,e01f35f2,6f14811c,bb1b36ca), -S(db567947,4a29e5aa,b6cd6cd9,9e92ef97,21eb61db,37b0d0ef,2807624a,e50f1b30,1132a05b,f945f3b4,3bb70fb2,1ef08fe6,c2d4f18,ef2fd356,73f3c430,6ee73ce3), -S(3b4569ea,9feb4458,1c89625,5f39f4d8,3f590d39,c50f3df9,1f061019,c8094e53,97fabe3a,cf3f72b6,c1f01688,690cdac1,c92afe2f,9b1a9138,b9951f97,ddbcdd8f)}, -{S(b3dee3f6,cc08c0ba,5b7ba3b8,50469647,34f7dca1,630e806e,f84157e8,2992c765,d523bf3c,6b004cbd,59db62b2,58395f63,d487d6ce,31799ee1,59ddf96e,d9bae2e8), -S(93c41e9d,ef80a2f6,93cbea0b,c5c111ae,11fd8a86,3940097c,b8753970,e3123733,83a51bb5,849464b3,ee5be4b6,5c5215ed,55e5f157,db8b64bf,aaed7099,497fee0a), -S(6ac20b8b,6c5314e1,72a39c51,a30fdd47,db16215f,e7ed2283,76f74eb3,718ce734,73b0cfa7,ca3836f8,15ef0ddb,d74ca28a,b83093b3,4ae41a94,e92ddfe0,89af26f3), -S(7536c8f8,dc949d7d,c43910a0,8007d6dd,8398f8e3,28ece93d,93b95171,7d2a6479,43e214ad,2c36155b,187973d1,bcdcbbd0,58448490,a1a835ae,2f661084,d8370a10)}, -{S(df9c2e20,68e1e333,f6acc6c3,ba9928eb,e761d4b0,27eaa1de,dae18079,29705021,491f455b,6e937f91,35fe9060,a8c5b6c1,60de5af9,ba90aba4,c060145a,da1b032d), -S(db3f1233,c95cafc0,a5ec4224,2a62e08,745dc259,28b9a938,e6940809,9376dee,94903b4b,2908cd49,95f0883f,1a11d65,880673c4,ef07aa9b,5416de42,8e4ed716), -S(a4eda54e,c923719f,8c4b217e,2c20690c,5986c871,fad99156,8a1f6614,4d48e91a,87736a5f,e71db939,3a673e7a,9bc89091,2ee0c459,5150b88c,792fc2a1,bad3a6b9), -S(ea2475a,ac3db1d8,60263b16,aaff75d5,3c68bd1b,da9123ac,951a8015,30961202,2e723212,716c3573,e58765d7,459070af,45a48555,c176af74,fbf212ab,ff29033e)}, -{S(afdfa934,6f7bcc74,ec473e17,f5048650,11c5251b,bd6c0c70,c25cb561,4b004da8,b16eec26,d575cec6,b8720f94,4ccdddd,78a5c446,a0cf286,fd933f6a,999a4a39), -S(e529f606,84edf5b9,5cd3aba7,233959e9,65639ebd,13c58d6b,c8824fde,3f6e94df,93354f65,e5299a8e,210a94ac,8a871f2a,a7a0a6d7,558fafe0,f67f7c5d,ab304610), -S(83438a3b,47df9b79,baabaeb8,40ea82f4,e7b6aa6c,49802c24,d380fdfa,2f453d0f,25fd4329,e2ac037c,46025db2,16d1d18f,395797ce,613c8c54,beffabd7,eb17eb73), -S(30b3d04f,76e7f7ca,9ddccff1,f904b937,dd972f39,11092f75,9070dd4f,f67cff48,b70176a2,30e72a7e,645c2122,4b9194f0,3c38f18,7020ebed,120df9af,588dbf4f)}, -{S(c8e9e9c6,55d9d7e3,16a16971,f7b7ed06,fa5a2ddb,56288169,ea96c439,6a53e01e,3bf36e6e,8cb2f52d,8a7a155d,1b3e4a17,e06ae0cb,b1dec52a,9b5fbb2,9f0b8a1f), -S(b6b755d8,3e6f1b3,e19a079b,daf2cfe7,22dceea0,2791b200,52ce09a4,d066f196,350f105c,6e52d1b6,da090848,1e338375,7f78a1b3,da3d64f9,eec159cc,ee2c425), -S(713368a8,f3fe29d9,cb8dbff8,6b74b41e,bf2fa4d8,11aced57,47cd800b,afa434cd,2a99e4fc,a4fa0758,8c6ff4ad,968323d,b753d9c4,42b81496,fb0cf028,e9c79173), -S(9e8a9fd0,23b165fc,8d95e7e1,39804c07,aad352cc,18b803d5,b7bf8ae5,5f2fb3,dd7ead28,6afc6105,89e1f4a6,386798e5,97e92401,397f8d50,2ad9802,71a1e81e)}, -{S(9d687619,c1c2c42e,3e466fd0,1ad5a0b8,b459ab12,642d80dc,1081ae1c,a8009f58,34fa7382,687f04f5,1fb15740,c31df8e3,145a0908,ac699527,983a712,23414391), -S(aff756a6,6ea7ea7d,85ba28df,fb25a543,f317f806,f18a4b62,5469ecc9,7e5468aa,b344ad2e,b5cbf601,805017e6,3f8a3d76,99ecfd82,28a9d2be,a7f34436,9e1563d9), -S(d7f37592,cd207f26,80c3e659,ab26a9f3,86270623,bcfd6737,fba2839a,a2ff3f7f,46a52a06,fec906ae,79a81333,39659e09,7ad928d2,4b9495eb,98e89062,d87b0d3e), -S(7fa626bb,98c9f1a,84db146d,584aa1a,3ae75f01,1a86800f,21c2ad77,eb1df5ec,c8a92713,ee8edcdd,3954b267,cd1aed45,929599a3,3d10ab09,5a1703c2,447bc9ef)}, -{S(bede42c9,3086c85,d6793a53,5fcedc15,6202042d,35051eac,a86ee941,aa961d84,e0e7ae8b,a657730c,2fc631ce,82b58bca,1dcd52bf,6f071eb0,cb7b9f7b,24bdeb5b), -S(dbc001ae,137b542,ec96adfa,367531f5,a88b124e,8dda4600,1b14433d,acb50db0,e49c3c9e,abd1e5c3,c5fa8df9,46d7705,e54f594e,d31a5b81,bbc9cf68,d15fd7fa), -S(e199e2ef,a5120572,b844d1bd,76b2b66d,e7f5d2ad,283d4b87,3dda2597,f739733,9926c3f3,88af1ded,eee14bc5,bbf3310,4be655ff,c3ad4798,5b8e4f13,48f3f5c2), -S(19df4eaf,d8bea6e8,edef3a83,415a7a15,a2c3a8a8,95d19651,6c0b0f1,1628f9d9,6e36af6e,9f01cd77,dfa50cc4,a647b222,d6503c57,b4b6cccb,7b9f96bb,d68fb968)}, -{S(998c1a4f,52aa78a,8ab3a94e,66d787b7,145fdaa6,4701c0bc,8bab6933,3ca18ec7,a069228d,355e75be,f50b4682,b210b776,95b997ab,12d87b3a,29e87b1d,289de833), -S(6388dbf6,171559be,2d7e02fa,2bebd597,c373c97f,95d7c4cb,614db1a,9c19a82e,b1d06e7c,83dd9880,a7e1582b,27b3be98,e2953cda,505ecf6e,3ee88bec,713e6035), -S(66f24649,523c8820,798f6e34,a3c0cac1,ebaf194b,c4c32c84,a8ec5a2d,2dedd188,ec6d60de,74e50469,64ab846,1d09335,ae9f657,bb8b6f7a,85e02867,11390425), -S(43784439,5667fc87,d1b4486b,f798d397,e6aa598d,be9f6b21,63fd8218,ea7c8490,dcf33b4c,5738904e,6a4a67b9,a6360ff1,e603fc6c,617a7b6b,17095d56,e6eb2989)}, -{S(8c422f9c,4e2aa24a,6513390,fbcd3531,50b28c5d,40ee8add,8c9d5591,6440cf99,21809c0,2c3f1879,f677997,919d0deb,fd8b2d00,5f249de0,e3df9b4e,8df20524), -S(46f4b7e6,6fc006d3,84e202ce,e1658299,cee653b3,db8672e2,a2e26506,8bfa8b73,d09d2a58,d6c88882,2b2ef6e9,3cd26cc2,4c20f338,50d05e7f,6c937a9c,f8670e7a), -S(a19360c0,66d42f02,541dffe7,fa9aac94,26a4de5a,8a756643,cb812e66,9be21d42,3dd23994,8e869afc,5ca5ca6a,f51fd836,7c612022,d9b78aa2,4a78b8bf,d48a7958), -S(53f1c8b6,f62e094c,3a814741,e2c31259,95fb285c,d8e12d1f,9130c9ce,b1eeb63f,9129139d,42e3c44e,f124685c,fdddddd5,ba9bf1ff,5a61534a,d48503c,b48568b5)}, -{S(3cd27c1f,ece87bf8,10e9c382,a0d7939a,de6f757d,9d0178a4,ea486e2e,241d1216,806192c8,1852c43b,d2439452,b42152e,b0f8a728,50f3af8b,be9670f,fc919897), -S(e00029c9,85a513c0,9eb33ad3,5d0b712f,30bed96a,48eda85c,fc2509b5,99f7b3c0,bc83f8eb,c1bbfb39,981c89f5,7c23912e,780e6cb4,e3a97599,28e51430,a7a205c3), -S(85282c5d,fe004218,1af469d8,8949c331,545e94c2,3a7782a6,4b5b2afd,7e2bc98a,88f0b05d,4032c6d2,8b4140dd,482fdf9a,724181a3,a1ed22a0,ba4b83c,fbd6a61c), -S(8e26c183,26188725,d12e7726,9eb3afcd,121c2b17,6d7678a0,93a496e0,9c4f65ea,a574d95,7e9eb080,5f83e417,f145a708,971e2153,a8ab8462,99d52583,8472e368)}, -{S(7e562c7f,87ba4090,c3147469,78bcb59,722627af,75555e0,ded87772,f67a5ef,433effc5,1a6da4b4,14f793fb,58961db1,fc6681da,2e367f06,331eae98,4c1f31d4), -S(b273ce89,62c52be5,cb23cae,d2b98015,78c7dae3,d10af405,461b4101,c0ff1c43,4ebad439,72b99896,f7f41019,57766925,f145d0ce,59424c8a,6c5cbacc,a3979f16), -S(dc301ce9,26e82026,38b1fe94,7d166507,642a89a1,509fe1c6,5c13af35,9fc34c11,a7230a1,52c96952,a6e5bf42,c4fb504f,12d2577b,40e8b947,53db719b,52ca6b53), -S(4a9fd32c,a97ed57e,83e5c712,5b7a2af7,3fa9ea4e,d96ed369,6aa9f0e3,cbfafda0,4659c8a8,b9d5c6c,cbfcaa9e,eb2cc24a,225de909,faba88c2,132ecf8a,da456ffd)}, -{S(9189ba51,a650f218,5b0e78b2,4fc81b3f,95896526,65bb6ec3,506eff71,71399ad4,981c7770,b6d9fe5e,f55f55b4,4dcd4b29,57ee7078,5cd95d84,d59bbf8,6049a067), -S(8043092c,79a5aa9,c85468f,3e95665b,f7742d3c,78e46529,9fa55525,df768f,5d4df375,eda914f2,49b3755f,365412e8,1f587da9,b444cad0,d3ff87e0,4a7d5f55), -S(c4ceb96c,c733f959,70fc29e1,6abc8ce6,61edb654,6ecda22d,854552ba,3ddca54c,6c1a710a,f15c503e,b2e4ce7b,341256b5,ab3f5a0d,bf1ae1ae,f47d12d4,9c6e3b4a), -S(ef2ffdd3,54249e01,63e49632,c12f236,f71dca92,536ac805,70792598,a46f784f,b121fddc,795491b6,97a1cd12,9964803e,68f60f13,55cee300,5d64f761,3fa1e3d9)}, -{S(b381f721,8381bcba,39ce4649,ded8aeed,43d5548a,b1b09981,a704856a,9b2af576,fd401803,9e993bc,1396a459,8270d4b3,f26f47f1,8babbdc,bfcc30b3,671302bd), -S(9b88c66e,8abab5ea,b4b0e3b8,10bcf0a0,d3987e1c,c53b04cf,9e445f2b,a50b1744,f2f8df3,6fdcb9a8,abe5778e,33fb1912,20b55224,85286f25,3914d175,cf5b85bd), -S(3da8ba80,a6744737,eb75edb4,3bdce32e,f6f1b74b,bc0f7f36,3cc2f342,209a4e52,d61d3a19,bdb8d194,1ee3e2a4,50d7e87,bd00652b,4a52c415,825185b4,a2ad1467), -S(a23779f1,b3716be7,82d4bbb4,3d81677e,d78ed041,c2786f33,49d56666,8bfcec02,33b57d01,c3f38b53,d96ebc7b,2aca2c08,66de0c9d,9764dcb8,dce0c27e,f4217963)}, -{S(e2937985,7de31ced,bca13b56,16a2b853,c1f6c915,8ba5b999,405603bf,eda41ce3,bfff0870,88508486,361a6388,b70638f6,7eacd5fc,a1a1e187,93b2c282,d4d90ec3), -S(42e86050,d6101847,d9aa35b6,45ec7a23,2fd77d5d,c60ad7cd,a10e531c,876187d7,e0a1140,b5e0ab81,79c4a1d9,4e67f6da,ff166fdb,48dd3dd9,4e110519,fdec0563), -S(236ce23b,a13fb252,ee19f08e,9a3948cc,f3edf6b8,9802175b,67d34e91,b82ca1f2,3b569c1b,5c8aae64,b154565,70d7335b,e9f4085a,a2c7e522,96094b93,f9642667), -S(aecaf4d5,282956a7,5831cc6a,a2c09b93,655ab061,1556fba0,8b81bcd,9d9284e5,efdd1e5f,f6c357f0,21d1fe01,d8c6f2fe,c2d0e85e,12b7fab3,6920e684,df21e93a)}, -{S(9eb2f66f,e59abee,bd7c1bd8,dc102027,e94890d6,d24cefe0,e0e3185a,d84567da,123480a6,b2109616,2f5c8bba,4c71ad28,b1ef6d3c,c6b864ab,eec3bfd5,15069b19), -S(e178a416,f501623e,5fb17e46,9d7ae900,1b508178,91f25b5a,83adc565,7556ed18,e0712be6,e78d1a97,452c35a,c19e0459,dd6762a6,9b5ec073,ad1d6ed5,8ba3b369), -S(99243b08,6c3ba8cc,f44cf61e,c7a4ec89,541019e8,65a04ecb,da7e4683,16b5e883,9fb51a9f,4cab9214,d5247350,10a557ca,403fa1c3,b55d722,19557d8b,df2de0c2), -S(c33c61e2,5ceeeb1f,2fa47e22,a93f16ca,123235c2,b7cf9af5,e712e88f,808fb372,a72ded7f,3a362df8,a0992be1,6ab23f52,996f200d,b4981d5c,9cb76712,f0a88274)}, -{S(46481a2d,9c09cf4f,e869ece0,3f065938,e144393b,125191de,a52975d6,f6e0f3f3,74245935,50f81ff0,412a2ccd,f0ec2149,a66a61d0,d63cfd19,74a672f2,ba3dc512), -S(b5d5fb4a,ff2752fb,114a8b1a,c285ad44,5dbcf4aa,fe8f75cb,31bc43a,4298d86f,6f2e10cb,b36e3f26,ca280661,3ac0c052,1fb0781b,214e404,92574c09,8d87e519), -S(308bac42,a25bafbf,93a6ae26,cf99cbc5,1a643215,2cfd927d,7250a964,bc459289,ab38c54b,5725609,3d83bd6c,1dcd4242,e13bd844,c2b7b6c3,b1fdc8e,f7c1abc4), -S(b3c63fe1,67804d24,bf0b00f4,1c4a0175,4886e9c6,a9047439,adf365d6,bca491a7,d0a1a577,da95a3e3,6e2657b9,f9804c8e,93b5e635,6e5fa540,4fe8e3c5,5cf89b2e)}, -{S(5111fd06,525fbe47,3fbd604,6faad331,e715cc48,d2851a8d,70b34c5e,35db531,96ffe690,ff3d3901,d9505f1f,a13c446d,4065ce5e,fabd4ced,59c4f8ca,440d1515), -S(bc12f2be,3b0f27e1,92c9d446,59bec78a,4a592f0e,997be28c,313d93ac,4769fb4a,143f1a68,1f6d69f,66f49543,b131a1f6,c8e3b933,271dd57a,3be9db9d,1f9c31b7), -S(edc09cf5,6730b640,689c052b,989bf0fd,de56d4e4,8079000a,b4e8eff2,23ab61b3,57f21a98,eadedef2,8ff6063d,53bf158b,c38e1c1f,6df2d6e0,5ff7ad18,47c91bea), -S(4ba6c933,962ee6dd,7b7a80fd,4102ead5,d94a224a,4236234a,72afef90,3537c70f,f84264af,c8424c8d,77b4cdc0,37f4fdfc,3b1c7dec,f0fd3da6,f696beb0,98b2840b)}, -{S(6d3b19f9,79986500,2f0fe9f7,67efdd28,73839d01,3b7f4cc0,842b0a85,c1934182,b261bd9c,c90bf00c,3ac67bf3,728ef44e,2aa1b660,6cfd4c41,20d1bab3,aa05efc), -S(b9e6fbd6,bacca67c,d2977ad7,458d006,bea2288f,598904af,6794cd1,dc819231,bfd5bcf,2aeca281,d596798d,482ab975,73b15bfa,db7df642,abdc727e,cf664f1e), -S(f2e3c13c,8e1da25a,3b05272c,fa653ef5,487ea653,6d55bed6,c9ee0e77,85325f90,7bcae36c,67ec60cc,108a8794,cb24a3,b70c5f0d,2d58c813,77dfbd7c,10972256), -S(1317a41e,f4f09481,db342808,63d49b1b,dfb2a11a,f843ddba,29499f1c,69cba337,28aa8ec0,ba9021f,c49e90f5,65c61254,3b2e6e0f,57370374,93fe349e,11ea5eed)}, -{S(5a9ce5ce,5b6c4aeb,88f47c4f,680002a3,d898da92,603c0513,d72ae0c0,239f10ca,c1d25370,ef453f49,7982bdc5,d7062098,1a0dcfe7,d07a0339,eadfc5bc,dd0d7874), -S(575eaa03,caf5e2bd,eea82550,f961b06b,e8c8a25d,a13f912c,856776a9,2c3cd783,732a2a82,da6c4d7c,79f5bef3,9b39831f,f8f79233,f9700346,fabff503,50624616), -S(b70091c1,99c77e1b,756625fc,de51262f,93e236ca,f48d6f79,d5ad6d2c,1c4eddff,d301345f,3d600128,503f3b0a,7ecb44de,f623c9d6,b3ed8cae,d676cabe,695cd53d), -S(338ea0d3,6d5d98fd,b95db010,633555de,c9cae973,720ac4e7,bfddc91b,176103f2,bd9e4e53,e18e541e,8ddb1d24,ffbf38d5,d2529ad3,3c043c07,1fe78847,63be57fb)}, -{S(cf850614,851d0868,16a329fc,f5c1afc,6dfdbbb0,ed9278f1,22de3890,cb693837,b768ddcf,f8dbe818,fcda1d41,1133a9d8,5ba6fa7c,9dc85b1f,23b3174d,69e3f33), -S(e3195ebc,5ee69554,73a626ea,14332378,1da933b0,fb5a1484,da2363d,65cadc7e,d0acda43,e7ff4df9,dd1f46bb,93e8bb3e,ff73644a,e024b5ca,8996a750,91928bd6), -S(5741cbec,60c5375f,6dc383c1,9b0dd4db,1a6a8aed,5658e87b,fef33a14,2e281580,66e9e972,2a6df27b,24500496,ded7638c,a19152d5,7c7adb04,74125ff5,1be6cb5b), -S(7e64bc9b,ea4c6460,b9b1ef71,95a4f4e2,5601d616,11ae689e,cb05b0b1,ade57298,bf43d8b2,65094986,324842b3,23fcb1f6,5d0896ef,1537630f,e42b669b,42758a62)}, -{S(17631e86,523e4d18,51417204,dde16c6a,bb7ded2f,2504bce,6683159,63e9b492,cc3a083e,e4622c59,4d934ecf,2471143f,4af9c4e,481866b4,637104ac,d815c97), -S(69d98c81,2dd5cd4,229eee2d,d82f75a4,986e514d,cd8dd1aa,1bed8447,e5f46fb,7d72fd27,40e91bbc,64a3ca20,243eb038,9cdc46d7,eab75343,8103f4b2,43e9de06), -S(76f7c0d1,c661944,5f0f5beb,568cdeb4,9cd483d,e5bcb737,2de66e73,cab23c2c,540422cd,994b4411,6ed2d068,5dc78193,fb5b5fd6,28e3f432,ee2d221f,8783ef7a), -S(6938d574,f67039b5,eb87fbdb,b759fcdf,4fc2c341,ac5817d6,8ea8277c,d4297574,5a2679bc,83685ca8,d3961d51,1a5ea081,8ae917c9,4606d552,620093eb,f399de53)}, -{S(60ad1b2,a075a3f5,fcf72668,cb48703a,f44c3442,23566340,b0fd682c,ae829ddb,534bb9d8,46bd457d,3574e528,87787f61,743b8cc8,e7b9032c,587992fa,c0ca2818), -S(1d66875f,42d8e75d,5651a635,1db1a820,725a29cf,74e0577d,833bf841,94e9a2d6,803ed33d,2188877a,c2e3d4e6,d78aae19,8d2eeb5e,a9e2c3cc,29cd5214,c20a78be), -S(cf400141,4811b30,70345420,e23ff7fc,bb800b9f,ea2e18cd,84b1b637,7b59ea39,2b8ca9bc,722dee2e,29996865,93178cdf,16503531,e3885322,d42b0ff4,dd091927), -S(ff2612ac,2f9925cb,cd76b975,b23aff70,428062f5,8f64a507,28b3021c,6548495c,e3bc502d,6046782f,8d2cd0f3,f5bd7ea,f661e4d8,5eebb56f,cf2e9d78,535994b3)}, -{S(4839ed9d,4a5e9c82,4c6ab373,b9cce0ee,6d8f19e4,2185c791,89b52aa3,52533187,a1663ed9,7007472,8367faff,33ba90f3,620b6b18,a816ff71,7fe8e97,20304323), -S(ea4b17,5edef6e2,46f8eb69,5bdd5b86,f06231d2,38303d94,c89399b4,af9a4531,aaf021e2,555632b4,da731da2,fb3fa644,2e8c34f7,9ed5a701,d9ff6be6,c3d3e7c7), -S(62def07d,3b90500b,548c2126,5d65f122,edf17b97,9defab64,3e702276,774ba43b,1caa772b,bd3ecd64,c83d903f,ae57a9de,49649abb,5aa7a21,2dc2a904,e97f9ad0), -S(b8cab6cc,e7898d3f,ffabaa1f,8bf0fcb6,fb00239c,27f33ca0,dd893d98,b2784eb0,96841107,cdcc5d3b,5c1c9c7f,39b92ff1,5831e400,73762437,7d062af3,4b0a1db0)}, -{S(63b931af,dd8dd850,d9b2f2fd,480e109,14365299,254ae0a7,b04cbc2a,def6a5a8,dddb17fd,8100129c,27b1122,34587e41,e6b47b01,9ed91775,b217a10b,3030288d), -S(a2a4d3f4,40c5500d,a0cca022,21cea8d5,89410fdd,7782d574,85112d8f,e6ffdd61,adbc7f46,db8b0f29,31dec8a,bdfcf396,96f158be,f6f28d4b,d88e14f5,5ecd7bd7), -S(242766db,7d3aa77a,6daafe42,1fc02bc2,d78bb495,771264fe,4f9ae1d7,837106cd,f9d7f63,7f83f5a0,6dc4cd42,af1aa54c,821f1711,66bb9c02,58ff6448,de3da6ac), -S(c089b764,f873e53f,9fb390b1,d802c7cf,e68f8dab,6f2ba524,4e309027,8ea60dda,7f83e920,b2fb47d1,c7b9aa13,eca044b1,7ab67d0c,94767d39,80aff8a3,1d9effaa)}, -{S(ee609aa5,cfe0de2c,45d1df32,707e4e8,d8c4c572,3acabf20,c95e8d12,9f237cdf,27a1804f,d2ecbe1c,9eb1958,d8b7898e,968c6e5,e798b2b,b86b7a55,f0b00695), -S(16c7fca9,8bc28613,af1133ca,6c3ed5fd,5792858a,73a87773,17c004d9,c88a81b7,7d6d7f8c,4ed838f,7f96a060,32d20e01,b792a729,57d502ef,575e68a6,c55c8b1b), -S(c2c5cfc2,4e16cf88,af21c30a,2e37461f,230a1401,2a970057,f20e87f1,de517cec,6a6c834c,bf6d682f,b1b4779f,1629b1b7,3feac678,38e34a08,74d335d4,9245c37e), -S(1c948040,7673a271,23dd0fd2,85de249a,49c94348,75ec6660,3d0afdb8,9edd4642,2122d99,6781bee8,628b27bc,cdc00293,43e3627a,f14e8e23,4a144b59,3ed887b5)}, -{S(a336ba43,9d7ddf1b,91b05a4f,72083cf5,1f8ff83c,15ac69df,7bcd2d30,c645cead,a99919fc,a5854c02,e7246315,477a6cca,e29005dd,e950c35e,7aef7d4,7e4cacd), -S(211e7055,6cf61cc9,9db2576,20048424,9a5cc104,e818857c,2bcfd86b,35f09d24,f69df2c7,d480cc49,8b605364,e4f64998,a7d26b26,f354dc7d,1780f0a3,324f4bb), -S(781b8f44,86276947,6dc1b3c3,f0935984,6e827615,b22cc0d1,4e92eb46,4420089f,c49a50ef,3ecceb1e,cc6081c3,7acd7449,73b8c2e1,9bdb9802,f55626d9,129bbe09), -S(62161d16,921adaa6,5aa8a7c,b3dd1dab,1e32f9c2,e4ddd119,e5d8a321,3e0f262b,eaae5b60,49d51781,ab479eb8,32153328,fce9b678,3778a06e,581fc028,e5352d8b)}, -{S(9bd360f1,9a65f3d3,757a6d30,74e793fc,8a972315,9dda6f9f,f84bafa9,8b70cfd0,d16b8dd1,5937851d,6382b0e7,f6f858f,862021cf,857f4576,2fce65fe,ef5081ac), -S(820f3f6d,f4747a54,563f4a2c,b1f9a2a3,4454d1ef,c28c4f87,2fa123e2,89a65fea,27a82421,216b7b0f,2cedbe3e,d45d4b1b,c70e47c7,cda3929a,f46d05e6,5b51124b), -S(37e88e66,33965cc1,c313ba45,6762548f,147eb369,debf6661,c8c63749,afca6d30,c2573a88,f797bf94,cb42d82c,c7e1dd5f,67b29517,f41c8950,cd27f77c,f4c4885f), -S(39d0df0e,22fa1770,3ebce0cf,753134bc,5ba82a82,b50886af,ddb4afa3,c67a2df7,3a05b6d7,3fef259d,f900ad7e,23ba9ca3,fa0e8c22,75a98ea7,d60d3ef8,5116bb2b)}, -{S(47686db4,ef418446,4955455b,8aa0cb42,9903b2df,9872087f,74923a43,6a5fa06d,997c2258,ba1958bf,6801fa6c,56a1eeaf,2f4d4f6f,16ee1ec9,389569e3,6abee360), -S(ef85e550,7edfc88c,697e9396,e700cdc9,70a0c65a,cded23ec,97e8fac3,637ff492,7edffbeb,c39d7ff7,90fc479c,704b5717,231b6c17,8a89a032,35b64361,c8f37bed), -S(4790f35d,c4cfc648,cc011693,d4de07b8,341a068d,b89bbdea,b5dc26e2,49673db,52b2c399,97870c54,98427e7c,3a1b1e6b,58151033,ce11d5e2,a07950b4,c0d6a228), -S(b4fe974d,2de71dcd,b6000352,1f2920c3,9c898c81,cbe9953e,41db3462,f298446c,f2f7921e,28e06841,1b7da1e6,81442a6f,e5df27bf,307fc5ad,90268199,eb8dae9d)}, -{S(17d69e5a,f192e0f2,693926e2,adbccce0,8aee8656,5b1838,54cb05f2,d8563ee0,ff0c4e1,bf955a39,f8d14bfc,68094b97,6f1f5429,e04b21eb,9a86e4df,d2e11507), -S(e275d881,a266b218,77523b34,6bd25e69,5ef771a6,b60bc0f9,44b9be13,fcb937f4,50917dec,bfb8c492,97254e5b,32635da0,e16f8a1c,cae44508,546e024d,b91710d9), -S(594e43dc,498fed,9206ecb,8cba88a8,789f34a6,c17700fe,b0b99533,3e18010b,100741ca,9d03b5ca,a094f383,78da3ac5,8d79081a,1015b133,1ce28e1,821eeec6), -S(15f7436d,98885865,3d74e5bc,8210a6d0,73e906f1,25f2f317,63636f8e,4d2a5bad,9b7d4de9,b9379a04,edc9b47a,851385c7,ad8263a4,a0f0735a,d990eb70,dfe860ef)}, -{S(dc728a2f,6062da93,9d72b4ff,2595991c,5eeabdf3,bdc7128d,2fc0f25b,aba482d,297fa2d7,8f62f21,16d3a68,e60bebb0,1bedb0cb,370bc401,30062a3c,f5e57c8b), -S(f842bf23,8f136dd5,db77b46b,7b55974d,dc4f02ae,80d80d4f,7979212f,442f2ee4,fee53360,1c8ae94e,b7fa61c1,5daf3bce,5f8d21db,1b38617c,d9a5d547,58279ae3), -S(5234fb57,d95b1033,21e67c8e,cfdf9983,c7f134f,fb105e6a,c7c11dbd,95a39d85,85abe819,a8a8df4c,c77eb61a,8ac1536,2985c508,f10f3280,e8585c96,f21fdd66), -S(bdcd155c,dee8a06,f8d6449a,f43af493,eba8c6f4,e3dd53a7,a7c880b2,155a04b9,be820a74,41ba1bb7,417901a1,99fc9f22,f5d8604c,42f10c5f,7d423081,505daf20)}, -{S(a00355b4,d41ed117,b9ee9146,de418905,aface350,60c02d8f,d8bf4af5,a20b77a,bdd0dd35,cd5857a1,9b3d0a67,a14b6047,acc7ffeb,70cf4409,633f53d5,bd85395c), -S(3604927b,eb1fa6ac,409d084c,86c8cbae,484e46fb,c9262f02,fc316fe8,ddce379c,5c92529b,1b66b9d2,9b060a9,10ed2da,4637e466,3957349a,83e9ac45,5dc17d53), -S(a681fd19,69da961b,35aca5ef,3a4325e2,12766646,4f63f019,90267865,1fa896c2,f3becaa0,377d0878,462005e4,795bad58,daaae64b,67b7db29,82d2516e,4c72811a), -S(1a87a251,7b770c6,705140f7,cea0bdb4,5abc9a6d,3a0bc0c5,1d801caf,907b635b,c18b4034,f7cddf7,b23673d,b8942ab1,93a698f3,15ef0849,b2c4601d,aca264bb)}, -{S(69ae3d10,523302cc,bcbafd00,1f40f48c,b4f918b9,65190983,24cf0479,f9175e18,e9583688,9ae86eed,ebc7f99c,19af452,7d239906,aa96c92f,2dc91f60,4704909b), -S(18641531,3ec224e9,dbdb0254,f810c2a2,85d477fd,357ec222,1b31617b,7bf51e15,e2900618,7bdc64f5,bb04c80f,7d7ea5af,2adc7d24,57862959,5a598240,219b2faa), -S(c3eaf844,8e1506db,eb0ad332,b26cb2c6,ed2c1d76,36a445b1,b0af2743,122fcf50,f6171ffc,88d5d448,d828a445,d59f7edf,fc37241f,2af04d39,1cdc4d99,8b3b9172), -S(2019838e,f4cc5420,37d97952,ac870d9d,abf443f5,56226166,9ce84839,df69e527,a70ac8e5,e8f76443,fd4765c3,84abb1bc,5ab66333,9c4c555d,8dd840a6,7f87049)}, -{S(90014ea0,f76360c0,aad4ec54,8698e053,1445716d,57e7bd8,9ad0c952,b806ddb7,d039a3d3,717a3b7,68822dfc,94c216df,26249d04,d2995fb9,559fc8a0,53b51fc6), -S(769e1d8f,67248191,113b7ab0,84103fbb,cf4950c8,7b19d6d8,65cafd44,b8bd18a4,8a7d2d69,aaf91be4,d4e86de9,35883b60,8b931f61,67b9e76c,ea43db6d,66952560), -S(a9ae4006,c04ffddb,ecc638c1,e348a014,b179dfeb,b9e8743a,b2d9fde,1a48ced3,30f74acd,4a29811e,718baea3,11d4f5b2,b70d4339,e83550f1,f4ed763c,52907908), -S(13f000d,912ade2f,c6a1c2a1,5dc7f3e6,380df54,44fabc7a,80ee4723,ea27af10,6dcd578c,12d35e33,1e202b81,ec93fd6c,30523f82,a524669,2b7896ef,53db20fc)}, -{S(8cffb25b,9df2cd59,a3d5efd2,bcd2f2f3,f96bd063,14c04246,a5c29083,eb08b219,113d1c14,753ccadb,4b5b8991,86c93f02,13c43711,305e7056,fccb8f5f,8f265714), -S(a3cf6723,3fab81a8,5c04d80a,5118132d,df914239,67a5e486,3f30c792,668fd49a,99274ec7,9a8b0188,a91971fc,631926d1,72923ed8,a91eeaa0,21494bbc,33ac92cf), -S(470e48c9,18310136,80712b3d,9a673795,91a4a7bb,2e25f6c5,59700ec9,b5f87692,3b9a2d0,d9ddcabd,511336aa,f0c1977c,2e09e37b,96664531,48b82476,6c562b8e), -S(eadf65bf,cb609b05,b000aed4,98e344ea,1913d376,c0200c2d,e2747e5e,a24d6900,c42cd81a,756dcd9e,687b42a7,2ad9621b,dfffa3a3,c8b7398a,ea0aabe5,fd737b96)}, -{S(68d83fa5,58a5eeef,8695eb2e,409a1774,61d43b2e,81e2d4f7,efcdce27,25a515f1,679ae994,24e430ae,7cc6d403,afcade07,eede7dcd,3d597717,fe93d1d2,3df076f8), -S(5a55b581,5c824e49,db51f218,913eef58,e8a666c,4191a290,b66ffa0c,abbe6546,8674ef7d,9ea73c1d,3a3915ba,e118c742,fd4d4e88,78adaacd,699963a,5eb9f796), -S(48d7425d,376cb7d9,d32b164e,920cbd7c,e7d174c3,7afc191c,66267221,6ab5489e,d8ffc4e8,29de5c69,dfad7fd2,3353bc49,a6e4fd42,c31a4b8e,16bc0bfa,ce26be4e), -S(ffd5b298,ed5a84f,e58e09bf,8df83308,3ffb4a1e,8c5ac3f6,1e594b03,406565ce,f56678a7,fece6530,6ab4a556,d7bdf41f,353c5470,d2b6293e,a97bc396,d8ee0fcd)}, -{S(3432345c,9df2e165,daddc0ce,9903a17c,2070e055,748a0695,123971ff,440a92d9,3b05179d,dfe73d48,4477c69b,434c05fd,55ad860f,dd286362,ac39cce4,5b7e5c47), -S(abe99ae7,698019bd,66615a5d,7df9c4b,cb498915,a868a48a,25ff29ed,747cff8c,f9b3f71,113c791f,b3353724,a812351d,3988b8ea,3a93821,db26631b,6907ea72), -S(4c493f53,3d4c0b6d,17fac73c,4301a054,75353360,1536da94,bca3b454,767b86c8,8c9743da,8b125a52,20a493d5,2c31440e,e1fb6fc7,dabe35e,7ac97c1c,94c85e0e), -S(2b73a96e,70fdfdd0,ffc601d4,9d78282,f997f73f,eea4ad75,f8c5d753,65db2f2b,994d51eb,c58dcdfe,a5fa01f7,522e5d70,1c21b325,9350b7f6,34c75fa3,1d4ab6c)}, -{S(bd721cf7,30d8cfc2,3bfd5778,67f40847,4fa01225,ddbf427a,c7cb73d0,60046af7,62fdc9aa,b8836c11,89e4cdc0,3d1c6c87,927e36be,2e4d55b5,76b1e6dd,91d7c11a), -S(3c3dfaad,d52f2531,cd835de8,b40a005e,aa2c015c,40366487,962d1363,64f4fa54,a2143a66,a76e30e8,150918d4,1d9eb97d,a69694ae,c426b6c5,5125f88,a22e9ef9), -S(bc075398,462afa25,57c6bb69,b6cc9ae8,75a490e3,e7c65b06,f7d70efa,166534fd,47309e89,1e0c1c68,c6a5532b,b34989d1,658f95fe,7dd7ce94,d2346e0c,15936758), -S(407ef9a4,a92a8471,400e2bdf,7620796a,410c648,e5a12c41,6fbab33e,2119512,60a1d1bd,aa7a7e88,d67b9d50,b20cf09,7888d0d4,5c83a55d,4ae93dda,49befce0)}, -{S(fd8ea149,749825c9,1fb53bc0,329e218c,2b49f62e,a56e7637,730f766f,527b7981,3c4cdba,1c38f4a2,82864b88,a58300bd,d885780,c63ce34f,4c7ba30c,5c55147), -S(e6163d4e,af44e81e,1e32226b,cbd676dd,1e299b6c,249f4fc9,b2706601,ae17f754,4f754176,cfd4ca24,b7c14b79,8149cb8d,40809aae,57a11764,4eb43e6f,22403d84), -S(c23ece67,f8260a8d,4d18b1c4,14ffa33d,d93b5a19,ee0903b4,c4765c03,414a17c6,8b448722,5b20ee7d,fe6cf78f,7220822b,e8afdf97,190511af,ac225a8f,1da22526), -S(3a73ac57,746f5de6,7deb557f,2bd4686a,72c69f2e,b9b2afa5,d8389719,5f955da2,7fb97414,c9738999,51310a0e,85e1e92c,db326de3,a5621318,6ad34638,832112cf)}, -{S(c6188e3e,4da144f1,a71ab806,22998e3a,cc580ae8,28b08c4d,f8ad88f5,5d0723e,d16037fb,b08be935,f89b12a0,810b2574,b7b0f9e2,5039c610,b60267de,1e8895cd), -S(f4eb0af6,b09cbbde,4203443e,2db7cd74,25b3aef1,4bd470,84fc9c6a,7781c45d,84e7dd03,9d221757,d29ef906,efc5124d,7d2833fe,b0d381b2,1d4a1e25,45615bb6), -S(4457652d,9123f6af,79613e87,eb90e62c,e4c7b4a6,3a5b2b2d,b183b23d,bd659f12,c3879b4,c4f249f1,f0cb1a52,874afcc0,46ed7c4f,5b346a63,dd798d0d,9179c3f8), -S(e5aa444c,ba5c8588,33e215c8,a521c552,bd6a449e,a202d2f9,32dbb6e5,4162adf6,111a1695,e7513c72,69e65977,3171da1c,8727b590,32de1df2,1d0ec7ed,67f5c16f)}, -{S(9d12d4d5,8f12e305,f34f165b,c5f000ef,823e4229,6e57a67c,22f3f2ec,bd5c5f7,f8ea4dc4,131d6d1c,d97bb52f,1c03a060,f1ca0af5,71269506,609f92e8,1409dd24), -S(1960c8c4,f9eae197,29769442,a86fb7cb,4a4ee4db,a577001f,13fa0fc6,342ccbed,dec5c3f2,9fa2f71b,992f3aa6,213f5bf5,d7c8a0d9,360c25af,b35f2bb7,776fbb74), -S(d5c94e32,5fad15af,bf295b61,900bb004,51cb568b,ffcd7f2f,c04e0f00,5a596114,e44ccfda,83eca7cf,babf25e5,9be125b0,c04c8130,4f188706,6824ce3a,7409a551), -S(db1b05d,cdd99edd,c6645c81,47aba91b,dcd1ae44,18e4a5dd,94812318,fe9f1e8c,f9818f9a,8b094718,2b88fa1b,689d1495,e94adb67,6e924637,b8dcd799,a1ee3262)}, -{S(7f07a821,c2102e7,c726a07a,892539aa,85e5e3ec,6f79691,37d79611,43b79b75,63411bd5,5ee5f782,e1d2788a,317d8689,6035663b,68b96438,711e74d3,aeb51ef0), -S(37d2f5b7,c66b5439,26e89aa8,f265679e,3b213098,6467fa97,27f365db,ba93c0c2,a1675968,10cf3f94,84455ede,f6ccfdf4,afc726ee,3561c081,8e535f74,cd324cc), -S(d041cfbf,b5f525c9,65fa7741,25b8f9bb,cda162cc,2b1f280c,a41065c0,56474a60,34c757e1,b819fe3d,fd62ba93,801491d,d4c1d05c,b973df22,fc64f23,1cc68550), -S(c640c211,f3004673,a3d8ca66,a18872ba,bbc1dacd,61347d87,78bb4d04,4892ab83,ac305f9,8a267919,68214e95,47d64d2a,c015c740,5619a73a,162287f1,55b1ffb1)}, -{S(760a6682,57ae7b8a,96c5c769,9039a102,cbaa111e,ad076621,88a45a4c,168a482a,ac81a374,c2da5e80,d22db86c,37302c9a,1b154e45,122f9d3f,b5c59b2,bee89a36), -S(5770bac1,871c8262,b4fff00b,a7520d55,d65bb0a4,7c9598db,3fcfee9a,27ff2763,825274f3,44421047,2390a3f3,a7b98de0,ce70bbf8,6d7241ca,a93b5955,24ae94db), -S(9432cd1d,8a62e580,16278ef2,c1ea2703,e628268,3eda8ca5,bd1a718e,6de864d1,5c7e685c,443bff0c,1eac25e2,489d0c15,eeac20be,bbfcb62a,a277938a,21901056), -S(32fa8231,6af1360c,9a58fefd,baf51580,6860463b,7325443d,ee873f40,8d7b8a26,b9879293,6561b733,948a7b6f,535e4699,515a442f,1006eea1,999be950,d2e04295)}, -{S(8f2a3f96,165eb6ed,6e04a3c3,6bc98bbd,8e224687,7e1f5279,4b9457e8,3a098653,cf4e0357,cabc0d24,b1eea14c,1b9bc9dd,e513584d,4d476a02,bfa3305,f9561360), -S(b590c88f,653caf4f,ef1395e4,3438781a,594966e1,fa38d019,c6297350,7cf9e142,b5f13a30,c368d049,7c3dbcf7,f7b07a19,350c5b32,248fb27a,a2a9ba33,5dd18a11), -S(71836bce,72f6b823,8edf858,ea84f2a2,4a0bc6d1,7419d751,e14a4813,bc2668d6,3156f04d,c1b89f36,1e7c878,94b92a87,2c63898f,38cfa4f0,48cac403,ca57fd5a), -S(1996fd72,66c764df,a93b77f5,c158a41d,adf46d38,ada30dca,62919df7,ab256fb,3990ba0,814ff4c3,48822de7,a4e67059,242d4990,78bdf784,28dc6c97,f66ffe48)}, -{S(fec456a8,6cd530b,d0512eec,301e3ef3,d5537be8,974bc23d,60e2efba,71b55ce6,bc77af1b,426e3427,6660dd70,2ee322ac,d1e19d0a,7b1d41a9,8bbe3866,9d087371), -S(9cb7d661,759605b,2237d552,e4967b9a,986fa9bc,8a602343,edcc429b,1b20b0ed,217252c3,1413ebaa,d31cbd1f,d0f6ee4c,4193475d,581806a3,6a864be3,918c9f8), -S(d95a3a88,9c8420d2,fc6b4d65,7f868305,3ba7888d,c946973e,647c6acb,82f4d86d,d7f4973c,bd3ca3c2,fbed8b4b,e78d665d,8140530a,ed5b81e0,c5ca04b2,c8cbb617), -S(8cf3ceaf,7cd77738,d6941ed3,3215ccf,cdaf13dc,910f126e,43356a45,bc9c2822,833e822c,cf90bd9a,dd06b052,dad6b73c,b5ee7678,c1a5e35f,d3e851bb,a9a9a6ce)}, -{S(a258e5e6,e1aac3d,707c5567,a9caae47,1b21224b,87828cbd,537f613a,6cdaaba7,d349347,e8f24cb9,1202c076,6c7247cd,e2eebe9e,62baeed4,aa51191,522c2c07), -S(f654c148,6e9e5a4,2ecd19c6,9b42e27b,94f3c3bb,3407b584,42684229,da0bb67d,cac5b906,d0665fc1,d7efd4f8,d1927f4b,98b9199f,69ce7614,b40ef0fc,dce340a), -S(f30d89a3,a536db35,b040eda1,5189a2b8,166a9e06,4cc92952,386be62,2f43f389,79ace00,4153547e,bbb903be,beceeb9,a916135f,42cb9a29,54817f9d,cb11deb1), -S(3e6e3577,bc22620b,e9a97210,74bb4bea,97379d57,bc1ed61a,33882224,305e4e1f,f634a97a,2e483822,3c4ce4de,50dbe0fc,117ad913,c3dbd75a,69ecaeca,1d413d62)}, -{S(316c28a3,63bf9651,2cd9f688,1bdf7430,dbf7e594,e6a7cff4,bd991c18,d2c0833a,4222087c,65b29e96,7c2562a3,4a491c0f,5ab5db22,2fc30d37,4c1157cb,5bf17741), -S(3384a50c,9f621970,2bfeb9f,5b6259ca,6062004f,b4375f22,22259e2e,ad496236,37afa3b5,23a6c185,3817cb56,e5f87e20,5f57f186,75b66ce2,4c1cb55c,fbe63b3), -S(32082a9a,45f6bd5a,90cf0efc,8c362da6,5f01a679,2c735f2e,a14346b,984279ec,fbfa9371,7ea480f0,a05c9de9,f6a50ed4,5a36b950,fe837c96,b8eda38c,1ad79b9b), -S(d7d044cd,fcf11946,97c63a98,94b56b2d,2b328eb,8fbdb2f7,f919479,2da1f0e4,46da7078,4a495b7b,e839d3c8,10cd7624,5f501685,15661bdb,4e786135,271453c1)}, -{S(3ce0395,6908baa4,1efed22a,3cd2b18b,e14bc3c,a17e8e46,7f757e56,5314f27f,fce17fc7,7d007d1c,25558760,d730019b,22ac9cff,6f4ba689,a1885b2d,5f0d0440), -S(2f5a7352,11a250d2,cb126237,c2c8ebdf,e9d7c628,9a319903,5a1ede18,b585cbe8,e3095320,3f1a2cde,eccb1e9d,5be869eb,f447471,9f7670de,f1b86cdc,fae5da73), -S(e86666e2,980948d,28d2baa4,c4a49d55,fff25b39,55695ac8,11ccd6d8,f882988a,823aa73d,20c0f848,66a8c63b,5631db07,b8a15f5d,90d79e3a,16c4040,a5106987), -S(1b1ce843,955f9c8c,28dac111,5e8a357c,dee3b723,70d1cd36,9d03a3c6,1b7e7342,5f8648e0,4965445d,cc8d6917,db45d7d8,3145d7ec,71f6e117,8e773724,a39e784f)}, -{S(feeaf523,3f208ccc,11478774,bb05c1e1,cc7ee923,32e6f84c,970a0579,aefcd4f2,47f6e6c8,3e5bf7be,5743f776,e607ba73,a83ffbc2,f1c581c5,c0cb1d98,b10be58c), -S(42086c81,d2685972,b69cc8f2,8fb8e949,80417664,76c11dad,1afddef7,773d72fa,b0e1b1f3,79082879,512302b4,1314b3ab,5a3f739e,aa8ac1f3,cb82ebc2,c2f9d13a), -S(5f8dd0eb,57f8a8f9,d1605e28,987aa1dd,bbbd05fe,8ae2aece,48fc6392,3bd6,c7daf790,b90ce9b,a73a3c1f,4b30a508,d41c0d53,f375ca86,b0ba2901,dd9ad482), -S(c92aad54,6d6046c2,4606c934,63391e5,a13be77d,e3eefe17,3b0011bb,129d3ad3,288c9ed0,2db46521,c9249b02,8f262b1f,9e684530,2cba4ae2,506025ad,ca0b8168)}, -{S(e3ee8330,33377c46,d51c8aa0,7919485a,ce3c3969,e533150d,a3e15479,f26c80a6,f757943e,9569814d,1d6bbb71,55294783,500c75d3,7510ac98,18497bb2,9388ca8f), -S(95811875,6d6505a0,89b46ec,648a2297,de391535,d3873b83,a7db485a,1ab8ae01,baa7fd9e,bf67d8a8,c1ac73dd,69bf264f,e0da962b,e26ce223,dd3dd5b9,8154e3a4), -S(1ea76ec,a1955521,2aab3141,173ddc67,8463fc79,2e887297,a713fea9,b6064fc8,c8b34073,8c73318e,d757034e,c947c5b3,ba7baed7,3eea8ea5,2c4d5b37,6186e283), -S(38281ae5,371b347f,bec1e9c7,841cb3d1,5a7ddfa7,684e9e93,e2c12cd1,acf0ee5d,8bf4f92d,92fabcab,c814e790,21ade825,448ffbc8,782ed1c5,60c72149,67fd5cbc)}, -{S(6bd00cc4,657b1902,51f8dd4b,9bec4668,b0c8cfb9,651395f4,8badda1c,a1dbcd3a,84d71092,e37a7401,810b17ec,3e0e4871,27c4847c,afb24d91,241514c7,779c61e5), -S(804cb958,a76c7348,17a62e10,2b1247f,462438e7,b0b3a96b,c202dc5b,c18de9,c775f60e,9e39fb0f,788e4447,fbc40690,ccaef5d4,2e9d7e89,e6ae41b5,8fd2fcb2), -S(d1050190,fb46792b,c29df9c2,5f2b9e48,99125548,336115fb,b7449c74,681c16ae,d677925f,e9448af3,76734c13,af2f7433,a9ab84cf,b7a6c4d5,d6091afa,766d878), -S(b81ee327,adb39987,c8d65543,7b7c771c,9061623c,bf36da42,ecc7c226,4ef708d1,6ec466cb,a3a52bad,a9f3f7a3,6ed90d4a,857a3570,610023a0,94fc5107,df2056ba)}, -{S(725d64c,4128d78d,11b4f7fa,eb9f04fd,9075ac9f,e1129eba,8544c3f6,685ebe04,36eaba03,94b7511,31a9c5f4,292a7307,1862fbb7,c43fee3c,1e5eadb2,7fb65db8), -S(40069204,ebd45314,a4d757ce,5a4020c0,e36f3bd7,fff73d30,60628b53,8d685861,d81134bb,5ebd3d7f,10a90cd,369ec3d6,9cab48c6,f49e5583,d766aae0,4d466d27), -S(901a167d,19e00cc5,14b3b724,759efa64,3eb7a8ce,9466eaf1,b6fab1c8,63b6f9bf,e100d9d1,e1451f09,2b5c1761,1e2d2376,75b1c95a,a71a052c,e7497a63,a9fea105), -S(f0fabd37,39f53d29,801e00e5,304cb5d9,a3553226,fff9ba5e,c8fe1030,26739c1d,cd23a575,ed09eac,f8446c8c,7f311ecc,78acac27,3a0fd6f7,988bdac6,361a4678)}, -{S(8f4e8dd8,20d7e026,ce2fba81,19028ea8,758f99ec,f7bc2f09,d239d60f,24027c9d,81b9197d,7374975d,1bcce80f,1a8a1e84,19a7a656,70a5dc21,49b00aa1,60055743), -S(e8e4ac24,1b8568c4,cec4f08a,9badff38,87c132e2,47add60f,3c39cb7a,8905027c,89c74e18,74737819,6fe1a4b6,3b2893a4,865de0b0,775598f9,33504aa5,ac453a91), -S(e6a8a510,f7316ef1,4e50e9f8,c8843220,c03df75f,e508d820,f3fa0dbb,5e9d0f94,1ecda600,14fc8668,32b1f2f1,b80ccb12,aabcbf94,f74f0a6d,dc6c692a,a20040af), -S(752c8264,bfb10ae3,aebbf561,3f65d191,d2956e3c,a7578e53,2a8b85bc,eb1d294e,1ff5c140,6558073,da1cc7ab,fa80d4c5,d557612e,c990206,6fd895af,11cd493c)}, -{S(9a9a4dfb,615c1e79,c2c19a19,34300742,7329b1f2,b7ae815,8ed8ebf1,5878d02e,39da7ba5,f1b9754b,e6fabbf7,a45b7ea,5cbcea2a,da2cf2bc,82aac66b,468af931), -S(14159eba,90d658df,ff2a3726,9ab60c0a,7540c68f,a77e0339,8caceb5f,6262d656,4497a299,27b365e1,35a77f61,bb6bac74,6918e3c6,79f97021,972c6013,d8109e6), -S(d4d3e7c,2ea5fb74,45160de8,19bec4d9,bc843b9,fc14fa74,6c0cb842,1b02a765,b55606cf,557bdebc,90da9255,f6a38a95,5ebc5998,bf021708,ee0a91a2,147ac684), -S(1acdbd72,130fda7a,122e015c,f3101670,d8090193,828710bd,1ff2b242,5d3ed896,b8cc1086,347ace8d,858ca6bd,56a80125,7d0f4333,b26541f,9865fb44,c5f349d7)}, -{S(93871b45,831fe55e,82338224,aabcb408,26c13f29,64c57fd1,b93711f,4ea53cff,79303c6d,1a8054f9,d66c5524,8ff9cd8e,17b5fdca,f9fa4388,9b0055e2,15c0a54), -S(8319d182,59cb7c75,228d314e,7db1db16,e34c9f62,2bf4e893,f06f86c4,3122dc51,5cccb4e,e295cade,ee396b80,10f6043d,d9141412,b8eb4216,60f9cc63,ee96f6de), -S(1d139778,64726f8b,7713beb7,6066df5d,d5116728,d5688fee,e20fa12f,14f9857d,3fd0294,d9ba6e7c,7a08bd63,d747365e,eadabab7,5ff1ca8a,95174569,c6fbe910), -S(a2c17270,296ad5e1,7ce111c2,899411a6,276efb6f,d6794a7d,212fc3cb,7d9fba31,b0a2e976,582022a3,a2c636c3,2c0909fb,533bbfa,193f8366,e65702c4,e0d8629e)}, -{S(24b75440,39c1351c,ccceacda,d31c758c,206331da,87a277ea,588a4376,82dad76b,854ebb44,a351e732,d900a1de,dbb0a5df,168a311c,4af01dd7,64722531,a3132213), -S(c89cdf5a,c0bae450,ffe0bdc7,f01ec47e,8a036cc9,43e0cd72,245cca5c,308d0087,e54935fb,6eea8620,a8b85fa6,d63d14ea,16c2edca,92fd6adc,7feabc35,91599acb), -S(255e5f4a,2bc33aed,aba2b7ec,b22ec225,30d3bb21,f7a63be4,bd5e2f6d,ad48e927,79cbe440,8da8c79,74bfc4ad,2715e2eb,eec2c950,8a01538,be795d21,c462b208), -S(e1497ffb,ab348f03,ea075d4a,bdc3d5fb,b2b9b413,5dab5190,2d8e1959,2be57e00,e3194cad,50cae1f3,7e713ad2,5bb635fb,74f6cbbe,83782411,65a8dbb6,ccee6faa)}, -{S(b9ed5a31,aaa443eb,99d8afea,7b32b81f,5860946a,5a5e63ae,def2a6bc,25c43f9f,e5bf15af,3e0a5fd5,12a14a6d,e03ce09b,a82b2fac,6fb8e16b,708752df,95f080c6), -S(45b0720c,7c7a16f5,9e07c7a2,b9f79ecc,194c4497,2a076bfe,cd662189,f51b5f4,b8acd754,a68d90f6,928fb515,d51d5c86,b86a832b,1506a251,447430a2,f255bc8f), -S(8a4c2587,cd27e533,7d848f56,43327489,19d3aa88,6d4b944,d4d44689,5cbe1ad,581ce4f3,7471bac8,9e904daf,c42013f4,2451a155,6ba12aad,deb02653,95926838), -S(4cf058d0,f5959eed,87402967,781dbfa4,29df9de1,327633f7,a6b354de,ebde5aaa,9254c0b5,709fa08c,684a59e1,1864a10a,3c4e9359,dd91b39b,15066b2e,e678a1a8)}, -{S(49208997,3351bf26,e5245cf8,afc6a69c,baa24dc8,5565ef5,d39e6a05,8b3cdf17,a4276fd0,1f754f88,11bdd14d,d1ced0d7,8bb7843f,a876e7d6,9531c223,2e9c9b4), -S(7b098cf0,f897637c,cd32c99d,de95acd9,2e05bb47,b16a58cb,d5e97827,734648f9,1d4e7732,2c99b9d1,dd330ef6,e955138a,6d0b606,1948b067,edf1c39b,61ab0505), -S(222b1686,82ca8f4c,b333da8,3a1f3cfb,e19f9e3a,8b597ceb,ceabd65e,720af23d,7278370b,c722a13b,d90164df,41323da4,6cb7b346,3c1428f7,265cbfd5,6d0d8d35), -S(97da8a09,8a3507b2,b5f330b,b405762b,cfd5c631,ed835bb0,842ad75d,a2175c31,5c051aef,a278fcd9,a2e230eb,993fe8da,f0c06306,14a5a6b1,799c0cd4,d3911144)}, -{S(265747dd,9f0d0396,faa54221,4a050192,3de7d376,f13768a1,50daa098,92ca71d7,412f5e39,db7cb201,3d083c20,19ddcb27,2ffd0a0b,89413e81,7718bae2,f1120fab), -S(918a2f6e,863bc4fd,87b5db45,15571d62,50e87c47,fca0914c,2b76d9df,185c0a32,a5551dbd,5c739407,880a5487,8ce218b6,766f0553,78f1a053,179ed3c8,3f362ff6), -S(6da6ff1b,ecb936d0,1ea353c4,ca3f949a,90153ec9,13329206,8b9be293,ae28998e,822ea180,8265bfb2,3fe6c6c4,51f62245,4185a813,e3f61604,c89044e8,555ae0a6), -S(bc0730da,9a06486a,99364ded,b612fb7,ac36cd21,466f7acf,e0be262e,55e0d269,7cffd8a6,13cf43cf,7eca904f,96a9e9dd,8b54dd22,49372095,95483592,64d7b8a0)}, -{S(96f6ae9f,84281919,50583f91,d4b76ec5,3c01dc20,6d06d33a,2560a8fa,11fe5daf,aac32455,acc71276,efed23dc,ab42fb8c,24bd18da,604b913e,bdd1318a,d1bc223), -S(f24cfc1a,9a29848c,f1d996d0,7fdc3ee1,ff14d1a3,a7811f18,e8bdcc47,a7806534,e0e4363d,2a227fc8,2df704b5,316410d3,a671ea2f,34702c0,7208fb27,6c1d12df), -S(1123af94,e86f2def,561f490,94ab160c,996f1955,dc2597f8,fe765c2b,d4793679,39d160a8,caf4b2c4,e4e95087,6e9a3183,55d4da27,9c7e2429,9762065,af62b2c1), -S(f5b8a7e4,6d4b110a,46d12dac,d308dad2,3f7f497d,b5a8a76d,c9577da6,f0943430,835941c3,b12ead86,6ca3f05e,c4b09953,9a8ab640,3e450590,37a990c6,88c1922f)}, -{S(f307f4b,b76a7bcf,1fe75d85,60a4c64,c748b32f,489e30b6,170057ed,225c9e95,fc200ac2,3ba3be6d,aa4d4f86,c89fdc5b,8eb00f8c,ebcf6a41,51411042,ad181fb5), -S(dbcf10f2,e43ae854,85fd600d,ca9ab27d,7ba393d,e6a333c0,7901cfc4,55352569,48d4448d,8ce674df,d254f09,17fdc390,de9aa8ff,29869da7,4c2529cc,dd476fb8), -S(38a07202,a23d26fd,663fa7e1,8e8a02a9,2631011e,57731024,3e717ac3,a0390078,fb6057ac,aa4fabb7,c4e922cb,ab2b7fb1,e4f0b3a7,6be215f7,7de296d3,ed709def), -S(5bd3e7ac,5f8619f,5db77e69,f7416149,b4afa5c7,95d25fbb,fb1da1ad,9e4617e3,9ae709f0,d7278b4e,b66919b,c666d63b,46bc228,8ca956eb,2e20238b,24725d56)}, -{S(35e48872,5074158a,8d2ed392,d178f6e2,e4c43fc9,689b32d,5f374c05,d637a53b,95143742,7bb0105b,5e7f60f2,d95ff164,ff808b7b,c2ad592d,68988e5e,bb5d5679), -S(8619863a,d49d8ab5,6c999e77,4653e1a7,4acb7a63,edb65840,76f3b3ae,903f3579,451500a1,3dac87a8,ace7fe4e,64dc6174,896b5002,67163bea,1d3db275,b8274cc5), -S(afeffbdc,dede5aaf,dc91475c,100918d2,f59039df,b5754f58,a330a469,1855e858,e05eacad,fe537099,35be0173,3d4b4dc6,7674d1a3,7d911d02,ea4f74f,6b63da04), -S(2b697c1a,2d2de701,16536722,945e46c9,21f02fd7,d8e9fd46,8fa9f159,1dec4273,6dd6ad5b,44541355,83b4833f,10de56a1,ed16c5a8,77d593ed,2538b95c,ce8785ef)}, -{S(cce6ccb3,fc1cbcc1,1f40457f,25157d24,6d3fefa2,24c340f1,ebdb3b02,3f02e3cf,9797a15e,ace0c660,eb93b185,7f6de7de,2d1d0f36,8c9a2eeb,a53b2860,b392bf2f), -S(71e75cd4,592214c9,556dc1b7,a7c8c5cf,77ab0249,a6a7ad9a,378e3e5d,d150939d,4e0c9607,c1b2866e,214f38e0,d4759bf3,b38f1f7a,35490b6d,70cf2e65,fde90bc4), -S(dea94d9b,c0222c46,c66012bc,91a3be34,d5df8157,56a9d97d,52c8c4b1,24ed243c,b3df667f,2615a0cf,2e7c0122,63af5067,b47d8cb,d22425f2,1bdba132,5e333588), -S(67bb4796,c88ec279,87e7d4e7,bd2e4e9e,bb1806b,95d3d8b4,e1a5d367,64e6d01,2af04b47,62d5a122,3bd0fd46,49be2b1d,92df5d8a,84ceb205,f2b70f2e,b5679290)}, -{S(86592c40,71b619fd,27e3825,ca585cdd,ea068958,7b59e3bb,b3581075,a3cb8a96,923844bf,2a197b85,b232b973,2922ce0c,a2431dc4,a59d27f0,2ff3b2f4,af7703bf), -S(e82a2871,fbff9467,96109300,26ffb096,d9509b43,6e786697,e85c57b3,389f4fbd,7732b419,f0d682a7,9ab047a7,d4a51685,fcaa3c8c,cd8115bc,4f7514f4,1717c804), -S(9c079fba,32d2288e,a0829fa1,1482dbb,8032397e,c676d744,c7b0ce84,a1c4f539,2b171739,85fa643a,ba7314d3,86f086c0,d4884b63,4062a4c8,3f7f05aa,575936a6), -S(78ea5f31,1d3c1943,e438601e,a885ae8e,efee93e9,26768d82,3e88a71d,9c22d773,953cb0dd,893aed33,9021e63b,277cca61,4d772c7e,a2b8ea3f,bd151b14,5cb144bc)}, -{S(4929a368,f9842917,73f5236f,dd5cbd7f,a8e8dd9f,261cbab,5948ad57,798cbf79,26a2a40b,33630e55,7b376fd8,134a8d48,542c08e8,c2d01a99,586d33c,66d37426), -S(bb4b9ce4,b8dd22bf,2873b2de,f29c494f,621d89e4,aebf3c23,566e0cd4,b4ffd288,d4f81742,4f778966,1274fc8,e8aa5c54,4434fca7,6b73b639,a04aab65,8bb77c2f), -S(6ff70715,17bdc2a4,c0267caa,38ca96ad,8a235744,2a24db87,a07cdec6,c3b022fa,2f16b295,a2db7a6d,321280c3,a53dfcf4,674dc215,38e2a556,75cd37e5,d3ee7362), -S(b5619c5e,edbc92f0,c88a9cad,9955a08b,764dd683,361bb7f2,8c611857,d473c45b,11f6864b,36116181,d2af3f6c,fe738c84,7820ebe1,53f0c82b,14e5c67a,b3a2213e)}, -{S(c7452697,d7691662,ae3b754c,7be11df8,ac70cc8c,e2e80a9b,9638b0f2,a323ecd5,fe84e963,3231caac,63a5c7cc,90cef693,a69ea140,c846e1b3,b96a6fc6,68b43c68), -S(c797ca59,95cda70a,a33093bc,4f7f83c6,1a31ab1e,dbd6f10d,31e0da05,64f41407,ce4a64f9,ae7eef1b,7abfad94,f4a6a7f1,c746268e,9006995e,8f7d311,1b81f85e), -S(288a2e26,8fb8fb28,29bd9d21,4ec5860b,fc1ed577,f40c6184,79a0b921,c2f4b67a,8343d03d,556bfee4,b66ca598,f4fecbcb,aa2723c2,f3c35203,ee12710d,d9ff0b52), -S(7aa02a72,adefd779,fd994c77,697ee142,dd25d168,38c8b8a0,5178b7e7,37f33032,a060f7d4,8e0c2929,864208a7,1668129b,3b3908c3,7e89ba0,e7e55aa6,5e3ed98e)}, -{S(34925d1a,b1c7c081,e945d66d,60ed394e,f474e38a,423562b3,95bc51d4,c4f55321,8ef8dd58,ae1661b5,a7c327ba,ac4105e6,d02d6a30,2263c5f8,62b712fa,b064e562), -S(2bbf19eb,9a6211a,7881c7e0,5483a318,c9d91280,d09e0634,2a54a9f2,b5654be8,3cf7b41,bfab218d,e182cf34,32450abf,88da1e16,fdb79699,ecfeb962,39d422d3), -S(97f1b30a,6ce2dd8e,1d0358fb,45b432fe,be6d9916,34ecc7a4,b7cb4f3c,f1663fb8,c7cba22b,88a5f5c4,498f0f22,cea6830e,1bb44e1c,7f9d9833,60139c2e,97dab7da), -S(b5d0e718,621a0a40,c2adf34a,3e1e64d6,bbad3598,e6944436,f8f87450,575d61ef,2e43eb70,8fb8e2a0,f24a1a12,7a890c07,d79b51d,60e3a281,649afa3c,182d5b77)}, -{S(463080f9,19ecd42f,593dc20a,2d3160cc,74d9592e,446f299d,be5446f4,236a5b17,2a65200d,e1b16975,9d5c75d6,fa6c666,ba45728d,343d6339,48233391,60c14a16), -S(547eef23,516851a2,2f160ec0,781a49f1,1480d07d,2607ab5a,89656c94,2f774b5a,eb6f249d,ee624cae,cbc59f02,63da0fcc,e33a515c,843c3632,661f13e4,39c4f0e4), -S(77f0c9a2,51d48b39,62f92e2a,679fd9cc,f458f17a,edf588be,d4bd6448,47f9306f,355f4827,b10e614b,4590242b,da546e53,dbd419de,1d1a7fa3,208d9350,3496db0c), -S(81e606c1,19b6ef80,418aa008,7ebaf9d3,7adff1ff,a81f739a,172a580b,27c7545c,ddb0404c,e56113c5,93920382,6d2adab2,6590b509,45865406,ce1fd256,6565209a)}, -{S(92d469ed,e0969dd6,7e9d7b31,f0f703e3,97cad53b,e6101b2e,eeb8714d,645eaa9c,24a0a786,916297f4,6a53c7c2,29a3c95,80eec521,355b823,f0488460,39595dd2), -S(e5035341,5c49c24d,f672a74e,4eb2d108,57fa987a,afc50178,ffba8797,5503006f,38522661,fe682984,7b6dda61,9dbbe47b,35c0c9eb,b79b5d2f,2c6ba882,26cb95d4), -S(d0777020,cf6dc469,cf020ce5,e64bc2e4,1e2bf116,4f4e814f,18bbbc4f,f468b0b8,997b2163,c4670401,281ad84b,a914cbe4,e76a5cb1,cb90c1bd,ecdac585,621cb0a6), -S(881abd9c,717f0a2,360de50d,66a9b655,b9459e62,80a985da,e811f2b2,154e307a,beec571,1375031f,354dda5c,b9d8377d,1cb49816,1f4c738d,f6b9d323,f9acacd)}, -{S(ab7d18ba,955fdaaa,b1a0bb25,25844e2a,9d2e204d,ff224588,ae96c41,e690e010,4e0090b1,dcd619c3,10ff5027,9c534612,84ec2467,77b63179,c80724c4,42d00204), -S(1a5982e3,37e3eb50,e679f24e,c3473b4d,1af3dcbe,ac3c7a96,a95f51f9,a9875266,dca6c614,85d55985,1fdc229,56ee59cd,fac74069,6276299b,a199f39c,869e5c9c), -S(bcdf870f,8d5394b4,f1f3446c,a25ec6d,5b4c939,b598e596,814a6dda,a054bb2f,71cfbdd,d1aa7722,892f83e4,ea2dec50,81c4d14e,548a16c4,2818b76d,5721fb7c), -S(cb28eeda,338a5088,db505da,949cddf2,741e071e,378f92f1,dbba270e,9c322c57,d98cba61,cceca53f,7d84d71f,f892b962,6f26e156,841d2dfb,7aaab839,3f515903)} -#endif -#if ECMULT_GEN_PREC_BITS == 4 -{S(3a9ed373,6eed3eec,9aeb5ac0,21b54652,56817b1f,8de6cd0,fbcee548,ba044bb5,7bcc5928,bdc9c023,dfc663b8,9e4f6969,ab751798,8e600ec1,d242010c,45c7974a), -S(e44d7675,c3cb2857,4e133c01,a74f4afc,5ce684f8,4a789711,603f7c4f,50abef58,25bcb62f,fe2e2ce2,196ad86c,a006e20,8c64d21b,b25320a3,b5574b9c,1e1bfb4b), -S(6ada98a4,8118166f,e7082591,d6cda51e,914b60b1,49696270,3350249b,ee8d4770,c234dfad,f3847877,a0a7bcda,112dba85,1cdddf00,84d0c07,df1d1a,a3ec3aeb), -S(a94ae8,63264dfb,b910ea95,4ce9ca7e,4f86f92d,9f3a95d1,ed61552a,7a3f5743,7f53f7f1,6ad2d08f,15e73314,6d80467,41557acf,19556c0f,ed7117ce,37040823), -S(b692c750,d23d3674,c351e3b7,e1a8a87b,14a5df81,852eaf35,209d0ec5,6e22a2cf,b18c4f17,252db89f,838de32f,b3340ea2,bb961a39,54b38c47,f9a8219c,4820a0cb), -S(691fc741,80e75b55,47b375f1,1bf60abe,451d27de,1743a436,5f8e4bac,ad421c09,8eb5fd9d,f3c03240,6cebf370,8125955f,bf2ef703,475d3fd6,1a0291b6,69b52d9d), -S(703b5f14,a7d82473,1196b52f,ae9ca8cb,b245b004,7a9928d7,d0c42f33,391411dc,5ed74eaa,49f276c0,4d61f31b,6da4137c,bde5673d,8e3f815d,efea7951,f88585c), -S(29b8ec47,d241eda1,e51bbb1e,3928444c,3747b4fe,7cecb365,2bbc4587,2f504875,88693238,8562f8bf,f7d72324,62ebc54,6b93a95f,77936b02,eb1cd6a7,d4199bcb), -S(444a07ad,e81916c9,32bdeec2,21c556c4,6b7f6491,e99b479,2cfec82f,4ec17910,2e084c2f,eead5200,77c151b6,eff9375a,713b9d15,5306708d,b3f538e1,8eb18cf), -S(e0dd618b,226ceddc,f560527e,20b4fe58,e5fcf28,39911ea6,c3e8a4a7,e15f9121,a063a157,3377bbbf,1b9a5ebe,afbe11aa,660c1e65,df1392b8,97205858,3c86a3fc), -S(9b99461a,2e8360f2,f2ba0bb8,bcaeb699,159e0652,69d9042a,fa0c4e30,a7b6f30d,3fe7fe04,3cb45303,3d4f5560,7d41cd76,9036a49b,82912350,6d8b9995,254154fd), -S(504da3a9,d9d9c81b,c2065398,4ed28cb1,b5beec9b,6ce5dfb6,cea94e54,fdff044b,cbd40d1e,858133c9,cd20b9e4,ff9fe94,f7cc9579,39e6df49,7a6bd702,797f96cf), -S(ddec0aac,1ebce6aa,ad6300d5,60f0e503,829f0bc6,479641f9,b19d9f6,484376fb,332ff5b1,fc83085e,736736bf,3c265e4c,8f80925e,6f38479d,6563bc34,e5faea1), -S(dc530ceb,b82c246e,41c522f1,d2571d31,4b14edf3,91577a2b,64e42172,b23562c1,563ddd93,857d6529,8b81de24,19e5cede,7a4c5b7,a2fe98f6,9efb8906,6f32a98a), -S(7604d60f,418dd132,78058942,fb2d2153,c0a2bfeb,e83c5011,a451bcb1,58db0773,38be14ae,d9e1c404,63ef92bd,d62c599a,b37625a8,182a3763,4fa2de90,535d50a9), -S(cb896744,77b20829,f5e2bd42,8852c70b,91cbd0af,cadf219,a69727b4,cbec8d7a,5710d17a,20ea0dff,980d3f06,38d8b910,b8940d00,dd4a323f,d777d942,213e1093)}, -{S(1b8462eb,1ccdf7b2,b8372f2f,cec1f479,ab07c09f,cb26d6c3,965ec73,4d654f81,62f6755,b4a7891d,55de6427,fbc37d33,e4eea418,a2c04392,a3d11807,ccc9025), -S(f6fa4c02,1b697e93,ae34145b,481a3ac7,462343dc,6022040f,834dd9d2,c69b5d,5de5e04b,351f9928,b84abaed,d3319e61,ea91fc59,8d6fcac3,401d1ae7,c08943e), -S(cf805a58,d8f9b414,aa73cd0c,e545c9af,3f7d6543,8ae57688,81d30866,e81242d4,f455c617,99a2ca5c,fac3eb6f,23282774,7c9e914e,fce447ad,8fd71ffc,4fc3306b), -S(48dbd9a5,88d1f02d,6eacc5a6,36c0fb4f,de87eb44,11329442,1265b0ff,a72e473,9a206d25,5dc1d916,e3b1e301,cab1bd91,ea29eb7e,979c0b84,608ed770,4af325d0), -S(ceb3637b,28997733,ad6ef0dd,5004e32,9c87981b,e6d811a3,88804884,652780d4,6aed5e97,c0e836b2,73a309fc,5d389779,1f6f0bc9,246921ef,5fa9767f,dacac3f5), -S(8940dca2,52ebefad,61db720b,e709c749,7302b5e1,a4174893,9626910c,43708a18,e1b0d7be,1e36c585,8bc6125f,7fd5c423,5e643f7f,11668026,c1536e9d,f6305efd), -S(aa33c3cb,bb97ccee,5b8f452f,6a615900,392d78f5,b8c1f022,5266b8c,cb3449e0,e9ba50b4,7d3e3279,2253e925,5261f2f8,263c30dc,e613ea9e,737c3b92,8c8e3eef), -S(39f3965d,b455a466,930e5e82,ef214452,ef5c9019,bd805fe9,67fd362d,193a1b2a,8f69a32b,35bd6f1b,c5ada308,f61550b1,534c07b0,1a3465f0,564ed6d,a8f443c1), -S(6725d4a6,a827fef7,a0fb0214,900f526c,e23cc0b4,a6e291d0,ccb96ad9,e77393cd,69f91bac,b09facdd,b55fb70e,68164028,a8cf1bbc,207653c2,d898992f,89244f35), -S(3b71b2f,84d355f4,d246a57e,b235e396,ee236c57,d6ab3a46,f89b5d3c,1a911c1a,7616be06,59e5b42,9f105499,38d17654,c605f81a,e4bdf2b7,b9c1817b,c8db03b3), -S(a346e9c5,d8cc2ce1,1a733026,3136d92c,925f1b22,b27d3037,d9c4b109,9a06ecb6,4a3fd930,54f0cfa,6799e236,add0f928,6e45b77d,cef57797,7dcdac63,485c4f00), -S(8e3c768a,ee07f0aa,3eaa43e3,f6986805,b7829c50,d67861c0,c75ab390,5a6fb794,33d3c292,7a9e9c54,a671788a,fc0ec58d,cc2a0574,a172665e,347690d7,50de0acd), -S(b231176e,d39a928f,76a60397,79643e94,d5e75d17,238487be,f9b38b60,748711c3,3ae1ccae,204fb13d,74705b0b,8a0689eb,aea16e8e,c2f3d5db,177609ec,64027f0d), -S(8afbe02e,161ed971,44075da2,cea389b2,f53562d2,dc771d3f,9405259c,fe4232da,e2c16621,f38a0831,d2839585,9cbceb53,254398ef,b58308cc,bcf3d79,ee0af228), -S(1a263c8,c2c9080b,b0d4d61a,bb5d6b55,e6a7f520,80ef3f36,706e685d,7a527957,3925a458,779c3c25,7b546b99,7399a56c,b3c0b9ca,f6c77f9,c41b708d,f831253e), -S(35d88ae9,b1d3ee59,fe79c24e,de6cad1f,6d822f57,708ee54c,26e7495b,357e92c6,de74f353,d8115188,724c2a32,39b18661,6b8f7951,34aefc75,8e724a30,8be7f31e)}, -{S(6ae991de,18418b49,160194f,a735eb72,c299b987,1981a4f9,aa717ad2,bcdcf13,7ee8011a,40f384f2,e50add2d,97005173,2787cc7c,89dafb66,301bc94d,24b913f), -S(22165bce,e76e1594,5b9041e5,ccdee553,eba60e4f,1ece2d9f,e0ad7440,565f2665,fe8f383b,bae7e284,d1d890bd,569ab7b3,ebe5f1bb,b60ee19e,8e8de65f,88f3ab96), -S(a2600e0e,9265b7d8,fcc46a5,51872122,66ad5334,4ddedbf3,ac8cdf2a,b86f2b8e,d00f90a0,97fe3863,b4854dce,fa5a36e7,3f94015e,f892303f,2e5cb2c7,aefbf15), -S(38758ff9,5cefa7c1,b7a2443a,ba29b65b,aee1fa81,5ed49595,a4ec760f,b995df1d,43bc94bf,dfff3c59,7a6e41c0,52194d41,c1601b91,792f42a,6872ded2,a5e8f4cf), -S(57122897,d98019ae,a6dcbe99,49682895,c95471e8,d53680ac,49927e23,16abfd27,c30cb105,d9edc36c,9e237e93,2edd6bef,3d553d67,fec3a37b,fbe0ef56,a3cb6c), -S(7b7247c7,73470f13,2477c974,7820ce4d,51dde95b,dd14923d,e31dfb13,5a8aacdf,2e7054f4,a33361a7,a4282bb2,7e738884,3a91b211,3f71e160,60fb2235,6b40ffc1), -S(1d3f0661,13c271db,374adce9,ef0c444d,4ffbc1b2,a34b9c91,55986371,52376f68,1a4c07f3,e3752c71,f772c55b,d269f3ae,a9cb40a1,ac8a96b3,7387cd1c,bf22e864), -S(456ada98,2bcfa52a,55018711,6926b843,82754297,9af5c113,8af21e1e,3b625071,a7141c4c,673e441e,f67ccf99,53a7a6a6,3a77432,76261717,21f581b,2893243c), -S(b898efae,8582d8de,b315220c,dc79d2bc,1a221072,300e0971,c4a610f4,7f6b70dc,8da8b020,8d674418,5620db55,fa3cd928,be672c5c,22897030,bb5a5957,37758a8), -S(b732f7e6,9280227d,c1f56e84,7e72989,b834be6b,f04e2e3d,ca8553b5,ded18493,9157298a,5ff6e6e4,d705efcf,7601f33f,76cd2a64,6118103d,98fa000b,8ff9ad99), -S(9601ce19,964403b6,a58d1d51,be876199,d63755ef,91bd657a,fbfac3ef,c85c78d0,df06aeb0,517ae1da,ff3a48bd,7ecceaf5,b10ac9d9,67e7ef4,520593cf,d7502058), -S(a95814ec,11446773,36258a94,56670207,d068d8ae,19ada794,52210f2d,bd67bc5,29d7e4b3,5e5a4300,6297f9c1,f71a6a26,118693ce,fc738fea,ccf1b873,339617b3), -S(d3533330,c6afe33b,ae921c0f,558fe47d,b97e7711,ce98c884,3abe894,320e8926,e1be0b16,72f8ea16,b59a6b9a,20c27621,e63854cb,4efde5d8,d1da8929,4f777383), -S(4f05f649,e8ec9fe9,f675957f,7454a89e,c020feea,217782bb,43bbed43,b0a62881,dde64c2b,255d8518,da7461c6,b160286c,5222baa5,483fd5cf,dade9ae4,96432904), -S(1a06ead0,5ef3dcc1,a9080234,b6158fe5,681cc5ca,acebbbf2,c336ecdf,3505768b,63661e6e,816bad91,1c7bd073,a15b185,c4c7b7b0,ae440dd7,40a54286,3a86721f), -S(e2b163f9,f1b6ad48,e8bea9d3,b199cfe,378fbd2c,8f005cdc,e5959154,b2eca0e7,30759d6c,f55f7f15,a156a705,1f702294,72b9544,ba73fa40,27839cd5,67147083)}, -{S(64850a04,76870a44,2cfa57e0,4e4707f7,eccc5e99,12dbcb07,3b457317,717f5686,7c5facd2,91a6defb,a1837cb9,3bcbd0f5,bc37572e,68ccb2a0,c062a155,46656fcc), -S(4afd2a50,f79b1403,844523a7,e88e0156,f77f7856,8668ac7c,79d2160f,cac27acd,40346549,fb5b8450,165c2a4,c47665be,b1d31f73,1cd758ce,6c8f2b17,37a832d1), -S(f4132840,9cd5ac7d,7a0c92f2,5e39eb57,b8fcfbd5,d535ec00,a281d3d5,1275199b,6b66ce56,99a92cf1,8f635a0,7441f0c1,3561c8d4,cb0075f8,8a1596da,b6da6d29), -S(1a6c66d3,1a54ae12,59b709b4,c70fb434,f3347d11,7921ce06,fd4f0dbe,d211e4f4,b6438fae,74524dbe,2d03e27c,8af409ad,67af8eb6,84760c85,1e81c6af,a4cb004e), -S(3afe6f2e,8b5f1cf4,20ba1dc9,f527c662,a3af94c3,9d0e726e,b7942a2f,c9c1a91d,892cde5,f1420590,ff801f3f,8ec2ace,69f0dd74,31ca7e7,aed14c37,c2c12492), -S(28afcf30,a1f5079d,e6f340bc,9e616ce0,7a89b67d,4e7f0dc0,6f54fe9e,d17f1519,b7cc26ec,9a25b585,33a43369,40b6bdc0,c2462e39,2246a863,e67bdefe,1ae51be1), -S(13980996,af67f2e4,6dc5f389,d0269d1f,39a9341d,5e941e6,b4ff7bdb,ea54cb65,37a37717,d206b584,9eb79193,96ff5af0,449f3164,4c9eb31c,f27d8a,be66c741), -S(b7b75484,8966d79b,aa10ad77,4c447872,dc4c78db,84a58b9b,a112f5ca,77630bab,ca5111f1,55becf6f,1a546463,8a417af3,2c72cfaa,da56f86c,d7654c06,bc8fdff3), -S(b957ab6a,c7d7692,65adf169,492b00eb,4d8a351d,1f189d24,3e66453f,17696dcb,47474297,433f0297,231e0d7f,e51f1846,3af3e463,e071859e,d6b12b05,2191b839), -S(53f2395b,af57e626,f977dead,da52c4a3,f8b98701,f57eb79a,735e73b4,4d4be4b5,1a31bf14,36b5dcfd,5dc24ff2,ab5fc7e1,15940bf,12ae40b3,73859ce,5e26d55b), -S(31f8493d,8a81860a,3762fbdb,5b623358,af37ca99,3ce1bdfd,91f41acf,5d8502ce,1b231e3d,9604e28f,65d06f18,10931210,3a4cfba3,95c6d856,ecc374be,556a296b), -S(77da894f,ef83a273,22138b96,64df3b02,fdb5bf02,4963a103,1000ab37,a821460f,86cdc4bc,3269d02f,d3e97843,fd2c9dfa,c9ad2d99,f7503222,ac4c4da,5394809c), -S(d222a486,cdb8a4a2,8c1030c4,39b512f,f849033f,cc844e08,fcfd8748,1f68430a,2d7d7e4a,281ba28b,75f2d966,1d25a46f,5ded9066,7422a92c,bfcb1f1,797b7e02), -S(e4431b98,21cfaa43,8a8dee6d,b7a19a38,729622c7,67cdc941,789a6b78,c7a2ae4d,770e652e,de9172c3,4f50ed14,bd8f83b0,720ee2f5,8717fc8,a07de08d,5f8ac400), -S(1bb4bf1,1a1fb6b,78093ad1,5fe5408b,f9e1477c,3844e243,a14c37b4,f394254b,d9cf3fa3,25a0ad1e,fef984c5,8cbe25d2,f88f3051,788cbd42,a8f71791,5229e944), -S(a8fc65fe,e4df466b,d6651ce5,7ef030f8,701e364d,f1de5334,92938856,deb74235,b4c7da06,4f7bcc17,b3308c1b,e7924317,fc02c53a,808b47b,d87700ce,1adffc97)}, -{S(92133195,a4fd0c59,7e0cf65e,8ce1d939,e333f7a8,441523aa,31e339e1,2ae51e8d,556a388,7a7d579e,87de7f49,8c54bf24,2ca4b8a2,8b959e21,ceec4555,b8fabccf), -S(1badb614,6a647a09,894f60d1,6544e992,6da742d0,32df02d,ea347ffb,dd52f93b,6927c950,828e5449,bafee29d,e9977bdc,cd6a0185,3d3ef286,d9854f9a,75f5d4ac), -S(dbec52ad,5b8257f8,f41612a2,70047e4a,715853a5,f22091e3,496a238e,cf61379f,1ed383f7,dccbdff5,bebe8f0c,235767dc,ee220fa9,8d1b5ef9,6aba5ad7,87b46252), -S(5d2fc0e9,a5b1a743,131b4b16,88d504d,76422862,942de800,6c6d3611,3443999e,f7f89299,64793634,4156dce3,ca77c2bb,40536f50,60afd3b0,a3b37d3d,869dc11d), -S(761a1b70,83db07d7,340fb1bd,d5309ee0,e9e05bf5,6fc34a53,b6034365,ffd91ac0,82b1fac0,3d382fd0,109e45b5,8a07638b,1ce9ff2b,f45d3cd9,50843b69,43c75c7a), -S(ea397afe,9dcad2b9,4ad000d1,7abc4e5b,739e4132,997a7898,3c6c5c29,ebf7222f,24a87ba3,411ca610,5a696969,f86ab751,2c61e189,5ff4ad18,7193b5ef,7d8d2034), -S(3dc03137,8776b2ba,83a8124e,821de26d,1a52855d,d610eec2,d5c7eec5,9c92e81,b774a839,6ad7b7ad,9e6275eb,2731ad84,271fb8b4,6c3e12df,b74fe942,e6dcd35b), -S(49b98bed,ac9bbbbb,75f4f3fe,310af59b,1ec779cd,41b75982,6a929bcb,d40ada85,c09f3d79,3b143720,dbc1d04a,4d559f35,c650d372,12668736,1d824a9c,b100630e), -S(786555cd,2c6344d5,7f819963,1ee8536a,ba3ed77e,88501a2,20df332e,b41c9aea,f3e046a0,3ea9d39b,31377a11,dcf7c2bb,13ff138f,f021902a,4f927e3f,f48a60c8), -S(413259f7,3ac4366c,1385e7a3,79f54796,4b6295c1,298fdb7e,6046f711,44ee3055,a7a62864,4717b82f,b3fbb73f,fae2318f,985f1923,7df110fb,260434bb,81bfb4dd), -S(64922735,de394c7c,1d42e1ef,d8a19ef6,ef34e69,dc12bce7,c320f748,3993bce2,84bc17d5,5711e228,7e81ccaa,9625c73c,60923b0a,f266b70a,435b1c11,e7d29fff), -S(32d0955a,c57511db,5f27606b,67cdef94,a001bdc2,cc228bf2,951f5426,69d6dd51,7f9bb41c,d62d5863,c2dfecdf,8e3cc9c5,d104abf4,56b9030a,552ed607,73719520), -S(2428069d,b3ff968b,d1559c74,c3f38f17,e725340b,e956e6b6,e6ae3a70,4fe8af4a,1f074994,b487ca2c,9bf222ec,41cb54b1,bac8dd57,50e47f00,59ee74a5,1de0fb4), -S(a7f35a96,ab880ce6,b4e3c5ba,6502af7e,cf00c685,b260fe0c,380ff875,2bcb3e34,7d47fcf3,ed09412b,ed9fc737,212b6289,8b415372,c9338673,a14e7f42,7b4ac9d3), -S(ab624def,ee301beb,96d2626a,88a9adbb,665f9e83,f85640f3,79e4ee7d,c9282b2,4dd486c4,3525c5d4,668c5fb2,7d03c985,df69a344,62187396,ed9b360d,fde32f72), -S(f6b26f3,cb13dfe9,dca461c8,5b480140,df4a0c0e,b1d2f5d7,58de5173,eb4c4746,a5ab6d87,e6852ce6,9965a774,ccb94676,a440d1d0,c8b02f54,21c11bdc,b8406cfa)}, -{S(ae5fb021,e9256cc0,6236d667,b76b9bdf,304a4683,d2916ffe,489cf019,6b4c5683,e768366b,5c8d36b6,18e45550,d57493e2,41fed17d,12627e37,b29b4b74,d3603696), -S(a4e569c7,5d717deb,360a18b9,5bc0fc36,af132603,b74f3e0b,1bca3e31,14c28e64,a70e832c,e3d8d514,84136fba,9f81a2d7,8ab65b93,dc9f9080,1fcf3712,74340130), -S(2e7c85c5,7e68056c,e10ae193,66807434,c048a046,430d2087,92fc9b01,dbe06508,8c3f82a0,b8cb5022,dc7b04aa,6445b06,d251f9ed,bee00246,c33785de,979140eb), -S(fadbb0f0,b4bd864b,73527365,6455cc26,71251519,6c63dec4,41052585,fa86eb52,bcc086d7,54f08f77,1888bef7,4bd3bf9e,35f8498a,aa7cddba,acd63f0f,ef676738), -S(4aa439c5,2a0dd24d,c5f72b14,9a39e991,6dbcd4bc,4619fd34,94012a4d,430a2b0e,5482d41c,7fda4591,4150d653,2173b658,b5a06046,8270fc7c,2ea19d58,7b96e9fd), -S(2e1c9639,537015af,7de6bd50,e2697661,8ac633e5,f1946af5,34bdbc5c,9797aa4f,b6a39518,c607d0d2,94a36682,f4f6493b,c80f1624,792fec2e,e971f080,37dc6dcd), -S(63f28872,6d86ffbe,28a516e4,75f67972,e6266038,3be45c0f,d22e9a6d,d5d240ed,f62ca816,59ac13,10854091,c7851bc0,4d315466,b6187327,3af16f9f,68597dc7), -S(576c051b,2f4d2ace,ca5c067e,290a4d5f,d8f9b6f,19d4652a,449fc1d6,9d4b762d,a2b94a16,903d80d3,f965c43f,b751dc44,690f18fd,bf3e29f7,e21b855a,837664bd), -S(876afd3d,8466f7ea,eed3ee7c,e809528f,c4b392c9,efcc1f9e,753b4dd9,b84722e,e4453b1f,c3fcd636,b2c9bf97,6816b60c,246e254a,67bf2e59,22f835af,103c1107), -S(5a2ca063,6453a00d,b8cd6f60,3434f0d8,8642c119,b6302766,8ee67dc7,c10c9e3b,17be303e,40bdb2d5,9dfe354b,e58a387b,ff64112,3f6a13b2,80876a7,24c4d601), -S(46fbb84c,d08ce9d4,73e3b00,f5ba4cc2,f10fb84b,ea34a8f2,de114c31,8616def2,62410bd7,2ffda863,2400747d,1984d1f7,da285e9c,592729bb,ad9cee72,d266fc78), -S(417f7895,e2bc2999,469ce63b,66cc9bbc,4581b42e,c62171a8,ac32bdd5,23435283,1a5e10ef,826f058a,175fa5d5,21594182,a61a5a07,406e1f00,396935be,f78c9ef8), -S(916866c2,f33c0942,c8f12e54,8771645c,e1581ee8,6f58a90,67ededc6,b70e93b4,c7945f0b,d100c3a4,d624e527,ea9a8d9f,cedc9934,f903955b,aba58be3,c23819b), -S(c3630c36,acc78b38,8c5e8604,8110f113,3638c78b,fad169d9,d25d66fb,728ed4b,5788b6d1,7c74f601,e2bf5d77,eec182ad,1d9b2a89,6da8962,f9887bdb,5a6918e0), -S(64fd5fe6,cf91f11c,970692cd,d2ba6bd3,4d17faa7,77ace6db,d161e63b,93a0ee19,37ce3afe,f75712c3,301e4c97,6456ad79,e09326b2,28b23e10,b033bc53,a6efd060), -S(2ff8f0e0,5d514fe5,766bc683,f82af019,471a173b,b0e2ccb7,53eb45a5,8047041,9a13b872,e26b58d8,68e1db1d,7391afc1,ece8e410,a4bc3f42,dcae2b27,ec9a6e98)}, -{S(782d5c9a,d970322e,deff2e7b,57844184,c589a4da,c042fcf3,86c1a9f8,26c1babb,27bba565,405cb392,64762d97,cbaff552,1bc38b20,56afe313,556542d3,f200eb06), -S(69040dab,81af8b4b,759b852,40c16380,cc2bc3a5,bc8e9e68,7cee93a3,352d8055,e48d161e,b63c619,26c78402,528ad5a7,19a7fef4,4c03b933,37d51bfa,ec497817), -S(d00d4407,f7a1bc4a,57ce72b3,6fba7d8e,ca4f2303,292c2ebf,6940b34f,fd98aafa,ebdee075,32ccf753,1806337b,54a36a53,1641fb80,64d928ac,5a3626bf,e16dba4f), -S(9a3ab165,66f8c8ab,7b3d0d5f,7a3ec7bf,3cb69c0f,31346486,10c552f8,17a4abe2,7eafa760,7fb4cea0,dedcfb1b,1c16ebb9,8904a79e,37395aa3,1ced5c71,fc8c7774), -S(f9028f3f,4f5752a9,9ce55412,876c7067,a199a338,1d707bb9,3d2fc44,b165d000,a7346d7b,6ea796e3,2a19f104,34a7e0d7,b7e90326,81374d05,9b81badb,4dd651da), -S(e7bd1e16,60174f67,13a8db0d,2bf88a45,275a44e2,9a461c1d,cc6dc5c4,fd2b5c0f,9732850b,41082c88,5ab49289,fe11094f,c26bf80d,1b0998c5,1ce63cde,d7bad0fd), -S(d8b88e20,ee8db21e,28bd271b,46d77769,b446994f,5eb35ea8,d0613b29,67f8c1a,8b9905cf,547475e5,838e9191,388b1c64,25fea463,1e4ef825,e84e2226,2888d0b7), -S(3dfae04a,180749e7,e6949aa5,600ebe40,af61d644,ab5446dd,4b3334dd,f9bd7ce,963fb79a,a952447d,e274666f,16c08a2f,d5864825,78b870de,afbd98c6,adf4cca4), -S(4e0f4c4,b4905983,e12cf9cd,7dbcdf18,db9782b7,d4ea7e11,280d1f,7bc01e53,3305aeb,9b5f23af,bf1c759c,14a811a0,1bc3a5aa,19e26176,71690393,f3318bc6), -S(d74e6ecd,72453ee3,f68fc29f,f0de5b36,82c295df,2fc568a9,d68ad747,d4409b77,46dfc1af,819ee0,fd04e0cb,1af0835b,e8f6e53f,1ed28d67,6c0c172b,2e56a74a), -S(d1ef8f37,78dfe4bc,83c48c4f,e9aeb917,34320f2b,a86630e5,28f735d4,fd78fc68,6cc62683,1e417caa,9bdafef9,92c7267a,e7ace1a9,27d225e2,a5000b97,c45007c1), -S(64457682,4f541ec7,d8ba1964,32146322,3d1bd634,5cd09f03,a91aff2e,b9502b15,236ca78e,bec84846,74c43c52,55e2cb76,b41b01da,ded4dede,1a99e1b5,8fe80638), -S(f557af63,f3d8437c,1c48619c,4bad3e7f,d92c6ff6,63b86121,55bba4b7,efbf350c,efe2dfea,62a12ffe,5e4208b8,e5af4f07,13f8de73,824502e6,94b08d34,d1d92e2f), -S(f45ade55,84070898,1d244e7e,a546a34d,85fb1164,5ea86188,43d753d4,2baa1ecb,ec25cb2,6574f472,69a90070,3eff9a68,770ffa2a,7b12efa1,dcd81ce3,56a46978), -S(e3169959,74f4127d,e9002439,582f9790,6047bb58,d4bfdf74,3b6ebea5,b5663d65,cf7afc59,efac3d94,88260d14,a3e252e0,b51345bc,d3e07c1d,b07ec4e,28b6d60e), -S(bc9112f0,137446bd,1a218167,72b6afd7,65b19569,90f8e53a,f8db935c,2a88686b,a74e4d7,1e24d149,1667dced,bd7f58ab,851d685b,1c29e38d,6c9e613d,b65b7864)}, -{S(ebc119d3,8e794efa,85fcbd,5affac35,f73c7428,590ede0f,6365f1ea,87c65b4b,183a9992,3911b1b1,cd9b0fea,3667b6e1,52af7499,8d32beb3,d2ecb91d,af6e8a06), -S(7ce4a044,e4656f8c,687bc693,1c6fcca1,95322643,db41d,8407d880,4d6b6cb0,14fe83fa,eb944cd6,dab9e7b6,279ebde1,6ce1028e,5df74c77,7e6e00dd,55f69465), -S(5226b60e,b344786,bf572e3e,33e5aa14,6ee6feaf,35c3a2b7,22118560,183cadb,cb650e9c,e4f93861,cdb700d,13557323,8a7d7686,e22943f6,433dab6d,96253b10), -S(21c0342b,9a723249,ae7193fe,aa00baf6,beeb376,1f1bb125,7d0d9549,d46b403b,5b2dfee9,4a67c6a4,def4f55,a14af716,ab1be308,ecac6042,f86679a2,1f5114a0), -S(82e97dbf,f1d0d9bc,65797145,7c5aad62,ea75753f,df9d3e15,efcd3ba0,285d3476,7f67ccc2,f0aa795a,890d9a30,6838b9d3,c64c1371,75b0ab05,68622b3c,fdc8d25), -S(6c02ace6,1f479fbf,11059054,d8dc5761,ca0a97a0,22e520c4,8aa2f32,448b7392,4e57f208,ceed832a,3626f347,f8a30956,13a17e57,b0159ca5,33143166,77b91469), -S(8a367826,e40db24e,28fe31c2,fe24151c,8e4702b2,43a99d86,5448d83b,cf49a6f,b2bf6c78,299dc024,2fc66392,cf6c5097,42a05f15,935c835,3944e66b,bbb87c26), -S(c1c3921a,14f64598,11aa70c3,f756e689,82233a48,588bdfb7,84348459,19125af6,6f7109d9,47dabea5,da858a4c,75ba6c3f,162ad404,15e7ab46,7247963e,8f4a1326), -S(ebedcd5a,e0f0005b,2eb70d40,4a1bd4a5,f0537c48,e8f6149c,c042f9a,773c75c5,2b7103da,d29bb9d2,c07def6e,1094fa50,ea70f7c0,4f609b4c,bee0d576,57e506d6), -S(bda6fac6,99e09a50,ee0131c1,efaaec6c,7cde205c,d3b55c83,176d20c7,80678bc2,881c023c,86b948ed,31a5cdff,8f3f985e,cfec9111,627d813f,177afa76,89a16f89), -S(f6d335ac,66fc71a8,319eaa38,3eeb7fb7,41118280,531434f9,cb0b364e,90babd42,b14c40c7,8846262b,e117735a,30a3185b,49f8852d,2e3aa8f3,3dba4806,ea7ff2cb), -S(c5588c4,fcaa5c53,79f910fe,9bfa1224,fd20aacc,f1efdb2d,7ba87c5,3615ddbc,e60ac5b9,fa96e150,57378c1,11f384bc,16fb32a0,a0482f26,603aca30,ed1315fd), -S(db88be26,bbab7b99,f0f20c61,40ac77b0,28afd465,aa4d1294,9011a47b,b1d87f89,e126d612,91ef9a77,e90a8522,ee6e7dfd,fbfbc2a9,90986da5,65919317,dd4ebd1a), -S(1150279e,e9c0323b,b122c2da,6e8b28ed,5e5b02a2,162067ba,67f5aff5,e99214fc,74d876d8,4d00e091,ef0aeaf9,5aefda58,f3da4d52,51b2b28e,cec41a23,4b420401), -S(1bfe1d76,43526f3a,e0799982,69f9679a,9a54f1ee,bdad1f6c,9c8e096b,6e771023,ad94d693,961644ce,a37ee705,e06b4b5b,32c17011,7aba021d,6cf48746,d8637dc0), -S(928b3e6f,a0e6c2c5,896f6eb3,972fe96f,7e446782,50d313d1,54ffd666,2b43a615,50f2d7d5,fa221867,3f18540,f2f7b513,b6b4875b,9ed4a5ba,73de7800,37f842d8)}, -{S(bc4bb9a6,292aa09f,5c66dc9b,667c4642,6b08211f,a9a80f5e,f3f17b,21f275de,5d0e0492,39a862ec,b9649572,6f11bc09,cebd9f29,d9407ab3,1603054d,d9b76b07), -S(bf330f50,a9c015fd,8ff93153,561ecb91,27b84420,62fadf17,3dec27e2,a5f7b0,931f0891,94aefbf5,9c530d74,8ccf5a5d,83f3fb1f,cd9043ee,ebf50994,d8ec1248), -S(33db24e,b1ba1a5,cbe2832e,50d877c8,a4fea4d3,e63d7c71,fe8cf9ea,9fcd1cc5,8b0db6a2,37555121,ec8a2ed0,e8f80dfd,37082a0a,883d3fb7,d7d2dbd4,7c01f6c), -S(eefd96d2,1d6639db,6a7f3a79,26f5bcd6,618e6ae1,70551973,7dfca216,565513d3,d7644dcf,e46715c,1821babf,5ab153bf,a80d20a1,252718b9,b72f299d,21ba7218), -S(48c08093,fc737bb5,70a31154,290f709,3467c915,c4afcf6d,ae372e42,3ed69815,29581f74,659462b1,3951d930,a8912e33,a2928e34,5e3563fe,f88b42d2,28af2f26), -S(68c61ae5,15c1ebb,d395feba,8661a967,162dcbac,5cb13303,9a354c11,ee217267,9db2d6cb,b3880ab,ddf58293,7f76ad7a,70fb1c58,d2eb9a5c,468331b4,55c5ece9), -S(99afe669,baf69344,16b388b8,30b97e80,86886c62,86870e7f,58d6efc,377ded78,a684a9dc,84881a2f,bc340b96,4180a966,d00aa5ce,513693e7,9052795d,74f08f7c), -S(3e893680,b103cb80,e6a4eadc,abdd4eed,6fd53341,d08d6d78,85fde37a,49621bdb,d342db6a,a942396f,76b79de6,a6d48943,2beb59ec,4d1d6399,9244bd1,731a6855), -S(e19eee8c,7206fe64,a217e60,c791c834,de7cecf4,3ae1cf42,b697941b,c556252b,cf79152b,76b0ef1f,abd36175,48701716,32ffe2a1,57b006cc,4fceb313,17be8fd8), -S(50d544c9,b3a10831,e325dbcf,6b13c6ce,a06ba82f,ec3e5b9f,9442101a,a4c64d46,a89b1cfb,169019ac,19785c9b,8fd27f1f,177adcc6,c9b995b3,43b373f5,cd82c9cb), -S(e34ff94c,729ca264,1cd51264,1eea2aa7,ebb5c577,71bd1900,86a02aea,7cc2c1b3,454dd58f,c46f61c,30efbfe8,49c7b2ee,b1a99bbe,6c8a4f6e,c0063a46,a1f63f86), -S(50a5b0a6,919974b8,14c10ffc,8c6233f2,843840a5,834ff5b6,75134ee8,4f40a716,6cbafa57,ec555bd5,2f656a95,3d592aaf,e963d403,40a7540b,644855fa,7c94c3ad), -S(b5f7dfc,438a381d,edfb576,aa62f2e2,12264e1d,8222bea4,f71ba06a,b2b6f0cc,396484f5,3a14cd16,58813612,2fc55f7e,89c4fcab,6d73e5a,fdeffadc,3c9f9b0d), -S(4e2a7b73,1bba01ce,68f4becf,34ab78b4,3c89f711,3214fc8f,ba3e19e6,a449b7f2,aa85874,bca558b2,e674623,3e0ab93d,4ec34eb,6998f0df,3f153126,93739077), -S(3835d447,f4da18c2,1fea247c,9ff3436d,bd60878c,dd347f4c,ca1168f7,ae189ece,df5da21f,f6a6add7,17e53e6a,ff0220d8,9b1e71a1,30339194,81bbec2,40414a1c), -S(82452834,e84617fe,d7d32149,6abdcc54,2af5fa13,8f55faa7,c2245cdc,48c89f06,c01d6da3,96b923c7,290dbd1a,6c16a69d,8a872638,4f6285a,f589a0d0,20e892ac)}, -{S(c8e595d2,666f4913,1f375b67,81b9113a,d0760e5,9477ca17,8863828b,307488f0,a82cf2a9,d823af13,5c23a04b,bc12dd81,2c352a48,27e19030,8e089d9d,9c316596), -S(26da38b,1bfa8363,6be480cb,684ee5c,70957f93,7f9a2d57,3ec75396,bfee49fa,9763277d,f3c228b8,515bd08e,b29dffcc,eac8e3ae,786a9655,5fc1be21,cdd20d47), -S(52063926,34d12242,b2ff32c7,d0a8bb47,fbbd005a,bf7f92ce,78808a5,7b1cbe55,d0cfa8e,49b45823,881819ff,fdbb6d2f,5c65f35f,3572e13b,ff7af252,95efe81e), -S(af61f7dc,8ceb2277,db16412e,dc469b2b,f0e188ac,89c72bcf,20654379,716115f7,524b9b25,925b793a,8bdb8e06,83cdb414,db0f6dfb,e7e06274,d61ef87a,13493b66), -S(39e53a5f,f553d89b,dcbd6688,9eabd7d3,8c5fc6ba,24618d98,88bb6e42,92658f06,ae8439bb,6d32531c,45ac510e,20f1c7d2,b8dc70a6,65c11f2c,cda73603,97c6580c), -S(b687e250,531efb00,f7e12690,659bfe25,429ea2e6,f1dec5eb,74bbd1e4,89a95e31,1033e5b7,9c0adb6d,c0f12ff,afc5d81b,54d7930f,f6190dec,737bbb3e,c4c774ba), -S(4c17f5ec,34cdd368,dbb62f20,c3b86483,24e99e0e,95a7e624,64cabe76,222981a9,1e37e3df,b690b574,a11c9803,f1cb5618,ce4a0331,e17c5cb5,4873ed6d,de217019), -S(bb7c4b21,77b77a9f,8f78c2e6,25bb943e,9d05dbed,abdbe02e,497e5dab,c31dc477,a5f38fb,7ebbe67a,869b90d1,aa4fbaf5,cd7173b0,46cf3c5c,b31a272c,c0693c82), -S(3b18ce78,6688a74a,7256c067,a412aa59,45fbb506,fbf801b8,61734ab6,400744c8,d4f01881,47809cf6,5226529b,acf6e81b,7fdb609e,3eee050d,ec0f3140,2308ae20), -S(b671371e,2f0b770d,af8fb77,6a64948c,1481cba2,afd1a3c1,bd233946,e34c86af,4a58dda7,ee794384,496c539,7ccfaef9,fd75d05,c551e26d,2ac631e0,3d124fec), -S(caa559f1,b0afb30b,d62ede02,a9e28a9d,8bbb437d,e9a8963c,37e25898,428b845c,f73a14ef,2078cc23,92b99742,9dce6a50,5682bdb8,c2b5e587,31786814,9c777411), -S(2676f258,a761c508,5176ceed,a95cf9ea,4d6640df,a2c4abc3,e4954225,c23acf9f,fdc42fdf,b1636050,67786940,3aea320f,8ec1e8fa,b9033c3f,2b919f50,fac0271b), -S(ce17ef68,f6c7b456,4cab6be5,22495389,874f296e,b62d552b,6d621607,192005e9,94fd30c8,71add5fb,5161b468,ab60d254,472339c5,2668437e,7e172ec4,957d00c3), -S(42fca34,df3ec118,417d8d18,4e507f2,91d402aa,32c00b5b,a1dee38e,7fb0cc35,a046e52a,fb7eaf45,bb3205e9,56e0e780,977bff46,ea65633c,cb0cd2b4,a3aeb2aa), -S(99926617,c15dcd0c,95ff4903,ed9d6050,ad0e1982,84a3c9f9,6a24ed55,45641b13,64437785,afc882eb,4a78844d,14d79cc7,cead217a,3cdba8e8,473374e3,4d416b56), -S(3d4751a6,99a8e88c,aff3daf,3ddcebb2,63f0d56e,6d305245,4c16b0c6,f80e0d93,162f562d,32595699,172a5c6,4ba2dd35,11bc5430,f21495d1,2ae9f6a0,638c613a)}, -{S(49e7429b,e0d97bf9,3f17e9a8,53fedb6a,a9bc6edd,8e85f44b,9d2f1469,b2d3b178,ff9e5dfc,2746679e,9826039d,578bac31,c08fbaac,a075214c,73c50f,74568fff), -S(1d1c9798,3eef36d2,75478b94,ecd3e172,a39e49c7,1c79f932,2077f410,e1a9d0ae,5d8d6ec8,aef80d94,3e75ab6f,68408d84,6cf94216,af6e06ef,dd7e9e72,4abcd7b4), -S(60f8ca6d,1d60f524,8d582e8b,ea2fb8a0,dd2ddb3f,49bedc03,5d24973e,aead0b41,7c4e8b11,b0e8b135,bedc60cc,fd540dab,da868d50,78386aca,117bb71e,e108fc51), -S(c6f57fa7,6d2ce583,415e0366,9136b21c,725126e,56187c79,577949d0,797e196c,2772eb6d,94a50849,e58cf22a,eaf1e35d,6e2bf171,f180a44f,42cd8659,41ac2348), -S(3766f2fc,83c96803,e590fb7b,ceb842a0,8cd5602,e57cd00b,5a6e340a,361a7daa,ee3e9d18,da86e137,27560281,8806fc26,199514fb,98c76526,54c85842,649ed048), -S(20de0b0a,6b2200b1,a89499bc,5cf2dad,7dbb6c2,e9805259,21c5e6a7,29c40cff,b680c2e3,33083337,3fefd833,68986b50,d2a28319,9912a092,fbed8b5b,1f22663), -S(d2f06c3a,add7cdb5,ac606876,e4093fad,8c626408,ab6e6dd1,ead7ec93,4e0a1088,990df428,517d791f,ad749267,7666dbe0,6b71436c,5112295e,ab7bfb74,b4cc89fb), -S(c583dce0,f9c32b0,d8c87a9a,dc7dd093,d12037a6,ec162d5e,22ba72ff,beae41e1,d9390ef4,9f7f10fd,7b8641bb,f2ae8388,ed08cc19,3d1e6a13,81d8c198,42025aeb), -S(80f61ba8,a99d2081,f0652a9e,a25b8d23,716d55aa,c9355891,9a4b4d43,1e967f58,b8df023e,56eb796a,e70296b2,b47dea6e,d74ac4b1,99fa132d,c9c464f0,ddac27e2), -S(4ae1535c,dba6c272,6e78dae3,bc651f16,cdf6634f,95584886,899c829e,df12201c,ef66789a,13b7244b,ced52d30,c9af6613,55d66a9a,9efd3a40,703d38bf,c69c7c75), -S(2143bc02,b46d41b8,766db211,61ed21ef,5b0973,b7cebb00,beb89b71,4a6e16d7,7dcb12cb,137dd6e6,96791345,69e25e2d,57cbed88,ce39aff0,3d57ec3b,85160fea), -S(5c0b84bc,ca8945d3,a2356c68,afb8d1e5,d45357b6,b37e5afd,c2b00e6d,1f6c5eab,1608a492,bfb97a7e,746218c5,f673078,c70f5880,de8df87f,8aa5bfb9,89b43ee8), -S(f6cc5210,fa45c072,cb95e88d,ca93b9e3,f7b35e98,13c29976,2ed9364f,8c021e3,ae959f0b,5ce17592,5046e320,f86d9751,a6ec37a3,a773e5ef,c4681ebb,f5aa1baa), -S(d4df71da,5f272934,8653f60,bb02deb6,c314943,f50cc5ec,e4974ace,b5b4d0ac,17caf288,b3286dbe,2e8d0616,df592027,baf3e59f,1e52fe51,9644cf5b,66443c35), -S(44e8227e,177bb9c1,5aab6cd9,d987ef1a,af087d4,bb2672af,1a8d5412,a7d6cb59,4b9b2602,152e1152,92fb191f,2cbbec91,5ecea9e9,ed75121d,5cc7a88,69527cd), -S(97f092f2,75d1ec04,96f6b14c,10a280f7,25c9e4a5,d16afe2a,3f0837b5,422bc5db,12f04418,c131046a,e5c7ed64,f69d6a8f,d3a3d35e,30dd273e,72ff16df,a866822a)}, -{S(9a1db7bf,53241ed1,df8d3ea0,f70c0b26,76b43ebc,bcb4622a,9704b0a,3067400a,e3638ad2,95740505,455b2e1e,d495c57a,54ed8e8f,c647a6b9,c69b7dd0,715cef52), -S(5aa4d7d3,745f341a,c2869a8f,ce1e2a96,e25e49f7,1e5cf140,c0ad884f,47d8ae86,9f03a2ba,989bd4b5,9361448f,abe607ab,210d3887,8da85782,260937f5,9910d8d1), -S(91910df2,7ca6ab42,17ddcf1,d7efbfff,e69eb9cb,24a6648e,3aa7d738,c76290f7,e99691b1,d883491,e79e957b,4c65f975,601aa5a3,b056ebbf,abea6c7c,d7b9ff2f), -S(b5b7792f,99303195,4024caa9,e08bfc16,53f535fe,7bc3e34c,8491864f,74f48799,6cade2ce,595b6714,5d376b7d,7b435a3a,76b15912,6340f6aa,68ae15be,26a159ce), -S(8b54ad71,6c724ad7,e47e5efb,e6b7c93f,8923e7fb,8517ce0e,6f732486,f37ba1af,fb8aa95f,4a6e3522,371cdaf4,461f4d6,8a45481c,da065f7f,a697487e,fb8ea80c), -S(b4896855,b2614337,8c5842ef,b7dfded9,ba6c80fd,2eb154f7,e83c4734,ed7dba2b,30e20644,fd8a9a81,9c622641,b525647e,ae35b892,91410141,1a5df15d,36c4efb1), -S(5bc3cc33,89816b7f,414a473a,2deae3e5,ad3e7803,b7532f36,d2b31598,7c35d6ab,4dfe0f94,86d1ecf9,7de9b0a9,3e437f49,c015b9a7,677aa2a2,74868a4d,512c2ef0), -S(230bee0b,5eaaf145,f18ec782,1e861f12,26cec876,a50ac94a,4a88ed64,4a3f7d34,331778b7,d638cc22,269a7a3e,abd0c393,f7e08d0,dc761da6,25b70b5e,14f18c26), -S(8f55920f,c479e736,3000b33f,ebbb1559,d41a5873,93429368,78a6156a,d476b8bf,94fbaab6,7a49ff13,2435b28e,df7253af,43420841,b721221e,b5606a48,3061e441), -S(d64edeb3,709907c3,761afdea,f9b431fa,7c0d5912,8a603410,39e89346,1561b7fb,d64ce942,eda3a553,82c22d7e,f9b20c61,ba09fb35,4401fdda,c054e891,15134b9d), -S(ab22f920,a97eaefa,25e46069,1123f499,7b3a78e9,af738ad2,266c6c98,4b5fb63e,27f41b98,a05a5599,eb82b0c,37a9a70a,f19df223,5254816f,1b9411b2,52b77d), -S(3a409fc6,f4a19839,c6bd2187,5e2f9b1d,5e10ca36,5711a0b5,67084612,ebe049d6,21006d4e,399d55a1,6a7c136e,b192543b,36e73785,36506555,e9c5fea9,3e5bf265), -S(57305b7,7613e53,635ea239,c9e35edc,1a2a1680,fdf58358,93cb226,c0f11f50,b3316b71,954f5a14,acfe28bc,9e90c27c,715204e5,9db9a74e,a5b5cecd,2f43aef), -S(d5c78499,3727b6d6,18bc7b22,4b1da72b,1cd9122,81e8e58b,cf2dd698,b400cfa2,d1aab246,fc2da7be,de9d90cb,2c438d65,310b4785,ece43715,dd3a1a65,c8abca8a), -S(13a05a02,7191a7f3,eeb453c2,8b76afb5,150bc141,20b90f50,dbd0d218,15453e2e,94ab710a,3736322a,ed6b4443,abcdce44,a8556a3f,85f9d3a3,701dde54,52aa3927), -S(3e6033fe,9fc41a9d,6037d9e7,ef11fdb6,93d1af71,237d3983,2da15f12,aa080ff5,763af526,e9187e31,89955a60,b3914307,99ed7de9,e41b6c,39d8ae8,748af8f7)}, -{S(50cd2e16,997d7d45,98bb2d9b,61aceaff,5ad5f38c,8286a0e1,d08055ad,726c7800,dd19c3b,c08b8d97,88f9de1,5941f5fa,6402bbbb,5fdc708b,cfc08844,eb23733b), -S(4e83070c,e3eba290,c6cd520c,dcb4252b,9098270a,55fd47fd,eedf36da,b1706d47,561a3822,cd94b2a4,1f30bac8,695e05b7,69de8ae7,4241d2ef,f084922d,ccaf09ef), -S(4cb0754e,6863546f,afe0bfa,edc94c15,6d9ac68e,db700281,2a24933c,a0a30401,6cf6ab8e,306e4400,427b7820,52534566,52d2bc98,2510c84e,43b4ec61,3194c402), -S(a3689f89,d4874967,1b205a89,8e6c092a,b0cdbe2d,f1530bf1,99201a3a,6b0e3da5,5a58acbb,e6ad1676,a328e193,30c3297b,81e52e9a,4abfcd4f,7e0bdc2d,543bdf61), -S(79617bb3,c57e2db9,b2978984,2544e9ff,61055023,80faa2c1,9db34d60,b6cc0c8a,e63a05be,be1da5f1,b74450d3,60092dba,29122671,6e07280a,d78a1f17,5daa191), -S(6a474afb,415121c9,38c73c20,27a5fc93,f7e8ea81,d7df1144,a50b1c66,5be0d8cb,5c643389,af9fd383,b7d71966,d251dc20,db8b0d22,8aa94a04,289ee8d8,247877fe), -S(7bbcb86a,ebb40626,ce142507,b8cf0801,2f706862,7a46c76b,fb8eb115,be4163ce,b18769a0,735707da,4b1d7a1c,7690f190,2a3a1f30,67d54f8e,188f8a41,3826ade0), -S(5caeb262,447b4224,19f66418,4899762e,2e2a6b9f,f8aaccae,a29fc3f4,68a1b645,b894f2df,20dec514,2792de69,86a9582f,d6e1e3e0,fd97c5e8,9798624b,9d6e2236), -S(a8ec4087,e144437c,3acf2ab9,3f339415,74e79f9f,cd48bc47,cace25b0,4d4e451b,ef3ce687,12f91e5f,b38ccc98,5c0641f9,d57a6ac2,b72f8814,3e85e128,c7012a4b), -S(724a5b27,5dc8ff8a,e10b34e3,5d05a592,c50904e3,32153a20,78809bc7,5d69ed79,488b7096,f471a9f8,583a9b68,3119a211,6ede4c52,bf817b27,123488d2,9ecb8328), -S(1d1ab819,80b10336,75e10627,b7293cb7,7f31cd83,ad1a043b,ae9aceb4,aa0a7463,cfd42f33,c57814a7,acbb3f08,dd882a4a,c572412c,8502e82f,a3180452,7d2e0151), -S(98b12e59,8166e430,ea43d632,f8a4b981,f3745420,6d1233e6,f9c8756a,47dcf4d2,4f65841a,b8f18241,a46eac62,b875173d,350c78da,6d6af3db,d9fb9bbc,77f33b96), -S(58dab35d,9ec4e48d,6a7e619b,e926ec2c,45f67be3,3d89bde2,38963966,c96b3270,e5d0aaab,6191f65,e6340837,747339b5,acd35b86,823e06af,85eb54c8,7f926564), -S(41dfb55a,cad77bbf,80435b8b,7f2366e3,f41e64f4,74bd9895,dfe86e8b,50abfb83,147a71bb,3809c321,d960ef5d,9f767bde,7873efa5,c590e799,db46d8ba,8c1dd2cd), -S(d739d1a4,72dadc,eb59a120,3b8de564,5d5c1e1c,5ee96ebd,533442e0,de0c8684,610f527d,8cc0ddb6,cb17e24a,51aba4ab,5ab0d8aa,9ebd61c,5d26cf93,30a18293), -S(f887ab66,ed92339e,8fc9d8ea,1af72d3c,6426ba1,a8be283,e2457a97,342dfb4f,94de30b5,4e69b56,fefae855,51fd5a5f,111671f9,c5a733f1,1ef7464d,88d5d66e)}, -{S(4bd266bd,4a730879,cb06d8dc,bd8e5854,c50b6221,d83e0a10,3afcb2a9,a64cca67,a4654a1d,835a51f0,5a877200,1768c549,909212e5,78e3b1d1,df935959,93650863), -S(15fce59,bb77b091,90e5c39b,ae696127,4d51068d,ea51ce52,6c8525e7,b1ee3d1e,b55eb928,92ae639e,da63a4a6,f14fc6f0,ee2450b1,94df32da,9a1004a8,699797a8), -S(d3e5b06e,7648321e,4fe95ed8,e1316474,43996e1e,2cff5283,26783ba9,1906cf7b,2ad6127a,9e45be65,26ccdf8a,460cd441,cebb5689,9f3cfd41,2aae39e,c838b2c5), -S(114032d6,8e474d1b,a9fc40c2,f22f5b1d,6d12b9dd,9cbc286d,38274501,218c54b7,9dd3d787,706a063,c0d81bf,d1cecb6c,b7b5b446,6d7c955d,22cf05e0,822a9ef1), -S(a230cd33,6bb82fca,bee35435,dd0d560f,d286785a,f5425cd9,a4c9abdc,819e58c,57d99f9c,aef9cf3d,fa66dfb8,bedeec77,e21746b4,27e4869,39cdd8af,5a9182d0), -S(593e3646,546aafcb,fc8a293c,6cf0530e,5f1f2639,2f3ac2b0,b136583f,2981e8e,15c4b596,6589f9eb,5fe0d0a4,91e768ad,fc7f5283,875bfcd4,3b698a3b,4f268b43), -S(37729a9c,3ad25a03,e1cb6fbf,ff486df7,d518809f,66099d27,d203dab3,3d33dec5,dfcbd1b3,7905c99,21269ca,283405c5,208ef5eb,e96c0801,f8868631,69ba2c23), -S(46d8c723,f0b889bb,3272389f,ba3ba57e,d30d701f,7f730d0,c7ebc34b,8212cb9d,bc41f981,2017d9e1,1e4e2277,92b6e804,6318776a,d552960f,c751c36,c6d00a2f), -S(fe29d8c8,fd38be9f,c316c2b5,ab74dc69,ffbcc390,1e59df52,66aa345b,6b1408a3,338ea0c3,f80e4400,53858842,936562f2,8b9ea4ea,31540868,11e87150,89e9e304), -S(99ddf18d,cc6505b3,78a4cbb4,f45bea9e,44726ec1,cd51397a,d536dad7,b1b3ca2f,fa8e8ab4,b6071958,c237e5ed,5e0c0962,61825572,3411bcf9,8e923b1f,e748ce4a), -S(14c9fbd4,a0fe77f,1f518efd,13dd7eb0,cb7695f8,219db1be,d4e76fee,813a34dd,991011d6,f67f3e84,a54c2357,9897dff5,f2a58cd7,40bffbf0,a876a611,535f2540), -S(3cc95333,2788684f,bbea85ee,f49a2ae7,51d5e29c,48642a5d,45236bae,a122e5dd,2ed99469,8084af0c,44e7c819,cdeaf311,72f08aa8,ee70644f,ffa2dbbf,bf9c0bd6), -S(9fd0c95e,f60c6831,959f2b44,5a15a366,6463425c,3a64d213,b014edad,bd22e711,8bf7b7d7,50558a66,4481df71,2c14fe8c,9411d8e7,13fa61f0,fcaac1c9,2c1990b7), -S(b23e3552,9d02bd4f,bd847080,a5e9dc69,964b324d,e16af0a8,857f46e0,ad9f32f8,f3b98226,f77e4393,dc35409e,69269fe5,957a3e74,e5e5d7c1,ec11c4b7,3f5ae025), -S(9b674b33,b7bac25e,88896436,b6c80dec,be8cc797,fd34603f,a4007318,415b95ab,50811d7b,bf49c464,de0b274e,2acb4dec,5786043e,6bbded6f,13d0e131,c3b223ea), -S(2cdcffd1,ac351cd5,21216262,9a401b63,2f4f9c64,9fd0e250,2adbd66b,3a0855,54ca3d4b,6043a79a,66cfb5b7,37127ee5,c0a3e0fb,a4214052,6da020b0,c757f73e)}, -{S(217de5b,a47e8de,cb9d8dc3,dc8fcfd8,203c514b,b9d7bb5e,fb03584b,aa1baaff,c77bddc0,3af15e63,912e51c7,19bd8186,67f999ed,9bd801b8,11bc289b,f12864ed), -S(799812b7,d79876fc,7290c3dc,18fc6ea7,1d224373,2e79d17c,9737a47f,29fa8502,4118e843,99b5d024,a82002f2,7e791cf5,badd2e5d,98ae1f30,6d98ea6c,d1d9b4fe), -S(8be7f251,78840efb,df56c470,c4db43dc,54bae1e2,7cab2bfb,c7a6641f,e34f00ad,6db39ad,c7ad2102,90c29073,e48225aa,6d51f27d,d97c0b0f,e241f9fe,dbe1564), -S(bcba249f,59646b10,4f6aba48,1e886117,be0fd815,a6220e4f,f5a08eb6,ac16c612,e8d84c45,88ce9926,99b2d6fe,5ead0615,4b32a372,209e06d0,c3d8c42f,a0e22b86), -S(ae1a61b5,deed4d8a,915b94ca,72aeddbe,2c725ca2,86311610,476d94e0,73fb1415,e1f62c42,efb2da24,47b3b5f0,834617e,e06078f6,78ebf4a3,d38c45c2,f384e1b2), -S(a1e069e7,74cdf680,41c5aea5,39552c4e,bfefd4b6,3869db9e,c5532b09,e8370996,cc1216a0,cea149c1,f19ffcf0,eea82fea,29fa7f3e,b19d5eb,7307904d,a38652da), -S(e6433844,64b7b1ce,bdbbaa01,aea053cb,a36e0cbf,e1c9a652,8c714a45,6b6b66,22f16bb,17b781e4,47fc81d5,1ad5ec9f,c158b069,7c446bdf,52da86ee,6b4ebe8a), -S(accfa38a,10f8d4c2,f8342e29,272f7c54,73d10562,82653714,8b67a26c,5735ab9f,ac0e6829,1043396c,be583305,106514ae,354532ac,5ead4594,dd5a6d4e,332cec1e), -S(d201c17,a1e9efb1,7bc1c655,48c100e2,450614aa,b45b8125,9f2f7e31,4cfc924,4677a168,1eae4650,5c5d6c94,a6984480,43f3793d,ab496ba0,ab86064e,8b48ae23), -S(6612ab47,b35d942a,98427ff,ba59b78b,fe44437e,b87442a7,794e3274,89c3b335,cd540fda,9abe6c72,e298eddb,6d8c5a3e,c0953eff,4a61cc54,22d01ff5,f7329785), -S(35b1b6b9,ce9d1a9,802dd987,745c615b,87a96a83,d1b2465c,cc9f82f0,1c73571d,eee3f5ce,aa7961de,dbb80107,36e6758c,e9cc8b0d,58a6dedf,ecec9f2c,7a73865a), -S(c798e22a,59e65aa5,6647a86e,f9a91e80,98cb97e1,81e07b4d,c3fdd428,dfc3b1b2,45f881a3,1b10db23,ca93210e,22398cf4,81a6a61,6496fb5,ab82b456,7f99a392), -S(39d9dd1,955b77dc,4f4d7436,9d7785a9,c8ebfbc3,d359f15d,8d38d8f3,1097a2d2,64040f85,819c8a31,94dc8ab4,5d794fd0,dadb6826,70de6629,5afaaa1e,c669126d), -S(a9168a3e,d48f2332,48bd4a53,dd37e37b,d24b6284,a2522671,c6494bf5,84738bf1,6ec107ed,6f749a16,27a57227,4d7bcf8f,8ff71417,7d38f6cf,64040ca3,3292bf65), -S(88b92b0f,67c3524c,3d7b04a5,bf539b2a,a244f3de,64867754,bad51192,292a6f3,f65e55f8,f9239573,d77176ae,c976c545,a0e4668f,8c2f2fb6,cb2499ae,94af11ed), -S(6c7ef071,c8f4b0cc,67e66561,38d5354d,fe5c9edc,5cea2eb,a43a5751,317da5ea,40894203,7cf76552,33da385d,43e1bd8f,cb871737,c4b7f044,a44042a3,34d4bb6c)}, -{S(761cab41,3916a1f5,e131f337,e9023519,6199f789,87ef390b,3f2d8bfa,b0e9bbc6,f10272df,f7e91c40,3565da85,17fd3011,bde7b797,526d3c3,f00fb28e,f26dbd91), -S(a6bf4e6,9cb5faaa,8b1308d2,da8e2ada,516b5f18,733156dd,2de04cb9,ab1b0e9c,b84be8fd,2ac4b2f4,2934490d,2c7de2a7,8be093ea,907bab1c,94681e51,3ba7f4e3), -S(4d280f0d,190ce936,11ad117,ad7ca092,d61fc8cf,db1fc752,5788c7d,9cc97535,f20a17ec,c8fdbfb0,2db3b21a,acd35527,25a7aa8c,d20a6e23,bcdeca87,a6fc2112), -S(fc0fecbc,c71d83d7,c888c451,f862474f,2538e8a,800c8a93,f4c30be8,ef98e709,3e809271,356b87ad,87d15888,26b055cd,6ec7e44d,3c9e404c,a27a473a,8cd093cf), -S(c3746b0d,f41e4a85,be3bbe25,c1d64961,f80ed512,8ad3c3d6,2cc5b9f9,b231dabd,382a6d3d,d970f8d4,abe3a72f,58f0cbd5,33dfb21,b92571e0,19a0ed82,55974b77), -S(e5749369,b1e25400,2927cc8d,3b15b5a,dad570b2,cc6ab264,a8af3de5,fcd9a458,38cc0e66,e5b86153,1b8b7aba,c266235b,fd34833f,9b0a18ef,9ac361cb,407d774e), -S(d3463d82,782ece5,999dee44,cca08ccb,1d908f11,7f19d0e1,93f42e86,505470ce,ebb2cfb1,f948fa0,4204c39c,cd3c12fc,6379418,33e9ba07,cd714715,268e8c85), -S(9c88be4,50bee26f,14afddd2,80e247c7,7d07dade,81c55945,4091d1a5,6acc28e1,1a943839,793d91cb,865a3213,4d4ef1cb,927a90a5,e9da30c6,c88d72cb,1fef79), -S(77d8a57e,81ff4149,8703d289,c6d2d6f,209ba69e,99350060,d8e53d5,eb3709a9,6b692bad,ab736bc8,ccc1362c,24f05260,5c3d2b0,23deacf4,641c56f5,c2b79fa3), -S(64ad7f39,a9e7027a,51eaade,8ce6650e,2141e655,b443fe8,f67afbf1,7c970189,a730c9ce,acb21c6b,ba834441,9f417a6d,47ca382a,904e432e,3fc2235c,222acd1b), -S(6f1c3296,67d9cbee,7c44cdf,e5614882,1ab9ca61,1731c1a8,28520698,7f94609,ecd182d9,eed899,f9b8e5f4,71e5805f,ef716180,b8d1499c,82f6186,d09a0338), -S(8116e0e6,75ee5fe6,f0bc86c6,c3830977,a4432546,4d027eba,fa242f13,abe10e55,8cae3d9f,af3e4b04,f9555752,74eb60b,1ccd5f10,8b3e52e6,47871a5a,1671fd), -S(1593b19,7dd26cae,e667733e,d4b564f0,ff212f26,1bd6e81c,61acabe7,37b62f8b,3c9d3e7b,52301084,7a5c2f2a,39cb68d2,b9a88605,a12cfb39,fa790749,7107b746), -S(4bde92f9,1335891a,1f40ff,e4310cb4,10e2b172,27223f80,672b313a,184c9a26,c24904b1,c5d83c4b,31748a87,576880f2,73719ea,4413f945,e8233811,5282347b), -S(e04ce78e,b61966ca,ccaad985,376f23dc,7f4e5c22,7bbba119,a99911cc,b7fe0674,f5e3bee,98daaa6,1f45a2de,6e95e919,68f33ecf,4a71be8c,8fe5d925,92e43989), -S(e30ce87d,35b2a79b,ac96ede0,c3b632e5,506b5b86,22a0c483,c4a6038d,d846d191,d92e324c,c5d9a340,e69050bf,198063b5,e4fddd9c,a3e466b6,9fd00831,3eb13453)}, -{S(60b01067,25cf781d,e78ba725,40508697,3f2ff6ec,1511515,6e19384,1fddda7a,624ccf87,f0ec21b9,82efbc4,6d4db878,5d20fb8e,dfe663fc,46660bb7,98c96eb), -S(3e169750,b508233a,580f67da,55ddf909,a6bdedb7,7a7c8a6a,ca262be3,d6e77a93,d8e9c3e8,733dd591,722f7020,a361b2da,e6a4e71b,7001f1ca,2ac8c89c,1b56fcae), -S(a502b4a5,7f7da399,710ced24,5452f975,314b44c5,2c6c1625,3e4c183c,d53f18b1,814e29d1,67240f5f,2a7a406c,bc0e4980,69def56d,c7e1c16b,2a67a903,59400c37), -S(710d4fa6,d7e2ef8e,373a011d,f28b2a15,88e9810d,c1c74a69,3b3e5de6,4bbba781,c39916e4,231ac0bc,90d1c25f,6768b4a6,cb3efcc9,99b42dc1,27065953,bfb3b307), -S(9735e24d,98430f34,7dba7882,9de4888d,1557f650,ca2ae2a1,48394c36,9b4931ae,9b5e03ff,c52da7a,4119c4e0,c86aadc8,eb3172a5,fc430cb8,ac121fd3,d2949b02), -S(3eac990,f2b5a7b9,7ad3c31b,830576f3,ebe86f15,efc78a0e,ce51e592,190710aa,2e75c1c1,786110a9,785a21c4,d72576b0,9fcddea0,b1828f8b,4a7eb45f,8d0f7081), -S(a797ac71,b5c615ab,52e5341d,5420684a,7ed20dd6,b7cfd205,2ef23b45,7302d01d,32fdc8e5,eee8870e,6bd9ee55,821bf2d5,30798606,85f4c9ce,4534b4e1,525e782a), -S(e9b05915,1e029c34,7c30a260,138378e0,a609051c,33b2da36,3dce9dc4,19b2deb5,5494d79f,9edc31b3,9259c82c,14f6c757,be0159dd,c79a8797,95af6150,484d8683), -S(8ed4c8af,27fa4013,a9d9826e,becd79a1,30cb2014,96e583d2,e2d80eab,573a5eee,4bd35c5,cf78a79c,d5568968,fb1043b,c8cb021f,b5729faf,509a09d8,b82e10c2), -S(14230106,2f11cd2f,b0e8abe,5a76a7c4,2eb3f019,ab8503f3,afa0bab4,487a4928,480dbfeb,2b36a3d3,4cdfd029,dfe3a42d,6297724a,15be840b,ff197fa6,ef5f594a), -S(425fb125,e156d90c,31dea3da,6ce5f3f0,2d1d78d5,9ec17c65,e89c3817,d10df34e,2e2a12cb,d621042,8cc2ce77,df2ec8cc,ec1a8a8a,9a2a2a3d,b537f1b2,13ca871b), -S(b54496c9,57e6e359,88118db8,26be100b,affc546b,511aaa43,6be0f72b,2072d698,4174ec3,ab8c5709,581d797a,831c341b,131d94f4,25715984,7c6b95da,e42d6ac2), -S(edb85684,1b5c164e,eed9b5d5,740972d5,781922c,e9d365c1,24475785,2d4c6602,56eedd35,dbb97163,df4f95d2,dc106a63,114e3f44,1cfb2d74,c57a51f9,87eebfba), -S(de82cea,e7a0a2c0,32db9642,49b47662,201721ea,754aefd5,b304d7cc,ab3ab426,8f533e0,81b88901,ebcd8547,3ade77,776ccbe1,fb1d2ca7,b038c205,be8a915d), -S(7e74f42f,e8d3e772,43d11177,ed249ea7,2e87ec05,cfb5af22,2de3120f,22b8214,2978928f,ca85867e,c9563f6d,5e044fa4,2eb480f0,e2ca86ea,acacb1d6,66bfc426), -S(995857b7,8066f2b1,473eeacc,fadafb7f,36fdc5d9,1ab5fd0b,3ac55be3,91935876,631de25e,51831901,aaa62ca9,391ae54,7dda101f,26ac6fa7,3396f885,3b9fb916)}, -{S(a707efc4,89165c75,7edcea3c,ce729b44,91f04142,3fc6ea9a,704f52df,c8a0650,f2e7657c,6c618494,c01c5a90,d06b625b,c9416d63,f7b8f809,dda5076f,74fa2c92), -S(e670a33e,75e7d765,9dbc17ef,a0466808,3c57e661,975e8197,84ed85c6,838bdc7d,df5e73e7,4a1f7445,d140fc7c,eee1038d,333590d3,6626d5bd,bdf399e,9d9b1843), -S(751a8413,11be980a,5a884850,c9101021,393634c4,862d6806,2b1e6855,2fb42d9b,26a416ba,afadc235,425ce35f,d72e17b8,6d13228a,ac64f30b,5cab853c,1d80a1bf), -S(f044f2af,6d6842d5,946ad6df,43784921,47c45378,721d1e39,ccdbc033,eb0d07f9,68e474b7,e3b1a102,efecbe4a,a20134af,9f3ddcfc,45213188,744f7816,f381f942), -S(24208410,f23c4fd9,42fca91,94b5da3e,de46e511,7b0446f6,e92eae4d,bfadef52,b17efefc,ca0bb9a5,1544f8fc,15474328,84d79be4,bb7cc122,9aa5d66e,450c4849), -S(6aee88ee,18046ce,6399c111,2ed2e9d1,5ae30b0,663b75d6,a20baa10,57a0287f,44155fad,94ff97af,ff36d407,4f0273a5,adaefee4,e2c48bd5,bb1973fb,53d65d20), -S(b112113b,921501f6,208ace14,74cd923e,c4ed6cb1,1b1fbdf1,2786f43,6d2efb0d,d63f1ebb,f305ae31,2b0fe166,23a9cabc,b7c7b76,1e62c8a0,3eb2388b,5635cdb5), -S(74cc4471,707dd64c,bc0688c2,1d15d3e6,863adbcd,3b6a0a08,78556ed0,239ae027,43c03176,1fcf3c22,3a7e70ca,9e27690b,53f8b3d5,a3782461,6d41fdd0,7202ee6b), -S(a23a0d76,d391dadd,23e1654d,a654f0ff,eb8eb983,fb4162c9,a9956c12,fb77d5cb,66e0fc9d,311c830a,3a2229,fc4f82e7,43592058,536a9e7c,722a037f,f87f1363), -S(ea0c9f05,6e39f66b,5ab9f833,5c8e4655,f4ec160c,7accf824,aa1b5dbf,2fc1f8c2,cbffc05d,64ebfc35,7df2966d,a170fd7a,a5861376,f8d7f3ab,6c004671,e0dc812a), -S(ea4ba4c9,2c8b511a,9559c223,abb33c27,22cec491,e48cd519,74b3355f,4e42cb7,4a4db6d6,f426d463,4d6717e3,d3b6ab71,88ba832e,8a18a4e0,4f17a698,bae7a41b), -S(939ad0a1,a64da497,1a6ff2a0,a709c485,30d752ad,a954c8a,f632f969,95561aab,9a763429,5ffe700e,e36d1d65,f53ecbdb,92bca222,e5e2ccb1,55cf3a5f,c751149c), -S(f2548d26,ae82f5d4,38ac89c9,f8a5f974,4632ce26,8fa7f62,9446a19e,2f7c8cf2,7e584e28,b1590b83,31ae2228,81eb28d5,14ac4360,b60aff7c,d5061606,c5cf4014), -S(a4156ded,fa8d19ad,6471653b,42342986,74f4f87e,a9258de7,6ad54fa6,f3b986ef,ec77cd09,b77e2ca,c7b4ad0f,5e05004a,593cef18,6c57145b,3f9510a4,24ca5ab9), -S(12575248,e8aba15d,28a06860,b5a03e0a,942e33b7,e5099128,da2ee781,98333c51,bd3aa2df,cf99aa06,593a3c9a,3d22dee6,bdcbafd4,414a47bc,38916a19,7c2c2025), -S(b4262622,5bb55310,903f5f23,3b0591b9,adb2a909,e09cac82,503ee54a,64372572,997ac9a4,f1a21373,121255ca,9b622dec,2b4e7652,89731f03,37fe5d94,24402685)}, -{S(6efd8760,aed4f239,bd97a00,63794c4,ef14acc9,f5b94862,4c7f8b51,3ff35278,74acac29,694c5307,aa221b37,f2ea068a,a269fcd3,c6d85aaf,a8c8eac1,17d7f997), -S(da759133,159b8d93,d75c9aaf,616d87df,8f7dcebc,a518d4ca,da418b7e,39a264ee,8ad545ae,37548bc6,1702d08f,8de7a2c4,3b3392f2,3b44b186,fe1592e9,2f102577), -S(29bc8d55,faa61a53,643e8a7a,8f8c039c,bb808abb,8ec4a96,b294e4e7,a5a1fd2b,4a170217,7131ba3,275bb1bd,797809ce,cee979a1,d2f161b6,8b632622,2f92100a), -S(c15e640,b71ed510,37d92f02,7de2ffb6,3524e1c,208a6722,aadbffe5,977de2aa,b208b26b,eeeb6d6,1d783e21,35e71c04,1ab78e0f,96315560,d3729c6b,cf69c6f0), -S(9a738ad5,89e86d47,84abc74a,ad4c781f,72ad7fa4,91654392,510ae297,4464c1c0,234423bd,6b770214,7e157d65,e35cab77,62794253,c3e82487,8a4fe726,6105ad55), -S(3692b32a,5be3acc5,3320e434,42c8d1b3,235d0635,49a493e2,e4a33b49,f02f5504,ac61c2ce,38ac1b0e,7b3c5d80,ce988759,18e9ff5d,669f61cb,b285ad07,6d436ee7), -S(dd501ea1,3aaa02ce,619171dd,4270fda,aa164f14,c90302c0,5a3e10c5,bcafaf5f,20ba19c0,8561667b,d24c59a5,a812fb32,972f9231,19a4d42d,48aca05d,9fdfb61e), -S(f7e3ec26,257636ee,74eb2c22,dc9da3d1,4d6cd511,a6c34d18,a59e3d52,b2099502,a2a302d3,50790316,f99cd37,66e61ea4,8b9b3a92,eab54f08,dbd6a061,5f495eb5), -S(281dac89,3afdc45f,4dba86a3,fc5b863a,23f55d97,e49137da,c7a31f64,a0621a04,12f9a757,c8ebf05c,8bf34270,77c6d2fa,852aee99,af3d4ff0,9c6522d7,5becb9b6), -S(8de33df6,91ab87b2,9e36c69,687cc788,dbe100bc,8be07786,892aae4,e44d5834,1a9c323d,65aca9dc,8a11b116,4fb2ad88,b8625f61,72efdcab,88da47e0,7cc74bd1), -S(f2b7d303,6342168d,75c1ab90,c7045095,d8f415cc,96a86154,97425cbd,e4067750,ebd266e0,7a10d930,80241d0a,218eb94d,51596e36,953ae60c,25fff023,25920883), -S(8148dcc3,da9ce438,7edd33f,484f6bc3,6ebf7b2b,5d5c88af,c22542f8,5c943a95,591a62f9,9796dd71,cb18f64a,8e30d6e,9ab8336b,e9c3a684,ecf891c0,3c6e836a), -S(ff688510,eccb5b50,957de634,e4324f21,5cadab7b,93bf0dc5,ce94736e,a93cde8a,37d46d44,e61fc958,6b0da8ac,2023bcf5,75f8a9c7,9d30c993,e3d9a650,764e1ce), -S(eeec9568,1a66969a,e524bd76,580efde7,99302202,16aa7549,d39a98b2,59d717e1,64c4db73,487b23fd,ab74b50e,53fc8d1d,336db703,444b5844,b0d8756b,b84c289c), -S(3b2616e9,b51808ef,430e714b,ceb9a747,aed9e31a,a9caf6c3,d57c1565,cd9b7f88,e6b4bdaa,aa1ea551,4af2705c,47f07417,b2a03bef,2b406760,e86765f7,23cb0438), -S(5f0eef38,c87db43f,6498709d,48c445a1,ac50b40d,f882ecb9,414a56e2,ec927ad0,8197f585,73b0c534,49c04d6a,b0baca10,3c97d9c3,9a61dafd,fc793c5f,df7104af)}, -{S(2def7e67,7906cf3f,3677e7b6,1b0a8f8,985fbd9b,23265ea7,18a5c16e,139f0a8,650a89bb,df8c8326,d364fae7,558de827,a529780c,9b7bf8f1,c6925632,7c59c74c), -S(170634ad,de4863bb,3090218e,543c310e,9bef094e,94003fb7,5f89b076,757f8900,b708e4e9,cdb53954,2bd573f6,eee4774b,ad2cd18a,ab0b0157,dd1d3aa3,aff70dd4), -S(caf1623e,21907368,7d3a686a,7d48f9b9,953fda37,3f68ceee,66b5647c,ba9ac0c8,95ec09e2,533a173e,1773b047,a0702977,3167a96c,c7a2bb42,74ecfd4,9b1b7948), -S(dd21377b,234e31e2,7a42e856,305186d6,33eda53e,5bdfb93b,f83159ab,9cd37bf2,27a40d9d,9bb0437c,c079c24e,e3a8a10b,c54c8af7,6dda2e35,ab61e260,ddf6feaf), -S(5d6d3e69,3865d2b8,4c0061c8,fc85da28,edd6ab37,bb6bc5d,eaef0d,6ed7d0a8,bb15835f,e6074d1d,c05e4840,a22532af,b33a1131,80073cce,17b77822,33dde5ce), -S(3df62006,31fbdf0d,8ae7d924,370927ca,f27587a0,d7bce798,e6556a8c,62f108ed,c4aa6712,405c44e9,389e0a03,952ce263,c073b849,ec66cb7,b9e203e4,12017771), -S(d49653b7,639eeba7,e9d82b1a,61b0e1c5,1363337c,eed06916,47f81c25,b2f71e6b,f1411513,77e6553b,66221284,3f390c4d,ef25b316,e1123b19,a5f77c97,b4559e79), -S(fb4a40b9,77153349,3d316d3f,2688f6ac,32b63e35,6f8fcc17,ca1a9008,b9a90745,d49d6d04,ba60238,5cca34c2,6e5e3ea2,8396a459,c9f54478,f1e93e94,fd3545e4), -S(2b5f9b4,512e7676,82d7f93b,39027d9c,4d2788c4,b587dd66,8e7e2a49,2d1fa3ad,507b76a7,33682d56,6a2773f5,c3cda342,2152e9c4,9c204aa,bd015dc3,9c9469f6), -S(55e1a77,2c3406b7,b300e7de,d35ff44d,76fbb312,7859c80f,841bd730,45c0c006,f7f2b9f4,7c2ec8d,9b476229,ec773a2d,7316b391,8f98d540,e110d196,58cdd0c3), -S(269a6ad,e6e25392,21f59cd,10456fe1,b5e3a756,1e13e578,3cc6b7c6,ef145ac,3827d2be,94cde1f,ded8306a,6619b933,ac2515cb,45cffd75,267caff4,1e76d6ca), -S(e48e1e7,87d48c62,8e85040e,2c836be9,cfb20d10,51a251cc,9e46b589,485a29f8,aee94719,b64713a1,ff2f2402,ec6a19c1,4df12f40,6214c49a,d9b00234,4325730c), -S(7612f9e,691cd23,701a213,79582527,d658be1f,526c220e,da6fc536,b3f7780d,a21538ee,e80268c9,ab6dbe6d,1890c4f2,99aa8dd9,82e9978c,b6ea37ed,53308c10), -S(34761add,2f2dfb4a,6adf1f0,81aff3c5,1faef7cb,bc1a989f,3e23afba,288c11ef,50c8b3b2,9424d319,8d55c10,3976f312,bfa480ee,9e93caf4,b75fa97e,1517d3a1), -S(8e57bcd4,5c8e9789,624ad4b3,8a9d5be8,bcac139e,a0abc310,a1c272b2,35942e69,8daf7fa3,43dd401b,c8aef9d9,c102b577,28535818,3e379de4,5e5ce268,e9f9b548), -S(b9c35f36,2b93a8fd,21c9307,91c659b,270fbe0c,965c8de8,b5b45ff1,e4c8eadb,2e506d1f,a9fdb177,e0a818d,b40d8f67,2b5ef2ab,72f051e,8f6eee9b,fc74b9e8)}, -{S(9705d56f,f75c7d2c,bacc47a4,a6cf8b10,300c688c,fdbd1b1,528f41b9,652d49fa,c53f7f11,896f2edb,fc957dd7,2cc90856,c5df9d86,43e42489,70182843,84201b98), -S(1fb0f8f5,ce10e878,abf40518,116bbc18,ee77a22,f701108e,a8c4f9f,f6562080,8f761286,34089abe,b48bae3b,882019c0,9bcc5386,20fa98dd,4a3710a1,e4e9bb46), -S(4a807b29,3b312ca6,acb43f49,6436b137,36748bc,15c48dcb,7dd35e75,fd2a5668,6115f059,e21f7257,c8888959,d1401db4,c77a0086,34cc2206,e8a8d4ba,1540def8), -S(288ab400,5444930c,15410269,9757d7fe,b8410241,38c45db6,d6a628c8,e0100ad6,bed94f18,78f4b61b,c0b557d3,cecd946a,f9d105d7,a298cb73,fccbddd2,4210cf48), -S(22a7d3c8,85001932,985e9543,1e470770,f664ffd8,e4593aca,7c93a7d0,9fe01b93,65172aa0,9a61749d,d0695269,4a15696a,947c8b37,7ab24041,d76aa7c8,3055290), -S(4470823b,bbf22c97,7602d166,dc895df0,a562a732,f905ea78,416a74a1,eb0f35fd,1b1eeff,736ef902,aff3980c,36b47ce0,c7611f5f,cb83658f,7c5bc15b,c6e35414), -S(bf345a75,c16ba113,a4255ce6,cd485235,d7b71b8c,11fd0d49,1bff369e,240aaaa,8a8b2999,e06ffa8d,89932713,b1bb5c5,6837bf51,aea390ba,9579f2e5,566e7c1e), -S(9ca5d558,2737e890,f9a7dbaf,d921177f,459d791d,21f9993c,481594fe,b9aa7112,808fbe3f,cc3e80d3,f6e2703,f55b32ad,cc1ee8e9,6fdd0250,d7373b15,83918a6), -S(4d3b878d,ac7d1878,a2cb8ef1,29c488f,59f26f1c,d56d5476,7b008e47,eb7a293,ea8ade6,a46ce8f9,4602d631,e0147981,3422eb50,e87cddd6,792a1ee6,2c338f40), -S(2bef9f5c,accfea49,697aac36,24c7db8a,62f03620,109f1cce,fc46af89,25489a69,b39a88a0,d7d59b29,b7773984,53e6eb2f,7b557171,20de3625,a917853a,ed1f8d83), -S(74a0d8dc,415a228f,3bfa9533,e7d4e544,f03551c4,d55b0d2f,fd524d17,835c3132,d3c7c720,c44b1742,49c2d9ad,3e9c5f9c,eb174ba1,bcecab7b,5816cba9,9057b5c3), -S(33b23068,27e030cf,f0673254,ee13b94e,6d7377d5,fb8c9a83,ed50e9eb,4ac6d5f3,b0116426,ca9fc25c,a4f9834d,6d8974da,1571a54e,1f507696,879ecac2,5f23b095), -S(a45a4cb8,24d90134,5ea541f0,6896387a,12711d70,6f07a850,69478780,2e49a474,bb236a74,96161e43,f708abb8,80e3d0a7,a6354a33,cb760bcc,593bc8c8,7c8f433), -S(fba31e01,2f38c223,3750fb25,85c2c33,4fe3afb0,36b17fed,5e8d513d,552dc2b7,d6d8f5c2,745b2c90,d5c201f5,524f2b0d,49020ae2,4eca8e21,b95cebdf,af25e5c6), -S(8a5bf15f,e026e897,190ee896,f79927a8,a8658d05,f9a0f6a6,79ac8971,4ca26fbb,639849f2,41d99df9,d217d702,4e6c5bf2,9e44b7ad,63e0b091,bd235d45,4cb07ebc), -S(43daf5b8,4f1706fa,cdbfab46,e4ee5188,b8697efe,f6d1274a,77af6bf7,b1ae23f7,d2fae1e8,721553b7,e63130aa,76f61e96,a34e60bc,fe7bdb8d,6879a39e,db08d8a0)}, -{S(5b27aec1,c644f0a9,ba7f6486,9a960ea6,28343ab,da3feab2,4a2d6add,754866a2,3d1f365c,2aee6c1e,ab2f1879,429b6275,5d1bac85,2998ef25,8a914bfc,ca280b43), -S(472e2d82,220169b4,e249b18b,ee3d0188,70b91ff8,77fa9f64,9a23ca43,a5aa9271,908226fc,2704e162,c96297f7,6af76d80,32b7845e,9b998466,cd106e37,1a61feb1), -S(e9d0d14b,3cdd4531,f8125e83,dc3ddfda,18d64976,bb4521ae,83a9d9aa,8609b431,e1f950aa,821f586a,91988d6e,e3ca4db1,1574041d,140c64,2ba9a1ad,cd1c52ea), -S(e47190c1,f5fa4910,6160e301,69e8a087,76a9e996,aebef7d8,2b1d7248,7d38ac4d,50abab42,dea32fa5,af0d65cb,3dd950f1,d2e54bda,47d990ee,9fd9cf49,cc552d1b), -S(dd7cc010,b8c93c99,84c19b2,37aa2b6f,1e51c765,7b93bb9e,e4d0ea60,2d6dae8b,9f2773e8,15aa182d,f6ee5e70,8af9e8cc,6ed5f82b,994633b5,545ff889,c5503e5e), -S(6e4656b5,aa8f321d,80a46a7e,721ab22d,f5216f9b,602aa74a,84de050b,a3851d8d,170a272e,f646cd5b,e3c1d9d,14e19601,2f7b140a,136b509e,580c4800,7c0fa08), -S(d0cccf87,813d74c1,e0ef5315,2a2e82a8,9d6729bb,23c8f450,d1e5af64,4b7f6341,b5c903e9,dc51b73b,5cfaed20,b9986f80,b19aed65,d11e624c,53162315,2ab2cb5e), -S(87f7d90e,8f519af2,34262929,c4801bdb,fe472f0e,3eb746a0,cfdde906,1697a540,36b97cec,b6a1766d,b349034e,a980f0d3,cc653b,5ae732f3,e9868d37,1343db0f), -S(feacbc45,43a59a7a,3fe37bdf,5f05885a,a38cc3ae,68e423d9,e90da9df,15569f45,f1aaa0e4,230faf54,c1a394c4,fab80639,184d42bd,62fe74fa,d2b9d8de,2bd13779), -S(db4aad1a,7d5b51f4,be47fe0a,d8b14711,e03e0283,3076470e,7291f310,bb88b65,51b5928e,9e6adc38,be8e5e7f,a93336ea,4ae1f65d,de69b73c,62e04384,fcca96d2), -S(f6a6bd4d,3f763afc,721fd2d9,ed42d34f,df38bc9,4fec069a,8f8aeb76,8b23f74b,d513f993,f97d6fcc,9a7fcd74,458dc00,437fb611,b7e09b9e,a9e85c93,1facecb7), -S(982457c5,6c22522d,e0d10fa0,64a0f8e1,52fe9924,6f20a794,81df8fac,8fc08ab7,2e080dde,a66a3e43,af44f9ee,bbb9962f,16110b33,b0e9d83e,38333aaf,89be29c6), -S(2cd27cb8,d3646f0d,a549cf0e,94e70cbd,c40082df,b4a04456,47579397,e3e12d91,c17377cb,e2ab57d1,1d6c5cbd,c5fef865,440dd8eb,cb5cec53,124872dc,a49409e1), -S(6f34f416,2a190923,8a2b5561,54a056e4,9549d6f1,72929ab4,fb49175,b7da0cb1,2a0ff98f,98422e19,e394f868,7f2eb9d6,dbf7129c,c98df378,31895799,445a5211), -S(3190285d,d898dd64,770729cf,25f59339,eee3971f,16b08450,a87c9916,efb1adca,5423d919,1eb4bf71,fa55c153,161ec8a0,6f5930bc,17ad25f9,39f229d9,8af5382d), -S(3a150c48,d4c56e7e,9d910864,29b43219,9c95881a,d481e0d1,59aaee93,b19ceb72,290d1c34,f241d3b4,f7bcd618,f585578e,7d17a89b,9be52eea,41020f37,e1f521f2)}, -{S(53512a21,4a659914,82cc157f,da02880f,7c4ff9e6,47a93136,c1e55725,9ce7132f,3ccac75b,13cc40fa,5ab2e017,80f55f2e,b8e6a7e7,22b2e6b1,13a28316,b3c99d3), -S(941512ff,9ddbed5,13d60b50,1f3425e5,d210fab7,f30b2ffd,db6bb10d,b102cfa4,ce038b23,257413b9,f3bb957e,43b25747,49fdb5c7,a975667c,72de28a4,46cf4572), -S(cc2210ec,ee7d9560,753ef5c9,1ff9590,230ea13d,8416d73e,47332720,ecc63f9e,cc800501,dadde2a4,152ff67f,9d430ed8,3ae15e7a,e5bb493f,95d41167,327eea9e), -S(384629d5,414c9230,60077a1d,e52fb3ee,ed883b32,46d6f21f,e18285c9,2b1562ab,9aa889f0,f0bb4632,7ff7ffab,beb7eb30,d8730560,edc85521,425d7f6b,372b2272), -S(1ff9dac3,a65aafa9,8693a45,3ac3ee51,915cf4ea,1651a456,b1a03aa0,250e9d97,9245a361,a7831503,be192d77,2f592cb1,f9129287,9ccfc15f,494eb437,9edafcbb), -S(448f1c1,db9f6274,e49511a6,26ad249,e2c0b808,1939a383,609bdabc,dd94ade5,6c142261,2a8a6cf4,1d4bf7ac,8e6e7c87,2dc33b72,a87ef595,e9e0ba72,c68fecb7), -S(c6b5006e,8fabf0c,d3e72c2b,45368021,b6e53820,59fcbca0,3da03181,b72e6eb7,c579f919,cb4bb266,a527a446,80dc9300,629ac1b7,4a5ed005,f5c455ee,bfd5aea7), -S(f4d156ae,da9f6e55,f455080d,35fc507a,bcd2b23f,de6d893b,5ba039db,27493953,7d45e992,a2d4b8cc,41c2849c,34e785b4,8fdb39c2,e715328e,9f7690a7,31bb5e66), -S(bd72705e,9d2a78f5,6d39be16,b1aae55,da527752,c3ada8ad,3f715d37,7e3784e4,5b5f856,7559fc2d,b7088120,9e71be70,db2a4404,e9076084,7f4d7bd4,e2aeb3c7), -S(9c6bce85,191030ff,c60b2b07,c8187f79,249fc982,47508c9f,2797da3,c21c06fb,dd7be1e8,86931a24,925e899b,347a81cd,85eb17bc,b73f9cae,1097935b,462d0937), -S(1a357743,84feeda0,405e9e16,28657462,218f4b2a,7921ed05,dccabcc6,6fe5aeb9,8e44029f,7b28b880,9640e5c6,60131513,e283ef66,983770ce,686aa706,81b1aaa4), -S(d1908dd7,f1b5eaa2,a1f9f066,683db7,b3ce644f,77a839f1,488c90a1,e372f18f,a221de7c,15bf27f4,ff71f3ee,fb068463,79d09aa,3b6e8b82,bbe9eac6,8c00738), -S(b7be7d12,1e964dda,820fb389,2f9e99aa,36e8dc2e,7498ea80,34af4397,ffb82b91,88813b9e,c333a6c4,78b627fa,afe0a657,dcf449ce,3a5adaa5,662a81b0,68b8f5ea), -S(6a66cc8d,27ad7843,ea1a9b74,373e413a,1b3b23a5,fd25a58d,6b75a231,b97538e7,afb5aa7f,f3cbdd2c,a4dc9694,e56141d1,85550285,8dd6c89c,7938be2c,a2856c4), -S(2b1e7d33,b7d1ff91,ac03cd10,f3756e9a,d39d358f,2f63c2fc,e89df693,5e16d3e,d42588b3,d1b1fdee,b860b4aa,d0ded901,bae1bb87,681fc257,e843ab8a,76280692), -S(f7745d72,7b747b4,e9d6e7c7,1242705d,140ed4c4,d43d28cf,a0a8afc5,37ac932c,f640180b,6b8b0eb,c94c8931,2f897e5d,1ecf427d,7c86d2d0,772ed63d,f4cc3444)}, -{S(534e9d8,bea140bb,4970b516,c42f2677,dc413f42,9b7c56de,e261f60d,ec68f9d8,e55aff90,1098b0a9,ea377acd,b62dc479,da109514,2654107a,28c68e9f,73b1cba), -S(f0e363fc,4c8761ad,bf4245e2,b151a7d4,335c9856,bdb9fb2c,1e53fc76,28a9a69b,4629a699,3f8753b8,6d2190f6,505e009f,6fe56739,9dc77507,a1cd4cb8,920b0ced), -S(a28116fc,5e3541e8,8ffe043,160a97ca,b1d6e898,b6a3acf4,d150860e,5bb6a1c2,e43aec5d,22795bcf,7979e260,de7da3fc,46023dfe,8db4851c,165a2fb3,47c204e8), -S(cf6eca04,328af9f8,e461b6e8,9251f94b,3156a63b,d440d6c2,b6dee5c8,7ead5b29,1dcf90f5,9bcd5c0f,362de1f6,1b7a93d0,6ab64659,7f77bf94,b8bed972,9f096f2d), -S(44bcd74b,2cdc4b13,f48e3cbf,b005bf74,bd114fe0,5c2661ad,46642f8,7e952fd3,8873b17b,67848110,fd200c6c,bba0782,34dadccd,70dd83bd,cafbca31,df373440), -S(2dd5eaba,e7cbff44,d2e56df0,14fe3577,efbe6df3,57b870ca,fcf5bfa3,78d35cf3,6922806a,4ed044eb,d711f510,e7c5c846,ce892189,ba4479d3,7ee95a8a,11983756), -S(98294f63,5eac3fdf,f8e07f53,d24e650f,2e470b0,6be9193f,1463f1ba,c37bcf5d,6a03ece,4f397658,f232bde5,71f33a4b,a8058641,e301c99f,e1df978c,74236a47), -S(c68b7c67,36003c06,d29ed03b,2faedf60,5ef705f0,f1172166,b63bdcc5,437bcf0f,a62dfd76,c1df5d72,680eaf7d,51359a63,82ce005d,fac432e0,672f63cb,cc4367aa), -S(10da4eb6,72c088be,d2d4a28e,3e48efb5,f4a456be,b501183a,816615cc,f23b598a,ab798e69,26e55eb,c0435828,a8006356,5cc6ea48,892f748a,a6ed1685,36a3bec7), -S(24363000,a821cc76,4bb2c552,3c37457,9462263e,df791598,cf7ab8f0,89178ea1,c6d07d19,d53ffbdd,f367f46a,6fffd5ac,e2236f63,26fb18cb,3a7d543b,9f193b01), -S(459ff583,3501bc72,13c135c9,be63ef4b,fe99b731,917dd475,b356fd72,21705c8d,9c3ef5e7,4483e1a7,42316df0,9f313a10,17858e7f,ef432763,df139b4c,548aa325), -S(43e3d2c8,44b6ec8b,b5ffc06b,d2a48ad4,39893fc6,a9748cce,e55adc76,d616b503,62efde43,b6525e9d,6de6a7f9,8831e194,9296aeb,7ffe715b,4a064166,c18144f2), -S(8d6eb1ec,5abe1d6,2ecf6a0c,e1283a22,e1259cd9,4ae96c8b,1fa03521,8439f798,9b7e03f,f50082eb,38098a19,c417c4b2,74432e47,79faa37a,2ed5e43f,daaed45), -S(fbaf2899,4a9ebe2f,cbd854ca,d1beddc6,7ea94f73,321f3006,7d75b327,bf25b65f,184a40f0,777c4a8c,6614f8a4,d5ffd514,3215c0ea,9caef82d,c20285e0,4477cd77), -S(c58395d4,623cf0cf,8c7b0abf,686f71f8,6c0b1977,44ddd642,7a1c05f0,1e9f938d,1d8eef66,7d5b8ecd,af794b8f,2bd30b17,966de31d,83ba46e9,73fb4a2b,914b06bd), -S(40c74e1f,f01ae64d,85f958de,6d1faf97,6169b00f,aef64c9f,23c5cdba,5e17d294,b21a6ec2,1b409a69,f8f6987c,1b1705f2,47781843,73ae5695,14b46951,48448e6e)}, -{S(dd7503a2,a3e15e7,39eb9b1f,856d6e33,be4890b2,f40cfea8,1bdf516c,b942731,ca9cd04e,c3789ab4,5088b819,953e08a0,b8adb8b,b2b6f7c8,661a2d3b,83a54c77), -S(a1df11b5,743dccf0,90fba9af,bc699089,bc923e16,96a7841e,5dd338dc,a8aea428,49a697c0,45f6232c,d0d7d5d9,c7e33701,758e6a12,9a9a50d1,f173beb4,5b9b601a), -S(fd7b2a1f,cce0c2de,e11c9f85,c245f43,1b9aed6f,a542d401,4677236f,4381b927,77bc8fa0,5639307c,463fd419,a784dcdd,be1bed1b,be42c315,dcbf9d24,a5c7dc1b), -S(7962833,c1cad761,fc1ecf60,62ab6f9b,b11cf765,2c5c2aa9,e4db18c0,544ec275,7a8bb3e8,209f1876,d3452f6f,40c3cab9,f7166dca,160e0f51,afc35302,75740cc1), -S(bc8ea787,2f386ed9,24197d6f,cde66dad,43b1bc,390ea517,ade69780,beaf444c,12f31c87,9b69c7a3,bed748db,6c0dc465,3a0c1cfa,e4cc7b97,c00abbef,1b86fdeb), -S(eb4a5a9,5957f070,73fd04fb,4f1d9403,ade11ac6,62f2db35,23a3c16e,4a34c040,277d8694,e598912d,7b1266f0,493d9141,febe0f46,bb69eb24,c8be701d,9e8c6f74), -S(391bb04b,b3b924d4,bc548329,64368cbd,7cbc1a79,c3410cf6,63565b9e,e62c5d44,951554f5,fc6b8ff6,40a0aa39,39929e9,41db1056,d05bf87b,ded15a32,f06197f0), -S(4b6a608d,baa71d6a,e20f543,f4a5041c,a06ab5a8,cfe0b331,6a6702b8,46212ea1,f3c31e22,bb3a2f28,bf1f0594,4f798603,107cb301,6bca7ea,a8b863b,5f85954e), -S(a560f348,ba8b5a1e,885158c2,a4e94464,1bbc59f,3fbf4851,3216f4a6,cfbdf8ae,98568f29,eccead17,257e558b,b3835772,5af94f69,42b943a4,36a95824,b92c529), -S(2356a93f,c5cd70f5,f5fde88e,6744efe3,d0d713f0,31f228a5,1cbe2c3a,4baf7107,59adb751,7111910f,9e1a690,139b10d6,f30c311a,4ab6b82e,d1ba7077,3a4994eb), -S(f7fefa64,ad63903e,66705d88,d5df718f,59b7e9e1,f9180d21,647b2a73,6e2f1d6,30b5d8fe,5393f9f3,b68dde98,1adfc77c,cb3953f6,7fbb3445,52fafe72,b9453532), -S(73d5d8d0,95d6c533,60914bcf,5b279c5f,f20145e4,e0ba1ee9,468c2edc,b59ee4e9,56df32f6,dad0b462,487d2b25,79dc14d8,34ef8705,d5efa77f,1f371bb7,641ff145), -S(a1d772f9,4377b24,c98933e8,47dcb51f,7a982940,d205e4e3,c31c2cad,9b90e410,617a72d2,ea1b82b5,775f13fa,1086eb6,2827572f,f6182101,3cfe60d2,7df6aadf), -S(28725dfa,ad66c6af,5f980f25,653ea5d5,116fcc37,be615037,48d71033,ffd322c0,67f3cd88,1ba30b09,3bbc1a25,34826f06,90b149e3,964e313d,e3706f60,31dd6c0a), -S(38573246,ddba2c47,a9d85ac8,c3a13ec8,4133da2a,cf6434ed,98acf5a6,84d89ba,e97fde8e,6b2c1395,a9f242a6,8fa989c9,5dabd2f2,ab830949,4c100a1e,fab317cb), -S(e69ebcca,426dc9cb,474c5f03,5b6e6245,cb18fad5,2d990ad9,6d29ea8b,e032c220,322ac73b,d7c6a5b,89f3926b,82578f6e,a6fc83de,a11da204,e15bad7b,51ab70a7)}, -{S(c8116b60,1f8d72c6,24957215,46b844f6,bf6bae0b,7575a77,f1f6c6c2,5524fa2b,b7477ca6,de2004df,34882c65,3a46821b,53372f13,ed822cbf,40c20bd9,ddd1d6bd), -S(db0d3761,c6b76d0f,4b3f6423,daa1acef,19d01f9d,c6230840,c4ef120,9e4f80e7,2ea359b1,f19e5d6c,e8360c04,12ca60b7,a43939ca,36fc873a,7a80a884,90d3d359), -S(a4539230,a9c0b4ff,65e2a8e6,47490c1e,752706bc,ece59a96,f2581cab,1b430bf2,9c80b433,f87ca7b0,3662b22d,73a99e91,a8c63fa4,9fd3b8b1,b17d669d,aaa9604), -S(a77cbd99,8019c652,7ad38d8,f8be3ce2,dfaeda98,d378cc3b,7f86e291,15a56adf,3d5ef26b,d797de9,6f8a0d9e,d14a5209,ffe8964d,2bb768ce,bc0c3422,85eacf77), -S(2b99d5fa,a416b572,c796d92a,ba9ad7d4,5b020fae,95aee14d,f114489d,cdbff30,4b89c70a,74e07b43,cbf503d8,86954759,9c3862ca,32bf168e,20a913c7,4fdfd266), -S(a007a8e7,a60dd06,6d11f1e7,4912eb12,91908cd9,a3fe6a8f,53393040,f9c6fa52,24b8c6a0,6160c947,61645355,ea365434,323c1d9b,2858f650,5526497b,d148873), -S(7f3f4e9,24fba80b,702f3252,64186077,2879a2e0,cf86c721,cb97c5a,cc1403f0,fa6c055a,4eaa3651,3746385e,c69170f,f3a1ce56,d9c06440,e49bca94,e97220db), -S(70f9b6fb,c3c4a20e,69c75791,2289936,4da614a4,dd49002b,291767cc,304309d0,5becf8f7,3c414163,6aecfb98,161da5a1,ddb08885,545d946e,c4f2f39d,66b15165), -S(ffd34a18,cb7a72a9,19b97602,2110dd29,484b3fbe,84ee3c9,46b370,f710d86c,b03c2cf3,84b6502e,f519c55,b40f0037,cab3e513,2304243b,f8e7117,cb4d4bdf), -S(ef8bb54c,c1fb8d0d,7be9f5c6,85dcc465,9ce9d874,bb1f860d,60bd0954,d751cf7a,79216699,1efe79ee,bd5232c,687af3ee,854c85f0,cc61888e,c2981689,b03060fb), -S(d1cb47ca,c6b4609b,3e7e8f00,76519a77,9d8f4494,baada6bb,43d3a034,5c3e93b5,a8bfd148,a40922ce,1a2a3383,ce323c5,32041c5b,f89917d8,41c79867,d6efdf49), -S(ed2c9d96,38443a38,9a00241e,ce1edea5,4ba0561d,a084d166,9054b486,89bcaf5c,f81239d9,ad7a2fe4,5a9ba8da,9aa306c0,3d22d79c,c80f7953,53c13a90,c81d0505), -S(d7174d31,4126e219,817fa00d,140990dd,43cbebb6,81c45d9f,c5e0dead,d8135ef1,38093e9a,ba7a7223,6a5e8a8,6ad4ee9a,a5cbd614,da2543ea,34021578,8938fcdc), -S(41dbba9a,b52c3f9,98ecc1cd,aea6a093,ce702077,8e5ac6a8,91be5bb5,f73cb8,5ef35b31,829851df,7c3a2304,5777b6e6,89e79e3a,a06c7b73,f3bd47dc,fff8dc99), -S(f9ab0480,d24efbbc,26f1d2f,f09db463,f3d50993,af39d822,85efa32,97c73b6c,40a5a11c,c647b069,4536d4c,e154a58a,db0cbaef,77b24591,bb39020b,ff9c72ee), -S(e59e905e,fe97f343,7bc6ef6f,b8e06ed4,1eeb5666,c3bf72f8,5fcd3fe6,d0f68928,28faea3,4fd42596,c3880cf2,74987c2f,2f228442,5666ebdb,e357d9f5,e8886c4c)}, -{S(e7ff8d5c,83bd5846,5c967b5,37ac0f36,b9ffe9d2,fc7531e,ef183cb1,7369c066,9a9c3c4b,e482031b,f6dc69fa,843ea90e,de165479,26ba201b,5f05b00a,dbcc30a8), -S(92932066,93f2280,8bc088eb,8b50cf83,93c0a33f,5149976d,27b837b1,2e769b6a,7d86f6a,418b04f5,2d01b933,428d1ec3,ce62d349,693d267f,48cb005b,1499aa0d), -S(10e4d4cc,b8efba85,37dcb831,c6badf34,85a3184d,b571fa59,55e3ed98,80fa8e63,270a80d8,ed085ced,f4dcac74,481a75b0,b42775bd,9a844a9e,e2de9be3,92781c96), -S(763ae8ea,212d756,ec3e6a55,9ea9575f,ee67ca83,9e61e61a,99315231,304eb9e8,4e1d3eb9,d1a49677,6d1619af,8acc9b35,c6135fd6,bf82845,5eb55a73,6137d0c0), -S(76ff82ef,27ad0b4c,157d0b24,d89aaed3,ea654fb5,e0492304,ab02b214,81eb7574,701384fe,e57f56cf,62930a9a,e1b5977,8071d8c1,c07746e1,b1b6e94b,1cece9e0), -S(fca9c2e,b84ac3d7,7a32396f,a0a1763f,7483aef7,2b171608,e34bf24f,2c0e3ba5,8678a539,d5b12652,78f2feff,bac321a4,ce2acaa3,d0983d29,27e9e90,1d46dede), -S(a75ffbd9,4ccc3e8c,93a54e06,e4b5fb2f,4410db28,b980283a,51ce071e,83572733,b0151288,ec977854,aaff4ae1,18b65289,ef356df5,1beabbd5,77054a42,da145fb9), -S(178095a7,416460bc,c42fd250,472e6d1e,3db37a73,5bdc0012,e52c4ca8,cf65d4bd,b9c37e8c,a7cce01c,9adeadd5,15759ece,60776e72,992b7c9a,c23b24a1,adde790c), -S(8969a958,1ebfb858,cac5b7f4,88c56e0a,966947d1,adaae934,6db4041f,4f8823a1,5c1ce169,fa336433,1aa72a02,e543cf69,9ebdbfae,2cc00ec0,f83d6f09,8e78fe3d), -S(a7e28d50,eb9a52e9,e18edd59,6b291fce,7024e915,e7ab8119,2cf4642f,7c54d8a8,e35bb3fb,d67ec191,b3a752f0,58428c1e,a92c2c8b,7e84223,363b15ce,28435dbf), -S(7a6542c5,2560ba89,ece8a01d,e9c9acb,e534ea36,48186e75,3bd214d4,cc8826b9,eb9a65b5,e5d3cfef,50f0876c,c9277014,af67ef01,b21fe8f7,13aa8661,f6be4c9d), -S(459ff50,f27af905,a415ed85,26564031,8e3a8b5f,11aa25b8,b0c27cbe,83448bf1,4d86fd56,e083330b,9053b2fc,88cf532d,7672912b,db7c2429,34c8be24,40be22a7), -S(e28b9feb,67173d65,78a8e38d,fdfa8a8,e71bb840,b1d97046,456a7aba,b1bdb4ae,9c8712b5,d2d7e596,d42e088b,801cf20b,7f6dba46,8438032b,c4b25d4,dfc5daf3), -S(3c313413,6261f337,e5b2b81a,6641acf3,4458c82b,524b88ab,844387a8,6acde303,c1948e72,3e2481f5,f0898fed,9c1def3f,8f88f0f1,b58cbc9c,69992a09,4fdf128e), -S(77774800,3a50c6fe,65a5772d,1e01b8be,d8acdfa7,da1cc233,ebe2620d,11b570cf,96522ec4,23bd6dbf,45969c79,15494f6f,bc4a41f8,b99dd400,b7f9b59b,8b45e279), -S(f491ac54,4678dc86,5ce81d7,60465bb3,791c9c38,a7f98016,3de914ab,4f488f23,9e62efde,f5eee54a,ab244604,a3357af2,729e8252,a04f006b,f0d61d7f,5f13437)}, -{S(d8f08d18,ece61855,5b06a3b5,ac8e7cf,a6375446,cbc7c8db,ad924f78,69e7f00e,46a91d23,910957eb,db830624,73839954,2cea0570,2f67a09d,d7d19217,646606e), -S(b1238187,25e216c6,631d4b98,d8d3c743,753529f2,8e02bf80,d1e9119a,f92d8b50,487f7171,60b8993f,a90edd77,3f7c1026,b5961881,895ad804,51b66d8b,d300e0f5), -S(b2ff5766,4b8079c6,3c5651d,e0b2fd47,80d1a18c,60d78c24,b2c57809,9429a552,c7ad3672,6d7e0618,eb506d65,c055a7ff,cba848f4,9b69dcc9,c02a85d1,5dd8ef90), -S(901272b2,bbabc0b6,12dba006,1d4e8ffb,e177c070,43f6ec6,2b437bff,9970685c,ad7c1fae,4b80cd30,c45516ca,e3433e8a,2d3272a5,79e4335c,22e452a1,845326a5), -S(1d5740ed,37452eb5,c645f8e3,cbc4969e,a6f419a,fc0e4662,8b017587,a6871ad0,c7a6436e,b66d164a,685a1b96,3387519f,b4179d38,40f2be68,28c9cd1f,8780bb86), -S(21f0eead,ca362d40,1abae7b9,2edccf19,70bd8c0c,35ffdc2,76820d7c,478ef1d5,d3073714,5d577587,db806eee,b9dc40ee,191f4b68,1c488f64,fee83a32,d1034ef6), -S(bebf44e,4cdbb310,16e0e43f,b183ebd7,263515cc,489fbce1,90cc104b,55225481,f7ace0d5,3dcdb783,e10513cf,2e6c5c63,c60efb67,fa0bc316,de0e571f,d399f519), -S(78f6920,e94f8d53,3dbcd31d,aaec5e94,76919efc,ddff1eea,4e79e1b4,3dfeb4f9,5696bc3c,c8dfd0c,490250c6,4263da19,36454cae,88f653c4,2f9004af,10eba182), -S(4a2d9099,949f854a,e13ef6d8,a0179957,a47fe355,92ed0ab5,b22994da,3e616e20,c922bf45,8feafa64,66e31c20,d99584b6,ab390f2e,5b97009b,5254d229,d2ea57e3), -S(762eb751,35672a8c,26fac373,af7c7396,70b8c0f3,336bc099,aa1f02a,7e804df1,edfa83d0,6cec4971,6cf3d1e7,fd2fcf3b,7e2143ff,8e67a5fa,c24f14da,b3ee01a2), -S(fa4621,897c70c6,8b62619f,c040d058,cc68275f,91b4efb7,b4f902ab,3059b822,8c1c575d,d6066045,9aa7908d,2246e846,103d887d,3b7549fc,b4ab9f6e,e1181a55), -S(6a61b260,3d77f92a,c4df3f3d,30000179,e6f0fa59,a6570233,1ccd0dad,6a146ed0,416c09fe,711b40d3,92723f10,688fbd1f,e30131ec,e8a0a547,9acaa8b2,ae8e335a), -S(8a80bd6d,316dbad9,41c345a2,6f3f7ed1,738934d3,f00efd65,edc54fbe,9d38d48e,82bf1bc2,468b4ffe,11561406,2a2f9ab4,71d40e72,a2f1a40c,8c573013,5a86228), -S(174daec7,77872ecf,46832a7a,ce3c1d5f,47304048,c9cf1248,124c2eca,3438a110,be42dc6f,b61964ad,59083c98,e459ea4,db3298f2,ea8c8379,be76859b,958b6f3c), -S(e11397da,68e78b89,c8f30102,f779e014,f572f9b3,a5d33ccc,b74c2234,ba9d294c,bff23953,fd62c1de,a4dcf767,924e5448,e6529bd3,85a1acdc,3efc0e8d,864fb9cc), -S(9f883f,27e68e8b,201d6ad5,28a04a8a,fce8b706,a4d6f2e4,5d07c4ab,8b0dd96f,965ecfd,1563f640,97f42529,305be630,12f9edcc,82ab67ac,9bee6979,b91ad5f3)}, -{S(ca3c008e,cf9efd5f,75cc1035,f9edaa7c,46b17d25,9895b0e3,b3523b6e,eee9daaf,a676aea9,3ce9bb,128ffc34,deb96b0f,72179d28,77406d04,6d0c8b5c,3572f4d2), -S(59d2d70a,2e90a652,54e06ceb,3793db1b,a78e9b4d,e043a3d,c5773b9e,4c200ea1,80d83c03,5aa47ae,956ded05,cab59b97,4f25c32d,9d6aeca1,32603249,b6d360b3), -S(4d9ba25,f51de6ac,3b63b60f,576354a3,40d89e09,51af3e9f,8d8eba83,c00160e0,218deea,f7a87a13,f7ca36ff,b4f85923,30ed0337,2665c688,e3632048,97dfdcb3), -S(41093dc4,cd6c91ff,67df50f,11031e3c,56d8e078,961e74f3,bf01b010,564e732b,b836ff47,2e29fdb9,c75a4a68,a3277d9d,d4568f0e,43333765,a7246fc1,69d6c074), -S(8a37aecf,7a111e82,21bd8aa4,756974e,adbfc33c,9bd6268b,247270e2,642c8abe,6a9cf7f,d48bd71f,d7f2dbf2,1564737a,2acff559,9aa3da27,925b6140,3e940bfd), -S(7b893836,b2777ef4,2e4a2add,c50bfe33,37f7c75b,f0acdb03,1829e372,129aa8b1,31b64a8e,fe772afc,eb8f631f,b3a4b39,39ca4a47,859a0fc8,59165c5e,d8fc0331), -S(2f493e24,6425e2b0,fa036211,5352d455,8357a2d5,b838ad4,232cf6e4,e4b7dc85,9cc11b9b,5c3a4da1,fdb1a119,aa5a546,47cf86f6,b5bea9f2,a9b6814d,6158fc63), -S(5622f09f,c50ac0eb,2a1fffc6,76604755,9d3a5046,54956aaa,640515e7,91000316,33e375db,350fc408,fff91c09,fd6ec673,4c12f5e4,46348864,b0586d8f,fd1205df), -S(fbe24d9d,29eead5b,72952323,df6e8b87,322d570c,37dd2191,690e9119,8a5b65c9,ca77d605,fa1c71bb,acc38061,f4b04768,e93ccbfd,dd626796,debaf531,6c17e89e), -S(1c324df0,4c5d8f9a,7cf6980f,7239d5dc,94f49053,5ef06925,6341ad0e,5099baaf,97611701,e282fde9,9263c30b,9439c244,b0fc4844,a61c905b,fc03d98,f81d025a), -S(f40508e2,4252b801,f4b34d4e,2941673f,be39a018,2d9e6b4a,e0fe3052,da22d16a,5477f0f3,f55f1571,8e070280,f3e5cc80,af79dc14,9954c40a,8c1aa63c,f1b52686), -S(fcd09f44,ebf12a38,8f12f1ac,1bcb6856,217030a,903dde22,5dd25986,2ada9b71,7d5fc263,6dec7d82,167f40a1,cf00cf9a,fb82a10c,a293c64e,8ff4b616,1f9f9d9a), -S(666675cc,1d4084e5,f4ac65ee,71fef1ea,66fb7b1b,f348d980,b11f711b,fbfa2517,93f65e6d,4038c57c,3e04a0ab,b3b1a45,4050098a,7199635a,ce8c8617,e14c6870), -S(8bacd663,9b1d1f4c,2038c96f,bfabb232,87aa6574,13b3b0ee,5aaac2cd,b8d629fc,50aef7a4,fdbf85bc,e0876914,ed1692f7,7f8854ea,a07022c0,46fe359c,e87284a8), -S(efa17098,da4d08cc,f879897b,ca2b4e3f,e19f1668,4428ae3,94a37f37,cb678d10,c43b0e05,584ee017,80956297,1c7602c8,3784c807,a88b6c51,7f25105e,d16596ae), -S(6c8eb955,497f33f,a1c0f1a9,a4f5017f,3f2613c3,3ab944b3,abee9171,d35f582,9e647007,dd811c9,bc1b907c,e1cc70a4,ae07722d,4dff6f06,d77f5937,9250d8)}, -{S(8a4e9691,3533875d,b8559500,65c90785,a78233ac,ef24113c,f6ed543a,e6a40024,57d9444,8d091df9,602e6c7f,c3f88934,d45a7c76,18da574b,4d4c15a6,6925bcf4), -S(d25026c,edd7663,2a256452,c6585ec2,e8c475f6,247f621c,c4438bde,b4a49ca3,4f8ab8c9,bf340f6d,c38a4830,3e114ac7,9406baaf,583533c3,bf6cc0d3,b529ed36), -S(7bb1335a,3340e2d2,ed2e88b0,5daf002e,6a903241,e142f9d4,e48d585c,a9cff8d3,eb65860e,c2a34d44,1f1677e3,f3cb2bb3,9d0761ee,200dcaac,68f683f8,7066bdc4), -S(809ab901,4a3ca64f,7dac499d,fbe84b51,6566f9b7,f504fd24,681fb9b0,be3a54a7,326d607f,e41037f1,bc1a4d56,4db58169,c637e902,99d52c37,d625862d,faeee076), -S(1fe79a30,e681a701,9c437773,1c99f7ad,b4b6a52e,289baf55,e67bc468,3a20b65f,b4843af,94698c22,ee928995,61418205,a745912f,3b0b11b8,b3a3cf5a,3008aa6d), -S(fb9ae54c,b674e5e9,ccb900f5,53d9cc06,949a6eb,76bcb6d,e7c8cf34,a6352936,3d2ecabc,841d29b0,b81ea46a,7b061c92,103c6036,5e9ce032,286243cb,91000b69), -S(d93164cf,ff3d386c,7d340da2,31479b7b,5167472d,a111e9bc,287be7e0,bbc06ceb,563ac770,b23ac56c,ba093d88,17e1a8a,47c9b607,eb773284,1c8b0c6d,f9cd9a9e), -S(3bc57534,178dcfb7,b80906b3,9db964,7e989039,1e13c2c9,f82d7b63,2a1b3367,5eb2254f,f7547cdd,745ca32f,e3ac49dc,2dadd808,558b7905,71a46132,d0293e09), -S(69c24add,b825c48a,ab10d0d8,36d2f4ff,79535742,f07bcff5,cfd568a2,ce28c8e4,a0465fd2,fd1f7924,e60a96f,472059e2,4df02324,7bc79e7,11f64d8d,a477dc06), -S(76d9304f,8dcde85e,9a331a6a,bc066d5b,72ce9fc3,a3e65614,37c376de,f6aea72c,6a31a164,af370f6d,2ba9729,fd2a7e5f,69d62729,bcecf340,48feb388,541e40d8), -S(f45517e4,13d15400,29e1bf03,aecbeded,9da08531,65a38956,79ca08ef,8d7c8011,7cb4b383,62f330f2,bc54d555,db060911,d7a0383,eda89b65,913cac4d,4098a1d1), -S(2e3b0113,818930dc,f9e6d0cb,d59032b5,e0aa1da8,1cd95f3c,1dfc8520,51135a12,22f9bbbc,e023e03b,d00f1c73,d2aeb9d6,96de61fa,47f5f6fa,31a5f269,b4029c5e), -S(11c85357,5073bac2,51a5f7e1,41aef0b2,8fa240fc,e8045f2a,e6fbe0b1,cf99d9da,ee8a317f,78545477,732e325b,4695f5de,b3bde843,11fb7fde,1a0e1cab,d8bc1c16), -S(f3cef221,8bfdda19,99885c8d,ee2e16a8,b53921e4,6045de20,94775856,9f2c84d8,a95ecfc8,e058dbe2,d57144ad,e65ac41b,b27cf4f,83150b13,f7f80878,81b98480), -S(b537bcd3,3bb129b1,db277096,afa2f42d,d63662cf,849a5c0e,f7438443,fd8d0e4c,76cf0b80,461e8984,bba8d8bb,f926ad96,6a7e9684,f09e4fbd,45657e65,d45ab69c), -S(4ca9dcbd,fc4ccc48,62c1b2ea,cb624698,40c3a0b3,95bbf084,9dfcc410,b89c3718,be50d6f0,845daab8,cb857c24,fa995624,dbf8c938,dbd982a4,85e66d4b,1db2c765)}, -{S(458f8dbf,9cef8cbc,5d2046c7,42ca6297,e8fc76a,ad22fd3,af4f9a8e,2173d857,57074c8f,14a36b5f,6924517,6e3dc7b6,4d12a08d,8d00565,e70e0ca1,56f29820), -S(d4e74c10,91365cde,4cf5168f,f4f523a4,1fe85d27,d50d2b8,76218259,10c3d5a2,ed9fd256,43ca55e9,53a209e7,5fd7e965,7706855f,d47d7053,ca9718dd,a834c691), -S(f992b772,821fc43e,61771037,acd07e54,96f61845,d5915056,5babc86f,11a766d9,8a8806f1,cf24eb13,e7b8cf1c,25d550b7,4aca323b,e3026382,e0dab78b,217a9f98), -S(1e9971ab,68dfe587,fe0f4612,ac8bc090,5c2daef8,616dfa6c,b7505e04,424f74c0,4e9c2118,6214b25e,6bca1e61,57ae70a2,5fcbddd4,7690acd0,e537110f,c08918b5), -S(ff3717b5,f433f50,9a4480c,80e6d115,c41767af,2fe6f0d8,679798dd,cebfa8b6,4e443023,e6bec3dd,f82b217b,d1c0c235,278d6fa7,8209e009,4c716c71,163ef474), -S(4dd0d667,f0d72439,b3d3adec,15bf05e8,129a1218,a8d7c645,307aefdc,616cbb0f,aa592262,93fc13e9,a11bf634,56d81d7f,fc503f33,3a523af5,1b1e9a9a,921a95ce), -S(c5475eac,51e02585,9916ff52,efac5c35,bf9b1b43,bd88e949,8807d772,f9e23b1c,2daa42ef,55198235,e8c4137a,d13bed86,d994fd1c,480ccbea,89c1c545,cc26fb27), -S(588d521f,6f9d2c44,e2ee47db,c05ea3fc,517d1d69,7c66a3a8,a62c72b8,645a6a87,24749bc7,3d997052,3eea9809,66701cd4,db072ff2,d9284255,e4f8c22a,afd75504), -S(d597241f,298a7b8,a1139b92,a8bde9b3,f91ea694,c450c808,e15df89a,feafe70e,5d17b691,ccb6cc27,79337e2c,8906b73,83876759,abf728af,c6889182,bf8301ef), -S(5d2d98db,c2d6a0f0,1cb8e201,516f65da,b43e704,78b0e5d7,deedde32,71614c03,c46181b4,d08d0555,7b031d3d,e5966ba3,6534c010,48875986,93584851,80ae7c53), -S(dceeb9b3,6e8e802d,f2ee9664,b3654b46,741ae546,6031162a,c83bb6da,98bae12,bf6e5152,53aeaf52,8ec5a0e1,de1f156,d64c9123,236178cd,ee9b2c3c,3e2710c2), -S(d4984e63,4d173439,e212d2e,2e8da9d0,d00d14f9,1c1d22ce,c37a537a,f3b0788d,c72c5356,63000ff1,9b17ebd4,be15230b,56528faf,c9622b2b,15e88318,4a5c359f), -S(13ccca15,767ae67,ad5a1b60,36bf0e3,e617d537,adc87238,be522265,b8fb813f,ac7d0ed8,2f30ba14,a4817fa0,9dcac107,3f3abde0,41da268b,c3bc9b61,38df6fce), -S(d891e13d,678ebe25,c129de51,7925ddea,c89ad77,4503bee0,d3be486b,2ed397,9a9b4d6b,62180606,9c6b5d9c,5f14701f,bbc8c436,9d148d40,dac50a58,4e87736b), -S(b6c1f018,2bcc65b2,be194313,9b2d61d4,20dbc415,becf5c44,356b3687,47c215c2,b7bae889,fab9f1a2,6050d82d,b983a6b8,c7edf242,69de609e,d963e0b,9230f79e), -S(853be70f,c6df02bf,271ad18a,6e94e277,53810df4,602276c,c5b0e9d6,2f55e587,bfef4966,5addf7bd,efe505b0,368be840,6fa2bcbf,316be956,53d2dbe8,c3db190c)}, -{S(d2fff4de,9ecfdbd2,dd99ebae,d038415b,19b6c44c,9717926c,9e9a668,3fdfd377,a7e8ef8b,89877e3c,cca566cc,7b7dd537,d157cab,121d1623,b6880567,ac66fa8b), -S(f88cac5b,7ef229e6,1a12c335,1603b853,4911e6e6,644dff0,16924cbe,53aa97f6,e853d434,c1dad0b5,4871e881,21673a90,71182684,12f3362c,e43486ff,61307196), -S(7e61ed71,5dde7b01,f1baabaf,bc1db38a,8074c3eb,ca665c4f,d70cf352,624d3d38,70bb8d04,ab22e016,1c5836dc,f08e2c3c,36ce3f67,f49e0a5b,99e21b5c,c6ed9069), -S(9df9045e,7deba246,11e8fe62,fb323077,dd495d3f,8ebbe4db,384baeeb,aa6b88fc,4d5f0bf9,f5cef832,aec0ae94,f204d1b5,18554378,440675da,8bb2d91a,8fcd5960), -S(5d134cde,d16d21c0,2bf962e,7f12f2d6,4e91586c,8070bfa2,61499edd,e00b2a57,b7b6bc8a,54e118e8,8cbdafc9,325fc6e9,125b46c3,66c85501,33561f0c,49c962be), -S(a565c3cd,2dfe5f28,4c98abad,82bd1a61,76bdbb7a,4ee51f80,29782d13,849f32e0,59ce572a,ff34600d,26ac0c17,4b5b508a,81e1a9f2,7f3ada66,44234439,63ea61a3), -S(8bb4eba,3d2b83f9,d6bdde6f,82253b2a,717cb133,f0a7512a,ddfbd29,c6b271ab,f0a0bcaf,14311a27,da09d57d,ce87ea6c,b2156be9,59982e18,5c92e64b,861f4ed1), -S(8b93bf92,a0f791b0,e60e4a33,8ecc5919,6fcb8f55,b7cd886f,cb71d66e,519333c8,77e26206,945f5dc6,ca3e3075,5834eb21,5c3111c1,4bc0b424,319d7d50,f42dbb8a), -S(b8a91ab4,eab1e465,e9ce0f05,b9cd5cc9,d7bd5ca0,29018129,7a2d2142,a3269d49,35eabe73,94dbc74c,e174be38,81b56b3c,d2ef6a16,4a7f92a3,17034917,239aa67c), -S(26f3e105,9bc8f39a,b56cbfce,cc7f8cfb,ead6cf57,ca4d6d4f,61653fbe,1934e2ba,7a970b03,a86755df,f2465be1,ba1634cb,dfad7486,ed7a8a57,b236ae0a,22993b3), -S(b1775563,68b77fe5,896d8eea,e8631dee,788d6b7d,b5fe84cf,66782308,3c0536c8,ed42a54e,36509460,ecaa422d,fade0836,8d96dfe7,ce4b0af2,fac64b84,a49c4a8), -S(7e8f9d20,9b9ae3e0,d8bcc4cd,8f678d77,b9ddde2,f85b811d,63558dc9,b82b4c2a,317ca8e7,697667a0,1d60345a,acc9eec1,57533739,683a3610,baee81d7,bbb2afe6), -S(ada7a37,a54998fc,ab666fcb,78189cba,f07ac132,d0ddb59e,26a959ed,2281689d,ca658fba,d7ef940e,61e0bd3e,41e04863,cfae0703,f997fe20,b6c4ff96,c1a6d53c), -S(93023c4,ec822347,55893d89,497ebce,c0a884ad,e93a5ee2,23514127,fefbd7e9,cbb91515,e8ce6330,55ab91df,96ec77e8,52a5ce34,f0fe3a08,315c30c8,660ec7c2), -S(f70d11bf,4b476ada,a3329b90,e5673313,2107c27a,da354d4f,53ca0913,117f3efc,38fe645c,7adb5944,cf396af1,3bcf69c9,f952f55a,57274f05,a88e5ba9,51b64064), -S(111c1a35,fab368ad,e90c5384,b0412268,a1a8f8d3,49662a83,4aa7c0d9,830a307c,bc8cf412,238469b5,7a316a27,1fe4ba42,f3fa6a62,efe1e12,54f20f61,8c0eead0)}, -{S(b3b5422f,1361ce5c,bf7cc061,3c78aa88,a02683ee,cddeaaf3,f5516cb,291632e0,1790cb50,cc2c760a,c7c2e97c,c44aff29,86c73be5,59a88180,8d036e7a,94347156), -S(a7087c6e,3cc50e11,5e42e86f,855fc0bb,8a0deae8,4c1f92ba,370152e7,69d7e73f,86a61264,c5ea922b,cf1dd751,b5296539,bc2c41b1,29d3881f,2affabe,51f6d1d3), -S(53ef19db,13d761c4,995bce5a,55365036,def1321f,e0b393b7,41b55b86,8ecc9ba7,7a7d9ef6,61ec075d,19e719ac,56f028bd,403609ef,ccc39881,189673ae,10ec05), -S(9ea51d5,4cec52d8,58f8c082,e4362b84,6a83e0f2,9c99df32,30c9a2d8,e5269818,41305f7f,a9535eae,fe7316d7,6ae49d92,47667649,5776c712,214b8fbd,f0c80cba), -S(9c0db1ac,fa10880f,d4da60e8,a8a7c6e,b4117f37,80394e83,fb591307,14dc6460,55b73b4e,80091775,1e680a18,6df01b67,cf0b38cc,e10bc0f4,dc98e0be,7b5c5a24), -S(9734eb47,f47f2b5,4edad15,791b890f,64794567,df7b4866,b8ccde2f,9890cc38,9bd277e7,7cecded5,9dfa120a,f6bf322a,910e972a,57543940,b74098fb,af5be122), -S(38aceb92,95b480d2,1ab23f0f,c2ffa615,ee4f6903,32aae091,596d0aec,a99e5efd,8a3c1050,4ca2b73e,c5249f9a,6edf0b67,65a8b02,4e8ee2d4,e90dd3a3,a8e3c4b7), -S(bc517f6,658a0f2,ec9bb49b,19573f9b,7c74a37c,c3f40c99,7c31db21,170fb0e8,b0dad7b6,18e1e061,902ad53e,a00d3cd2,e9a7821f,172caac3,3c1fc1ef,fbbd3c65), -S(6726e4bd,5ea071e7,43bdafd2,2fc7153f,49e36504,e8482db4,9d64f995,b8b073db,7cdfdb2a,6a42f050,841631d9,779802c7,3ccb6844,1ad48508,6598f6ac,f91533ab), -S(b586e330,a91d81ed,d9b972e3,d7a33c6a,b01019e5,6f809583,767370f9,2803be7d,8bea5cdc,619dd2b0,185a3242,1fa7dec3,662cda7a,9f1302d4,ffcdd31f,5959628a), -S(6a713584,e0d2fe01,64ab5ec1,f31f2798,fb85518d,7f91d512,d4380e11,3d3fd132,3a864153,4be74fa9,6bceb551,15d2b3f0,59fc61cd,54a046e8,d6216f2c,3cfe61d8), -S(2919d598,7a521f25,5dcdfb55,3e5a707f,696f3aae,47226585,248abd19,39519f38,bef08437,9a346d56,7c800354,e85aa596,6a0e2b03,91efb233,7d4a2df8,9d14e9bc), -S(78bd9c63,35fe26f8,68d85fd2,6ad879de,f582e074,fdf2b20,f6bde782,cced7a14,a5b6404c,cd6059af,2722b328,acc60b6,87759410,161c25c0,6866a6d6,89a26877), -S(fecdabd,1951afa1,406297f6,9ea98463,54e14a30,dec4e3de,8ee107ab,43f7e32c,d3095b1e,5d01e350,2a90289e,c508eab2,ee888bb9,fc72b16a,8625a42e,23ffec30), -S(e97f6e7,5ca07704,dca90e57,aaa27502,e1a1293e,d99e6126,d03c00f,53bad532,e07fe66d,9a2543df,5b618336,f75b0907,83c7d74c,d63d8914,22524339,1f598b91), -S(f7270282,7f520388,5412f3c7,9fdfc9ea,da219679,e78d089c,4c1117ce,d990c5e6,9711ff7b,4223c8b,f9aaed68,f70090b8,1f8163b6,7429ba7b,a59ac7de,ec2412a5)}, -{S(2e01d33a,c10caa03,ab514f75,46226f67,69a08f01,56017b64,a2436a34,447bfdbe,f5bd77a1,2c61f2ef,60a8c937,cf29e1e6,882b12c0,3e7a7763,f1ea498e,9207836), -S(7eab2720,b4dcdc09,8d85ef3,869bb07,9640ab46,2d6b186b,88f92426,ac563a0e,a8a15397,96e48dde,8137ce65,c55c6369,766b5df6,7dd0a6a0,6d4bdcda,a0c4c70c), -S(e6a98f52,eeb51268,91c4c6df,b6ae474,6cbcf21a,7352035e,6bb479d3,25a64de2,61c7b668,e144fb16,e72f06ff,71167211,6f6ec90,4c6ca901,61a71b16,f176e0e), -S(33cca5f8,bde4431e,40c3af09,2242f429,2dcb47ac,8b4954f7,3dd25dda,d572594e,5c23241d,46ad4994,1fc84c2a,9aa42bce,1ee4f3d1,cba680ee,8760cd37,e9924160), -S(e5daf317,a0024ea5,26bc1939,7a54d0e3,ff325e60,3ef6a0db,4ba1b366,e1f65c23,8d70ed47,6895c5ff,ec487a26,b7a3fb0d,73a32e8a,a4a80db0,ca00ac83,4371957e), -S(6131d574,7439ceac,e77bc0d0,b49981a8,4e3033e0,185b63b8,a6ea9dda,cb45e7ef,6e01f69,cbe2af0d,a1826d6c,ab34121d,6ab457fb,770f7450,c366010e,20dbee4a), -S(8a7a6e0c,5deeaa35,f13a9bd1,51c737ba,bbac2fc1,924318e5,8b71bb4a,87ececbe,92fdb178,b2834b39,7dfba6b,69e8ec68,e8db5368,546c54f4,a1ecec8f,e4e0c351), -S(585670f1,f244de6b,fa6c9b23,6f034fc9,47e7075a,59c7ddb7,f744e6d4,af423e9e,d337bcf,822decf2,3ebd7101,6b54dfe0,8dad6082,4a6307cb,f0ed140c,3bb14a59), -S(75a87820,7db72c1d,355cf92e,a74b3b78,fdc5c56b,88c698b3,7eb94e2c,f02d6dbd,88595a5e,e6444a98,3647cd80,cade49cc,92a764d8,f710ba67,63e012d6,b12e5d6f), -S(b6dd4054,943d57ab,3ec4897a,8f755e9b,42c3aec6,7860e182,804490e1,91b342a9,dc70eca6,9f7d62a5,8bdfbd97,dc0e2b83,18d1f890,97e8494d,9632e3db,c6168783), -S(fdd92a7f,566e855c,cc134e03,8b5eed94,39023e36,7985a077,875b150b,1663143,ee7b815b,19e1fea3,fbe2d687,b3611895,48407e6f,b4136865,cb2df984,fccd893a), -S(20734455,8b2ee591,756fa103,2859a08f,9218b547,ca7b67b7,266bf648,25209de6,b389f394,2c3edb68,468dc1e3,73ca3649,ee0f0bc3,78b8da6f,aee8f4c3,90867040), -S(1d29060b,7b0f6884,2ca58992,48e6dc57,f491248e,3851bdd9,80837ee4,a777f4e5,a3ec51c7,888554b4,1b21b6dc,da472271,8e5e70e5,8d7bb22c,b8045fe2,2a9ca251), -S(324ff1e6,4d1ef0bb,e5439a5,a3642ed1,f97b7ad6,dfeb6c7c,9af9400f,f414cca0,9810fef5,762b6517,5bb1469e,9ae69f94,68dbce8b,131a7e,6859461b,25581d94), -S(ee2e5e82,e7106cbf,47093a31,e88fdcca,5e00957c,1020f858,bcaeba82,f21c5b31,d75b0c29,e9360215,7a8d0359,991b5991,8bb17a64,6bc27e9d,4e5d2a27,3d4b43e5), -S(a2b27628,aae04348,72814af1,392c5872,1b787dce,6a78256f,3af5fb33,43fd9fd7,d2ac734b,639aa92e,40362fb6,42bd3de,9272c6de,81cd3c56,c802db25,1e20622e)}, -{S(934807e3,60b79e08,d1e28924,2478db59,331c171,6366f421,eda4417b,c0699286,f7f83c26,50e7a77e,2f760e68,7f475858,b2c2d770,195c199d,33a84324,e23f02ef), -S(73da18c8,9bfd61c,b2b6cf49,f776d53b,ff85de5f,796bd870,efd66099,a97ef7b6,fe5b0c10,1c109bf4,5112ec0c,205c1fdf,6feae62,e907c57a,c4c960be,22dffc8b), -S(19239b6e,d7dfedf2,6b926ff6,72905d85,1b0b39b,a20d0ac9,d24dff81,9aa44b0c,68108879,65ac0e8b,e19a9feb,70980400,fed7d280,a75f1990,65b911d6,39a734ab), -S(e03b6633,7b60f200,38d28ed4,1cbe30d,c84afc0f,1bcbb14d,40b73636,2ac08147,e3dcfe11,5065cd9f,f7ef8225,e9ee3685,fdc1c8e0,66306022,ca5aa599,977db560), -S(7f1744cb,eb8020db,13d21f53,81e7dfdf,b98624ac,ab4bfbb9,1dec9f5a,ef410ec8,fea6fc12,7ea0ebd1,bb3772c9,499bfde8,cec1cc40,e33b2e1f,a4fddf45,d03ce9ee), -S(b1d67d78,979a525,2093be3d,cf10125e,df13734a,eda07905,ad2fce0c,11015bc0,9d6872cf,b685ca9b,42e808c,8f854da,ed0c3939,40ccbd82,49856e84,ca2c9de6), -S(cc9c4e59,fdb57caf,bbdb63b2,f9c8d283,5d332666,96beecc,28d8c28b,2bbd4df6,a8aa77ce,fbdc1413,8d9889e3,55338948,82a8c56a,3c80516d,321d38ae,27c55ae), -S(c0a0db13,6f2dd096,412fec0f,6fb2652f,63346063,559525fc,1da8c67,12e1bc30,3b6257a4,13efda21,623c63f0,d78668d6,93dad095,8653942b,20b8bf3e,ecf8d542), -S(72abfdc9,eb47ad36,86fc6428,42d99247,d6331a5c,113f3f04,b5ada07c,dcf7b706,79cbfce7,65d63523,c7b02011,af3135b3,a67be602,c8e87754,53c45f6e,8538ba70), -S(85670d7,4dbf0d13,4c0ebe98,7f88972f,82fea44f,da5bee6e,8c865ba3,6010e45d,8a7b053e,f8336fb,a9e198c6,b8b7707c,20fa2224,a5d239a,7e40acc3,699d7bdc), -S(21c37875,d3577979,8693da88,85d2e0a0,5faee58d,ea74b21,782ad05c,7108f56a,30f8e75f,6f7caecb,ebf8353f,f06264dd,7b5638f7,fbe48e70,c76b0704,6ac2e3bc), -S(f73ef2db,94358b7a,ee9b7046,8a345c4a,94845bf8,daee156,f5fa9332,c9c2cb5,cdc5fde9,995563fc,612e8e6d,bcd21863,f8e83162,4d3a85b4,9a3d750,665c635), -S(72a27f5e,12944a7e,6406cbce,dd90c43a,bc6c1016,3fc0d325,f3dbac3a,156a2767,e09d85ec,963ebce6,26cd0f2f,16d882fe,488d7bd0,9888a2e5,ff05f570,86206a9f), -S(1e6f7788,61257d8f,ca81902b,394d9815,26f5a703,688c0636,a51853bd,85f05ead,a10cb6b5,e935cb46,cb1239a1,3d08c85,bb387812,9c21af4c,5781c345,f8a3ec5f), -S(ec27394b,44d9f24d,59384965,4c3d3662,a9a45cf9,cfa23557,9320c4bf,1e1dfc17,d28e9133,89c41173,89b8b665,b7ec1f7d,b2cfbb6c,9ff7363f,1f26948,517a12a2), -S(e27482fe,5e305f85,a4ecdc26,22f25c06,ac7f82d6,230b8c8e,4d8bff9a,8a78db10,e426cac3,b02eda3c,1b1f90e8,76f9770,29ed1623,62df1ae6,e68986ac,c346d7d1)}, -{S(accea070,aa6709bf,efd88be4,bef1d485,a0da83e7,ac9a1eb0,eda8387e,b9fe666b,93fc1c9d,fed8fff9,60ef750e,94dd2342,5fa08c3d,8eda3eee,7f51381,196080e3), -S(163e8e65,fb6e7ca8,585fc072,3750bf68,fea588de,5e713e7f,9538dbf1,1524dac8,1217686b,7ff2f144,88d5c121,df15026,b6757b8d,e72b1303,b830f516,4b4cf3c8), -S(7bc1be5d,358d6d0c,a42ebfa3,7d208024,d3b2451d,fa0dd7dd,d6c43159,76483b08,42dbc796,2228db1b,8268dfa0,2725fc82,5814a893,dbabd144,ec5a1cc0,fd8e31c3), -S(6fd5e39c,872cdd15,19df9822,6a0f84b9,a5cce99a,b72d3d54,27e24d24,d8b9655f,7969aad,162d6db9,973d2f9f,a1475ccf,39eddbe1,a205e28f,54594ed0,108136fb), -S(d65d659c,adf25d7d,6ce5fd2b,e8794007,6a4ef262,7284bc70,c4557021,4239e812,c1092daa,39ab1efe,480823f0,6038e5b0,35e1d2cc,1caa879e,1b7d057,8dcdd241), -S(754ebd39,5f6a7a88,b051016c,3631ab36,68733921,b9b95386,d924f6b7,aaac42df,95a20483,80e9a9ad,6b165cce,db441b6d,e439ef5,92802fb7,e314387a,94b2624d), -S(67340806,fe427a46,b9c3939,3dc5c7e6,680f5a3a,275c1008,408a2a11,ec43e2d8,ee7e2b49,b9e508a4,e7a3b6f4,72ec3a51,b4bca79b,897b08fa,e9ba77d2,90a0b4e8), -S(ef822b5a,2746c477,4f4089ef,a33f39e4,2e4e3675,69cb95c9,a6b75148,c0e76e86,9784c76c,6d35e6fc,aeb97de,6daf3401,4e594b81,c862e8f5,cd197e08,3a180888), -S(639bf346,fe9a3915,5a718e2c,c4191bba,4985c628,b5d504e2,de39a421,ae0b0415,d1bb783b,4bd96366,c4e9f82f,e6544bce,df39cbf,592a4aa4,7695182b,b632c443), -S(5de8f2dc,825fdea9,a0fe2aa9,a49b38a8,6f23e639,ee25668e,7445b607,df79ed02,a1a17c29,df23dc19,c013c05a,25094dfe,984591fc,a825aa3,577dae9d,6bb1c513), -S(467a55e3,c7f904b6,308f943c,fbf1c9c6,c8489622,9533bd31,5b008c0c,df5c6e5c,59c10ba7,ddaa2005,a169a884,6f5bdc83,633d260b,762a6bab,2cc8d9bb,401d0ca2), -S(6064e78,170d3667,b0226c1e,628c25bf,3fd01939,132f6fff,bec47896,9cef1880,d74e855,68d86986,f8850360,e74faa47,697a7ba9,9d7cf241,fd131af3,e90b0daf), -S(8dd19520,5cacd63f,7586954d,3f1cf4d2,25303baa,a56bfab4,c25fa9a0,63621dff,e772ecc0,dfa4fc98,9b6ac1e8,4a96e4dd,f1cf84ee,37e0a2c5,126f3dc5,6b8bc142), -S(178ca7d8,807067b9,253ce61a,cf0b49d7,1f973fec,62bbaf65,1af01974,c102ad33,293ae890,98cd4157,db11f6bf,c46414c5,47e152a4,e5276433,6d3a4ab,f9f2c798), -S(49fd915f,42daf79a,648d30de,c913616d,46e89e11,afb9d46f,b18aea34,e4203d2e,c94be4d0,e2ccb36c,c306aad0,940f23d5,20c2a29a,4588a78e,c4a8d792,2d96bf9c), -S(a76cdbb6,1982ae31,8b5d3be4,eb03cefc,8958abbf,578bc99c,5081bb2d,ecca6328,8f0ad9de,7d0a36e1,e27e5bb2,9510734c,509c5f60,c905982f,23865986,784134d7)}, -{S(a488f83,2bf3e57b,5225f748,754ba2b5,cd9657c7,175198ae,122c3d1c,ee336ef2,4e326d40,648cf269,2db42532,55391fca,5c2b48d7,44a9e39f,bd1293dc,827e9021), -S(c2e4a4bb,4cc75a7c,4e5fdae1,3b6910ec,7056bfe4,5c0ab7d1,2146bd69,5a7eaeb3,72b2d74b,6181bedf,4bff36d5,e1162304,65ad711e,c13c099,1dbf2b43,c567a603), -S(9e95d628,c5278b1c,56863ad9,e595739e,8cf36103,75e29168,5a5654ba,562292d5,8abdc7c0,8a472f49,4279be90,6d575b7d,17fbbfe2,47d97022,533fbdd7,1d4ff8e4), -S(76fa079a,2b9a0dc9,3a12d28e,cbede965,e33afdf6,ed28f3c7,c7d5295e,6b26943c,cdd558,61e9b7f6,ba779158,65b37c6,ef665077,9344f7ee,6e8d4b3,ae658c96), -S(a0269bcc,a3d91987,737ae43f,2d1b99d1,18a139b2,5d5b4ba9,cab55c62,66e4cc78,6febb984,7682c796,faf098b7,60c5ab58,b1688f3,49abaf25,3456c3cf,d60fd361), -S(f197660b,f5d0e191,d2a75f95,4230ad48,4e28027,f5e61d49,64f02fd2,b239b18c,cd05cec7,3eecdbd8,fd186f5e,73d121d8,2ae2df03,29bd7e44,408bf7f8,5b3009e9), -S(584dacb5,735c38ab,366ebb74,8ecba797,5be0576b,a52eeec8,c6fc353f,17d783ca,198e2b4,5d1e6ee2,888581c6,5dda9b44,a2441d09,4945deaf,77232861,4d6f0c98), -S(eb6d53e9,4f34c551,9fc21d83,f2092221,457e9697,9e535980,31c5a853,615637e6,b958d521,d74b297f,6e537d1a,9512c5bf,74a3a134,b2354d21,b24b30c3,1eb0e607), -S(d32c2816,b28e0bcf,d477c631,7ca9cea7,51c3d7a2,a4d2aa70,b6ea5568,63581e21,7e42e895,c6cc4eab,c85b2bdf,301e37ed,359ac182,ee1d6843,a3c1c7f7,d253cd0c), -S(bab8ec85,d297ac61,8aeca643,d3e54750,5974d165,4a2031d9,3fe2a865,7efaa8ca,f4544105,4f81f7e9,1a8c773c,369689ff,ee5b286a,ea652d22,7812c8b0,57ffd710), -S(7d75e064,5542097c,d70982b2,92697b2f,c3439a6a,26f1d51a,15766ba0,10c80b5b,9868b21d,2fd0340b,712b2958,ab4925ad,d22eae92,1ca2015,5b578d05,14019501), -S(4885a359,cbdb926b,3d2918e7,a7bfc8a7,ca9c6a8f,870824aa,fc2911c2,be3be588,7cfa2021,bc9eba8,27729709,ba83cd2b,d6c1d68b,2217dd07,c7af1977,35ce7206), -S(52c4990,8a3b1b8b,3eb084f5,33f5f559,e9113d53,8d753027,3b1f9bb5,d0fd03ec,adf0c562,21176de9,b5d54273,97feec53,735f430c,44082b1d,7233ad36,472815bb), -S(b07e4e7d,366026b1,e4487f0c,3a2d6825,909f526d,dfeae840,334fbcb7,b1681beb,26d3eb64,c795a304,f226b341,d49adab8,4b427557,1f683268,140853fb,dbf65459), -S(41d028a6,260d5c21,f3d31771,eb876c10,189c367a,b513b761,2530e974,6ef3b4b1,f8b295c4,a2d2d5cf,1be8fb36,9d2472bf,85263bcd,3a36a42d,705d2555,1a501791), -S(da36f37,ba62c357,1fff8b97,39d77d44,13ff457d,5933e77d,e4dc3d18,7bc601cd,ec0e35b6,6d1ef946,7f59d7bb,534beb75,13f8d2e5,1919d914,f10a7778,4d4abbd1)}, -{S(a473de46,a554667a,368fd573,168dea23,3f81153d,e1b35b26,90da8863,71e6c131,4ba0b462,92aed936,7a2bf9e9,de48a08a,874fd681,aef86a15,58b49e4f,13dbbcec), -S(ec3a1d66,a1f76399,c683837b,7b53e05c,5df3ffbe,325d3d4f,de12cb19,c44a8fc1,73392723,41f63fcc,d994c0af,d1459f82,c5479fc8,1628b8a,34b4d042,e68a23cc), -S(8de418b2,77aa4dcc,11619e6e,f76d6a5d,8ae48448,c6dedccc,f32b7238,b58a2e55,11e44fa8,68811549,8a7cf95b,91eb8c53,7119ef6c,3b9fd2d,37f428ce,94060ea5), -S(eaef8564,efa35058,1ffc48eb,329fe037,60b85bf7,864a433e,70b5e227,9282fd9d,90eeb6b4,c3252fa0,ae0ff9c4,ab2974ec,12cd8b43,8af9a0ad,64b8b3c,e404d35c), -S(6985a408,1a00ef94,ac404379,dbda4471,eb99bb45,69c90da3,241743c1,afa865e6,2485252,3273c205,8321276e,1cc4af69,380642d,3e2ec299,64da2d75,b17f3865), -S(df779625,ea469eae,1463fa21,b088cc70,6ac9d3e0,9c4ad69d,554222b7,7a2bdc0e,56e00902,4defe4e0,5f097ebf,ae0c4782,a93500db,bffdd525,8ab8ecd3,1253f224), -S(1a2d4b3f,29fec403,5b3cb811,147d66bc,70fcc480,4f07bc3,169b592,e4622665,600cc9e2,370d498d,d4db60ee,963c5dab,8da8a23e,8db3cb01,d805ac2a,d77ddb46), -S(2d8e71b5,17971a2e,351221d9,44e82447,e913772,216a4c40,f067087d,4106aa7d,d9284393,ad9a63f1,2e0981d7,aa9107de,21a91a16,ba43a25d,26895b4c,d793d525), -S(b53f44cf,a4f24aa5,a57aadf9,cfc0ee9c,d621d482,3a7046d2,8058f086,cdc91b1,8148f9da,95142591,dc71b505,ee60dab6,a680d0c4,1ddd1fcd,d59aaa3d,dd4a901d), -S(f31db738,2a3f41d8,d4079efb,cff1e3e1,e818b2d4,f83dca09,4a044a73,d64a7452,8eae5b98,cb9e9dd7,2a9332a5,5abb49f8,9bcd4b0a,d8f6913c,e6c1cafe,294ffc87), -S(7ce5ec00,ff2a3001,9eced47,3a891bfd,f2c2a9a1,8fd7e18e,3999ad19,b60d42bd,c514419e,272c3380,a7ce5dc,1883e7cb,2df64c89,5f2a730f,cde2f3c4,945b6ff7), -S(57ea4789,f7e02c29,7a089cff,9ae71fcd,f511cbc,926b9299,25a1e184,c6157c5e,c696731a,51132560,c77afd16,15cd5072,4cf0d136,7c4fa3ca,b19aec05,a8d701fd), -S(5cba3f4e,8aab710d,878697ef,9a1ae299,821960fc,caf88887,9c6f38db,4be1dbe0,336cd748,99412e3f,9ca14d01,2cebcce3,42ee9e97,638cdf3f,df5c0077,8d3e37b6), -S(56b0894,7d551fe1,2e9ab57e,a70d342e,3cb74d74,f549edc3,f7551eef,ca9f9fc0,e7ac85d2,a4baa20c,4e1bab03,7190490b,e3574ad1,f9cbc392,f28f45cf,db4dd2e1), -S(7ca03c7f,ab7f76a5,a258365e,55473083,5a9850af,6c83c311,b487a8c0,4ba87a28,1d144504,193db309,170a3ca7,36b39bf,46d08596,552a2962,6a3c40b0,a8f95e4), -S(5d041b98,b864a305,117791ec,21de3fbb,cbe58a84,8429d291,bad63895,442c9fb,46a179d0,decc9e6c,9b642c1,5fa126be,619872f,17c6273d,30e2ecb1,1d3c0252)}, -{S(476d7ba4,35177a71,299267f4,14ef275d,48b434e1,380c1afd,9fac4606,f8e02be0,7f1255fa,57a60447,c14d6574,1d7774b9,695e6d25,1b46912d,d33c77f3,f756edc2), -S(c68ac953,985c624e,dbbefae0,148f049b,c9de0f23,7b192e7b,e8f13921,dc478295,77efcfbf,a08be5c4,632cae8,c7e9e6a,520ddc19,dbc1271f,ad0070d8,366dfae1), -S(31462a8,ae0be4c9,b3d7a28f,3fe28e1b,994961a5,80cdb3ce,4ced5b5b,20077b77,3137a2d3,5303daf6,441b0ecd,244ee32c,1c87dcf4,27449c65,d3cd9bc2,6189db3a), -S(d78f7afe,6bcb8574,27dd87fd,3869e74a,760045d8,1841a895,f8e78697,189ab251,8e419b36,47160117,af77b5c7,97e6d695,65ac587d,ce16b94f,c11ae91,72b8eca8), -S(827f5436,f983e162,42213577,76403af3,d700ac7e,57e10ee,53985649,19922086,9f64f7aa,ff4c6234,5ef6017f,e027dbd6,26592cc4,f050ff48,ca4c8fc7,5ce87356), -S(6ba0ce5c,6893ee03,629f90e7,841790f0,414410f,8526e56a,b0f74f24,f5c2fefa,25d44a39,961099ef,b341c985,d1f7604f,298838ef,422ccd0a,91195f2,2b48e7d7), -S(2c43c784,bbbcdc5f,34789f99,46a9a5,59be71bd,3fde6f66,b6faf050,99b4dcec,4e5fdc4c,83eed83c,db5b5030,91bdeac6,a70cd8e1,ed187ae4,469b9057,18fa5386), -S(4faafbdb,1806f138,a265e889,db4bfeb7,ab53b2c9,622ed6b4,c6b392d3,1f7ccf07,d1843334,387f73c2,da122ba6,a633fc2,26fa3f70,e42d41a4,561e111e,aed5b357), -S(143b5028,c0bee52f,9dc11734,292d62b,17672d64,559ed0c7,49e02f20,8bf84bfe,887d583f,b7d6c57e,c1c58895,aa99ea4,7ff5406e,fc5e15eb,3d8db3a6,e8cbd4b1), -S(394ff209,a9586a19,396143ec,f8ab1785,a661b80d,8d2d9b28,c66c372b,add96e03,5ce203f6,801bd8b,92a673b5,486f8f03,8bebbcb,bea85bd6,7cab24ea,92a54895), -S(3e2670a7,794a06f4,2928430a,8bce2866,eebb6e38,90fdbc94,6b2c794,d32f0452,31d2e49e,9a6ce422,36bebb25,cb243965,6aa2a1fa,6712f17e,6d5d2b58,ae91c3b8), -S(c4cb5059,31eb4fb6,66fab44b,6e063435,35699e3f,8c3d4957,b971a271,78430a1e,9fb4a0e3,8d46c234,eba2ecc3,8628150f,41cbbde0,734453f7,c65f2444,c52a9565), -S(695d0e52,b32cf29d,2230b84,c1260595,8470dfe0,713aa116,61710c,8ce74e91,f4ade5d1,6d27de08,78d907aa,34b61f91,4135227e,97f0979,f4ff6241,4164ab5), -S(5aed2254,27ae4f7a,92292498,a345b20,49b00c0b,284d55dd,51e6cc82,154a4cbd,6da49cd4,5a48b051,f20987d5,415d58b1,9a4e1744,d83a5ff7,6bd95cec,1c6dbb11), -S(390aa9f6,18e5660,cd158531,7d0e01e5,5e6fb9d2,aa785533,6747eb80,caad2bb,bd7e8ccf,34e718ca,947500ca,a2d7e3e9,3cb0c6f7,d8b7c50c,7aeede81,95d0271a), -S(41ff7ecf,227a0f62,236265b,1bd5649b,96666154,115a2840,c37be05b,776c85d5,fa47dd69,a1d89724,f8801024,dbb52b83,d162f2e8,b8614224,4744afa3,530aa1c5)}, -{S(4f62ab4c,b7fb0d13,12620121,9841e932,b0de312d,674cd002,315594e9,81dfb3a1,1145fdd8,c5d16653,a9129b0c,39fcbbd9,5968d22c,ff2127bf,91e89847,35e2834f), -S(99813c3c,dfbda83c,a798f7df,5ea4f172,3de535e8,2f257577,de67250c,6e11370e,38bdd34b,18bd081c,83307a5c,fea76990,11a50437,ff93fc6d,aa22f9fc,d5021226), -S(75771c9b,9b6e8b88,cedcf4f4,3772b3c2,45f72319,7544d57,c6c920cc,137aad40,d8867e96,7b79997,c0526603,a2a6c201,18d93115,4362d804,1542e3d2,51a8759f), -S(fbc16489,7bebf96b,ca01a281,f2ca36c5,dbe51bd4,1a465b43,3311e163,16bbc85b,7959724,16729f2d,9ade6f1d,97157761,a81baac3,fff31e85,13b9989f,12f72175), -S(2d625707,d2c68919,8ad1b321,d60f6ba0,5e106abd,41bfe029,cbc60bb5,d5e0ddc4,5b3e78b2,a007c909,3722440a,d40c2ea3,6f71717b,c5822eef,322a13ad,614ba310), -S(cf23f492,64ab8e60,afd8c0d3,a8a6e938,fb6a3b06,66b9abed,23b6cb45,d5b33a78,479d121c,571eb9c0,e24c14eb,b3be4816,1363d752,fba522ef,a010ee7c,324be8ca), -S(c2f0f458,e56f387c,a92c2def,f02c3e44,dcc010e8,c2b7917c,751121e1,3e49df7a,d2bdb0a0,f56b97a0,ffd8664,1b34a1f,24ba9123,d089b256,6a50126b,90dfd936), -S(4bbfdb7c,8b393fa4,bdffb5d6,cfdf0721,d17e03d5,ff142b34,a0741039,4c84bed6,c115eef5,b815b3b0,c2f2ec4d,98b6a09c,36d8a320,2f81e777,eeea800c,662441ed), -S(49868964,9201341d,bb24a12d,ac0cd8cb,d973640f,19f13540,dcc9d21,d67a7d76,3bcc0077,5c6c7256,fe0e1d3c,a812ce2a,c16294a9,7b9ac6bb,32f796c1,3a2b50f8), -S(a1e22bff,d0567bc4,f0261a3a,db9c918b,a7d81791,d68e99f7,f8247ab1,1fa7591,9d1c7ff0,db87b176,5e284432,11299012,94ce44eb,31a4d6bb,49fc3cc6,d4735aaa), -S(2ad5fc7b,610a3ddc,e4950765,a86b12,e1f5e0af,89da287f,c930c035,b81fbbd0,9fbb7378,36c20ee5,bd5c081f,5588f57b,4fff0b1c,71a9f334,cff1df26,60085c82), -S(fb4dde8b,40a51684,ee59627,d5adba43,50d2ad89,3b0f4aac,6f7a9900,22b0fa1c,753d7603,674cd3cf,46ef3a5c,e19f0d8c,3be64921,6a581cb8,6dc62674,abfb221), -S(f36e438e,9180c9a7,19679a88,51f96690,6dc096ae,4a86e60a,a2a72bd1,b06ddcfb,3fd68d3b,64d890f4,aa653b0c,5a670273,a53409e9,242f0ccf,fb7ea68c,c91a553b), -S(7ff1d3bb,8de59536,19b5fa0c,9519cecd,fa121bde,ff31a689,65c18c42,d182e4f7,2953d0d,7b0d215d,f75955d2,97a8ce92,4b0f6ce2,726b29c4,2b7a2786,a459c551), -S(9385aa58,1de6a3c5,4b479bc5,8823f699,e65da4df,bfb277d4,b56b76e7,c41ee4f5,95d109c0,5e67ff73,2ef10f46,350a7578,f7aca034,962a573c,707b3977,97af5c72), -S(4f3891ae,e86c16d7,73237e7c,d2db7c7b,7ba260a0,4b85f6dd,91e2443c,bd21c831,a96dbd49,371bb1f4,9ed1dc90,17927def,30810e2e,b938de57,ab5665b,8de5e86f)}, -{S(110f05a7,489138c6,51e48771,d505c7ce,68bd6e61,67cf4c3,3933441f,a236f263,761652d,178d0d5c,f6189501,d02d7078,2f10f835,27894d79,4f93dff6,e90a3b16), -S(928df081,cd85c375,e53e825d,4a250160,a1a893f7,95e0a9b8,5378942d,e206a1f8,1f86b51c,49582064,f21e9673,3786eff1,dab4e713,69273cbb,9dfb3d7c,2d930fa2), -S(ed504706,702b297c,e62c2788,54a29419,e7e0f76d,d6eb602,e0defae2,8f74882b,67f3801f,31e2c8f8,5c3e409b,b104323d,ee41c794,802dbafe,ba832409,4efd3486), -S(d620c03f,dad08f0a,a67287d6,7b68e8ff,57d8fd09,2ecc0731,a236db54,83d897b6,f2a66048,6520abff,aa6cab39,b90c1d3d,89ac4738,fe560114,94117a73,60f30a41), -S(fe57b1d3,b1b33889,148509af,29a3c797,3bc726d2,593b14b,1118580e,6b8fc04e,d69026bd,820418aa,74e6c115,b2bed0b,d4f48cf,f1022367,230679e9,7d878547), -S(1de846e8,8e3bf169,465b4d66,6c0cc230,36c0bf12,b35ac6ca,5dd59935,59c11063,d925394c,c8eac4bc,31a49318,1821560b,bbe38d67,ea0040a9,42a1747,defb69da), -S(7a4dd28e,3ccf40d8,7ab743fb,6011acd3,981e4322,486d38c,6b6bd69c,368e9391,89e0dc28,680ddf3b,1a6ee4f7,b2b5a0a4,c417a9ca,4cdbaaf0,b08b4de2,e2653010), -S(593296c8,840e55ee,f7477ce0,e9d5747b,ce2a24f,e5e518a6,7813da6b,347fbd26,7ea971f6,37522c0,f0bfebab,17fef91b,8216ed49,1a0ec5d6,55f12062,6344c124), -S(b784949b,4228eeb8,b8e9979e,fd7309d0,3e5e3a2e,e658b017,86b664e6,db7afe2d,7f836c1a,3f93744d,e4f0563,456e3f36,56b536c3,1e8e7b39,5c0bc78d,9864910e), -S(2298a36f,6e66645,5ef8ac54,a3564c12,59b2ebcf,3a1dc1c6,8f290f78,fa366974,da9db0a6,26701765,293d39b7,1600c991,effb9ab9,2bf6f95b,a65f6b2e,9c3477b1), -S(253bd683,f5421bc3,4bfeca7b,5b48e6e6,d1db6398,983b451d,6f327288,513516b4,61b02eb9,b3d32555,9692df42,b4ce3267,297aa78b,7ac94afd,c08c3534,3346f8c8), -S(cd328c8f,5aa7ced4,d0b0744,39be20d9,f44924b9,c84fdee2,8363fc9c,1cfc80b3,9b0dcad6,5365b7bb,822c2c73,30105fe1,907e674f,9f11b13d,63385bba,b3278d3f), -S(29c6e1ce,3f8caa9c,d366a0e2,3b86fc16,986c3d12,7c391b2c,aee4ff5b,5c229a7a,dbd8686a,e8f95d99,cd7f133c,3211620a,b02d341d,2a50d04,e27a2430,de9f8371), -S(c2a3ace5,382bdf5d,a5dc3c5,9994d92,88efd495,32a3f0b4,a129cb69,a77fdfc1,d79b9211,55651adf,bacb249a,42ad5059,9bf0eb15,1d8b91a5,f6033c13,73db0480), -S(778c13f2,1cf131b2,86bbe8d6,9c4913bc,a0932939,a79a9446,a8c908e8,bfc396d8,963bd25e,461b56af,990fef90,5af101a3,a96299d9,44ffb8a5,e6c59359,a4d0129c), -S(c65a9cd,15f3b7f4,c0f668e8,53227b2e,4ac01865,37c58514,165b6bac,93e43112,ae0f8b04,1d5dc2d0,7a8688e5,ffc70da8,e7d5b4aa,92faa455,64fe31db,2d24929d)}, -{S(81f4223,6a39a14e,d2764665,22edb719,f2fb72b2,c571ed67,343e2c57,4fb60e5b,34f10ee5,6c1d5e02,51e8ba8c,9f129391,521f0601,2ebb4549,7377967a,d8347e4b), -S(bc6f8e27,8bc0f3f8,6bce4dc9,8ed98476,b4d7427c,3e3f3a79,f488d8bc,3f11313a,5a54bc1d,4b08aefd,53d16afc,79b5065,b637c0e3,d74dd46,62728307,ff6c7611), -S(259905bc,501d58da,72ff446a,315b9f75,89df7c14,4d9cc937,bd962d74,12ac343a,3c233cbc,a1660e91,fd41cce4,674386a5,d949ddff,2477cbb3,737e03f3,3adf25b), -S(5051c982,aa4a5d22,d8c4f57,42130c23,4665bcb3,4cfe0567,dfaf3e4f,a03d9721,9413cf4b,50784ad6,1afd8a6b,8ce23ae4,80480b86,6c08ac48,24379d57,8a4062d0), -S(c0158ef9,e70349fe,2d32c1ed,30c87c8,90de8ceb,46ede75b,2addba8,de2b26b,b462c3ff,b14bd8ba,c167709b,dcae0d46,a908fe55,2789e2ce,c5e43d62,b71aab70), -S(740d9568,b420a2dd,389b3fc8,67065e00,10eb2961,56eb6774,15755b4b,5e277ebd,eec4d9bf,693994b5,13ef673,987ec7f7,2d2c767e,9b41cfd7,858aacc7,edda7aaa), -S(ff333278,480b444e,99b65b7d,926675ec,6b16a64e,dffa2b75,9c5410d6,5fba02ee,1d0f842,e584e31a,480c8202,1824936e,e2f717e3,df72412b,155dd2b3,fb1aeb4b), -S(79b0a263,dd3a2b33,31d1369f,8e94cc7f,aa9b8364,2918f9cd,aad62d9f,7a5cbffb,225dec00,4437c7c2,2055851e,1c4968b3,f699dfc5,846c373a,13bec08f,5cc3890d), -S(2a12e289,7cc085d6,30996a53,cd9b0e64,4dcba64c,7a9c4a5d,c4affde5,42717d25,2b8e848a,43566c29,fc5242e0,4892cf58,1afb0667,9bb15b87,69252962,637e00f2), -S(dbf0d2c6,29bb1f42,10cfd3e7,2d119391,16d23a94,fe0c2828,9140a498,1cdd0749,54594d41,8b87961e,b6486d09,f717471b,13f4d39b,1b82484d,8463a4e7,b28ba974), -S(2a1eeaef,b3478200,de3fea29,c1368d22,ba52fed7,1175ec88,4325833a,e93ec8da,1220e686,97e0347e,d0117f98,ce8929ed,eac74f0b,2fecab82,11bc5eaa,638742ed), -S(8ecd4b9c,beaddc70,f20c09cd,67314d2a,3cf3c115,44cd3508,e74050ed,16e9f34e,52ddfd1,795af7cf,9f083a22,35c15084,87bfbf79,4e3af1f7,2183790e,a27b73c), -S(82ae9584,b592fdba,88ab48c,ceb9ff2e,b95f09be,29ad4700,104bf18e,bbf3e036,ac06c9c9,4d3f79c8,8ab2313f,dd507808,36cfa91b,f65c06d,76b547b1,24067fb0), -S(c3b19b24,35c6c07e,4d3254d2,1e0a30bb,21c2f45f,68a441e6,925c3ffd,72b230a,3bdd5ded,600a0c77,3c620ed1,d9545662,af5f3ec,b3b0763,6022a466,866aec3f), -S(49622f79,9672c94a,26f86edd,22e9e5aa,b8ad1a62,33abddc9,fbbabbb3,3fe276be,c114c6bd,f30f79c4,194100da,847518c4,f5688a3b,70dd60b6,c4f765a1,cd324d6), -S(c07b88f5,cd465622,2fdf8cfc,c7191c4e,a3dd6d18,21adf780,63d62d31,2b9e02d,e601c411,839e2371,8136fd1e,e5adf8b7,c5e59969,35bb152e,955d2ffd,58964059)}, -{S(2dc8f27b,b3bdcaa9,2feace80,f2f6212f,8209477e,531e74cb,f497372e,9a2f2263,7feb63a7,96b55bee,ffa180ba,fef47776,fc4fabd4,2ccdcd97,64b4bab3,10350790), -S(ac8dc04c,1c1b8c7e,abad287f,a1f62206,f307ee19,4ba04fb2,fdc0a908,98a13387,a06c53ed,5fce8db2,a52ccbde,38121da,fea83bcc,96482765,26522b5e,d762b0ae), -S(20c34368,618099a3,d6713278,7f2b5c9f,3aa0d419,40329291,3c97237d,b44c9072,e1d3f30b,8c4f9d31,df2dbcc,435a0bd9,e4ab9342,7df8f04,90c820d7,dd620444), -S(dfa3550d,49bee1f9,304f5bd2,5deb92ce,b1e5d49a,4e3535eb,5b55d429,e133d559,1ddc87e2,b3cad5aa,922391d2,b9bb11bf,a3db93cc,244dcebe,147eaaf7,610caeaf), -S(40510142,20037393,7df28434,48899fe7,2f6469a2,1d77e591,d77d2a16,b3cd9aa8,588afafd,85ed985d,ab38fee9,306ef133,ecb087cd,30ac939a,ff13e1ef,a0b658fa), -S(120068a2,65e77949,5450c83,c6ec07e1,b6825840,ca7a00af,6ecc6d3d,9590e73a,e2eff01b,d4aa986e,dec9248e,f69d747f,65dfa98d,537d5443,c1e7d9be,317d371f), -S(52a1135,9611cb35,6b71c05e,c0376ea4,27c9938f,1191cf3b,dc7d17de,9c29b39d,6299f3f3,2f0bb14b,f1c94b36,88fcc301,cc25c90d,def2f2b8,7b0d0050,193c987f), -S(23000a37,c68fb1f,4ab535a2,db033b76,10f252c5,7de5c03a,47502282,1200ea26,3ac23fb1,f0a42714,829cf914,ffada79f,234e1e5a,dacffd5d,34d3ca52,976c934d), -S(810aaf67,f149fb01,a64e25e6,55888a74,f6eea8b3,c5e96fa0,9fd9c689,3e7543bb,abfe36e6,3418a26e,7a19f2ae,aee72cba,416880a1,770e2bfa,79eeff32,35885e82), -S(cdc0b689,5afbdb4,f1c9521e,280cfbad,7b543619,b8d77c2a,20fdfcc4,66129e45,9d59f91f,bc3894f6,820fda03,ae13748b,572f9a2,d06dc312,4f824831,778d62ff), -S(1bf8e290,19706636,e5d2c34a,39de3f02,331460ed,916c17fe,8e36d097,9a5edcac,e15e619c,f4f096db,1ed1d51,ea5208eb,41625ee,6546f40e,324b754d,e0e202c5), -S(e54a04cd,f5893d80,1a1cc8f6,9dae01e5,34b92457,ab7319a2,4d2b6c2,78f57f76,8103dd9,b4a89691,b079aad5,71267e5a,f601dc04,858f065e,aeed5e92,34dffc0e), -S(711f6808,53d18d8b,911e2342,a301a805,a1c76c2b,b5987775,f5867df,e2325d00,91630ab,cdeca550,a32e9df2,30f02e64,983eeb89,396487d6,4b3c9d59,8350ca01), -S(765b24fb,d42d4d4,a9dec609,48ce7f91,7c3eee70,49a36373,9e44297e,3cced026,56408d2f,d859a211,26d14e77,81302eeb,87371c17,b1f9bf50,9e15f545,c240b79c), -S(b68f07de,6b13a7ce,739a7e9a,1c6a526e,d1df5cda,b7fad149,df46ace,3acc9919,5da1b851,a81fe645,47ef84a8,fe9a39ce,fcdc9abc,a3e95818,b34860f7,f54230bb), -S(d98bcef6,cb3e4a1f,5b9ff8c9,8ef7138d,ba98e80c,200113da,e7508497,54954a96,456c5f23,96fc1c71,79f6b3a3,a82d8bb7,8ab73d62,61b6a098,77527964,5ad80080)}, -{S(118d5053,fa3ef05c,810cf906,3a410f53,38a9e6bf,513b9a7f,5259112f,f84ad7e4,a371fc9b,c9182528,27d6c842,32e4e44a,9d32eafa,84f1a02d,a86039d1,6309e92), -S(ce68cb2b,ec0e3f64,ecab8273,71f248b6,9b25f4db,94ca333d,c8d3595,e6f4db70,a8355f23,f22d8225,7adc9865,55350250,8c0bd086,ad7d8b74,ec3f3ea0,ecc17e88), -S(7834c202,977d96dd,d2897bc0,b2e9b093,6b3bb91,36f78002,85dfba94,cfde7d74,62df13f7,87aecd0f,5f299a98,1b4b6763,82b69aa4,997c8419,1f93eee5,5a8da0e7), -S(5dc11a79,34d41b29,5b384824,89cc2fc6,eae9c348,2baf631,94023e2b,579b750f,bc8719da,924cd9db,901bd524,a5eee1eb,fc161286,508e192c,10f3b786,f167057a), -S(40f1348e,a0032b45,3f2b5339,d687a06,3790503,b4cc7b5e,374828dd,5374566a,b7c04bee,58dd65a2,b5417ed7,236557a9,5d90f89f,2f9be760,408f3806,5ec9c1f3), -S(5bb43572,6cfefc3f,dfcc3a89,3abe627a,3bb9fe92,2dc39256,368b630a,1bbc91c2,4266fcb6,cc3d664e,72943e33,3fc94db2,b76b9b43,1e5956a5,5fcdb36b,27d175a5), -S(c61ca2a7,48faba61,93325019,dde522a4,b4ad7ffa,ffade4ad,84bc46be,390d6833,88fae1ef,1728b211,6a24bf40,7df169b8,5987f26d,75a86b84,37b91bb5,607b4eff), -S(ebb9b8ba,c980a86b,9955a450,493875c1,1bc446f5,ead71ef1,8eeee3a2,ace3a417,77aaae20,a2959de0,8b53b7ad,6434aa02,f3c56dea,877d07b,fdff41e0,aa463b7e), -S(fd3b8946,296987d0,22123898,bffec5ec,b1072fed,c8e66617,a8d1b00b,6bbd9889,54240cbc,7512e6d4,744393a,439e8b4e,9973dc40,34c68b72,df04ddb8,b89e6acb), -S(80aac570,6eb40c4,c6b5cdf8,e25e5740,3aadbc07,f75b190a,444ab53d,4743ca1b,196c7cc8,3ce92b15,ba110e5a,ca1ca0b0,c3205f61,e58c1e4e,fec5e957,72274710), -S(450df283,6de16aa3,3b893d69,39c46224,6ac30dab,941be908,42b3d5c0,714f9670,970c934d,5b242d56,b036b8d9,4b1e8661,45181ae3,cd286bc2,962035a0,fd852a57), -S(64c57089,83eba9da,d7871fb5,64481b9,12612c20,4f2bfaf3,635314c7,3cc9bdb3,7abcce5c,fcfea03f,74665734,13a66116,d6289bad,2209253d,45e77ed4,bae9a738), -S(4692afdc,34fd208c,72726495,7517fe0d,b463d39,6ba454ab,c1b81898,cd7343f8,57b67c27,8a0ab12b,5eb4a55c,933cb45a,d6b5d955,2110762b,61fe79fa,535a783), -S(511415a6,1371abd8,c86d7fbe,4adce11f,f6cdf1bd,330eb95c,7c40ead7,e5fca53e,4adfb29,87b9ac39,baefe7c8,69aa931b,c07fe15e,5a5811b,9add7b77,1d56c8d9), -S(4aee2f4a,ab479df9,b2e1ed5e,19230669,e15d153,22b5472f,c8b138fb,7d542c30,92c8e16,fbea4d0b,114a7d84,292a9643,6839624b,daaebfd3,9d621f3,7f8b141f), -S(8c0bc6ef,25a255c9,3816cea7,599c39d7,acee681,9373b82e,96b81a43,dd267223,8ce9ad90,e893c56c,c0392afa,24109c94,2098b5c1,15468b41,e444568d,9904efa)}, -{S(568b3e2a,2db4792e,4ef4ee66,14e201f8,a847fdca,38bb003b,adb06d74,1e4f999b,7334b395,61cbcce4,49d83eed,205a4c40,d91d2751,938ba7d0,6ed9e5a5,e1ffea7c), -S(ce433da,719f5582,6e69f248,3c3db9db,de45e0ff,fa2cace9,f75cd210,433fadaf,c296f641,5200cb35,cb8e1f23,20b86cc,9b341541,b9256d77,afe302c0,1e2420ea), -S(ea19269e,945625dc,138b9e60,249baee6,8c63bbb7,2b898569,5459629,fcc7ecf1,f5a7bb81,53552b33,86deb8c0,26d88504,f6a85ac1,b9290ef6,f91c0278,2cbb370b), -S(19e8e269,b972af70,c61983cd,cb7446f4,23dc93fb,b0e3d8ba,3fd02476,477e596,3081973d,f2123602,770716d2,6937f31d,f0835148,8c9d1375,d2bfec67,24df9c3a), -S(4968feff,d34e4649,9ca759bc,8e90d374,de9e3199,a13e2b04,28a10df6,15fb7696,2936b2f5,8491cc78,38bdf347,a4ee0b36,db288e5f,9727980,810c6eac,a8d1edf9), -S(d258654b,45fe5366,3552e85,a7da0755,c4598eb,68aa96d4,624875b6,580ea359,52501a5,e7d7d931,417373ff,ce85e0fb,43ef595b,2056729e,b1daecb,91998d1b), -S(b86b0c06,76f64537,f9d38200,66aeadad,4f3b68b4,2b5974e0,9f218d81,a547e04e,52a0e4c2,b827e0b6,894ee674,88a894f7,577cf3f8,fe83ebc,9e103a28,3c054690), -S(9212971d,b38b95f4,e7b9cae1,f1519878,80ca177f,73adcd28,a6d03e8,cefe9a31,9ddd4828,3b079a75,74afcdd0,e7cc4c24,45a4e893,ddc2d2e5,d24c413e,9c676041), -S(42a070d,929191fb,fb691944,a311c931,40740061,2bf33de2,809dceba,ace68f50,5429699e,47e22e59,b6cf8cc7,dbf2c81,23d90d2b,a48f6839,db4dd0c4,7caf4412), -S(895744c5,5b460749,a1e8b784,19e8f6a2,1e53f06a,ae99bb50,df9bd94f,e1a20610,a1ebffc6,da8a497b,bbc52ebc,4de1f196,881d88c1,948b05ca,5b0641e8,c56ab005), -S(c9e8e6a1,414b54f6,c19e9ab4,bd9bfee0,86a3e8ea,7a6b3e58,80cc5988,20fa512f,6878f69a,59a5be7f,3e60c1b2,6e9b9663,9097a6ee,7facc8e0,e242f56,e9a2904a), -S(dbf66722,d309634,872fa8d4,d9ddf8ad,2d198344,41a8515,7521b491,1e9e3473,1823095d,dcf42369,f3ff23,cb3a6ee5,273b8f98,7de2bff9,67dbac10,6b76928f), -S(b133817c,f965b7b2,f5d80c05,b82049b1,464713a7,7cc80d53,1e930434,387ea7d,db03e202,2eec1d26,4cccb613,7679c6e9,e08ef66c,f11378ac,add8985c,88f5e693), -S(e198a2c6,3f0bbde2,f31b8d67,776b8aed,bb86ad58,e2896a67,11b5d5c0,fd3a8d3e,e8df361b,ef77d3d4,4ca4f7d6,c554fc2a,9e2401ba,96769bf1,503b243,8d8306b7), -S(5f3ff8bf,148ec6f7,18aba1fd,8ff0b37c,18e440ee,51beef26,59652c0e,39ab7255,5da559a9,40e22dca,bb4270d9,31acb7b0,2b19d7fa,3495abd6,d5ca7f50,d6281445), -S(1e9ca439,c93cd0b6,d9886234,105fc1b3,178ba0b1,c71742cd,5c043ed5,56045c5,f7d31c2a,1890f586,214371c9,77501788,cf162d88,641a5540,c49ce4,323f3ad8)}, -{S(7c32fcd7,13305cc7,44fc4ff5,2d315e2d,d4cdf7c0,31b41a64,db6ecbf9,fd4edcbb,7f002bf7,b8e1b8f4,a4a4f2b,1922983e,fb901e13,59cbe934,8a31d91b,7bc86bf4), -S(d8aebd7a,db0ece5b,ff422046,6856ea0a,6446862a,4d0a94ef,ac7327a3,acb201ab,6e96ecfa,e9697649,faff155d,cd01bc34,e6c8630,616dd143,1c816c4,9d1168d7), -S(7dd764e9,40746adb,e6dc9e23,f113209c,7fa75c21,7da4cbc0,dbe257f3,cc0e3064,97e244c1,a0c8d68a,fc7a3192,b1f029e8,dbc41d85,8e0b273e,c4eff27,97e63ce0), -S(394a3fb7,320acea1,cf99bdeb,fe686508,15b3b06a,500df196,c05459cb,80b7781a,ec88e635,9615da20,cdb6a16a,245c694,ff550cf,cfaf2939,39103517,653f8986), -S(a394cc44,e64c4b5d,b36b4dad,d0a458ea,9c760e80,342b99f7,5227e22f,6acb0de6,de19b475,9fe10976,e9f38b74,1738b12f,e69df952,26c20d19,5f9135,33458682), -S(1277835b,322b7118,9ea416a4,c9a51518,e3a42d8,419f723b,d2b242ec,f904e26e,ce764cd2,558ffc31,779f610e,b33be553,a80a0dd0,1136132c,6e84b142,e5f5a8b9), -S(7c7527c3,ca6c3b60,18d6af7c,9ad79f0d,461e3d0a,c426e0a8,3bc1610a,80897370,fa7dc6af,7682554b,9c6f4b9,3822bd91,46bdae61,88fd2626,6f13af48,55ab23d6), -S(aa59dd0a,2e342733,a151e156,a82d63c8,9e992530,7bd774d5,d08c327d,27409a89,f14bb267,18ee5ac4,44390439,b8727f1a,f5b62326,fbdfb36e,23ff2f08,3a60e223), -S(733fa3dd,25e41c7c,4e548de1,17572b87,31bcfb22,57f0b822,1be31943,4bc2560c,976fc63c,e29bf97c,499e220b,80bc48d7,1fc07e4f,27afbe03,fb4a610e,e79bf820), -S(d6bf5a3b,ee8b720d,266586cc,70fc5518,a577cb70,44dc30f,210912c9,f1609bdd,bbb5bd29,290cf1b4,28fd9150,db667219,878b1507,121c6fe5,b1730f05,474f98a5), -S(b3a7824b,4da122ce,1120fa6,f5046205,e2989b8d,7c4bc118,d540c91,ab1e4b30,c7e452d5,d23ab126,28301b38,d2286c89,87d402a7,7b5f1fa9,ac033675,4f4461b1), -S(383beab6,dccedb68,d6c461bb,dffd27f7,1dee3acd,2d9bfc78,f9c723db,2df57ee3,913f9d57,286e287c,594a99de,f59ee375,c8d5fa1a,ca9db39d,6397d1f4,ac524650), -S(1de5be5b,6fd264a3,f9445660,995afa2,39587660,9d224d8d,6d02e600,4e7f74c0,f3abf699,af7033f6,cee828e,3bcbdeb8,fcdbba9d,d0f76121,a77f1e9a,cc65c1fd), -S(787be997,f12fb2ed,744bf579,eaf42ead,86d36029,e3063ab0,78e1c932,da1896ed,d652cb82,20ea596,70a51612,71249ce0,62e5c584,bbfc385e,622d7e0a,46a243c6), -S(f5870f7c,4dc65314,8c4ffaea,79154e05,1fcd6769,54939f5e,cc33779,f99634ab,fdb57c99,9d115b59,6d77bf19,e42ea2b7,c0dbf4c1,acccf2c,ef82949a,2895ef3d), -S(721a5aaa,c5bf9886,543b1e42,aff4c222,c6a63847,df9d72bf,7feb57a5,a007e26,94fb4bb8,fb1f945a,d53dd78,82f6a789,ab0dd874,9d1621ce,38bfa0e5,5b50bab6)}, -{S(29d70da5,92094c96,e293c115,42b9dbab,b30df8db,ac98416b,65b0b75b,b3ca446e,a8a5aa3c,c3269596,dd8a9d98,87a3b772,efa1c668,3f8a947f,ff80c662,31c70799), -S(357c14b5,2c0eb735,74f675f9,cd9ba0ea,9d0b5334,d7cd5dc,a8d6cfb1,1359a86e,85ad0fbf,9b2f48f,86fa016d,89824a4d,eed06ad8,3db7340f,986cc8ad,ebe9b5ea), -S(72047bc0,29b36192,b1549087,5e360270,a7fecd3e,1ebe8815,61e7e0e9,2ecc6973,7d1153b9,54ec6a42,3df1157f,fc9d413c,f8c3837b,d4c84bc0,40ee5654,6ec95d2e), -S(a459ac94,974bb47a,8e5d3ba9,169e7327,349ad551,ba8ad12c,fb4e15bc,d4894e91,699eedc9,aeb4bc3d,cdb97dce,2ca019e7,218ab0af,2790bf80,c59ba156,9cbb8c74), -S(e6f35f3,4a17a4a0,a76d997,afd9a480,bf8ef1e4,29441d2f,bd9f9d2d,b3b93bf1,67feedbc,de8e075e,fb80a4d9,2959104e,a990d813,2b0d395c,8e893212,d47a2047), -S(88924114,3997a2ef,1e36bc46,7e7f2fd0,52fb02f9,cd79f4b5,e6ddc9c8,51e26aac,3b1ba5f4,8b0a89ff,a4ce1113,934d11db,26b88e8b,2eae3680,57048db5,e5488936), -S(9ece7680,448a953e,5469839a,12fd31f4,f6d07a2d,434159ab,414bf7dd,60d783e5,2d60b5b2,e6966e5,7969016d,74059dad,c03cc7ae,f7b80825,9a629041,e0cb1b1f), -S(aa98d665,de5df68,9e7d323e,943d411,e98db3fb,51124855,256d0b00,579caf90,ab791e6c,ebca5631,22965594,b52b43c9,5f323834,53b37368,281c895,7d1226e2), -S(306bf517,c30d81fb,1d931b26,49af7c70,87246821,8562e255,42576f53,2ab4e48b,d0d15fa8,1391438a,5416f0e7,1c7b9ca4,512fc802,d4c46a4b,779cb1d5,2842059b), -S(2c8ed21a,fb154f9c,c3e9a6d8,dd047af9,c124e6d2,46da9faa,36a580ce,91b1788c,7dda9e28,6803924c,d8ce710b,d68e0a85,fc2f8678,45258f99,43bbeb2e,f6a7528e), -S(4acfe8f4,6ea97663,56ecb2e1,c3055379,cb4a311e,7e4dfe9f,642fbfb4,18abf5fd,a5d6abd0,d44bc614,ddf25ec4,24526070,100873e7,c4501c65,c3045e24,7478c836), -S(f7b1d348,378a094c,3e8ccc30,3dd8ca52,fcfa019,24c52fd7,32544a40,cf47d783,b92c436a,8c7e7ca6,6dfc1223,c7fad4c3,c65aa955,b8ce913b,45437e54,9dbbd1c7), -S(1ea80a5c,38827511,69cb24f8,64f4c1d,a78f4dd4,6509a73c,381627a1,7862ab8a,126c7a44,5fd6d3a8,f57a3a55,4fbe3f1c,eb9bde07,99afad93,fd7aa6a,11a0dd16), -S(e76aaeb3,9cc18870,6067a0f6,54bc317b,89a72313,2b2bf079,9ee88af0,41597d5e,6d75f6aa,19727219,ea7f6f57,c0a7d801,3b9bf256,d8764219,d261b79b,48ad6108), -S(c6d1b9ac,f9fec422,e89102ae,4fa07021,e6c81049,dd1e66d1,d0903ad9,e072398,2e971363,41b318a4,dfc4e5b9,31a79f35,f90e673c,6bb7aa17,a2ec5f35,def14ff9), -S(d9faf06,ba5bd56b,ee78db82,4db777bc,e57aa5ce,5c4b98ff,8c736164,d4d8b2dc,97af746b,fb890c20,7af10658,38d9b850,2d8d0524,7a5592e2,89f6ffec,a66c5168)}, -{S(7885bb79,25196ae6,f45b6658,f3c04f5,a3b76cb6,1d60eaf2,45cb35c2,2552267a,9839aae2,b4d9de01,1a119d3a,d269a821,dd88d287,2f031910,a2f3cc22,2e8555a7), -S(fac317d2,cb5e27e7,74deba28,d3c2cf69,4364a190,329787bc,e325d80b,150c9fbd,c56d5053,b0a73378,b0d5fbf7,940ac348,abb46107,1b9f0100,c721154a,4d084e7e), -S(9ed46b01,f4e56c79,9b3f582e,2e35434a,25ec32e6,ab497137,6eba881e,7ca96ad4,5e8d2e27,96b8dc65,867f45bb,a623c59b,a365d840,1d9e889c,23d6acd8,d5bfb365), -S(6acaf24d,fce1919f,c8d8743d,7a5b64d3,3010a8e9,cb6340e9,7400d143,53620af4,b767f30a,87b29f8e,308a95b9,6848eb5d,c8bada19,74cee095,8fb75735,86f1d733), -S(1a2f9605,fdb3e5e5,3445c350,4e550312,b36a7dfe,5df0dac2,23aa53e5,dcd7264e,cc4b4a0a,6febc03b,155a755c,187421af,52a7e6eb,2227858b,c56b9feb,4befb45a), -S(4fe527ab,42540438,9d9afa,2a1da83c,968fe9c4,f678256b,d4998bb5,af963a2c,66dea7b,7e0540c4,75799ec3,3987a775,6ae86d43,56a295d0,fe8242cc,27ad7c4), -S(756ee16,fd1019ac,30e50f18,5606d1f5,fa91a7a0,b01329e6,2a949c80,b7590bba,4d190439,98483880,6323163a,6cb23a8b,e47152e5,a5439d24,513d30e0,21511050), -S(63935d2,711ec4d9,f33fb116,ce09ea58,b45b29ab,79614b14,278539b3,4ac44e83,703a7f21,c47d413c,9235fb0,36a7b441,87a90768,2d435953,439f0624,6550944a), -S(fb6bad0b,3503cf55,8a75531e,9e8915df,9a88277b,c766b37c,d9685b58,a91e3fed,483feda,8c214ac0,92ba5274,8b158b62,3a0d541,65fb5b0,7ce07e58,78cb39d4), -S(30c7d349,a9fd4825,82fb09de,f7d638b8,633fca82,b9bbd65c,ef8f6dcf,1c8c05b2,56c76d9d,6df4bd0a,a8030dde,a3839728,71aada1b,61bb34cc,1eda08ee,a14761ae), -S(13faa439,f73bb77d,d2423e1c,9989808f,96d98080,af214cb2,e0cde511,9eba8a14,ef6ed341,7ff03112,ece400db,b274d225,bea30a63,c9a063cc,9a987827,d3e380f0), -S(42112f0d,7628b3bb,7a0e4f0a,eb58d2b,9915f797,10aca7e2,67214532,2ebf502c,a1ad23fa,d76d983d,6cc4a654,95da8d6d,c5372849,d7fdcff1,34e5903a,e8441ce5), -S(d23fef28,114b49b9,77faea5,2bd0e30e,6a9ef11b,c513cb8f,3107e04a,e26a9ceb,5a4cd8b8,b0dbab13,2abc50af,c9d700bb,bc28dc84,3c12060f,612134f4,fe40aea2), -S(463bd8fd,21ba250d,1eee7500,e88aefa8,38211947,fee2be73,d6511300,6d28b5da,20f6f300,e2744ea0,1ed033c4,b5b9e7b6,707c06d4,d97c4771,ad35e305,b11aed86), -S(21795062,e337d1fd,994a7cb9,7407d33d,f40ac1de,4a585c1a,2b3ad400,8e03c4a8,e93a4632,da05b347,8be71e28,c55af8c6,b4b161b8,9f48064f,31755a1c,f6b0ed96), -S(e8f77f4d,272c5dd,f001f939,4b658b96,d58a54aa,bccb9de2,c501211c,6cf9364b,7044feed,21d1dd9f,80705bf3,d68fd160,31c02dc8,5a708f18,1bb7ce91,8655ea61)}, -{S(422f029,1f51c4df,af233322,7015e4c1,ec8175b1,a8ab6b2f,60a9e291,7242d940,51ae32b0,ed5d39d,e1d61437,d363d59,181a68b6,4e052bc5,9d132da0,9c1f422e), -S(f560c762,be8f90f3,b12c1447,4c3a2d37,53634a4d,fef3344,ba8e9a65,1becd50e,49bc8c46,e3207440,76082021,6d203410,fda33028,d3ff4ee3,af065502,ec96609f), -S(edc545ef,2402bc41,c4d7b437,65830ad7,f79128d5,91b4201d,1acb5f90,a7ea6a46,ec758c41,e0ff7bb1,fc28a91c,435c09d9,90338a6b,216504d7,a538691,6af80454), -S(67709f77,e324ec1a,fb57e5fe,43215f07,3cbd3d48,f6cd0bbb,c01f3ae4,1a3c5905,e65102d9,c33abbc4,82f2ed0f,fb156cbc,20210eda,19b5b345,f21150f3,ffb29e79), -S(6b73d1be,a5b5ffb5,438e4cd8,9af6d9c2,bc41a2d6,a9c6b405,ac6fe5d4,6ff920cb,84f7e06,6dc9bde7,782c7636,8aed4a2f,e570e51a,8494864d,88e6c1d0,ed732be9), -S(5aa1e427,64c4f0c8,60423a6d,54cccad7,f6093ba,b6a0e383,9e1e0b63,cd652121,3245d2b0,fe27d590,15cac18a,861d9ed4,a5131871,38faaae,4c01d1d7,759fc9dc), -S(a8460aa6,9cd68695,94288486,1f92a61,e7e924f,1d61b9be,1d31f923,efd803a6,f6bf9b9b,f65a68eb,925f6c63,4d16a6b5,6d92d68f,fb807084,7f09c0d9,d95b852a), -S(fa3b7d59,bcd32e9f,a4cee765,d9b54c1c,65d8cf67,8a88f6e5,3c3192e1,64143cc7,95ed2300,2f55b1c2,21061dc9,bd26f0ed,82c05ee9,4bcf1bad,3bf878e1,3ff33b84), -S(febd5d39,68446d45,fe1daf28,2018c980,f4a5030c,7710edfd,b79daa69,c10f2296,b8c37c65,bc7c42a0,65be333d,1827feba,70eb75f3,5f289e1e,413e2325,5ab9d551), -S(9d696bb4,4dbff608,af3ba93a,e98993e7,4a6d8902,42d406a1,7ae9c609,6bb9b29e,d92c5408,c0ec7131,9efb50d6,18875060,da65855d,8b2d1cc0,9f07f3e8,c0e1d77d), -S(8f4c98cc,21d39520,e837b075,479b8646,2837665a,ac82541d,1bdda842,ca5c2562,3de70692,afbdd878,5a858fe5,51321576,95f464e,cf2c1237,545b1e06,a1cbbe6e), -S(6d31e611,2317acb5,f2ebfc35,a4f66f05,af86ed84,720335ec,535c0f5a,cd14d952,8d22c3d8,32324673,9b20d9b3,7fc73b78,fdaf98a9,6cded077,6e561037,b2a85b1b), -S(dc891a7b,d96f10f,b6d8fe8c,1c749ea0,328ad2e1,353b49a9,8056c5c5,b637df01,475aca0d,c67d1f8f,92f6ffea,20c48300,2b0f7d3f,f5d2526a,cbd8b89f,25ed3eed), -S(c77ede67,1432ef33,73af321d,7d8fc6c0,f254aaa8,37feb14f,34817740,a54cb5b,ec2f427a,cbb9cd4d,96f83c7a,450efa09,6e12917a,122eb466,23c6b63e,dba11010), -S(7334718a,cb39692a,91c140fa,67c21c0c,da368242,aa1d0d2d,7223a0d8,5ce102c3,e3051cf3,4d5e51e3,901449a9,3595fcb4,327c59bc,1e2d92cd,4d4699c2,26ae4e84), -S(23c7e5d2,2b0bab9b,b95fbfe2,e39e6902,5c7bcc89,fad1a0be,1f5da48e,74b3f622,bc5a3ef3,c4679a16,ba09f2ef,4fb202a7,83257a5b,3f95b629,455e4173,9b5b317f)}, -{S(43cf2273,e372157c,2180640,594c144c,93f64fa1,75f28cd2,5e7efebb,14028a93,1f8b092d,4cabc600,33782374,10eafd04,37d6436f,6064932,6f8de6d,94059d4e), -S(83bf8ee2,2a69edf4,74e5b45e,50aa0bdf,4879b4d9,61d4b937,ab18d3,7869fe5e,296e8081,cb72663b,5223c040,a64c7aa5,273fc6ce,70261af9,cb3e071a,79b7c3ac), -S(66b8e44e,c913698e,d68f3b1a,df750442,442a4376,9ebe7859,84e4d233,9f666b1b,b09c7c2f,852bae4d,f90bcaaf,a664c792,ee88ac87,2d2e046d,aa6009b2,2412af94), -S(fea69879,e4eeadf9,275589dd,6339111e,5d29c581,30f22fb7,c6755d5b,2f5840f7,814a6766,65b54689,b3e2d415,4519bc8c,9676cf4e,91b928ef,3586da12,416f546), -S(bd147b40,5c3ca694,ceb4fe83,5f95676c,5428a065,add89f79,ac5859c9,7dc4d5fe,67544f50,a639f7a0,602a5fdf,2d425fb3,edea0cdd,f2cc5f9b,c61189bb,79cfbf58), -S(b3806514,838f93cf,6118c8e,f759cf82,394bab94,e020ca33,7d20c8da,bb61c79d,bf4c1bc7,35c5a806,d682a1fe,239a1027,51a547f1,7d1d87fa,59c9384e,3ca1fe45), -S(bb002b37,60adf886,a89d4ba3,23c17868,83f0f3dd,fd4232f1,28410770,563ba5ea,4aca65b6,68115f32,186773d8,41c061d6,8d4a860c,442b3f8b,c72776b8,3bcd22db), -S(7857b661,420c4251,3db90fad,ab97bfe1,9a1e3f91,5d524f66,86d0cc01,70652ac,75205776,8c2e420c,f255f9b0,df58bf4c,39316f63,612711c1,fc7fe5c0,b4e7ef7), -S(cd386b61,bfbd43e5,109b74f0,5d765ed0,5c4ceac7,85bff4a3,c8386ca9,54fb4553,aeef237e,892a3a1b,84183222,91f9119,64bc7240,2f32da46,47a159dc,4a7d6611), -S(94dcee6d,e36b346d,4dfb5ad6,3f488761,2a5734ae,e251b07d,6f81a3cb,7d255409,3265f73c,af4ef3f0,40919637,4e273be7,c0588085,1940bdc9,9d0ab66c,c488e203), -S(53199671,628f4a30,89e65e28,67489a1c,7f29c9a8,a34fe8a,c144623f,9ef9fc4b,45740e72,3b787de5,1ddf66db,96c91bbd,19954170,62fed0d9,69522916,7b2b10aa), -S(38596053,40ae3e91,d005b3e2,3a998796,195a5c5a,81b24286,458cb7e8,ec905e3d,5484588e,c9dc9485,bce07479,b1dfe9d5,c5007d9b,eb7c372,f52e526f,7627131), -S(594e1bd2,3a5ced9a,98e48bdf,dde40807,b9c2871f,79e1948d,7167b59,9ffecc53,1d7fcd4,bb9bf0ef,e0af9ed9,8da3e36b,2ceb0ea9,e1e3358f,4a590022,f5c530ea), -S(bef8b23f,95e0bdbd,3c0ba1fd,7afb8a58,1f038e23,e3e9eac2,b8848a08,6f23f816,9a234d55,f9c810b1,afff2a1e,b1738d18,4308d19d,11a0e1ec,cc571eaa,b9663c26), -S(632003fc,f53c8833,5542f216,e4020ef5,3eb225a4,be6c0e59,b92ebfe6,52721652,bb4d2dc2,f255b8d2,5c1803b8,88f40d8b,bbe6b2d9,f6754511,8264f809,cbd61844), -S(b7ae730a,e74aa208,9f3266b1,5358369c,4970c009,e6318581,4d541b07,c6c80a96,43a7b349,66b4bd5c,a1e45593,42642d35,ebc969da,544d4cc,65519915,34e80d65)}, -{S(9f10aba7,5a7b9fa0,233bf53c,d819ba2d,919f8acf,9a5e6717,2c93229d,547a40bd,85485295,254a4456,87b065aa,dad21f32,b31735e1,96333fb8,11117a00,d0bf2361), -S(75f8bcf3,831197e8,b9053c1e,5194155e,dae1867d,52f74911,a478085b,52d916b4,90448c24,35180385,a15a335d,a33af722,c9a395a7,16937aa6,b861aee5,b0b9567d), -S(2c05f980,7e24fd5e,87e4562d,65aeee0e,315ebc12,35731606,81e99bc6,be544c8,3a3c9e33,2e78cb5c,8ae90d20,edfc9eb0,3ba0ee07,82a158b9,154999f9,55e89210), -S(c8ff77e3,76a2c4ce,46664e1d,b33f281b,90e34103,500a9a46,83038062,42e59969,1d609bf6,2f6d3e86,c0510de8,4a42a45b,3fdaedd3,77101216,e43c2d86,751d7456), -S(b3205953,aa71cd5c,88ef7e55,3b94c8e3,ec4fd654,b7524c80,51908174,32850864,2c5d67dd,479dcdf3,41db7c5a,e0d03776,f3fe9ece,32dcda0,274a7955,b45edae3), -S(cb903c76,7ad3cd58,66c66429,9e9d07f1,cd35043,66784cd1,af3fc75b,73c4499e,8ef65e96,f1998688,2af0fedd,e0266d80,780ec031,fa47cc38,9e7bd059,eac83ba), -S(1a975b06,9e3f032,7fa9b706,3533fee9,f72c6c11,7ece27e9,cc83934d,a0c5d1e6,2cf46c5b,9f3596d9,5739dae3,a87564f6,13eb944c,5d1b6da5,3be8d76,14ddccf9), -S(d708ccf9,4dd50c89,de00a127,1cbd92bf,29f440b6,401c28fe,699f6f6e,50e0367f,fb173384,e0463978,a15de0ea,2ce146d7,b826f6a2,616d38ab,ae0a3dcf,1e11a1e), -S(11d850b5,4aa10ef7,8959f5dc,4aa9ce13,8ffa25cb,1034a365,234d0f6b,46458146,33162f6,bbb5ce33,af19cdaf,57dc82ec,69291c12,38e8f266,fd0becb0,bab02e8f), -S(7cd60401,be3033a1,85784a4b,adf9dd84,f4bfacc1,952597f0,6730f2d6,924332a2,6efade89,37b517f2,e1a1d41f,d6e6c137,d581d7a3,b55ec632,74ef8b87,1d9dd370), -S(bd82a0d8,34892e4c,974aa93,a64edeb0,9aa2e3b,16785166,c970206b,53ecf157,541cd14b,1fed321d,5a044abe,aa3bba7d,74c3f44b,db3f1fee,b05ddaa2,1f034ac5), -S(6f77bfc3,760934c0,edad8b77,f56d6309,179c8fd5,bbb731dc,42c279d,89f99a44,662854fa,e1da57ea,7e8eeb13,b3bf6744,f28cd210,ed461ede,7883dba7,f7b59d6e), -S(f31d35d4,dd0b2e6f,5b236e98,df56ca98,a5b6db2b,a2a8e0c4,eba41ab3,20cde154,e33e127c,b9c16469,83d71085,ec7ec9aa,12d41302,fa769c61,55af26ef,a7d1785e), -S(c0ea3ba7,be2030c7,790a3d48,7e720893,2e070691,82bd0024,5483be62,7916eab3,f5055e6f,298bb6b8,47e99275,64cb29f6,54d2131,1ff0a3ba,20a89ef5,992c0342), -S(23a696b0,e70e4197,d299abd0,b301b383,3df6f123,80120247,9e8b59a6,10a1fcf3,3af29a3b,ce23b0ce,afd9a25c,f1505958,b85d4f39,318a402d,cc48f98,ea953edf), -S(ac79289d,c14206be,742005e5,f367c4b9,e2b645a1,2c21d30f,ffeac884,e6f888da,27c49ede,7c0b42cf,91de7682,e6f224b,2a19f98f,72f40054,69c3121e,da2c4379)}, -{S(b365ce49,d21ca341,c173b6d7,2238c56b,f080d218,a89e57c6,ce1664f6,5c290a44,e77935dd,75d26531,d4045f72,3b4b5dc4,6608f8b,60f58989,d2ac4002,c304cf04), -S(af35612a,d1230c6b,3a260abb,69cc7099,f7025c1d,2a14d196,1914236e,4d4e1a44,b67d23d0,8737e96e,f629634,44b08f82,822c690a,b3d2838e,46ba259f,bb951b2f), -S(183181ca,37069462,5de3c48f,b8140ce9,84029874,e8189b4e,bcc8d91e,eb8d681d,a1780f41,8e7f00e1,e5ff8147,33a34699,79e6fd38,bfc03491,8acb042e,6ef4d6de), -S(4c1db656,41753e4e,5cf10f66,9a3e4b06,e18b3d0,1b56961d,8c400ae5,9ba239b8,cc57dad5,77b3d6c5,d96109ef,1006e33f,9c888598,c7248f60,5a531800,dd0c957b), -S(f0f61e45,cbe01564,17fdf9e6,db32d3b4,84fa0bbb,4be30aea,95dfc8ea,31529ee8,4b0de888,b71c441a,1c54849c,7e4a8129,d757213e,52b1796e,a5ab02a7,87087757), -S(84e4bc99,7066633c,a3997a55,a3fd3ef1,b4b99302,74349fb3,5da10b39,2f49a022,64512422,1acc41ab,68644fc,73b39a3c,6bcf1268,849bfc5,84aa7c85,4a48efcc), -S(a71007b1,e0747b7b,1b8b4398,232ee970,97f623ec,4924b8af,16ea98d3,6f98102a,91039909,9c42dbe9,1bdd719,d31bd00d,e040752b,cedf9927,77e0863a,96a5a259), -S(2f72cb7f,f0aed6c8,ef75c041,4ebc413c,21705889,de3e33dd,d3057668,4f882553,86450b7c,bfc89e63,ba1a1754,ba42125a,8b41f12,d5a5582f,ad86675a,b05bf998), -S(99f0e44,e11ea919,f16fa130,5ac6e72e,c11ae9dd,e08d3143,2ea9aed0,f902cc77,43f4e6af,ca0605e,749623e4,18027ee9,c64c059e,560d6c80,6219eec7,e475367d), -S(1aff311f,bed263a5,edcebb0f,e149302c,c0cc2b0b,92c69d33,d31c5522,eb9c9a94,8533cdcd,97190439,48d38bb6,845ca07a,9a9485fd,dbd44868,7f06143f,e85f046), -S(4a2dfcd1,4f601607,43273bfa,3702be5c,57f99a6a,29fa7f92,666d5020,6ffc852d,95931301,821cd6fb,63203fbd,a894de3a,57eb75b0,2f273f3d,bf462727,301dd9b4), -S(59c5a0da,480f334,944608fe,a580c302,965d26a0,dcd43b31,3854b302,af6abe35,40e27b3e,932ede7b,40490224,7b937b7f,2938edb0,a11b667f,16a90ed0,2a0309e4), -S(570bc6cf,fec905e1,564906b9,ebdecc13,60abe5a3,61f7c5c8,f03cd2ae,3ef9d125,55bff728,1f73045,82fe61e5,d4a92697,77503b39,9b320c45,ce5bb9bd,35def5c5), -S(bd7dab69,88ece4e3,621efa68,38a24032,ae9721c4,fcd835d8,6283b5f8,f9f02ee4,c7442cc0,95009f1a,193766f6,d050d165,d8cdca90,2ebe6d8f,237fb922,a1b6fb06), -S(a780a23d,eb8459fd,7195ea96,e8fedf8e,8b38edef,e0e0865a,b1d69d85,1d27c65c,f8c94632,a11f7185,9e3c7963,f24904a6,536321d5,f5e4652,3195f854,355de49c), -S(f0ab42b0,bb80f147,7f9fe3ae,f5944100,14a94142,e8312b91,86b0d6fa,3f0243ea,237a6ab6,b5e08f03,a7b58f98,e72227ac,6d3660f5,43da0694,b6821c9d,332724a4)}, -{S(38186a1d,6092b158,554f3f6d,c6de049a,2037577b,2da8db39,163fde30,b19dbf2a,a8cf045,9c7ea28a,415d01f4,47566d54,f986cab5,eb272326,442f32ef,cb6c43c8), -S(aaf937eb,c2084f16,301bdb4e,aa106263,cfe483a7,d0ba1b16,b93d921e,80f03a4d,7e18642e,8be01d91,86366b3c,c94aef09,c02501ea,e084a87a,a94d2d2,f85f84d9), -S(128b8279,ec2731f6,cf2ceed9,fed2cb49,f53d6237,112a84fc,c678189a,8e19867a,fc0dedbb,32524c1a,f44fefc,6b0e6bd2,ba65f23a,54f69986,52953154,41a89489), -S(7c3dac1e,6d89c8b6,e9645ec9,39dc634,a2cf5adb,323be29f,625703b,caeb21e2,a1b87f33,b5bd9351,15f16702,ae411a91,b3e9eb6a,814e678e,b3dd7431,6dff896a), -S(609d5c22,c8c7c1ae,211b4ca2,f709a1ab,75624b91,cb95d2d,6ea6baf3,eacc12c4,65a7b252,f13d08b,4b007967,69e6bee8,edb5cc68,d4ec8c46,527bcf77,535bd7bc), -S(691534e3,2faa9206,5fe7e8a1,8a863d78,afeeb581,97b1f48f,4f090bb6,9d3f9d11,2bfac0b5,35202013,60268e74,2376b901,a027d6f8,f0d91aa6,59341544,118a325b), -S(e6736a7e,e2f3f088,27012faf,3b3d1b7e,ed8dc136,3421e438,8ba70c5b,72eb4eb9,5a9b2651,26652e14,8fa3639,be0b4d5,1ba519c0,1285964e,7aa8a699,45bc71ef), -S(e3f05d6,2aa7b9d9,6e9480a0,a3eefe32,f1f6d45e,2fb1215c,ee5a3fdd,f147b154,47389f33,e03817ef,1051db5b,26efa711,46cf673c,12831163,2ee13576,b8508013), -S(b5041a3f,cf8b742a,dee6540d,e9974cbd,fe527e2f,4842a208,630b9d2,239c0657,4ea01569,fdf5b2e1,7631d2e8,2c2c0bbc,291d69f2,fdeb077f,4ea1df9a,6303ad57), -S(e5463af8,5dc090f9,9ff72771,c1cc3585,dfbf9dfe,329e69b5,fd0ac2ef,3f715ad6,c54085dc,a966fa9a,985d8e46,79335dcd,2d22d470,790f71cc,1d0aeccb,be9c5fad), -S(104b12f7,8fdbd727,2a5716f1,51238362,94261142,48209abe,e4dcbb4c,d7bb0416,ebb07749,12a3ce9a,e20b6696,e485811c,6a15ed53,a1015291,90672c47,e4442c6d), -S(1699a1d8,d04a07fb,32fcecb6,ae89092e,fcaaebd4,fd9c4af7,d79a5eeb,2c18da72,cff1a93d,4ccd9199,9c6259bc,fc975ab3,4992c8e1,8d1cae10,b0c1ce2,83101103), -S(13df43c4,4de2fda2,4b932131,e7c7fc62,896f2747,706ff959,85f98248,4cbc6179,1da341b8,734cec8b,74de0c08,a040ff68,d8d30ef1,dfe1ffe4,72ffc73d,a6a82a74), -S(2e101469,1b7e08f2,d3aa774c,f8f91ae6,e9aea711,fddeccc5,d816e5a3,dd752dfd,cd4e7f49,998ec720,a3ed2e45,8136fbe7,9942011d,da5d7fd4,2c56ed77,29f55b98), -S(b0296b3a,f9e819ac,a7b01bd5,7977ea85,5d2ba87d,24f820f0,c1ad5f84,6b9d10c1,192cc5d1,b6782d9e,e3f444ad,61c0b8d6,9772062e,7b03c615,b1cb7550,a76e1d11), -S(f9a11b59,6e369694,fd62d423,518e355b,a796269b,d2b5a88b,1c8bc812,40fe464f,8c919e60,86160ff7,8d1ce269,4512c16e,75f8a79e,da39df1c,ad104555,6d1543dd)}, -{S(d8e5f3ba,c152215a,8cf8ca08,40aaad6c,7d001aa0,140bb0b4,dcac726,229ee272,e59390a8,21e8608b,e53fb258,a426dfb6,ca762fd0,9d574f7c,5555cb8d,7174b381), -S(c2d7dc95,6c6721e8,6effb64d,5e1c4ec2,ffb13a28,706669fb,ac30f035,9d202663,8cb207fd,63af5339,f9a705f5,79f446cd,1a11c0e4,cde750cb,803b840e,5a4970a5), -S(bb3445f8,d7f47cf9,befd1a73,76dd9c96,f6d76fb5,b6d4b7de,e7f96dc8,c9e8f025,c1fddada,756d03aa,7d92135a,a8dd783d,63920238,1c2f5af4,7e702cbb,97ea783b), -S(1271c587,d72e74bf,286ae688,c022e129,f9a95567,9f74755a,24e85d81,486699eb,1259045a,cb14f2bd,7d5fc85d,d8c58303,9181d367,63e4733a,56172be4,b19c4a40), -S(76274ca3,884de253,ccd8e9fe,b2f7ceb6,1c7b6c49,1a358b42,e64994fb,80808263,d2639e7,539ec38e,b14c7d83,47fc4d10,c2a2d83f,81a1e4ad,1ba8267e,bfdd4dfa), -S(8d80c172,ea0f7e79,d3f2569c,49d49bf8,330cff73,fdce6b14,3a4a349d,e7cec2d8,86dd76ee,63fb3a85,ae315029,3e2d024c,ff1649d3,c823ca63,5a1fd992,975fda33), -S(441e6584,10404939,367bc434,f1c64c42,5b2bd11b,5beeec47,35919f02,4a4626f,3db30e8e,29e6cedb,7bb465eb,92526c4f,4b7d8361,b151ddb1,da878a87,86d83573), -S(10d89274,b0d498f3,d29df723,937c3838,49b4ffd8,b87427bd,a1d142d3,160c2b88,15df3d2d,b11e35fd,a423c709,24e497d9,77941b44,20e3093e,539d3406,e2fcf435), -S(3960dea1,9431a970,6bc4e886,8cbcaaf6,dfb9c87,17e664d0,4ff6eb5,4108f2ce,3cd86dfe,6d967078,9f090213,4661a7f,78e4854d,7e79e519,7283f8c9,a89ce6b3), -S(a1f9b8bf,15de0a59,141449eb,3a52a335,ab881489,7a7ae82f,964d3bff,f1dd38d8,dd563a40,ebbf06d0,84e21a10,dfd117e3,c8806975,53556b4c,2fb51100,6b498d6a), -S(17cbba26,9cf2b92,7d442075,396090da,62a2026f,ce3b3eca,858feb21,76659de2,71f31851,a2561f97,b0ac2495,d72904a0,bdddd83e,83a1dd87,b0db14e6,ff1348b5), -S(10dd7c20,902512d6,6484c830,53063a20,c7474504,3a378949,280a90b9,f8504102,1624bb25,937d3b47,43214401,c8016fff,f770f7ae,7d78d8df,381c2de9,13bc856c), -S(7ecc1dcf,5e9c56cd,43cf311d,5b31d269,50db89c7,2b51b624,745b3c75,eea68899,3ae1b7d,2e8252e6,43b73aa5,6d7c9b62,1f79d1bb,1d2973c,1bc3b150,a17d1ef5), -S(f57d8aa8,ca4c8377,14ca1ac8,e2fa456f,4c94b304,fd0b268,2084ab52,3768827a,2c5bb2ee,e4b509b7,7cadd78,4202c12c,3644ec47,9c599009,581f8b6a,7ef5bc83), -S(74905ca2,7116aec3,b96d16cf,fba3431f,5ccc3cb7,e5747525,124b5b31,bd6fd066,7d26da6c,1268cf67,846954f0,48c7dcb3,3a1244b5,8f0a8026,c3dbc651,68cbe871), -S(4e0b7166,de12f0ff,baeb2464,ba205624,e85b9238,4a3ebbcb,db9c6038,94ef0cef,8a85223,cf784126,3419d777,93fb66d9,19e3428c,5ab844dc,d3d9cc46,7ea95c10)}, -{S(f41bd2b0,e0f49133,747e831c,af4c7a0c,22d2b55f,1cd4ca53,1115d81b,b47754b0,869485d7,26d4687b,c57a9eb6,e90e93a7,bce3b523,998d16c1,297c996a,b68c4fa3), -S(ce2e4f9a,3c32ea4a,2198e61,8d7d88a9,153111cc,fc114a46,cb9b47c,63842146,5c90a793,c4f4b290,240dfc0c,1dc0df9d,a33214d8,3024304a,d49eab61,8c4d64e9), -S(924f51eb,823a89d1,3194305b,45ba1f8c,40a58987,73cb1a5a,a4a4017a,b55af76f,8cfbe8aa,d3b759f6,14c98aea,3b3443ac,46400a2f,5cf741ac,c7f590b3,39f3ea0e), -S(9f985579,fd32d32d,90ec233,c5577a12,b1fc350a,e94b5f08,ccd31cc0,33495f5f,ffae345d,8bae4446,bfd5b6a5,117c0b77,49cab9ff,eabbc8d6,531e0c34,fdaeb328), -S(b4d25ec2,6afed742,2ae7f209,f4201d0,91dfd595,3418bb05,12b1ce25,455ba8e6,8a13f82c,47489b6c,72223047,e8e079e0,165edf0,4c335814,b971a5d8,27d2cab6), -S(7f4ce1f9,acd1d262,6c6da2f9,7dc19ddb,ba3f15c7,7b6c88e6,3b0d4e41,a40a3c7f,750468cd,33a35da7,242142e1,e68128e4,b5210635,c4739aba,910ba9ec,c9c01fcf), -S(67f46710,16d87e34,b2d53d5e,c54f9fa5,f22c283b,a3dc5a17,70fc4a16,1a2be4c4,70503598,1378a67d,16827d9e,c87c591e,afb16fea,6a5ba182,4f6cf6c1,fa92b772), -S(1c30c0ad,43b0a74d,fb199442,b151865,7cf99e26,fca6e2f2,1cb97a6a,53c15893,3728e682,72a4020d,8365b4ca,eb153fe5,162e79c6,ca6a851a,e233a160,400b625d), -S(d92d821,8443e951,ad6ad28d,b7bd7101,756d91a0,cc3deba4,219ee34,ba2f6017,fc3dab7b,ac2436fd,a39a65d4,596dabc2,b65f8f0,c1195a51,5d8f2bd8,4f5530de), -S(3b6264bf,a47de486,3ceccda8,fe6c55a6,ab1d8188,d111b222,4aae150d,c3517ee3,e3f786ce,5adc8660,98965a41,62f4f510,8c1f34d9,2451af03,8f68e5f5,8f6c58d9), -S(c6b7190a,e4d0c14d,b3cba3db,c72fadb9,da9391d4,2eb7ac68,4e1b20fa,d89749ec,f4b7f04a,b1358c35,1b2c622b,aabf3e5f,dc5abd87,ab3cb388,86f73d91,202ce359), -S(c2846da6,a821c506,e022a927,257b8d21,57d82def,196f32a6,78b8cdca,d085779b,d5431c41,4ea1417f,3f4d90cb,c776ee29,9a6a8557,a256b3a2,58a887fa,fb5aa256), -S(7bbe2521,1f987b2,742b6266,d2c598b4,1de04ff,70b689aa,8be97f8c,63829bc8,dfb605ca,3491a434,e53fd0cc,d8bb2188,c6dbb06,cb18a9a5,cfc6844d,400982fb), -S(81a92f34,ce6c4383,a058d74,ac36b44f,f4bad7ad,b6ec6a92,87db84c5,9df3469b,31639fd5,7842ad40,4b204b26,7570a557,91dee70b,ac71630f,90924443,47597c32), -S(9e309152,54a25340,8a533606,d8f8dfb6,9ff93f1a,9d97212e,c261dcf8,ea3d1d7b,ab95d903,ccce7769,cc185c1d,4e24da15,b9c05bc2,7977c754,1b1023d4,39d75d26), -S(f72ff9,92e06721,559e127,28169de4,888efbee,e87542f8,fe0fa971,189baee7,db2e60c0,4678d370,cef335d1,d3e007ec,30dc03c1,f31c02cb,796de00a,f856e440)}, -{S(67c452cb,e71c61c5,8aaf68cc,b1f6208d,5646432b,86774f8f,60081179,6d5337c9,d5f859de,a125aee2,11dcc7cb,b50b4fa3,ef4f9767,7eb94f65,b6a181df,9b938c0a), -S(b068a1a0,e36426fb,2d959715,63faa818,1da81aaf,3ba3654a,f2570e0c,3d373d2e,9d29d11a,9333182b,3202e348,f547a9ac,ed5b6468,83608526,682b10b6,e1ad0f0b), -S(e33d0069,dcc14230,760f13d4,59c4ae5a,8af0383e,e6f37eb3,13a8b7c,587e0c30,aca7fc55,47536053,97b56a7,4d814548,993e11c7,4b89bf1a,b50ecb40,b9cbb5f1), -S(77f40f78,10b06a83,71c1493c,61a816bc,10f3b70d,5fcd025c,54de5036,eb6b2ce4,618187fb,f124b864,d69ae6f6,c9eb674a,eb73a074,b95194df,967b804b,c66d3e56), -S(d0ebe599,772c1450,979c403,25ef498b,69548f62,907bb455,1fba8f0d,c7b076f7,d0ffa315,3b96c94b,cb97af89,2f845295,ccfd1146,d8c682a8,3bb7488c,3fcec2f6), -S(2fe20698,39f33753,819d4b74,f0a036e9,2aefe03f,5b55f504,d3e1af7,eb5cc0eb,27e67641,1aa1a970,fa0fa0df,8a147716,b52ac4be,489194bf,3f192ae0,eceab892), -S(94dfb5be,319f7da5,ef283791,e6375480,1c337607,32f8e66e,bc649943,af99262d,4fedb692,4c6dbe8b,daec8caa,4273f77d,4736b73f,80446c5d,d4116329,5008225), -S(a0147c3d,f958362c,177aea45,908de2f5,afdb005a,89182e95,edd3f4e7,74ee0cf6,c81c0014,b273d2b6,2e7d40f9,d9b169cc,67ebc773,be51d8bc,7f35ff75,f0eeca0c), -S(91fd8598,f0a9c4b2,130310cc,417e7a3a,c1374b1c,2c76e675,f5f1a7df,32b1b96e,f2f277f1,154afaff,774390e2,e87bf67b,a722ee5d,b502a1c6,24042a7c,779d5a45), -S(613b839,a2dc9731,a2ba890a,e8f7c966,ab3c4237,fc14b05,7c561f6e,208c77fb,22b63998,85a758b5,848a318a,5aac49fc,aa14c4f,cb29f020,842280fa,618f235a), -S(653389e1,3b7f87e8,8d22d0de,d8b1de4a,b4902d12,a0c36e76,11ed3d0f,e1efcb86,ba710bfd,95e40d1,a4e8b4c4,cd1ee147,e01ebf1a,74f52483,4fc5148b,65a86e4b), -S(7b5aaf67,bd31c86b,e4877624,85b35fb1,4f6f480f,69aefa91,30e3208a,f9f9997,afdce71,1bf55d3d,4cb01dc9,3870e40a,851a8c7e,a7217607,1d3285f5,c727a9ed), -S(bbed5d70,be29d810,51bd811c,7f237856,7d097da5,cfb2d891,c0bc86da,7d680dec,229ba9e5,ddeaa4cc,498cce34,abea1d19,567e3a6c,878f8fc1,31be7b06,f8550aae), -S(1c4562b2,1dc0d0c,1c4bd826,603d07a2,8b7545f9,29e0cdde,77a1ce23,5d378d1b,b8976266,79671f6e,bd0b43da,9eef06bd,99dff8ee,5092e19,f260f468,ef16ef0), -S(a9edf307,c7fd7446,d71be12c,267a7135,688bf7c6,8f1dd65b,eed8208b,897dc380,9a20e692,9437be50,36a7b701,ad3a6a77,82234965,cadca1bf,4992da4a,24438f9f), -S(3bce25,ad7ebdd3,43645652,954ccfe1,1c5e9597,fa3a9f83,d51ea36f,2b55aae4,cfdbf98b,7f3575f4,4d37ac16,41352d12,bbf7e13a,4315cc04,3e9ab067,b3e41c52)}, -{S(56d09714,cde8f0c,f1956cf,a56bb0aa,b73507c8,bc0399f8,c0fd17de,19e48e9b,d62e1f31,b40ca6ba,71de9059,8a9fb911,6c5f0007,df0c33eb,f50db688,ef0ab90f), -S(8fd887e5,50b3b108,f17bf25a,12187b64,4b173b13,15d5dbb1,c9821c4f,9d05a37d,7b2d3e3b,731d83f,535c0c5f,1df2fe54,b1eb7c02,e43e73e5,42d0efc2,c9175fc1), -S(64331c37,736130c,78f719a7,52603e28,d8a48c9c,33e3676,2ddf079,4647588a,9f214dce,bcf18bea,5aa4823b,e72df87f,634e37e4,6b8e696f,41ac44f9,76834a5d), -S(6bed1320,7626f62b,4e323e92,ffbca06,4b682d74,59192c6f,a3569567,cadca363,8d435e2c,da580046,755f375f,b226ac7f,86d15c33,71114737,fc09b8f1,ff9d311), -S(e1c8c67c,56fba327,fa0b3790,8dde77b,a187df50,e2b0217d,8a151344,4cef208f,7be39f85,450ba36d,b2d46fa,457c68bc,e6c7d140,ac1f6f60,cc95d12a,b3dba197), -S(9e927dc5,427d6859,30da46a8,915934bd,4483374d,263d962c,fa0e9710,6cf285c,cb9b2596,90224417,d65d7bad,f89a946f,df0f7b68,2a28099a,118c146a,598ccf01), -S(fcf97f06,f70b77dd,47ee5661,ca5c5653,5b770d5a,ca61e88,10542124,92fa3748,5df3187,1f5af498,605324c,81dea770,67aa4952,7736a0e6,cd3cd6a6,ad4f185c), -S(f8922d31,8ee1c47f,29a5df4a,66ea44e7,7ac4ecbf,2440c4b9,3815f249,bc5a1b28,9377d8bd,548e7fa3,bfef786d,bca70039,24509e9b,d22e483d,9218fc48,34941d62), -S(6b7de62b,9c928cfa,e9da1197,951c010c,34dfbb7b,b111274f,ed5f4552,20909188,207d06d5,719938a4,f69be3ad,ffe9e83e,17d2e500,7d3dea3e,f34336f8,df3d226a), -S(e948b128,c6217752,8f1d0569,697c656d,92a92b37,34360795,73c9d7ab,61db30b0,7518e35e,1a5e4e2b,64966fbc,1185e7f6,b59766d6,a8fbd37f,36dd9354,14d68af2), -S(9d932075,5fd767b5,87d8cc95,3b2b7d49,4967a9ff,9fe673d3,8b7aa621,3dc4d7ae,80c62686,e574233b,21f8892f,7f8e3cf,4e05c47a,db687e38,4ce2079d,16fd7d36), -S(46eff49d,a6d4dd71,108dff71,e706a9a0,952a8774,efe6eb8,6cd28a90,1b89a8f6,8b26310e,ee49ba70,77f085e7,cb2f82a7,97fa3d50,c96e7148,892f57db,f89e3544), -S(72a59c5d,6286d1fe,c37b7bb0,ff34f67c,4a632530,37a22efe,7dba0305,2cca87eb,a3770634,995ae65d,c48151cb,f2e5efe4,bdb30825,cccb1277,e9728741,ea2832b), -S(1eb0e1c4,8471f8d4,1e34c22d,16bad4f8,2f0cc863,db92d412,8d7487,1f7f2f3d,232f76b7,1cd83c5a,4349358c,a661639a,b4d6a5b6,8eed0f11,a674385,8ce7bf95), -S(d4173198,3c8645f0,ec134630,7c6974f3,1aa396ad,f01a91b4,b618304b,34cad3b9,3825cdf0,bd454a15,ea3d18d6,b07dd5fa,42e1c46f,7fb6a1cc,f1a707e4,74b83550), -S(aa030fd2,52791775,e051f0ee,be7d6902,7da01452,67b4e712,960692f,1d59f72b,fc83d72d,5a0edc4e,c05ecb54,7111a10d,9341df1,b0544177,c2eda0a6,70980ba2)}, -{S(31095045,658b8c85,ec0c4ddc,7cbce691,d060181d,ffa08855,f3f36722,4c026225,9a8cc527,1c231ce7,aeb6e73b,9acbc16f,4b331b01,4bd457b8,799bad40,547c210c), -S(372f6cd,9a7b7907,4f730fa1,8cc1db50,a9747818,99df942f,4f2ceaab,e85c6678,7c9b42a3,81ebd00a,8d4aadaf,2e34daaa,e57f0633,94631677,ee675952,3c72753f), -S(77e7096e,7215e184,cb096b45,54f60fd9,4fc5f7b7,28bba5bf,be2a85b1,1984daf6,4a913cc1,dae55633,9a90de21,746d3e55,7e8db814,c23aa361,be967ccc,cd319643), -S(fd6c827,34bfd6d0,a6130095,d2c38135,e7992c34,6e85d7fc,e5b13410,767620fd,a3996aa6,1e87830e,6d2da97,5bd318f,c44ec9bd,ef552204,f3ecb761,b4541df6), -S(24824f95,be9fea47,be33b438,d855e2c,d0d8982c,2d8a0b0b,d84bba5a,eb8cf0b0,d7e5c1d4,d6c708db,a5b51a46,310bd68b,18b521b,e765fb50,e1d8978c,6460f1a1), -S(d1d2e882,62b62a1b,63ee8e90,31f37d7e,ba90b95a,3b577af4,c0bf5d4a,9cbc65cf,b88f4f9f,62ecbd5a,5165ab8d,92126053,66d719b0,9c5d41c7,539d9991,76d004a8), -S(9118fd29,acf4c565,1ee732d3,c606d374,c4e5306d,90614ae9,d5aab499,4ad300af,8498b6d1,dfa4b247,ddc437e6,cc2f4dbf,d46b4562,3912a2c6,1dea8068,c86d9e54), -S(c303d808,8f33b08b,ea8e2490,d8f4a108,27569644,9a116564,41166838,d6602b9,af7a213f,d6131447,4be0c27c,39abbe1a,3cc45c97,6f28182d,cddd7d86,ef1c26c1), -S(4f09e673,cf4036ca,6b466d49,11b21cb2,421ebd98,f336c6f,9be27aa,7dafa17f,d0b9b5de,d7517f0,f452d744,cc5c7201,f292df97,e70cf642,4879267c,160ccc96), -S(cea44dbe,7286698c,dfb48302,deeb4345,71ccabfd,844411bb,f0d63c70,626c8bfd,2cf9e22e,16dbc1fe,8f159bd0,36ff4496,7eb0d11d,977e181d,a885b200,a552108d), -S(799d8d8e,8297a1ed,5052961d,646c44fa,787ec15f,62c0ea1d,13ba4ac0,3b42dc4a,9ac6c9fd,e28c5dbf,23c76484,6ebae2ef,b4cd7e57,592d6608,9ca6fef6,faf148ef), -S(b7630524,9472c060,168677df,775b6696,97f281b1,3204908f,dbaaa74,b87d555b,5b157540,7c35c69e,9537a1e9,10410d6b,9c6d461b,9a00520,f6850bc8,9628bdcc), -S(9866d83d,7d9fe0b4,8db8c7bd,557326db,c74d757c,d0f063b5,a05eea98,7847758a,f664b109,f96f49f2,b06f3886,4f7c7e99,de8ac6b6,ec08f946,3855bd5b,c74f512a), -S(6b5cf6bd,565f780b,ad85093,3da4f5e7,6a168a5e,bb3c4658,c9ad6945,99ac1d0a,210f9b03,96d9d3c5,f2fd3ba1,a889cbaf,fcfe0bea,af2771fd,c021659b,835e639f), -S(1164bba1,af12b041,55796a4c,d5b17da4,db37470e,782b7875,ed553675,201d72e5,9f5e04a3,3b913c09,56e72111,bd99f2e5,1de13c2b,f496b72d,3b7bf9f3,42572d37), -S(ee09a791,3ddaadbe,13b1b198,a3e4e63b,5cb2f591,475827b8,1f9b81b4,1449dcda,88fafeba,bdd965bd,19bc434,8447f3b7,91de017c,3f89b292,4a6c6f76,839bc6f4)}, -{S(da34375c,e38127dc,cc88a823,55d763a7,2dd5d733,d9bac216,7c3e621b,ede529df,13426579,db1353d2,8095e1f2,a007904d,5c04a725,2c621ce4,41157aef,d2e28cf2), -S(a781c07f,cb52597e,f229d634,b3036507,c297843e,3e784024,d38b0025,72dc3009,e4fa3bcb,511877f0,8369465c,475dfbfd,e0973309,acd09a80,a9d191a4,e21aaa84), -S(d879e837,bb9174e2,19108746,91cbe6a1,9e19efc6,199464d5,2c9ba4f1,d32fa31f,e092c41,35550370,40c786e7,c3d5f72c,6be6988d,441829e3,85b1bfc,f1f00bd3), -S(9fe2fef4,5f1c5e21,110aa61,ee83af2d,2d409120,c6e510d4,dc2945b5,936c8ff4,a1d3701e,26007255,f4b8db48,bc6ef057,a7c146cc,ff50ef2a,e5f8d868,5a684a4b), -S(f2266efb,749fdf5c,dca22eba,8b9d8141,4b8cecf0,1bb25dbb,85f6e3fe,d88e55c4,11acf31c,ad2b4ab6,f3036259,a3b54bdc,6b8100f4,36bfc1ae,a17ba08b,8fdb8bf5), -S(527063af,4e7ebc65,2d45ae2c,e2149c26,f591b12,da157351,bf8b97d9,d998d007,3cdb282,740ff232,d9ac9988,8f0c20dc,96476b79,133af243,eeb01413,54c71ec8), -S(aa067591,c038a16c,2bb18b54,c6357140,731440f2,2b972152,d08726cb,f5654abf,81e8b530,a4997fd9,ff4122b8,b559c6f7,915b3d08,96ecc8f9,dcf01aca,f1f4a61a), -S(7a147e92,6e2b916a,c23e4fa8,d9349aa5,449e65fe,c52f01cd,a7be7863,fa2a1bd4,d13d4e2b,4e64a8c7,824b3051,e277da45,fd947048,ba7f9f09,6e6a6189,f6ae356b), -S(394773be,c4c8587c,a330f243,5ac5057c,f833333c,4693ed63,3d0e780,8d31dfdc,1374bfc8,7b1a7ad2,7c119dbd,cea325b2,c663aa4,18e9f62a,d5cdc878,88c8874e), -S(a1b4edda,14ce5c2c,ed276886,5a3a1519,ff2b56e0,f0e06741,613f7b3b,37d001b9,e462525e,6a1ca74c,be1e0973,139b2f1f,2b1458b7,dacf6f66,cd80ba4,1195516f), -S(a2a20ab,b8cb4a84,9625000d,a2ab6d80,6a2006d7,6994069b,2e50c83e,4aaa183d,3850f9d7,bfe1c1dc,b066f603,8a71f78,352d4cfb,44a7d646,81b86a7d,23b0b468), -S(d66412ac,30ed909,4c282dab,c40624ff,7fc5a593,494a9be2,954d0cd4,961999fd,ad6ad3d1,e3be49b5,402880f4,c67d1546,7b6d01fd,63e4f45f,f87e5901,7b8445a1), -S(ca666365,71fad850,3205e1d3,6c0b0062,9a6347b9,b9ad0a92,10ba208b,57fcd0e8,821d0dee,efc2bf47,4e575d10,83d63505,67235026,e50d9fad,541fb097,2cb196fa), -S(310184cf,7c38bb82,b04a80a7,5c4678a9,985336b0,f60acee2,2a048e87,bfbc6970,4e21334d,6440e46b,a12bc971,31d55598,94ec8648,ab901a94,c757b957,662b41f8), -S(e051316a,62329ec5,add4bf12,4fe30288,dacf5e82,b0977184,7c64bb4a,8c77802e,3358bcbf,94e23384,c9be2d87,79d56ab9,cc0fe4ce,23eb227a,741a3be5,3fdf36ad), -S(1dee1a31,e28d970d,11436760,7861cd75,292cfc9f,533197b6,7ce40e8c,62db266c,7f9c4f61,f534b388,7f00bf73,469601c0,9c6971cf,3ecbded7,63560e1e,ccd0e32b)}, -{S(a80dd274,9cb3c40d,af91b91f,6e8b0850,27fae17,96e416fb,8a172c27,d39e8789,466161e1,e9519ac5,e1b03652,cd1ce6cd,1d7dc696,aa59ab5c,565d822f,af427896), -S(493c8d4a,8a53ccc5,67d531a4,c833a8c2,6ebb3337,9f1f2330,9ffc7a5f,90ad860c,eb52116b,e4f5075e,e391948e,d7970c28,ce156e22,cd3e5820,ed0158a2,1158ea73), -S(42a51205,5158eff9,ed9b2df3,3f17a809,ddea781b,b0cad4f7,5ee9b16d,f03447e0,4b305c2a,987f11c,1700cc3c,b09914b1,cb30379,257c122,cab089da,b0115e93), -S(eeac8ba6,c3397ecb,ad93a0b5,1cbc9108,29aefb53,50a9bb5e,1db9ea58,a33dcab5,e0eaa01a,4596cbfc,76f418c2,6fa382ab,699e8ea6,1b700f76,98f5b913,da774b70), -S(33e903c6,ee45628,db06afde,dace17e8,bf8ff9b2,a4d1e3c2,c43ab4df,693d71a8,a9abf657,94edb2c,80a50e5c,e210f39c,fd37ce86,5eafac01,65191deb,adc9f379), -S(4af6278d,2c4ea624,c4a7c264,5fc4e5c3,85a983e0,1f5c0c2a,bab8c101,8ab36425,4af48c96,64a8e40e,33812cf2,6a4495d9,8bb7bc4d,3455e03c,21ed94f1,e6fcb069), -S(2855cffe,89b73f36,c4851fa3,92ffec8,5b7b4c7d,83998c67,ee8e710a,473c9f72,ecd7c273,c26c1d7,4de7bffa,6bd26a51,cfbf9716,7e9875da,cab2e632,25766e83), -S(1b06d384,d0fb68d6,396314d6,a6f12d91,3853306f,1a904494,24fb2c2e,d73e88e,3de9709c,cfb21234,f8d687a2,e6364caf,74ec05e2,82245cf5,9fe5d37e,e7e3e7b5), -S(cef34326,559a1922,ff354887,54a1bc1b,72d70955,33591c3a,9a2b871d,8845a9a0,aa2a7c74,6a149ceb,b276bc9f,860a96d0,285e9a46,d62b2c15,c9a78701,7cdba153), -S(39e39d53,d9c619be,c9204156,1c8dd8d1,4f5cba0c,94d93295,352c8448,d9ab988c,56c6817c,a33aabed,d8b724,754e8764,72e065fa,357917ab,d9d03199,4c04c3dc), -S(28cf0dcc,2765d3a8,ae99c40f,57d14adc,5d21e730,271f2465,142c5369,80b21878,908d84d6,3774fb34,774931b2,12530d35,8565392c,6ec35541,1cba899b,3fa29e7c), -S(383ae3fc,7967167,ad6dc50d,4af64da0,f5c44be5,4ac33d3,6779a8e4,7ec657d5,11ae57f7,6ef344c1,263974e4,25f27e6c,c68d25af,3c748935,f554e4f,5cc16ba2), -S(9f11beee,fdf9dbbd,c9487b01,869a7b18,c8db78d1,36027914,bf363f,951b1b6f,335899a8,7abd3401,d2ca87f1,ca330c10,c098f7ab,cc2d0206,faa0d8aa,e7726aae), -S(34278948,b6755e7f,2faa3674,f766e6dc,5029c644,55f7ba86,34e45370,a244eac6,f6e04f4a,f27a8768,23de58c9,d2ecfcaa,63a5027e,b6c7cb1b,428a159e,2110537a), -S(44828d6f,29e24d8f,1e1fd7e6,13bec429,27a1fa28,803b1ce8,ac43804a,bc2a4411,4781fc5c,6039f0f5,fba6d3fe,4fa8cc9d,bf9c3ee0,4c42a0f1,8835ecbc,b15a2168), -S(903910a7,1cb1f65c,838f84af,a3167c3d,f396436b,1c76403a,5526344c,ecb0a948,19978bd9,d0563fbe,d9cb07c6,f88e563a,7aa007d2,562feedd,5c8fad6,e555e66a)}, -{S(b3dee3f6,cc08c0ba,5b7ba3b8,50469647,34f7dca1,630e806e,f84157e8,2992c765,d523bf3c,6b004cbd,59db62b2,58395f63,d487d6ce,31799ee1,59ddf96e,d9bae2e8), -S(f5c52e87,8142cf16,d01aa78f,179460fd,7a8d7645,498118a1,a1ec386b,c2860a44,868b7621,a41ca177,84d6b4a4,d5a5ac40,ecced5ea,d8d5bf13,e5bfa29a,5f998c38), -S(26412ec7,e11e9347,d515de0e,98e14920,522610a7,2c090b51,f03bf049,86738df7,11a10543,394f932,19284377,1a2d0741,ebd89e8b,4a0c0dfa,8f8cc5c,db7cc207), -S(8e313452,7bc65ca9,241666a8,bec7c6f9,b92f2f46,c91c3843,e430a22c,4e6a92fb,bf6e2a1f,122f4b35,aadf5b3,c03be0d8,406c0b74,c3e48b1c,85023996,a0eb1214), -S(ed72bb0f,4800c2f4,2db83b49,137af4fd,40d53e5e,d690fe42,b93d8cf4,a603d3da,4dc24219,6e195c7c,c1bd412a,a0982a97,80ed39c7,c1f34181,6540ea3a,e52f0c27), -S(a84809bf,a6592d13,47f1f37c,e7a052be,d4a5e06e,e27c369a,61a74f26,552786ca,7bb26691,5e544c06,cb7aec5,aa61979c,a77bbb52,67dbaa2d,13517b40,3ead93cb), -S(889c0732,6ba150eb,cbe394a5,3bc9eed1,1c6759b0,4f8b82f9,79f24efd,b2469dff,6c9a2c99,7ee4f506,d3150dda,71ff54f0,88d8c904,596fd99d,d2f5017c,9d72fac6), -S(b6f64c81,b5e1ea08,8b712eb1,7a7ba7c4,ff4821e9,3e68c16,7f385e5c,d5e097e5,99286e7b,2c2b49f6,2c2a5d9a,58db244,5e5f4981,b1a7f40b,b0f86004,40e249a7), -S(4b131fc,5d5c5020,48aa2195,c079cb10,8bd101bf,bf4f54db,793bff99,3c2e4a0f,a689fc36,fb782cb5,c9722f4f,8f123ab9,5fc02dd,d1caafd7,eee117e2,e58c6609), -S(8bc5c221,9248c065,b713a126,facbeb63,ef435ce,6759ced7,62e189d8,82adfb92,6663fdc7,32a65abc,8b207cad,dd72ed15,68bdf3bf,c2e84345,9f964f73,fa325216), -S(ad8ca6f2,f29699e7,c4b055c5,bac3738e,d3b390db,21512a70,c3bc452,e231722,fbfd004d,174964ff,273fe355,d76281f,b47fa1be,eae7ec13,6e4cb5ca,5e703b54), -S(12270e16,b82ac7b2,20bee7f9,8c45c6d7,87d14d3c,2e9a2201,67650e2d,c56110b0,390c44c7,4d01351f,78b80029,e84b211d,4cba691,1201864a,d0632466,ee747bad), -S(48cb4d0f,e669f556,5c7e630b,bf435d0c,b0b47511,553301dd,a9bf6e35,b59fb9cd,be02b272,e6fb4e3e,79d6655a,aa37a132,8649b74d,4ab6d733,6cbcd1cb,d02d3f60), -S(558b4a91,b01ae7af,dbe952be,e03987d2,bc64337a,8178c079,f06ee88e,88b4fcc1,1dd61340,ab7dd93a,6b6e169,a4879fbf,75d24270,b0708cc7,51552ca4,f6018052), -S(af5fb90b,d4d48260,9fc8f8b4,34724c8d,162997f2,a6afe68d,97a6bf46,629aee86,ddfea22b,6fd0c331,68a196aa,29c0f0c6,7e828768,15527132,99c37e69,f788c4ad), -S(2ba58b64,b588a995,3872a303,8f478ee7,ae03b805,afa95c54,62920a80,8a12228f,b902f3ef,aa4a081d,1260030d,44d31436,7c5a5b7f,4ccc47c0,1f82035d,af92c39e)}, -{S(df9c2e20,68e1e333,f6acc6c3,ba9928eb,e761d4b0,27eaa1de,dae18079,29705021,491f455b,6e937f91,35fe9060,a8c5b6c1,60de5af9,ba90aba4,c060145a,da1b032d), -S(17cdf19b,1f93cbf4,47e2f77c,6f4adee6,bb62f01,8011e8c9,965eb336,899d4b6b,5d5d7d2b,33222ede,aa07c15d,7f07981b,a7a80c94,d9a4f2fe,7413b4c1,dff20e7b), -S(de7b1e48,3d1e4e54,39a65ab,b74bf705,92a75671,11f83390,78699547,ad798cdd,61087a47,1c37aa33,f538234a,9179e9ee,b4af8e89,7d1f5afb,497ae5ac,8609f8ce), -S(8baae56e,4774ca16,4bb58827,896bb7fd,6dbde044,3e88eb57,aef2cd98,e3968870,7edcb7e0,29411a39,bdc581d3,3a8769da,d0bb62b7,49e2e05e,4b698b73,d77471d), -S(74bcf4a8,18f280ae,6216e44b,fa8c65f5,4de08ee,14f2451e,ab85dbb6,33ecbc27,a72d7c82,19b2307a,3747a6af,e17480bc,12fbadd9,f326a09b,442e5f7c,fa18aa28), -S(8c24276a,5f468d59,d55a0ece,ffd642ca,ad8a7dbf,bd3ca6e9,abda6a3c,3e66c01c,b7463b3b,6fddb0c,cc2b9006,a7af9ba5,346921c1,ccfd24e7,4bb2d09e,9cf78c16), -S(ca4c86a5,438e1b85,aeb79319,95bb4cbb,c2ca6eeb,22eb18c4,449f8050,f8403023,6a86b9d2,d205188e,f6bd4414,1f9948df,7d9bb06a,538d5016,fe310d53,b3a95d18), -S(768b3d99,cf1a2d36,972615c0,b9dd964f,74692061,1d36bbe,892512,5855ae6c,5e821acd,1a49c270,b589b382,159ee4aa,ddf1a163,3f00513a,935f0f05,d4174dc9), -S(f69a77b2,368aa4d3,55639610,d3a4d6b2,72638efd,4ae36772,3868146c,50a81e0c,afc09cea,e975c008,c02827f2,86b4a85a,25e9f5ad,7e26ddf5,fe73f77,edff3141), -S(4d266e6d,8805e372,2ae985c0,3f808e09,4012a97,23cde34b,cc119732,1e3eeb4d,5747f4bb,38eb2a19,74315a74,7fecf1be,2633e3b6,93a6571a,e08bc2d6,8ee984ab), -S(6ccfa6fa,a5bc8629,10cffbd1,c7815328,bbe40716,62b6e66f,3e6db1fe,d796430f,1bb21cdf,c4aeb248,454a6e96,e6399a56,e872effb,ed3c89b6,95d52598,6b801367), -S(2bcac4d9,ad3f7bb,784ff508,3ee24058,871f92c6,db50cefa,3d84707e,8576c271,c2faffb2,f59066f,1ef1e186,3510f9d8,236d9d6c,37a9d5e2,9dc1bd37,1a349074), -S(4ab261a1,8413f27a,328dd402,4dcdc6fc,6d31d071,f479d8c0,f1857f0,2ace11a1,e53ea413,8cd3ff01,21acc725,345ce814,a6739aea,e4600dbb,258df68e,9e3dc4eb), -S(7c276455,398e6e95,45e253a6,b6381d74,1cee69cb,214686be,a81435d1,eb90c86,704bebf6,c434161a,66db20b9,5c859064,a339ffc,35510e49,bc378440,f6794d09), -S(b3a041b7,cf5e1d80,ed040d11,851e5e5,292b7a20,b125f018,979d2853,4e0b2d6,f8f8767,5801504b,98013371,525962f8,d40b44fd,d54862ea,4bd33629,b34deba9), -S(d10e348f,403ae107,5ac0f8af,b81b17a3,aa0d51f9,2cc8d271,2bb2d4f4,cea9a881,5fd767b,30135e1,418ee9b,b83719e0,5f99c3a8,87733c13,695dbdce,c1b26ec0)}, -{S(afdfa934,6f7bcc74,ec473e17,f5048650,11c5251b,bd6c0c70,c25cb561,4b004da8,b16eec26,d575cec6,b8720f94,4ccdddd,78a5c446,a0cf286,fd933f6a,999a4a39), -S(5a4fce51,d54d54ba,b8148e3f,2f8da91a,50c5a4c0,409be13b,723f3ed,7879e1e2,5ae7c52c,f602d6d3,b68f6989,f6e7cb97,484de6f8,d729dbbe,587756b8,cc8b2d1a), -S(53831467,eba14563,3181b826,839812e3,36c1a17d,ffe4bfae,f2baec53,ff428d8e,fa471d8,73ba000c,8d23b0d,6bf79d36,f57a7852,4aa8c52b,227fc42c,400b4fe9), -S(ab384400,3f19fcfc,10055f6,290a0540,cf2242d0,ccab8a4c,40319440,54f0aebb,af368bca,e17e62a,ec0a5544,4d65ecd3,a497306a,eff4a439,92e7d1d8,ed5495ea), -S(ed08f215,50f6510e,e8cb5e09,53ca47a3,9a140441,cd7dc8ac,2c319ca8,cd51c781,39e4c088,589c9851,b78aef9f,33678f7c,ed46d4a,658ccf49,b1c4de72,9fe3b64f), -S(feba0c3d,930d3c71,d2edd2e8,e63e5f67,3f81ea4a,5f8890eb,3fdc6e6e,9c729830,a507a2a8,a0fd3d76,214f59d0,cab63525,54148970,7cd0ae2c,6488efac,7d494d99), -S(f5da1419,be3e268d,b51dea4b,af8867f0,a02a29c9,599266e6,e0e37b,d569d8b,1ecd596,4748be32,44cfe953,6fa9ae30,104b1e6b,8ccd69f4,1e5891e2,242db1c8), -S(eaae3a45,5aa38fed,381ed64f,b6353d0f,2236d267,97f5dc1a,4e7a511,1654be5b,24f1dedd,7f3d9cef,572e7819,b09be2a0,de1f2f4a,6b2314f7,57a81b18,cd1fdd08), -S(a997a9f1,e9fb824d,768fa890,b91ec55f,c851127,5c16eb4a,99577fe4,87d155e5,9cf136a2,c3fd76f8,d4921bba,9d61917,b6ebbfa,f55a4cf5,69665d47,bce7a44c), -S(f20287b,958ffe72,72d443cd,de9fa6f5,f9ab208f,a74c6147,10c44c33,3777f1,ce614f5f,87c3a366,65d7f574,5446d80a,35a8113,1fb4dd2a,aabed948,b9e09931), -S(f9fb85f3,fc4e45a1,6b6eef55,cd8656db,de777390,f20b576,a28110da,e8ce5713,51de9f5a,7b2f0101,cd02e6c7,c98cdf93,a430d62a,1fec4f3e,95bdc3bf,a2212e13), -S(d5fa0933,f13c1f4e,89caeba4,101f44c0,420da5c6,7bfe1ea9,66cf01a5,ef48b1d8,5efc8918,8b9eb65d,faa6e0e9,812407ef,35d8db,76f9e722,ff63bc3c,3afc3b1a), -S(93899e6f,fc291a4b,e986f938,b8b378be,bf4c3d35,f9a1bdd3,ecea5f04,d8f4bada,a19a2983,55cb62fc,43334649,1c89f26d,fbb67bc3,872f7512,9229cb73,d126293e), -S(8fe07488,b5b173c,d530d796,a18eac08,80164c2a,ed787b05,90ac8dce,3bb120d8,829abce1,43ea8009,e4f5f481,125ca6d4,ecff3f32,577cdbf1,c054a23e,67f18b0b), -S(10c3b093,5461407c,369494a7,631eb4a2,365b122e,ce0a6b95,7c1bdbee,387394a4,f09d69ec,925c9a43,57648509,f7db85a9,22f609cd,32b400ce,3a80567,88a74627), -S(cfe48dfc,f5566fbd,7562ed68,576a7911,baef64f0,dc63e158,1a29bf23,3e1a058e,440c6051,19f2a948,b4b6c3a2,7e711cea,c7983d7,f4a2db9,537536db,fdebab76)}, -{S(53d772b6,b18211f7,1478e9d3,3a0c061e,2d232358,44177867,af91508d,e014f22d,b2e85a07,8160d31c,3ca32d9c,ba025904,1bea0368,d9eb13de,8af8f505,73142ed8), -S(b9d6067c,fc26ba4a,1f5bab8e,d5f28ffc,bb6bd6,b61990c4,1b091ec8,2cba973f,532d0ab,7731c02d,91cc7e51,71b625b3,af5a605,d92d02a5,fc4cee4f,afa09ebb), -S(e8a93ceb,3db0a4a3,9a3b768c,700fb504,652161e0,4a1d4d92,df52cd4b,83e65e38,791b967f,22543fea,9ec38e5e,a14a94cc,9d11ea8a,73ca0c13,e022d53b,f8bf1148), -S(ac6130f7,41e1601f,5a92bb75,90a799a8,3e8ad9c,c911ed7b,7dee1bcf,da14f332,97ea5d16,d5c7e368,c7b97c2d,7283cb03,f215f79c,d1d80276,6f9923e0,ce80ce44), -S(ac34d4c1,1d2d4ade,2f044e88,6b57cd45,c1b23550,538059c4,e9855077,4132643c,7191e155,aeb3b578,6b55db41,652e8af2,bac1f933,d6f62723,808c6172,bf0eb0aa), -S(a7c4bafb,f1988992,1ce15754,187d41b9,eb653dd,bc97cf05,ddf449d8,c9ff734c,ccf20733,da4aab6d,81db8d5a,d3f12d1d,9cbc943,8b92165c,e83c5afa,5ee108e3), -S(c04ba857,e758fdb0,29c02712,1671fe33,9b7184b3,50ad952e,9d234681,43f7568d,9ce5d9ca,65f96b76,b4b06f57,f34de7e3,c64a1d21,f07fd6fd,eb7d47e7,bbf4e6c8), -S(8230e7e7,81259e58,e9b74a49,340733dc,252bef7b,5b7dc82,a4e99f0b,2998ba67,9c71921,3b3254d1,f53b4f30,d0a8e665,186e272c,d0e5d316,a7451eb3,2ac8bb3f), -S(720c2f5f,6465d38d,3916939f,8d095657,e547cc5f,849f4a41,30485b1,2d94b5c7,8635961f,5f74d176,e4ae0ec6,e4b3b394,6d5b1766,fcb902fd,9f9bd982,2ad4e4c4), -S(263b45ca,b3547cf1,5eca4381,3d1c402e,5c209d3e,34a288cf,182aa4a3,f04304f,3516b1f3,524bbdcc,fddd94bc,fb86a43a,27a7a78a,fcbbefdd,6692fc21,87364438), -S(4edb7d61,a45ebb51,1fb0c220,6f16fe60,5a202976,9007c3e7,11b94889,a983d0c8,b482fee3,fe824b1a,3251cd2c,3f38ab4f,adad1fee,d398be92,58d2c81d,79b0eb36), -S(f44c286a,b8196e25,87c225f7,2091db05,e47f18b,5b9a0b9,79d2cd3b,15441767,b7aa2018,5925845e,661ad980,a6c215d5,fd7072cb,46010930,ae64089,4c8a0af8), -S(593f9bdd,b246bd1e,19eeaafa,17e348e,5199decc,8e63ef68,ed8bff89,bdffad48,5201d11f,a4ac67db,dd66fbaf,5c2ba20f,8bb1a6b3,18cdfbac,6b257aa8,d30dd316), -S(823b4c96,8be9e125,262d52d9,4aaff240,55def10d,6353a347,e4248de0,7889ecb2,adfafa7a,fb1c60e,e7fb3e2e,73c66063,5a9e97e0,4a38a120,b7a81f17,7d1a6c41), -S(8daef78b,c46e0f5f,858fd74c,68be31bd,3b474d9,6bd74deb,eeba69af,5ef3056a,15db0684,bb6d4e7f,b135a4ab,f4b81d4a,a9fc7e93,c26e3616,b7b938da,25d44a06), -S(2b7616ca,eb608427,5a14eb53,b67a2ee3,b831fb55,6f63e0b2,e01650f6,e6900a0d,915e7dbc,62f8e349,8ffdf22d,d3604d77,bb701137,b6c36543,84cce993,c4613ca4)} -#endif -#if ECMULT_GEN_PREC_BITS == 8 -{S(3a9ed373,6eed3eec,9aeb5ac0,21b54652,56817b1f,8de6cd0,fbcee548,ba044bb5,7bcc5928,bdc9c023,dfc663b8,9e4f6969,ab751798,8e600ec1,d242010c,45c7974a), -S(e44d7675,c3cb2857,4e133c01,a74f4afc,5ce684f8,4a789711,603f7c4f,50abef58,25bcb62f,fe2e2ce2,196ad86c,a006e20,8c64d21b,b25320a3,b5574b9c,1e1bfb4b), -S(6ada98a4,8118166f,e7082591,d6cda51e,914b60b1,49696270,3350249b,ee8d4770,c234dfad,f3847877,a0a7bcda,112dba85,1cdddf00,84d0c07,df1d1a,a3ec3aeb), -S(a94ae8,63264dfb,b910ea95,4ce9ca7e,4f86f92d,9f3a95d1,ed61552a,7a3f5743,7f53f7f1,6ad2d08f,15e73314,6d80467,41557acf,19556c0f,ed7117ce,37040823), -S(b692c750,d23d3674,c351e3b7,e1a8a87b,14a5df81,852eaf35,209d0ec5,6e22a2cf,b18c4f17,252db89f,838de32f,b3340ea2,bb961a39,54b38c47,f9a8219c,4820a0cb), -S(691fc741,80e75b55,47b375f1,1bf60abe,451d27de,1743a436,5f8e4bac,ad421c09,8eb5fd9d,f3c03240,6cebf370,8125955f,bf2ef703,475d3fd6,1a0291b6,69b52d9d), -S(703b5f14,a7d82473,1196b52f,ae9ca8cb,b245b004,7a9928d7,d0c42f33,391411dc,5ed74eaa,49f276c0,4d61f31b,6da4137c,bde5673d,8e3f815d,efea7951,f88585c), -S(29b8ec47,d241eda1,e51bbb1e,3928444c,3747b4fe,7cecb365,2bbc4587,2f504875,88693238,8562f8bf,f7d72324,62ebc54,6b93a95f,77936b02,eb1cd6a7,d4199bcb), -S(444a07ad,e81916c9,32bdeec2,21c556c4,6b7f6491,e99b479,2cfec82f,4ec17910,2e084c2f,eead5200,77c151b6,eff9375a,713b9d15,5306708d,b3f538e1,8eb18cf), -S(e0dd618b,226ceddc,f560527e,20b4fe58,e5fcf28,39911ea6,c3e8a4a7,e15f9121,a063a157,3377bbbf,1b9a5ebe,afbe11aa,660c1e65,df1392b8,97205858,3c86a3fc), -S(9b99461a,2e8360f2,f2ba0bb8,bcaeb699,159e0652,69d9042a,fa0c4e30,a7b6f30d,3fe7fe04,3cb45303,3d4f5560,7d41cd76,9036a49b,82912350,6d8b9995,254154fd), -S(504da3a9,d9d9c81b,c2065398,4ed28cb1,b5beec9b,6ce5dfb6,cea94e54,fdff044b,cbd40d1e,858133c9,cd20b9e4,ff9fe94,f7cc9579,39e6df49,7a6bd702,797f96cf), -S(ddec0aac,1ebce6aa,ad6300d5,60f0e503,829f0bc6,479641f9,b19d9f6,484376fb,332ff5b1,fc83085e,736736bf,3c265e4c,8f80925e,6f38479d,6563bc34,e5faea1), -S(dc530ceb,b82c246e,41c522f1,d2571d31,4b14edf3,91577a2b,64e42172,b23562c1,563ddd93,857d6529,8b81de24,19e5cede,7a4c5b7,a2fe98f6,9efb8906,6f32a98a), -S(7604d60f,418dd132,78058942,fb2d2153,c0a2bfeb,e83c5011,a451bcb1,58db0773,38be14ae,d9e1c404,63ef92bd,d62c599a,b37625a8,182a3763,4fa2de90,535d50a9), -S(cb896744,77b20829,f5e2bd42,8852c70b,91cbd0af,cadf219,a69727b4,cbec8d7a,5710d17a,20ea0dff,980d3f06,38d8b910,b8940d00,dd4a323f,d777d942,213e1093), -S(501915b1,391e083d,e88c795f,8464c846,f699a79e,edb1b963,3e29f71a,9ce4d022,9e1dcc94,17ceb0e,15762f8f,7d0db85f,3bce3ad6,fecbe2c3,567853ef,ccd6d0f9), -S(a63c0b8a,4eb2cb10,1e556904,a7246356,9909055,f45aa4c0,e89c2237,cbffafca,9650b428,12374811,738f4ac3,a2ac0505,396339be,4eeeda8b,c35e6fdd,c51a1e56), -S(a16760e5,c3643d19,da15c034,5feced27,488ccafa,ad5298fa,6ee1070d,a258a761,736a7c7e,69db053,6f541079,158d671d,598efb1c,d75ec804,c7b2b49b,1ad7638a), -S(840693fe,73b96819,bb1b24a9,35d5dc83,f361273c,d0989e76,1edc35ef,50faf90b,4294e19b,49558667,bc6237c6,86c30aba,a2660580,563d465a,fde9875d,74c9a57f), -S(97273c3e,26e12369,1d0ade3,3aa261cd,a45b2d2c,d749af71,a60c0d15,85e18e03,2700c565,dbb08439,fb74317e,60776fca,d0efc1a5,5d0ad87c,18f82f2d,a97caf19), -S(978d68a0,5ce30528,e4db2dae,99f6a245,f69cbd04,3c7171ce,ce2bee57,60e68b9,ffef379c,1515b068,df562f3f,bdadacfb,8aabe5aa,466105d1,97a8febc,1596915b), -S(dfaea7bc,c78d275d,9f6a74fd,21fdec14,bcabfa45,e44070c1,9c44d449,c5d52231,927b810b,c2994b8d,2ed5124d,98e2f5cc,58410607,82b1ed80,d0fae288,8c42d538), -S(ca0b766b,8b8d76fd,ce471a88,18e043d2,604d1ad2,b689cbce,70ceae78,fddf5a27,ddf9e3bc,935ea0bc,22f977ab,98a92414,643140ae,be0448a3,35d6d44a,1bedfc48), -S(11dcc001,3be8d4b7,85e87153,e060d13,57cabb5,34a2c1de,2a4a70cb,9803a031,5b5d46b0,6a96c30c,b1901c12,eaa1c656,3a2f35b1,e9026954,36e087aa,3deb777e), -S(a828121a,18d23262,bce26648,ab44c45d,c5027ae3,f74786b9,598f22b3,c408bf08,37893209,80d7d2de,6074778b,2e8916f0,4043a616,982a9b61,d4089623,31375cab), -S(291ec5eb,e010daff,3ac00825,3452b065,d9f7fcb3,66e125af,22f11358,6263fbaf,4647cba2,45d190d8,2337f217,c278c98c,370120b3,d4e04110,e6df2c54,92d63bb7), -S(44735d48,4c584d70,6afc573e,8ece7670,c79c7b99,99eb0141,4a73905d,34a1cf01,30a27c9f,67b47348,583f1e84,5e7af221,438d4c9f,a1e0cc19,7312ec6b,908d613b), -S(fce8958f,507d5d59,bf0fb944,7be40c23,db2741e6,f89351a7,f29fc642,a60c7d4a,69de744b,9d2ef778,a7280325,bc699cb8,29874d33,bacc1fe7,6264eff,600c815b), -S(171a3251,bc6e72cd,630f8130,d4695e48,e0e649c6,82bdd5b1,b87c7b7c,968cf664,3492ac7,faf2ab56,cfdd5278,9831ea1d,e90ddaa6,b4d6e6e6,fa960bab,2b55a55c), -S(adc566cc,6c9afbe1,41a011fe,e121f0b9,a5dded68,fa9cdf63,45a00fdd,d38d69b3,38db9e85,26ab355b,5ed12b5e,84e795e7,7e2d2c57,24cec516,9cca1946,1d8d9c04), -S(9694e1df,8067defc,de9dd34b,4a4bc91b,653ede57,3139b9f9,4df55858,74f04,f002d8b4,3940cd6b,7cba586e,18f1616e,db907010,230445d1,a96b9eee,b43778fa), -S(8a90adbb,a8c32e,a9149e02,57bd9d24,7da8b0f6,5cd6332c,5803f83e,26a1bdc5,f7f24ef2,aae5a954,db200e45,ae75bdfd,5f4ec6d7,b203459a,7360a9b1,5ae2a9d7), -S(234b3911,f965ef93,5ab16aa2,392d2198,f5df9022,962ceae3,5e73f05e,d7d8f817,a66aa264,a24e1a5c,e9bd5ce6,164cde8,4083c7b9,c354ebbc,caac78c3,f5da2aad), -S(7d22623c,84ed234,5194c248,eb984ad1,28d2d4b,638b687f,730a3693,10f1c4ed,f97e515b,618719be,ea3603ad,7c40e827,59bff425,a8633365,c28c755e,b06769c1), -S(e210b4e3,cf3a2e24,951b0623,a83a8793,11cb942,8d679cbb,16a15718,2e6655eb,f4bfb50,43768438,592e7b75,41bee9c5,f263dc15,59be620,c0dc128b,d5e29339), -S(878c0097,ddb0f977,d75d579e,ca8d0bf1,a887fe50,e33b0c8b,bbaf2874,8875b321,a3401763,39f99298,9335879c,dd43a46e,d21d1387,55be87c9,2f486629,49918020), -S(9a6dee6,4c79975d,2adcccf2,8cbd8bcd,c8bbff9b,2811039d,5a6fc051,9a212503,9c0f3d81,5d56afc8,31de81f2,750cb54,9fd5fc63,b63e2c66,ae88dffa,cd072236), -S(3fa53681,f50925b2,710b66ca,1efa5e8f,b819c5e4,206a591f,d1492a1e,d13279f5,82a5c753,367d57d4,fdad7e9e,8b7ba625,7c50c07,10f93c8,5cb180e1,a459698a), -S(7ce51172,8f94ef7,7924a1fb,fa8b7d1d,411d0e21,65c4a1ec,e105d4a0,909081cb,dbd596d1,bda2f32e,12cdc910,2762f3cd,627cf29b,1b145ca9,dd2037f1,7daa6a86), -S(afbee9e6,d5b0bd25,1dd70bc9,e3b3a013,40116e09,905bb29b,797ba66c,16db5135,8a315473,84275d82,3c5296ed,b56ef5d9,7af96617,dc2e507,c009be9c,f3d3da4), -S(14d13a78,96bd0978,d4a4d4d5,2266afd2,e0f21ea,5c1a693a,9ed4990,81e43974,dc84f2d1,86d91fca,62ef088d,1794715c,c8dcd9fe,efb4aa5c,46800240,886c41dc), -S(7bc1045c,4960054a,fc979961,5cd7faee,5dec92bb,98b4c3d0,9620a488,fd32c35a,b8f420ec,cb5dd9ae,3f075e28,811ec9ca,bd770836,ad40371,66073db5,c1166735), -S(fa24d112,4cf21fd1,bfb06c10,9fa49f10,c3ab248e,3d08f620,4529612b,f7a5328e,c0745547,b64a0068,25ae8f90,82f8565f,ed94865a,d185a364,602e6468,277b3cb9), -S(8758ade8,745d4d18,c8f7ad6a,32fa05e1,c7a08bcf,c7cad42f,7aef474b,de02cff3,7864edbd,2efcbdc3,946dd250,6fdc2ea5,2f1626e0,b7300f8,9ef16420,12ae4853), -S(d2783741,6944bdaa,d212dbd9,40cdc7fc,2847fe5c,a6eabd45,dd6daa9b,9e122693,c7139931,989b4f6d,3acf854d,5aec897,52c69105,2c6d2586,27ef13b7,66e91875), -S(624120d8,420a5afb,64673e4e,b272f7a9,3b7f1f7b,59f4b145,10115691,70a597a2,3e055b16,ce482c12,88bcb9f7,40128b71,e5a441b,4c45056c,dca1466c,6491cad2), -S(96a21be9,a6e8b94c,7ebd4782,809830ac,f2a373fc,6781405f,a320025a,e7bcb4de,772ce6fb,711c2898,dc8446,aaa8cc7b,41608392,6212908b,705ca412,1e2c5e1b), -S(a9e2a4b6,4032f43,46ee1148,46ba487d,9a82f80d,3408b8ea,8434c521,33135ce8,c8537b6e,51846fc3,18898604,192d86a6,36ba3c36,f7ec9aa9,6185e7be,f160b5d3), -S(b43b42e9,381358ce,b8a595c4,77a9caf4,afc6e0db,1f58af55,6dc5bbdf,2cb4449a,556e4e70,cf7d1a16,9249e954,b749619c,dd87aa7c,723176b1,7361966d,2d2b6fa), -S(224cd0fc,393fb763,bfbc3c44,b829f61a,22ae6b98,22622367,2d0890c3,eb9ce9e5,97273eeb,eb71bdb6,5ac5c677,807a533a,f190cd12,e01ccb9a,d617af76,c3bef1ae), -S(6c997b99,b7349b8b,6f399b78,34bcf510,56f070d4,b501f8a3,28ef3a39,7f6019ea,370796ed,ee708852,6ae9ba78,2aac403e,5b57dd21,cc77d0e,1674d6f4,e4ec60e), -S(9c8970cd,125f1c6,1b845a19,a153ef53,594bc62a,3121d43c,e9890888,9c5a7adf,2157717c,55747f64,b8b51feb,9a6c8483,6dc4de7f,40908ff4,4e37d7e9,ef1354b3), -S(eaf2ac12,6894bce4,8862c0de,165c03d6,4c561cb9,d338cb84,17d8811d,55af309d,f9e8f0f3,eeedcb85,67232a8e,cdbcbbfa,1a3b1a67,7a67c129,f07e091d,bb82ca78), -S(8b69c681,7de28f6d,c539687d,28dd6a0,7cf16302,f0cc0f41,a340f6b,2a5669a5,576e108d,b9ae716c,91859b28,25de886,2de16591,eac5cf3d,5a802785,4551f778), -S(aec8ab4d,f8c21840,c3d449f1,cf1100ff,baa91729,a35efbd2,53ad4ca,92af4d19,2350038d,bed217b6,353c31dd,bee52f96,e1706e8b,45350e96,6c55a522,b536ab3d), -S(32b75afb,9fc485f1,744c18ce,8987deb9,51cfd485,26aa491,3dcff45,6b5e394e,c5edbb3e,4b95fb5f,55d24017,86fe65e7,9b8c20f,4e927e2a,caeb2b0a,1aa34ae), -S(a2eba275,e957dcf1,a493b7c8,6ab340d4,647b6951,f8919dd6,ee0274db,a2178016,b89cabbc,ead15406,f57f0763,9cc5e036,45ddc32f,1283c556,ddf94eb8,e0e9cecd), -S(6af5da12,7be295c7,9485e35a,e0a6df36,302bfac3,a20a4325,13e81233,142d4ef9,c7df8582,7682d324,5f7a8d0f,9d17d460,53227aec,28c1de97,23afcf52,96bb8c7b), -S(1c06f8d6,6cebe13e,7cf9ab04,12cbb75a,741a2240,6b89170b,8e11c92b,84d5c9af,cb3b69a2,7a55b2f9,ba3f9ccb,67c50502,c024e8e6,556e7c42,9cea3f58,ad5028a0), -S(a9e3488f,c2dc8af0,a913227e,9ceb31a5,171fcbb9,752d8e82,1249a152,57b655ec,e07fb0fb,d8c6320b,d64645c8,e6785457,652e186d,951e0f92,f91a7ec,171bc993), -S(9d93b099,9bfd6ee3,2919d4d1,88896b80,46f07249,f913d92e,e1c27cf0,40d47277,bac5a0b9,cc9ff8d9,b6274be2,15c49e3a,67131b92,53f7e30f,44d401d7,97f47b30), -S(dd25451c,57c2ab68,542392ca,91e58a50,dd578648,36096c20,bfa8783c,1c359a8,5fcb8e40,32265bec,f5eb02a2,f07980d8,b56fb0fc,de51f140,a1ccf391,b8928602), -S(ca0ffd05,530a0671,fe49d0a2,4a0a0eb5,b19397cd,e8f881eb,542f7919,e793b260,638db61a,bbc020ce,ae9359d,3876f8bf,5ec75498,7f623d89,c3da60e8,f84b6960), -S(117ea7b5,1440731f,403d8485,a300d59e,a571deb2,44dc5bca,20352513,b5d0f691,7e72f426,20ac70e6,2ddd8ee8,edbdaa41,e9e7f46e,c8143f29,95c77289,298ca3f4), -S(c1791bcf,7d2d5477,24c30d4c,d5e8529c,2f03d7a9,711395cf,ddc5ee69,d0745064,30ba86d2,abed8606,1e9d2012,a0079813,26b232eb,34356b08,1afe7de9,3c79eb1), -S(2faa17b5,81123ed2,af8a2393,6b941de2,1cd3d276,4ca47347,5b27703a,f9b4b401,4fab0769,85484ad2,d2352ae2,9a74e90f,7d5d9514,c333443d,8ed54283,c7634ce6), -S(4bc4063e,68d9fed8,185ee402,8b4e1bf6,87c6c73c,c21f6131,799edc8e,83884ccf,3af276b4,24dc5208,7dca3be6,a5e0a133,2c427516,7cddfe4c,ec0710f9,41c62ecd), -S(e0c4a4f9,5fa0f060,b986214,68eb0131,1162accb,ec452a6,2756d36d,8aea45d6,88a49bb7,a66866db,e6905ce6,c15cae3f,2f98de34,7bbdbfda,ab2cd99,fc06297d), -S(6892a64a,e22fa15b,c0e540b2,b75d307d,ccb20675,10ed3d59,702312dc,27882d02,ffda7d9,bac7a8b2,4f83c1b2,11dbc454,8eca5023,30829ea,f5b47a9c,befb451a), -S(def9f462,12aa6e8,3d4578a6,9bece7a0,9e91ec9,28eba3f1,54afac97,d2418785,fba8f869,fbb39c64,8613ce1c,1c36d86d,f326f334,6de2200c,93c8e1f7,bace82e9), -S(32e37792,4336c65f,b112af1a,6978b5de,bc2e2f0a,f6f0b4cd,b6cad6f5,e0d4c177,d3cd48a0,61f45605,e2cfbbe6,9b636cf8,3c8afe36,6e7c8a72,b2cc1b47,a58abd1b), -S(1fd685df,86bfb84e,8bb90216,1a6a0e14,e111667c,aeea586,7f45b6cd,3f411527,be7d8cb4,c3723bfc,f2219442,9e164abd,65258c57,68509e1,a72e3ea5,b13ca966), -S(bc7775ab,a334a06c,c284be77,8e9a8b88,358f3ebd,7fa2a370,2f7700f1,53c93e94,dff3ec2c,84f8c35b,fc869ad,76139913,c25b379,8ddb1e69,4802ac27,602f4a6a), -S(2a3f2aab,10c9e9fb,cecb54c2,c411bd70,38334230,f2286b62,c06db5c2,6b74a6d0,42497e29,37395239,c102a1da,a08580ac,54fb89fa,7f2d2974,8b4f2081,bf15fcef), -S(d5c9be7b,985d769,3d5e7b96,3778daab,49944cf9,8ba2a522,b33d32de,1a7ca3a7,3122fb41,440c3f67,478e116c,1db5b65,2c8d137b,65cb712f,9d235e0e,686ea04), -S(aa772a33,12f19258,b1165378,1376caf9,16c73e3,8b842fa6,3237bf82,63ca771d,95df79b1,ca3951fa,3df74e4e,90db4a4d,b36fd7ee,1758e7c9,9e853faf,959e071e), -S(1faa7b4b,610b3060,166011fb,6eac0337,a8cb6dfa,9e90a8bd,6a84341e,11577791,716cedd4,ce760e78,a2e664ce,baf834ff,725b4296,3e23004a,ef309b5a,662cc36), -S(50a6be45,e41dcf82,659d0690,9aea539c,10fca3da,73a00372,fe9b2db5,46d7fb8a,ffafe7bc,adb82924,6ba72ddb,776b39b6,4a77627c,d36ac0b2,cc73e5ad,84740acd), -S(e27561a,6a206e59,2a8c7747,29d2968b,294378e9,9014f9d1,26eff921,133a1e2b,bc80b28d,573f7502,56da86d3,4118e699,75c671b1,e38b1d9d,1859fb83,681d9931), -S(cd5de182,85de5152,312ddef2,10d36849,a0a638fc,4215e232,13427899,268762f1,f0a0a3ba,b9149edb,c5d6586b,b50471d1,a7db3ec3,cc94ea9c,f9240683,d4ec2c44), -S(9f51022d,30e18985,ae67301b,5db7a3d6,2165335d,e3be70c6,e4f703be,d531199c,43c934d5,39144f1d,43401b71,605b08df,1bcb8bf1,ba3ee1e3,5c591a46,12328552), -S(b014734b,7b204960,adbf1329,129cb3dd,5d9b84a3,6367e643,76df433b,bafc9d2d,56dd6c55,46cef764,574944b2,c9cca7af,7ccb438b,2ffb31c5,7faff8bf,fc21eb09), -S(43f9f9db,bee57d22,e77b51dd,8aae4b30,3849d709,d06353be,8454db01,89b4a34e,f8962178,ae383491,28950190,1a290ed,23ca986a,dd0ea6fd,861f0162,d8032d4c), -S(1ce55c7e,10453890,c9b9171a,bc0d13c6,2ff6b802,1da6c47d,389d0558,c643a8b8,3363feef,920ea3e,b4cdffee,582e91f,7a02bf41,d11afcde,236369c4,4ba76ec9), -S(b45890e8,1ec53e8b,fa7373c9,c0160e69,1d739b3d,538d70be,2c2aea62,b6f2a4ba,70901d9,5e139291,691e17fe,f0d48797,60ec6f61,245f2657,6b9ef283,f81973ec), -S(d8f16bad,a3430da7,9bc7beca,660154b0,28d44348,b73731d8,b2f23229,6188bfe,f7baf0b8,80b60a8f,575b10d1,988aab0b,c29cc9dc,66494727,9c728967,ea24f26e), -S(e74323af,218329de,4aad97b6,c57db6e9,3dfa53ac,784224e2,6b087813,6a74ec3e,42a427c5,e1c72445,881fb359,265f4507,13e933ae,f3b8b10f,b60593b1,c5440236), -S(f5dbabba,6a55736f,b0e2eb38,973882e,ddbcda9b,651a10a,abf0110c,29b6f4f6,74846161,4bd5a349,caad7c3c,46c534e5,3b7e5440,7e3e31c,1247f0ee,4cd181f1), -S(e2d744ce,d24b72c7,c65aac97,b0fece86,77cd7edb,5b2029c6,41a0acf2,8cf72009,1895df09,8d9fab64,b86a701b,efc9c69,ca083ca9,e962c270,bd7af27f,a46d6e75), -S(e4181c43,1c9c9f53,362ecfa6,685d7d28,4b0f09f0,6472a5ef,6f3f77fe,6d24e4e7,d2eb8214,6dc4bf71,dc30e935,c5621b1f,c09819a4,8e572a44,1ea8981d,191f7030), -S(ac36676d,10365635,72c8205e,af547ee7,3e15524b,ab15b489,a0c68f7f,854fcedb,71038dd1,91a1992,e0864fe8,3820eafd,693f05d8,b32df573,817cb314,a24623b9), -S(aad2148d,fd0dd61f,81456435,22d5cdc6,8beeadee,6f60c22a,f23f7183,83f96d88,d7115c62,3d8455f7,955d0772,3f083a7c,341f5bee,64aade0b,426e781,f683b7fd), -S(7e8bd881,b50374f4,10aa55f0,e45991de,737cde63,f03e8077,e29bfd8,55f3316c,244997ad,ebd2ec32,71d9604e,6f9b0bd9,fe330105,acf71224,b203cf83,26b3b1ec), -S(a68beaaf,899a89d3,4c18576d,d9041b36,a1fc14bd,bb8c1588,809494cf,e87ae7f,3ffa0192,3233f77d,f47d8bde,3fd04fc7,f57c2af3,52508343,3f7e810f,4b6330a3), -S(fa9317a6,7e2a74ba,d53ae152,6e3a8a4,d7e8a59c,a1aba4cd,ba46fb23,a1870f05,b9a22792,af785e1c,6b1fd9a3,626ba75e,28583f09,fbd0d3a6,bc9a64dd,23bce82c), -S(2f820b30,6175e982,b1951cef,551a61a4,f9595dcb,35b5f647,fe8dede3,f68e5226,d4f915ed,4f8b3bd,f7e8e0a0,ddd97719,d3e22ff0,8c24c9df,c665d0d9,c4b2e4bd), -S(eaec7330,271b9056,6e98cb0,717741f2,7957ec24,c51f22c7,c25c2cf3,db09cf24,6d6e0108,e103be2e,3f4c8ac1,4a216e40,d8a993d5,5b0e9b89,2219dce6,3e47ae47), -S(2cbcf67c,6e1dd8ea,888c2898,8f636842,ff4b855c,9fb539c9,f3a9a4c,8885c88e,4031a26,c3b13bb6,d0027967,2e1a6e1e,af5d957,e841dfc2,c396c8d0,4e816cb9), -S(9103dd8d,6265d5c6,7f50eb7f,2227977e,53a48e39,a86083ff,965f5d3d,2032a29c,6a1bc02,14930959,ebb9f967,2f9f693a,ff3cc3d8,df65af26,21cba530,425fcb1e), -S(b47cba2,cf3adf57,e6cde1b8,9edb3303,d7c138e1,b59ce4b5,a57a517,aa497285,8d173f6e,af4c0363,7486df13,3fc64826,5aa32348,24f64842,5e36e2ad,226cdc0b), -S(6d59d90,23507028,6f36a203,702fc9c9,c9936b68,b08e5025,9584e385,1410ca5e,ca676e85,cc25987a,4c8e582e,ff1d49f0,5736517f,39e2855a,20cc77f,c40a0860), -S(748fc197,201aae7e,80e01c30,ce77c315,2469403f,a3b85be0,bece627e,93f657a7,6cd7f6ee,73015cc1,28562867,44b1f7dd,33293c72,a54f3e2a,2edd7bc2,6d2aa384), -S(ba8b964e,aa862c8a,9075dbdc,a69d2b90,aeaccf05,27c562c6,f310b3b,adb6486e,6531492a,64203962,4f3ee722,1bfbfd54,c66ec11d,93a66775,c305bc6d,c9a9bda1), -S(7b3a1c20,dd36acca,83f548e0,16907006,4dee8579,1342818c,f1185e89,5f6728f4,1829aa73,168eeec0,897358cc,3c4b8d04,da2b8ed8,1654c1b6,816452a0,943feb0), -S(8e39a814,1cb73d12,a18180c2,50a5c574,4cd0f4ef,42500d3d,a0892da3,bf5d24e3,2496a20b,5e5e3dca,30581c10,cc099093,5ee51283,79b6672e,ffc171c7,3f4fe34f), -S(89bc0ad5,d0b615e6,1510abfa,6ee0856c,d3fb9b33,d53738e1,827f041b,c86547f6,d5bcabf9,f555af1a,2f365910,1af8b19f,a12089e3,21dc2053,8611c3a1,e6f6a904), -S(2350902d,df8c0944,da5ba2a6,c5a9f16a,eb735474,6fbaeba8,4fd5a58d,c2571ab,dd1bf357,ab9ac929,eba9b93b,3f311ddf,2f10aad3,18871982,2ef665f0,36ad3fe7), -S(e53f6624,70227a12,a01f237f,9ac59afc,685276e,440450b4,b8d91e1b,9159a61,a95ee3d,430328e,116128be,c17a74bd,a87b6fe1,3e0adad5,7834ad89,ed597404), -S(dbdc2b2,ecbf18e,58e352cb,aaded3,7324e063,557425f4,a8fb2a50,637f0af2,e5a80b8b,4cb5a7a,af1175b,fd62dbc,ff044f9f,4f03fb89,b768c6d3,72729996), -S(7fa717e6,e78c1641,82b2e,78c2fef9,bda57060,3d0df678,c4716b0a,55f7ca60,59bcdf92,4c9b981e,ad7b30ae,937ef1b7,63b12c69,9fe20e6b,a7c3002a,edf82d34), -S(330a50d2,1a87984c,e657be73,d2570875,75e261ec,ed17d9c8,7150d1e2,6afcaa0f,253f486d,642fcc6e,5d53b79b,8a24bf25,131a1b2a,25b931a4,fb2e6019,34c7df92), -S(762b5213,78d46c16,70251e93,2737c75f,f28e0500,eedd6ae0,62919874,660e865b,efaee12f,3b411bde,7e6e8bf6,3d875a89,68164f6a,ddf102fc,869613f1,e8bbc095), -S(717d699d,f3a985c,8a8a8562,cced0432,4b616e41,e4bd8ebc,43bc1b44,2e2f7b35,cba0f7e4,f4d544e7,6127892f,a5ef8bca,13241760,5be8e7ad,4fdabf66,e8fbe571), -S(124de3d8,54e69390,b6908c5f,c770f602,8439082b,9f9e5e5f,cbf5f822,2193611b,c9b9d896,bb1b5cab,58c10bd9,b6519ed4,a1d3be2a,39ebc4ec,781bd673,351ef376), -S(fcbf142a,a6d9930,33fd9a17,2c7f46b9,63237738,9b76572,2975407,ea8b2440,4366db31,a5acd6e0,a8bb3481,9a654233,e6babe82,bbcb5967,cabca638,e9a19987), -S(82858b62,5d2bbcc1,372e3c38,256b9b1,cf018f3b,3e9d0b70,c17d1ac0,fbf75ca9,e6543ada,7d9a8928,e3a1f6d,b8c15649,379fae57,f99dd8cc,3b096579,8e785840), -S(577b38d2,ffb278de,62ac0df5,ccb6f2c4,e8f40e5d,c5549a7a,4881831e,bfb6b71d,171651e4,7f9eee1c,60ce5d95,9e77b98f,ce651c3,c661d8db,4798372,8ba1c03c), -S(28a83552,9aed0508,34510350,14bef19b,c1f20936,3fbb447,6cf72fb4,26267c45,cf949cce,8b331182,670f5300,29e3df92,57a576f0,e5923a0c,146aecdc,2db60446), -S(621d99c7,abe3982d,889d3b11,6c992a6e,f035ba8d,aeddd4ac,d5d7b04,bbeac79f,2a6b0dc8,a6ede522,b86ecbbd,b057192d,84294e8c,385cdaf7,cc5777d3,607ca69a), -S(8c6395c0,3ecfbba6,82926be8,b6e8d4d6,cf204d50,9f805453,ee40a010,1fab3959,d22e5810,5fde2b81,b82859ca,97a05e7,4c278cfa,b4fac1e4,50e70928,d73b67e2), -S(80ecc87f,b9d4bc15,8e365e31,4518beda,7087f9e,c8086e47,91314d1a,9b37398f,6bfef3c7,8d2e91f0,67075036,385ed8a8,f3a84102,1e44df55,397290ec,68e44812), -S(22cb24d4,e1354314,b1f9bd,c7e37963,3ee08264,ea7fe2fb,2b23ebf9,a35c1438,6e88715d,9d5fe90a,d0940724,b597a55f,386bebee,5eaf32c7,6e95b2c4,d407c808), -S(285cc203,a4eb1e79,1695f8dd,d34a048d,58350aec,4fdc8157,fc1a8427,76b56e19,59cae7e4,435a37d,bd3c3f91,279c7bd6,1cc466d,b1831a53,94f7aadd,4e1e108a), -S(61275052,386f258d,28af0420,d010fa87,c55281bf,59b68b71,698eee9c,824913cb,8532eca9,645479d,9ef72ec3,6d96eb11,418f9619,b0fa95c2,c4c81c86,75a81e76), -S(84d391e4,d946c2f2,b40b5b5e,b6a57463,1adfd4d4,9e034ba1,3a2c862e,68b36c64,f3384ad6,cb7ccfaa,567a2cc8,73c9e509,b4c2de1e,95f7ad30,26be00c1,83ca7419), -S(34e2a77e,cce22a6e,849e1b21,4a6cc570,10e3a0ed,73799e14,51616724,410d854f,cfdd8819,f0af720a,a372b923,fa81eaee,c427f3b2,a29acd3b,ce6710c7,c186d039), -S(bc45065a,b558b2c6,a28b0cf3,8bd26384,f82dbb36,e2029774,561883ed,e6600bf6,22c5a0b8,3dc2bc02,93d7019,b4623b10,aea9d36a,22b04882,954e3daf,e1885b73), -S(4b92a803,94dd5669,c0fa2d3a,c4d1e7ee,8e2954a1,719d37b4,4b02e342,9d183ea8,9218836c,698a5fdb,f95e0e58,8b64ad3e,e3aaef7c,613b47e3,f1464443,a48e3396), -S(acbf0ef8,453addbb,9a4b04dc,3acf662a,d069d5eb,530d7a03,2e6a8708,be241f89,d46405fb,3c8862d0,4e7cc53c,51beead0,dffb3045,a6349fef,6fbbcb9e,cb414036), -S(adbaa36a,4fb531ce,eb084fc,e65f3397,22188967,a947acb5,9f7ea73,52aae5d9,719265f,7e9bf7aa,2d789d96,282e527b,819a252b,7de8915,f44077af,8cc1a8e1), -S(3f5a74c5,98b258ac,b1cb3ace,e55a7a26,78f4613e,b85d784e,1b3c8abd,978619c3,ba16385,ce0487ea,67932ed6,23aaee87,2debdc7a,2bd02ea4,6a681ebf,72ef5df3), -S(6a231807,3d2c0fe0,c89245f6,5dac4052,ce931129,85b83555,c4cdf8a4,f1574135,fe44cf76,f44f3d27,bcb7839f,588fe09e,c6a5aa95,d6ae52b5,8059c7a2,c6afaf71), -S(35555f0f,4fb2677e,dd12f235,2821ef3a,331c78df,3259128f,dcf62f69,85892dd0,101d97af,b1ff1197,3c8336df,bfbc346e,5c5e06e8,f11bd602,aa93f412,2f66c388), -S(d45797ba,61a836d5,13834d,abd3090c,bd139f05,dd67be2d,cd99ea7,66565756,61b0aa,ec1bba4f,6040382f,cb049126,f7e6ba72,9cc4dbe1,f511b792,32204a65), -S(c06dc164,8c07d57b,fa6cb488,1d9c96ea,26cccb68,d40d169,1890ec68,d42d584c,fd4ee4f9,16739643,66ead6cf,fcf31729,bae2263e,c57c14f1,29fc61da,cce93dbd), -S(6826672c,ebb04679,a68958ee,3f64dc3c,69248f3,cfe0f8a8,28b164ab,417a508d,ce38e638,f19b1a66,b5647be4,3ec24f0c,562a8dfa,1b278117,87f9292b,8cba215f), -S(a2d998dd,a82576d1,6933b580,40dcec80,1f12ef10,34ad73d2,de3ee13,7d632abc,e168ae1b,7f288808,efdba59e,cea51299,d65a2c92,76ee7190,3f253384,30ff297), -S(2a9361bf,67b9e8c5,6e8d7b99,ad8b63e9,e10dd96c,1ee1eb35,40244415,270d9ad6,62bd2398,8d35c3a4,dfa31c56,57d099af,e9accd49,cfda6689,a997c862,5e05424c), -S(88ffd75b,7c3e1311,79f885e8,9060a662,460499a5,b2a457cc,47443183,a3015e34,a5a174cb,7b9b9c68,3cfac8cd,4325e0af,90f61241,28a83e23,ce1344c2,532e3a98), -S(2b9baa0c,d7f27a8b,4ada59a2,cd23c80d,94e8ef7e,3bb77d5b,a45b0547,c70abbd5,657251c8,2d564df8,a9fbc5f9,74c7d388,22089c1d,c338805a,33258c8b,db692bbe), -S(1fe51134,d37136d8,f473c5e8,7d316a8a,f0c63155,815e3b6,489f7dd1,91b229fa,f0df503,ee85d7e,b3c03545,dc491cf5,39ef8a3b,68e816c,bf94d126,adfbb343), -S(1a3211b9,9d946e96,bf190bc3,3fa2fcd1,f8cc0646,45599f81,dc7f33d4,3623c41c,ca6892b8,f8452e2f,5a78a463,fb325dcb,913cb17d,1a43ca78,bf2729f9,27a99ca2), -S(a6d7f275,c3600aaa,ae16a1e5,164084a9,6f8313c9,a71961f0,3b6e1a28,e0326e90,528756c8,ae9f109c,3a803d2f,d78dd27a,a66639f2,6b1e2fb,82a683f2,9e2d7993), -S(4acb6c7e,745afc4c,8258f92e,3a706049,a8c4cd51,6462b230,1a824114,e25c4352,3894a647,436c904c,6ef52e8b,6df86e61,4300894c,e0e7f87f,529e96e8,6f20796f), -S(245fd53c,7b9b6698,89ba6bbb,2b6d5603,c423d4c5,76c68a6,9289c1d8,54bbba73,e6a65161,8e8fe90b,36705e0e,82c1728f,49277a2b,6feedd45,d431f349,c759682d), -S(58e89f91,3383bead,5ba5ad57,bcb85f1a,44ef0f2a,4cec383a,7bc4fd92,9d78fae3,56edff42,42716182,9ad3b3c6,339299f2,1b56085d,a051e990,3ed02323,d9ff64b7), -S(e2f35afe,b9e38b16,a29a8452,a17abf93,36a82282,9fd2a726,efc2160e,10e7999e,3a19d922,d2d2b57d,927ae73f,80c7e1e9,40679fd3,fe34b4be,c4c2deea,13d94979), -S(558be465,de2edf0a,d5b7294a,69703376,7a96a366,e7f789af,3b93743f,372f5e1a,9dfd35c1,d1670bf2,e8696fac,9405330,62a90b4d,b4891986,9c8f98f3,6c586880), -S(b49f1db4,206a93ab,9ae73164,6f5364f,7b261d88,3d025764,b2bcbb90,6fecef01,7c81be22,2a77c149,14e48d26,bc81bc9c,2e10886f,2dec7f4c,1e7c42cf,d87c5f12), -S(6cebe305,dbf61912,36e37c34,31029ce7,b0059546,d5984f3f,c6d3b7b8,804d2cad,5e88f74,fb307758,6c7b9c08,ec2697ca,1360bc21,f453688d,edc82cf5,c96f16e8), -S(4e60a6c3,684a0435,99435fd7,7ce52576,aaca0b9a,e2e5ed78,b4f64044,ae89f6f1,668aef77,3c0fd526,e9b7f22d,55baba05,99ead770,442a23d7,fa0bf8e7,75385b2a), -S(d184099,4640c319,9a00608,aa1d3aa5,9527ef7f,46a08f26,3b83fc46,a10c0941,f7f89233,55989992,7b844a71,1f5c866e,3f4c981f,4cf6f190,fcd4846d,1d83d63b), -S(958627b7,214a7133,55521887,fdff08d4,64c66531,3fffa310,c53e74b,89194aeb,93ec45a8,e0aebea8,378b1c30,974bdcd1,4e7b8983,c8138c7a,cc85fe02,6884a91d), -S(7d0932b,5d8cf465,ae6917d7,450e9b59,da57cefe,dfe6665a,4338cdce,71cc6c11,85c5b8fd,757613c8,8ec6b250,3e15c412,4ef2ce44,91b7eaa6,5d512740,4dfaa142), -S(c8ef9918,55874f19,efdd5720,cfd9e164,ae2b1f14,ee745c4,1ec5cc0a,d776cca3,c0b00173,20111e2b,85faf602,cd01a186,8fdf633a,1b0f3017,682e5d65,3ba29671), -S(8a72c61b,eeeebc65,6cd8acd,8449ebe3,6f21dc8,1ba913c7,742247cc,c8c94bf2,98e7b573,2c18d201,c0faa26f,734d25c9,23411751,b03088ad,1ce102e4,5de36e64), -S(cf0c29b2,ce132664,c7bfc440,9d1188c5,33c8f5c5,643291e8,67a2fde1,6c5fa23f,fb317c50,1b3b354b,18a120e9,2a639dd5,629b2125,ebb8785e,2626ff4b,4f538e02), -S(8c9dc0ee,20f7cd08,e9d1db3b,a4569a43,98c3845f,7d02db0a,cf6f7863,111fb016,445b117b,c7b1a779,e0e9fea9,fcc31141,8aee8428,cc8e8e06,fcd265f2,2424cfcf), -S(650c7470,6f2a4225,eee93622,69d261ae,e18117dd,ae23680d,15c77d70,15f373df,6a4fbe02,e1701051,99828d13,84083d60,5555e2c,56e7799c,b2714216,b77f6591), -S(b0b31e86,19d20877,1235a402,94a884b8,1c83bb44,8db973a7,3783267c,8494b32b,8c5dd1fe,31e86a2,c40c1490,179452da,74fd5350,1ae38c1,1e1fff3e,a33f8cef), -S(a156abe8,279dd440,2762a28e,836050d6,7b782022,2036172f,a1a95984,49c15a96,b85356b6,c165788e,3c02549a,1ea50dfe,c557d7ce,4a9052b2,41deec12,eb08ce50), -S(c2919cf9,924df70c,f1f74e42,6f1fe48,1e4aee25,fa00291a,676f924,69002fa2,19067bc8,50deae06,1ca42c6a,3e252abb,d2c7c6cc,f89c3cfc,a6e7f1c3,a6fe1b90), -S(1aa1c198,d4f76755,ea94d005,b300ad47,238fe1fe,87cc1244,8f2a632d,4c922ecc,85e4e4fe,847c1935,f14d155d,a41ee4c3,f146a4f9,d28211a0,374ad6b3,c350dae9), -S(f1e9af6e,45296823,eb5a1d8d,a41c7904,3b8c1166,30213fcb,84e2418a,e161bba4,211963da,8aeed276,f390d6d3,6b958b36,da23f1c,8705461a,312a7687,bcb9f03), -S(47b98d04,1d7e118b,765fb3bf,5d30f5f1,6ffc7b4b,4745c02f,6bb807ea,e15aa092,d1997492,7099df01,f1d64610,700b9439,83970fb5,d7123922,39d790a2,a116d223), -S(2220fd83,794eb1d3,a1f842dd,9f8f849d,43d58385,25d30d79,9b4684b1,4c5406a,74f2715f,a6b77509,d58892fc,78915244,66b2db2,df099a7c,f7eb9e0c,c4d8d3c3), -S(be01ac86,5eef8b4f,e28e15a8,63c22adb,4607c574,c26d7d81,a5b69ab7,265f7bff,675f334,bb9ba742,445aa758,c142798c,bee1cd39,ebb01b65,eb4ca49c,8911da0a), -S(1e35165,2411e2b1,d491972f,61a42c7d,62c12f0e,25441aac,e4770c9f,254ab47a,ce7b801b,910e9fae,c9288272,18557cf4,73b0b8ff,4296ed2d,6e5cae60,f48fe3), -S(1585747c,d984fb1b,b34e0ed5,9c3c6347,159309c9,1524d316,f570d257,b7c3feda,9b501cda,20fc0f1e,a7df5176,bb6da6c4,585baacf,a08fae17,9d52ced9,c1991b55), -S(33fe24f5,4f24ebfa,152a2e59,c2445f19,f1b4bb7c,636a0e64,eea338a6,5f17e9cd,b65667f,f14ae54c,2c272efd,eb2eb1d7,2f9ff4ac,35430488,30283f2,cdbefc29), -S(783538ba,9f685c0c,f85376e7,dadabaee,527eb0b8,73a04007,9d0a8dae,80fc693f,16e846fc,bdb1fd08,4e7d2521,327457b5,93f42350,80b791fc,e91af5ac,8d35bab5), -S(ac1d5e99,bf673475,9c1118fe,44f0a7aa,1989be05,e117d2b0,d9946510,f932eb38,7a81d87f,aba5a37,9dd319e,793c2a23,e079c7e6,6dc272cb,5d787cb8,2ffdd6fe), -S(f65dc8ab,c670e7f8,753246c8,e5273670,d12a4ef7,a3296de7,3bbeb72b,20093771,6a4cf92a,7243fe41,9c6ded92,d51dc607,7c82ed58,60b98aa6,51614266,f9a2b8b1), -S(bb076bae,e9d21b2f,fa004ce5,e361f8cc,773b2d50,cdeb92bc,5ecca796,f10689a1,121a0fda,f6192c07,b2a734de,9d8b8bf4,609d2722,8b0818e0,a488f83,176303ee), -S(4eef5fb,85174419,7659a95a,dbb4d472,d418a8e1,db93ca1d,af6ba2f6,49ee31c7,91c54af5,7b5fa5ce,8e7c3ecc,f90b2e28,33a969e,e3f5bd30,4808e89,f25dbbed), -S(e3473056,711af387,2bb63d59,c92817fc,16c97b7e,33c1173a,df11633e,2984ce45,816407c5,3d1debd3,ade1d781,d46f8b03,2aa5bc05,e3c1bcee,5213fd50,c39b6d17), -S(f2356e97,555be224,cac10a3a,c6061ffb,8a67a77e,1d97f011,f86e7594,2ba2665c,8f5dbff4,a6ad3bba,ca27c595,e2d1eb67,e0f752da,817f2e1,5e27b9f2,d6b955e), -S(1c1682e8,1a4c6d19,dd01945a,34f096cc,1854dfa7,fe42af9a,b523f7fe,cc20b8d2,a610ef90,190b3390,97de87df,10d01c94,4a76610,6d8c7736,87d2b863,621ee297), -S(53b1dc92,d540faa9,c67410a0,901871ee,eb96beb,6809aa96,545b02af,e2cff0da,2132487a,616b4084,c2dddd4b,fba075b7,66607859,4d328d39,55c16060,249b1f23), -S(36623f66,417edc01,c4a43dfc,e97573b3,f14cd858,a6fbb2e2,54ff1df8,21dbde93,88cdd6c0,b3872cf5,9921d376,9eca93f3,d5985f2b,ce62d132,18de4cb7,f6ebc27f), -S(195345f,132c5c5,4f6e1bb8,52f1f76a,a7ca147c,e347b5ac,fada9fc2,f90d3592,2fb7f1d0,23f0fd8e,9ae691aa,3eff2832,4e6b4390,e42d7129,246f14a2,902797e4), -S(ef5badac,2143e60b,adab5ccc,a05f222d,426e0768,44e6edfa,4eba747c,8ccdc909,afdbceb1,62ee5237,f55ba6,71395f2f,e4429a2d,6d0c007a,30caf51,a53b29bf), -S(3c3dbd83,bc2088fa,65a9cc99,95ae0fcd,8a065e1e,9b8bfd2f,7c3a76e9,72305688,336470b4,54fad342,fc51cc10,6a88d82f,6a8ee961,46aeae6e,19e9086e,79325072), -S(1da4f2e4,af97ce25,1fb180e2,c529fe17,c30b318b,53c3b252,53d8feab,21b0a0d0,861cf8ca,7dced920,1e59735d,11d39947,fba5dd1f,dd507a99,a882ba26,6e468ff4), -S(d5bc320c,8618b30f,a9305bad,b6b1ce9a,f5fd055e,843891a0,b0d2fdc1,5fc51f54,cc8ce071,7cda58db,25628843,780d083,625d103c,daddba16,ba751ac4,5e3f281), -S(f5b3f6d2,9939f586,2943067e,361a7333,ef49ca55,70df45ee,e716ac43,cdcc4e16,7e522add,4cf6d92a,8b77292c,b522dcd2,1a456120,4b0abb2b,614351ac,ca1fe517), -S(e27f83a0,f2b76455,1e24d358,d39b946d,63dea7e8,5cee08cd,13762d43,a3b05654,fc5375a,cbc0c518,bf3fc169,3170f204,67ddde21,7db88535,74b6bd8f,4c677f16), -S(196b36ea,4d552f6c,eaa9f749,fb5ea209,92cbce07,f1cea121,9318acbc,7c87ba82,17eed0d5,1f7500af,3f11217b,b703a51a,bde3772d,d4bbbbf,1438af15,334c61c2), -S(cac69e96,84328713,e06a135a,ce0f0fdc,1812eafe,fa499993,980d2895,5804a635,f02fa499,9a54c238,4bef1f2b,89795b76,3d3e526f,aa1081f0,189b4488,1d5828b5), -S(1e1f25b3,d43317e0,623f07f8,3fb09946,6ecf2381,ab348284,8670a30c,2ac734aa,c096a239,3dd1ca24,12eb4637,1d6c3200,a5992f17,3e6203a2,4313f000,62076e8a), -S(77c7da51,12a668c1,666b3c79,966a9299,a033ec4b,976e1fdc,15d62ae,96021cff,6f3f728,9eb1ff33,e80a7c09,134cd880,9860f9d,8805c8de,e194f868,4852abbe), -S(8aa11355,a8c1444c,c1d2cd12,d613e6f,1145e417,d11d9e4f,d13442be,d7e23aec,52533b3b,1024e982,725f77e2,50e785a4,97e253a4,f816eca9,2ff20ffd,7dd733d7), -S(3f504f0b,647cbb41,74adbcdf,2d226689,5871107c,68e12cc9,dc30058,4302b841,22a53436,688d17ff,feac444a,b5ccc64a,f82b802,da8beee2,db623b1e,fcaead50), -S(3f02019c,4692ac29,5fed5e1e,5190269f,92a689c8,adaa9e24,2a1ae01b,d23fd952,704f03b1,c7c03308,70a6dd6f,60fe12a5,cd711511,41ed831d,b6e5194b,e3de6026), -S(d33fd654,d7164cb3,a1a40172,28559c54,25630cbe,e34c6c01,8a8757d9,6eae7980,fbe58168,87bf57ea,b89bd0ca,3effb305,7b8d5369,dd4f90cc,279bb613,49d2faf0), -S(fa3439f4,bb63e36b,48056dec,109e7ec8,51944d8e,d7ac278d,23e21415,7902725a,b427d74b,88806fdd,fbda126b,38ca725b,fa61c855,5118fee3,d4e1f586,e888feb7), -S(f5c58687,a83c7896,3c021e40,e25fb197,82d422ba,7df59a1a,4f56bf83,49b19e2f,6b94698f,3f286993,ad8bf70f,5ab72ab,12059f8f,bc4f7c09,e624854c,3b76624a), -S(18e582ca,88939bf7,16ec8462,91d1ac36,a39319ba,546ba6e3,b224d6e7,3b0b30ae,6d091b7c,69143704,eab7ed7e,deba296c,26688d08,7d36d70c,8540c23f,ba98b8cf), -S(a2ded3a8,b327cef6,84785264,5b9ac68f,8e43f035,fcf00da0,da97e6bc,6d36db68,31b2764,36139115,1852a944,179c86d0,955faa17,da85281f,af02b71d,ea120dfc), -S(da61911,1341a038,fc286fa6,704307a6,11cb4c2f,9f6bb51c,da89901d,cb1e0f2e,30cdc05d,69e3434c,4cf06c35,f852b6cb,e0edc7d0,a9ee2daf,d793d2f2,b2d522ad), -S(9fa4c9d5,103b0cff,2cf01cc0,65c7afcd,b02a0a9,72da4418,63cc30fb,572f2008,401b410e,397b98f7,5948ff7f,babf6c33,9b1e88ac,77455bd,9045e7f,a5489e74), -S(952c5289,fe18f7b0,40f8ab3,17bdb63,fcb610c1,a6b3a4ae,4a98c1b3,2f1af628,66fcb4fd,2d347e9,fe40e378,d3bec17f,94bfeca9,faa84789,98f24294,d3fd905f), -S(5372941d,bedf216d,2d79656d,db0afa6c,8fcff27d,7464cc2b,a53a6bef,ac01f020,79bc84c2,33f106e8,96a1130e,a841b690,ed5e6b7b,f1e1c8aa,d833fa56,5fd4678c), -S(a4d5e6a9,b72da410,ec56d24,c01ae684,fd8e029e,713f9a1e,22c660d3,30bccf99,f08fde87,df365268,226f68a4,52acdf64,23f31856,9435740,9fa06d4,564cdff8), -S(e6dad981,9b3cba07,1465007d,4b4b5343,9d548033,4896c86c,bbede7d,54c0ab97,9e43f1bd,949e54e1,57a4adde,61217640,f798775f,193cef6a,db369c88,3e784d6e), -S(dc666af6,71aa7218,bac55351,ee12b736,8a29a026,19ec4f94,b9de8b80,eb3232a,3786e989,c684d01f,a4b5ff5c,3b0619a2,d39b6543,4ff0dfcf,24b59966,9d7dc874), -S(2e730ff0,401bb59,6dbbf02b,d9fd4d3f,eb3f6f3f,51a2ba53,d77ca83f,a2acd02a,9c508012,5904059f,bffee85b,8fce1438,fd761f52,86f1d798,512c47a2,d96ffce9), -S(9824c6d3,9ae02d8d,3b59290f,99c1d183,1d5bf401,15d6834d,799c0827,853d0090,2062d562,bca410cc,3b5fd22e,497d8078,6bd1a94e,d7734a66,a5a3495,77c406f9), -S(b10e2769,8f6a9e66,65b330e5,4b52093d,caa4f57a,19cc314d,eeb2452e,60f05cff,a9729153,e267d4a0,5859a9ff,3ab88628,47f3c117,d6ae757e,a19246b5,448a20a2), -S(d8817793,68ca0437,c780b0dc,51db1f46,ba5ec6a7,566b3579,e157a421,eaa04c4e,94da7eef,255630a1,820abe8b,7d8bce00,dbe5c467,89a53be7,2698c4ae,925d1576), -S(5151b8af,bd8b69c6,e42db2e1,5876fe3c,2da5c340,e17b52bb,93170bb3,5351bc95,122d0316,55d770a2,4b493484,8fc1777,de9a0f1,a5d9ada7,df678e09,591c30c9), -S(6cd1c141,67feba0e,406e12a,2bd012b1,7dbfd03e,9bacc6c0,6fd6455c,76cc0c5c,131f4150,f7ead6e6,35e93fb2,e672cd73,7f8093a6,c27cdad4,ea4e7c75,5c2ed702), -S(e83f8bfa,b679258f,67bdaa95,5cde03e9,bfe4126,a0eb89e5,abfb072c,cf536043,a9fd9d4e,e5eb9d90,5d8a3665,73d423f5,deb868b1,7433af16,28fda09a,406dea8e), -S(afe4206c,ec19b5a0,77683c63,a4164360,54be1122,db0c0bf6,6e564087,c6ea2670,15db0d5f,75b53b77,52af9b90,288dd9a5,a26f556b,37adadad,adaf558c,587b9e5a), -S(73428153,102d29e6,6f006910,5116c7cc,ca8b93dd,fe1c257e,9e5003df,ff139d47,7fc6eba1,465f201,3d234be,a022ca08,7b981add,a5ebcbb,8704bd26,750303b), -S(424143db,9fefd615,c6a97e1e,c59c3338,f7f4be7a,def4133d,747b7677,b0227e85,f7dce798,10cbb1be,3e1a91f4,9d490b63,aa740517,3a84d96,b37867b,635f68bf), -S(1d2bcb78,17bb2cca,b5c7e058,be33a598,122758cd,92075f20,24a7bd83,7f8dcd80,363fadf,e771b3bc,46aa7a6,cba5191,3b4d04bd,e673615d,8550822d,d351319e), -S(5cfdd130,bb671192,e4edeb41,96008cf7,4ac47279,ea94487,5962bdfe,bb1f4326,9a6cb3e2,925e75b6,264eaaf6,4f56fdd8,c0f4c5d,65cafcec,5d9cb110,5900cc24), -S(52495f7e,1853e084,272d6b77,72dd19f1,4f874952,ea08afa6,6ac16764,9664904d,2bdb6597,99a1822d,9801701c,98646cb,37a1f6f4,cd503720,79c23c4e,872e3d4f), -S(d82e59b1,18786ae4,a6b227df,3f231216,f33d2e1d,b0adf12e,a515c9ce,83ee1bfd,772bb140,7f180791,25d23c04,558cfa84,9f0b716a,c0863361,819623ce,7af2e437), -S(f6dbc260,90822790,e71f8657,22df2bb5,71eb625d,ccc23d3,c61fcba1,b9b96776,c23aa922,ea7ac2fb,c88a860,cfc3d7d6,a8c4f599,59c1c3c8,aadc88e5,aca1a54e), -S(aa7b6845,88c07567,a634b1f8,2425a085,6956955d,e532e905,d6017ca,5ebfdc1e,6ce07cde,1c60de7a,ee80355a,258dae5d,25960af9,be9edd3e,dc234e57,7fba0eab), -S(68065f44,466294b3,ad7e6225,24de08ec,b910693,308f8d73,847827b4,b4318656,c6e68f0f,2e9859f1,a2d9aace,ff9b4c52,4329b8d6,12233991,900d3e23,59804555), -S(c3d14307,5a223701,4ab61635,db180a64,162901b0,cf175010,d55129ac,168b76eb,5bdeba38,2f747cb3,50844858,b161fd5e,3aa8e7d6,873cdcc0,1702d527,9c691172), -S(3a1b6c2b,145a2f30,88e3cd41,6d2a0b8f,60cf8d2b,b3960c40,9637e5d8,a316f514,d724b2e4,c1c2aa15,9b85c32,684fa380,8af93d3b,c6a9d647,bce39a85,2f568fd2), -S(d2520145,c4d27a54,ed6de50b,30fead1c,ec602c4f,a74e3ef6,31f6b88,23e68bef,7cca310f,d966d423,b7285d7d,f4d5a3fd,fb4ad29e,94e69eb6,2a60a9b4,c666be46), -S(d01ff7ec,b4d574f1,56755c8c,fd615a99,83018ab2,35826574,d94cce5a,f78ad3c2,d9d17ed,ea436ffe,fb2f97d3,58485109,3dc64f0f,5bf540ee,c98ceb0a,9cd4743e), -S(5456f76c,a9c7b5c6,42cfcaa,aa0a2dcd,883ecf8a,626786b4,4735e700,fca5111c,6b3e05a8,6ffa85d9,8b9e4eb0,72ff60a0,df87c298,c2da5a31,d2af1c8b,54b91381), -S(14542249,652e33a5,6283676b,223c3055,56196b3e,21e48607,2652f7d8,ce598e9,64e9dc13,6b8020e,d590ff06,8702f99f,91c42596,b7091969,e34f2f5,2e0cb5de), -S(26d85587,4888c76a,96a6dae2,26a6f985,6fb5b9fd,b4ded1f5,a8f843c6,7346f307,d1c71339,d7be6c76,f1a8b0c4,f047ec71,519bcb05,a25ce054,afcfda6e,19971cae), -S(7f8e7eca,e0257e79,ab2c04b6,dc045ca,363c307a,4b04ba70,c5c6272e,23acf215,fe96da11,f16d1171,9f91a666,23cc326c,57d3d453,8639377d,c6b79b63,56ff6ef), -S(4ff72771,ccd75c6,2ac827b4,e800e580,e6e4681,208d64d1,11c93258,2d188154,94e87e31,b2907d44,ee02e947,65ee5da6,f2bfd7b2,9808bfdf,dbd2825d,1b3d6c77), -S(afd475d0,8946f556,81284fd3,fbbf67fe,6989497a,481543c9,1d4f4254,75aa8d94,669a72c9,a8d0918b,a1e787a7,5b505f26,d002b417,f156d888,5ac02ff,bd29a920), -S(f5c11fa1,2912b0ca,e4d680ed,55ea126b,3c260a2e,b8fb10ef,ca21ad7e,65591590,7406281a,a8744da6,eddeeaa9,274c0591,fac0dd0b,3d7c3df7,e0f65c7f,a712680c), -S(ec9b680d,bdfb2a2b,fbd04bf7,cdbe820b,7975563f,6f0f6646,72236c66,17aed40a,851c69e1,99b77fe5,f16c4c2c,4bea6771,1a23afc1,569a8bf3,c91e4133,a8324e53), -S(1f73cd5b,34444b1f,d7287750,c213d5d0,17a8fb49,da9cc3f5,9ee30939,dedf9c0a,792fa236,514d0a6b,218b312c,c5b614dd,cf0a2960,ca13660e,f696d80a,b7faee90), -S(7b0013d7,a6c967ef,e1006cc4,3fb177e7,81cd4021,223ba083,50db6ad9,1e949e06,a2f8fa6d,b6416da5,d0b68bb1,c1ddb47e,8081a063,1422c72d,2bcd7b46,d2576a60), -S(14ee47f5,539c7a7d,acad832,1197c83,7daac6b8,6ba7a828,84cbf45c,ca70391e,7902e477,28ed6a07,80fdc510,c792103c,e4bc215e,390c3894,1a3fe0f9,582f62c), -S(fd75aac4,8e5cf9cd,9e14e7e4,6e980ccc,1a3948f7,41e0ba93,25f6d490,1d15d9dc,b544f9c9,febd77a0,89980585,9ce52db8,e1847db9,dd4a7857,6a8a9210,fb61d2be), -S(93aa7a40,c03e4e7,d605b8b0,3ac2a378,122fee87,9395aafb,4698d35d,8f7f4690,db2859ba,b6d5c89e,2fc4b68,1488ea1d,8d8905f4,a44af57d,3ef9f937,4872013a), -S(20a027b8,79a10933,519a97b1,72d77389,5b8722c4,ddc4603e,40319107,1ed4cbad,4fc480e9,fb55854a,f12077cc,dce038f9,3ec1f3ec,6a37d7fc,ec03b204,8cf9deae), -S(e0e26a0,862f4ca,96084cd9,bacbf501,31da0f20,1f3e4a21,f41f5ff4,853a41ea,e78c00f7,3dc8200,cc43d04f,6105e189,387fb1f1,47f39d71,f562d7b1,19c0f591), -S(fe7f03f7,b6633a8c,e514e801,bd9b3b6b,c4bd7790,69915720,8d49b513,8d5c6be4,74db79fc,180cfda0,c17ab6a7,74d73d28,3c9119b6,d85f3a97,d32389b0,102c052), -S(92b2bff4,c74df07,3cc3a258,fd4fc56,88f1eeda,1908036d,c0606994,92e3fb6e,f92ac36e,f10ac585,3e64a67,5e8e26d,b3cbaa8c,1670ff,ba060f19,bbf04fff), -S(fbfdc0c,41238a0b,ea6e3c4a,b09453c,2afb281a,4cfb5cf7,97f3f473,b02717cc,bce0f212,9d3407fb,c5541dfa,7d266788,72343f8d,748b7b3c,8c0cabd0,78378f85), -S(8dbba484,d9bd416a,f1e18a30,6f42c73a,cc15c5e8,49049c98,612a9d64,f8c99539,670200f4,96e34f9b,50601a49,32200d7,1d79e69,b7889f8d,ca45b13a,cd9cc7e3), -S(44193861,6c2332c3,1d35f82a,b35b515a,1cb3d754,3f83f5c8,63f809f,739448fe,ea559711,904549f4,b2986865,86467205,58420d27,46efa1c3,2ba002a2,64e84219), -S(acbc7bab,6acc8d2d,abf39739,fe9a560,d225d692,9a1f2e93,3a441173,5b766e64,e9f2c663,4104067f,5707f9c4,6a9a7d6,312bf3f5,6a851e0,d52057d,6bc296bd), -S(e3300502,a870f610,5d7b3c68,f26d4ae,bae2b4f1,2a893d74,768a6b8a,c66573af,558f537a,8838b676,121a9d0c,c62d862a,4224348c,1a982c37,6be1a255,a57caae8), -S(fc34afa3,8d658fc4,8d420c47,651057b1,3eec6863,2d3c3a22,bd83580e,3a6f8b82,96a3436d,228bb25a,fc274c5d,7f5da6e6,fcab6b6b,72ee98d3,fc293ef2,ed523154), -S(5e1cddfb,a73e3534,c0409da7,af922c43,7f9dc2fd,6f573ee6,918de501,90e448e,4b1adfe8,406274fd,6c1a3ec0,68568d0c,78132b3d,efe3a9f4,fb23a725,a4f89251), -S(d307c67b,cbcca4dc,89c680ef,9bfb7421,d2283fcf,90a07bfb,95c50cdc,f36deba6,254f92ef,5734f448,24ac8020,89f84bf2,b7e8967a,8afbc2f0,e01bea62,b4a90b73), -S(f4977bc0,e8f81cf,753a2b58,65b512c0,6916b53b,1a0116fc,a5528e2d,aba2f2c0,49fc2c15,8cf226a8,5099bc97,97b2eba9,9516ab90,1e39d462,3adb96f,c44e6c99), -S(e70cf22a,9099028d,96239342,bc94619,e266a53e,6df63d23,fb317879,cc547382,9ee3689e,f7eba3e0,f8715242,5ca1bcbf,fac4d337,ac4afb59,107788d8,6f0f61a7), -S(130fd05c,ea863c62,15aa8789,2d5e293d,3493ad4d,5f526a06,b33c4675,e02393b8,75c9776b,feafd1ea,252aea1e,5f8c8,9224ae3f,39c5ab98,98395468,6f45cb68)}, -{S(1b8462eb,1ccdf7b2,b8372f2f,cec1f479,ab07c09f,cb26d6c3,965ec73,4d654f81,62f6755,b4a7891d,55de6427,fbc37d33,e4eea418,a2c04392,a3d11807,ccc9025), -S(deb66785,6c4683c6,ad7c39e5,deb1b8d9,722ecffb,f431fa34,9dceab3f,698f738e,bae7261c,368ee55b,137b913b,8bfbbd07,de4600fd,7a071287,47c31531,924942f4), -S(75ae3c34,5cc1bc11,46c5f13f,a1144759,d39c4d20,4a8f2f0e,bf3c313f,707d49aa,82a5a9b2,2743788,938a0b76,eeba99dd,f85eb5bd,f7ab8eb5,5f6e5334,a00438de), -S(49bd4e57,c59dc8c,c4cfb0fd,83c5944c,3591eab8,1ae90f87,a8d30725,1904fcf8,66e76d62,610cae77,38976214,20955dd7,95e47715,3bde0ae7,491927df,bf2b1c75), -S(5f3c96aa,a71c774b,754f616c,5eaca0ce,f9d82264,7dfc7c2,ce38ac7c,d7429748,8c72e7a2,b7371046,94ce5e77,521ad47e,2fe5cfd3,10cbcec2,febdd977,9872ace8), -S(43d8f72d,fecd31ae,91eaea66,a7b96a25,2c05c3dd,8d7afd20,d64644c6,cad460fb,d6a28b23,50f5a7c4,cc8233c6,85c87875,9134923,55cd3532,f888fb79,10342509), -S(cae9a205,19cb6e40,ed8c6774,7e7c52fb,5c57f1e1,56ac6f32,9f1538ef,6971e888,959e5c41,344ff293,3387c680,54c03756,1f3b6a97,a75a3119,da25debe,7acbe4c6), -S(5f96d7c7,a8409a4c,d4afd355,1139ee0d,ae63bf99,2580cffe,fd5f7497,2bed3d26,972b40e2,83dce233,190e8961,310d854c,db5d4805,e045b4ea,29414909,592b589), -S(2ed0f7d5,a0281d46,61159e80,3cd6bcd,61b1a37e,16aa6801,bbfe526b,9978bb8a,8a6d62e1,2376a282,e62b21df,238ffbad,a055c342,db073e86,1107ac9f,2f2149e0), -S(167b0b4b,c6a4c17d,9f3a2813,87bb277d,fa30bf1b,f35db9f4,b521cc53,dd479a18,32d48b8c,535a49e0,4c412b05,7e000117,271dbe4,5b7bcaa4,87a857f,b723fb31), -S(358af81a,b1352729,f824fe1b,40eab58b,23298fed,82dcbeec,1ec3ba91,21438fb2,b5bada2b,3906f17a,5f882cb0,460252d9,b11c221c,1d316d79,c21dfa73,174c9cbe), -S(ce544020,abc6a8f5,4d911c49,4d0fe111,bba24b6d,7b5f43c2,7f307c1e,1c2a36ea,2d34bffb,416ce2fa,21db1ce3,b6a97aba,29d7a45,29081849,45df56b9,ebe8351a), -S(6057a2d0,11320781,132b5de2,48ad5fc0,d0b69de4,2587220f,2de808da,e61906d9,df0510ae,96a02157,bccc84db,32204888,277d22e4,76160682,65171c77,4766ab23), -S(4eae969d,c9ca79fe,8f61dfa0,e6f3525b,12a3602d,feda122e,1109e0dd,43ae07c2,7763de53,9abc7599,75f289ec,92866fcc,486b1b47,40ea9761,60aa37f8,f7fc142f), -S(a698bc22,7cbd5730,452aa9af,2cfb600f,425d27ed,716cbe96,603d3280,df046c52,c91312c0,7492188e,bf054f37,e20b68b8,9e135946,7180a505,389da7df,7d45326a), -S(52fdf09,1413d6d3,1f64df21,17d35360,16323b0c,e93c66d,257157e6,2e2f8197,d00868d1,b08ac819,9c4e0215,a0beeab,76a543c2,6e3bd1d1,67709cf7,ce2fa4b8), -S(c19e6f2f,98a0f54f,4f61eaab,7b4477b0,ddbe2577,7e82e836,d8b71e97,9782461b,65855134,75c8676b,210c29d3,89d30beb,dfcfb798,6841fae4,56e7b800,e2193d15), -S(7cf919ab,a90c3572,bd41f673,b63d761f,60f28dca,8b3846bb,dfb13545,1ba52fd2,d474c2b7,d6e83e20,12866c01,21f17fe8,e6b36237,45d162e8,4003f04b,808f82d0), -S(455e9205,4d052a0c,9e0a86ba,83ed7fdb,b2b0c06c,eb05b995,13f6ac0e,75f149fb,12b026df,332040e5,8e2f92ea,be60e016,cc8941e5,d7972217,dba58548,f1079657), -S(e066bfb0,1239eaf6,7599d76d,befab533,9542c16f,6b150dff,c96a0eb2,bb0b1622,a8f1743b,b307f660,6ef6485d,aacd5b36,93354863,1d287b83,11eaf53,77df9ea9), -S(f4844f56,52f6b97,fae41a88,3e433286,a0895daf,4929fa51,8aa5040,da2b79eb,a6c86fa6,5c02cc6d,25b6cd86,473eabb4,95d28ae5,b71061dd,8da877d4,9ada9ecc), -S(111d3003,b086df80,114ca249,993e9a56,43980184,66ddbe4c,adc919b4,d58e60d2,ffada7e9,bf38ffd1,19cb0568,da7c8354,ace0f714,6ba144e7,90b1fe26,5e97f82e), -S(4a556e10,ebe25839,9bc4c3e3,8f4e1c1a,7a1500ce,44c38a1d,94e7b516,18ba3b83,6bd865e0,2d756729,c7560a7e,5422f19b,2f9e5007,f7c31d2f,3ef8cf86,7eb83373), -S(10b0a6b2,dc05613a,c436d0a0,9b082c01,8197ebc4,f106ecae,feb40113,1021a9a,6d6ef39b,33023000,5d68215,aa46ef26,b88d6e9,73b21752,a2bbc055,5c88dd31), -S(a0666545,df775bd2,83a6237d,8b8a7357,7c6bf0f7,5ddae3d6,4e65d3a7,90c69336,e61fd87,f43a927c,a5817c6d,20edc6d6,c69e6667,8765be4c,dd260eee,6a7dd5e4), -S(a593c02b,d899107b,6c71aaac,f7314f36,a594c892,32f5dad6,15601ce2,de916170,52fda077,3ba509f4,a1eea11b,6d11824,83a7c16e,b4227d27,fa844657,cdc21d86), -S(46d914c6,a68981b6,99e46e4c,56a6c482,f9ca55f5,4618cffa,5446e93d,f11495a7,bf913796,9dc92ac3,7d52b941,e6199412,117c49dc,8c05df05,95b7721b,66ed1d30), -S(7882d56f,8e53e827,1d51c0c3,49d2afa6,d632fe6e,344a0e4e,c467ee9d,7399b953,345ace50,4127be13,989c4d7,38f00271,a3ea7d8,720ee6fb,82de9c1e,3873f95e), -S(78c6fc9e,571e02b8,f8bde2f7,9540fef,452fcf4e,2b6e7649,3748f594,aa4d6cb7,e7f5a947,b486be05,ad3b9b02,1834b360,ed8bbc78,6013f58c,dca02885,bc8f36ad), -S(562b2b02,741d8c65,6f457bad,56d7bc25,75ed4ced,46577b52,d8b35deb,e8a7504a,17169453,9746549d,1674a55c,2bea12c2,56074f42,91783f5a,59b92eed,768f4095), -S(81f3c319,ff4e12bf,9b7cadc1,75712278,eb9b9275,87df662e,a72fd92c,7d79232f,eb6ce068,131ac2c1,c31a19ab,9aae0633,ee184235,62065a31,59d978cc,43523b6), -S(8ad3bbb4,dbabc2ea,222d818c,6680c029,b0a11a15,7c175165,69a2729c,c4ba1608,65c3812f,9f645537,fc6cd8a8,94279c10,5eabceb,dcd21eaa,dae4784f,69db467a), -S(19bbdb50,a8ce9bc6,5dfd3006,3508bc23,528b3e3,e0615529,1ec0ff71,6a6b708c,75f8a65d,a25c9020,e1b3e26,929e67dc,9edbe8cb,7ce44e29,a3c2be40,50c3370), -S(8866249d,46d790ae,276930f0,8bfd2047,658cda45,ace08344,5d254413,502369b,41547dc4,2fc37c54,11d65d1c,83df2e5c,31285530,15b51106,155d7549,5e04e711), -S(b18db2b4,15471fbd,38648770,8075b1a,7244af47,5a4099cb,ecfddd0f,18bde801,1a2c7d97,23352c93,373919b,a28bfddc,1af8d2b5,953a7da8,2706027f,e802b77), -S(dcd6a63c,70380948,dff9993e,b163a6b2,54625677,5981c03d,16b7b46c,f0b05bd3,2db2651a,e5adc2ef,f2277b6a,d59fa0e6,d6975fc8,14c0c4c8,192301b4,63fc8969), -S(c66261f0,3bc15a7e,2b7ec26a,9ff9ad3b,ccd7a005,b7f9eb0f,f14dc9ea,64b66a24,975f18c,8eed73e0,c2873945,2fec446e,eeaaf732,c3406add,efbbba5c,8ce72236), -S(1ccedbbb,6705448d,9f5a6271,51bdc2cd,e4f57a4b,ac283514,3de7f244,b3fe2593,d58f089f,588979b,a8dd5e1e,e1f2b1fa,26ed488a,9b7ff553,4d4296ba,c768f3db), -S(fa89b801,ff0cadcf,e45d5e9b,b9d76769,a4a8c293,c4d7dee5,eb3b889,ecacec83,fc82e286,1e786cf5,854d69e8,e3c09ac0,4d584273,27f9691,33cc0087,cf7d3a3), -S(ba9e6bfe,2167dc7c,e2cca3a0,bd90050,6b4c5ed5,a65b6799,38850e1,e983c307,8076fb0e,e4b3bd10,5826a6a4,eaecdc6,198cb674,f62ab20a,dc8495ef,9c69df52), -S(dbffd22c,abad0651,673f6018,a4ec19cb,33e25609,5170c06f,b37aeef6,8a7cf6fa,532a4a76,56c364fc,72e4e3b7,b0bf6fa1,9c7c526f,89cbb49f,8e8ed85e,e85dbb48), -S(470174ee,d0a5ced0,3136015b,581f9e97,bbf2b486,6bc855a4,7f4447ef,c2465628,f6347774,94972ae4,90748fbc,631fa000,5c3c9b2e,60072fd9,fdaade69,ef0f039f), -S(e965ab4c,e7b53fa9,e47a278f,18ec2338,5bc8ac5b,ebd90260,340637c8,31585369,ccd9d755,9b80ff65,ee866c71,44abb0e0,3fa30c1,91bb8593,da54840a,cb2a9d95), -S(f4ed2efb,fbec7f8c,54de593,80958b35,e3e4f3dc,1af445b2,a491b41b,256ecba8,b23b37a,9c4287f1,392eee8d,50d8d406,cab40679,a66e0d40,544aa304,aecb9c2), -S(3d911698,27693d14,3b0d458c,427cd698,eeac19a7,8f64d68e,9cb43c49,5421d915,be75c3e1,fcd657fc,59806fc6,bf1df70d,59e44b4d,6d217c8,417d20ed,f4560432), -S(c4589f51,1ed541c4,c4872619,726e7381,a9566548,4e8f0c16,33cf55a5,61b4f33a,c31f26d2,48c2687c,e119bdcb,1aec287a,2f7e25bb,5b3b1ce5,3af33dd0,9a92508d), -S(b3ac12f6,f45d31,b1d6f44a,7d042406,c04ba3ba,ae68fa43,f8200717,b3fd7c90,d04d1b06,ea0f072c,daef4212,89667b3e,effd1f8c,3b4c4f94,ada534cc,552e6d1f), -S(73ed49b7,9a7ecacf,6dc8ef7e,663111dd,40351718,d3289287,7131f8,53fb3b73,e25b70d1,c9d605ca,571754fd,6b5b0317,c7454773,9f71c39a,9069431c,1c755161), -S(d0cdd56c,984d2f4d,6f5068e9,27801a78,9de020dd,32c70cd6,eefe8dd6,aff910a3,35152fe2,70b7bad4,f0d151cc,6ac69412,5b7dcaa7,c757ac32,3562dd8,45362494), -S(adc7e82f,bf52b914,cb3e3c4f,c1d96ee8,7c1a9b5,3a449587,962aa19b,b03967a0,4883619c,7be39873,9be896b3,b1fd6f9b,c62ca121,198bf71d,85e918e0,7ac115e6), -S(a204d702,1a346020,ab978bd7,78ac1df3,bfffb831,3699c3cb,64a118d4,da7f607b,18a0827,bd9da5f4,35ba7ebb,3c4f198c,3f5c3313,fc6f6e0c,f796e51e,3c2e7d5d), -S(8a6abcb0,2aa24acd,71168ace,c4aa3aea,1485f04b,afffc1f8,7ef9a059,d5996ee0,9979410b,afa6de0d,42852883,e13e84e2,e62db36a,6c2a4967,f8e30a8e,11775e5), -S(144704f7,f1ddfdf3,2e270958,99e0f74d,467b09e1,ef388d1d,954b6817,3cfdc2e2,60e0c043,c4bf6051,e09960ee,d7a156c6,5e66e9d5,c19d8b0b,b8ec9edc,6c3cb3a1), -S(4ba11b29,7cf62910,4d7bf384,d87bd0a3,2315170,61e58d80,600fd7a4,b8e93ef9,fd7b0cc8,5c9de5c2,184fd95b,d04d1d34,4c376f52,e9329f31,98ef2fe6,21fc6ad1), -S(4609bd3a,6d606aad,f372a731,9f88211e,31f8e187,d3d0f7d7,ee418817,13540066,62d5d099,88f99333,e309b519,93c17132,45ff5435,8c29403d,8cec5c58,ef4450d1), -S(66e02b23,5399ad24,6d898a63,6e9f968c,b8abf79a,d976df4d,962219b,ab01997e,80a6f6d2,ee813cd6,bed0685e,d42c926e,d59f3067,59a409d0,3529d474,92acdea0), -S(aa668419,1ce4a14f,450077de,e4588ff4,7565c821,7d7e7628,8a2fabf2,7ac7f1fc,e9c1eaf2,4b00ea7e,34f65672,4db33d21,efadb2d3,7ab90d09,e067a286,a75c200), -S(b4680ca9,f0d4eaf3,36cce2e,aa281eea,c522d87b,ac51995b,6893984b,7351daf4,212a1992,b7af5e9b,3d538c81,193bdd3f,61e24271,fecdec72,f1359bb2,95882590), -S(f682edbe,4cf0c8cd,ca5bbfde,4b1263b1,90a1dd5e,e8ea718d,7f01b892,1f170741,ef891402,e5598b01,295f1e5b,48bc1039,375e920d,550cb552,7bab7160,1ccba576), -S(a40a6aa,b4ac57e9,d3b861e5,2b70d28a,5fa6b9ee,1e1f7776,37397f04,6eacbfdf,12957e43,31a5c6c0,18d0c987,78723fec,e16182ee,480b8cfb,6506ca0f,70603294), -S(53b2aa09,23cf3866,61c0271,7b8302c7,4807fb5f,31641a8,e5c4135f,1e6bf439,d4eed7c9,8b265069,533cbbe5,a6be5182,9d79989a,9df82e71,61c3d45e,f0ff3e06), -S(2644109,54ff1fc9,34ac41a6,5b7cf7f3,d66a0976,999b3a90,bc2c4c0d,de3c4ccb,be2fbecc,c71068c6,4b692e1d,6ecfca5d,14271c40,d6713ca9,323eabde,cc7dc588), -S(2e63233a,4146d344,6ed628f7,a0fd277b,435a9d81,21a2dbdb,43dc38db,69189e91,f0d3d6bc,13ee5049,ff2deee1,a13d1e4,eb8a579b,965a86c4,1a0cad1,8569494b), -S(bf0107ed,190729a4,3e130ff7,5cb99a3c,b13392b8,7fd01e32,ae9ec3e2,a0a93e97,eb2023f5,76a06d93,27cfd3ac,c6ba3d5c,ba3ce673,f84d7666,bd2f3f0a,edb63b9e), -S(c22f151b,c978953a,f3a1fb0a,cd1f7255,b5923e6d,c5aa4c26,53fd2109,3b493171,fd3e46,cf4c66f9,c66c5075,313aa519,538b3df9,f2660554,8b407515,502ae877), -S(b99e5b3e,e44391f4,dc3654a0,86abd389,51c8d8ca,ead1ed8e,ccc1b7e7,5b5a4cf2,74b4fa80,bb4579c8,643299b5,5478ce5e,9566c1d8,98eb10b7,200e8854,6a20eafa), -S(b1734d6a,7d8e19b0,10479c2,49ec6806,9d42ffab,e8265d6,f5fffc06,fc1243fe,bed2333,91c587d3,8710f320,1e74fd1,5816ac9c,2eb70bd2,e182cdf5,986b550b), -S(c6c97574,dae3b2dd,9bd060fa,b0515853,b2043ab0,4e58993e,98aea78a,f5678b19,3127c67f,dcf8cfcc,f4b1ee2b,17abd614,ecda39d2,3baa99b2,53ea3c80,74f9b433), -S(14d32f30,f9268e0d,98452de3,4adadf46,928457cb,423b1d95,a58c9f27,eee95150,ba73964,1ac3088a,2285a4af,c63467f,9efeca29,5ba61418,f6d15a68,1d7b12f3), -S(fb71dc00,dbcacc94,39fc4949,ed18b7be,45cf50dd,8dd68c18,b0855344,fae8395b,789b4500,3add70d0,cffc34e7,5c348033,30965e66,b10e0b7c,eaa21f5b,782ed574), -S(97978bd0,2696dd07,408e4a82,c5e7394e,6379e3d6,314658d6,a37e302d,218c6ea,852fb297,591996a7,f1db1402,5ccbe65,9819dadb,647d28be,5f891bbf,e96d3b57), -S(22d18ae4,56cde12e,451f800,f61edc6c,e05a0fe1,91afbcb0,8dffc101,400ff240,4506e9ae,7b87bc3a,9e9eb106,f3a4bb3b,9adf5144,6389db40,5d6e3e53,22874552), -S(263a0e17,1c1271f5,82ccdb1b,5643b400,94f18e82,e8e2a67a,79ed2cbe,c8d7450c,3cf4ff5c,f9b9a42,74650323,88b5083e,676d0ab,45ab061b,9de8d16e,a5f63e84), -S(1fe94ed9,eb72bdbe,9ab19dd4,abdaf994,7e700451,eae8acd6,ab2a31e1,d97a9ab6,f87b6fcf,e01b375,244b1550,77054488,ed835f5d,3c0d27f1,5f150199,40b3a153), -S(65ab4ff,32bdc4ab,953e8983,11ff56d,2648904c,a6ff30ad,3e013c6,f6b46783,45106115,7e3c8b0f,8d362ab7,2de710b,833cb381,bff4d243,32d6532a,1e76cfd0), -S(eae54dac,dcda8825,45912080,6504fd39,a2237e5b,904c3b62,4c960fb3,ec235cb,790f33b6,6cf0a163,160eec2,4f43c321,31fcbe88,696956bb,8b355eb4,b00093b9), -S(5122f262,72e25078,a9c989a7,cb0bc781,47f0be89,6efc65ab,67369af6,8b1b8f41,612aafd3,a2f791b6,5d62a52a,202c58d2,8979e4d9,a856d589,ec45f514,4b7e80a5), -S(9884b4e6,5bddf06c,c3b0be07,108c4880,f2c9f4d5,58b2781,61e57f29,e257aec5,5d4c8435,c7b7a514,929307a4,ceddaea9,ff551c0d,faa2bcb0,77c68755,4f7b4dd4), -S(4dfcae95,4a4e92a,37dc6d8a,3e503359,4b193f66,6adda287,603499a5,f55f53fc,7aa5ee13,952a1572,bfb85bb1,20e0d2bd,1a3dc28c,b87f01b1,8f817b31,c143d58d), -S(bf8f8ea3,d37eee45,78cfcc3a,6f173097,abc2582,22128787,be7557ce,df4f9a48,8fc5aec7,129e9a05,3c6c4654,4559ba34,f0395264,f01ec35c,1eb11a4c,3fad198a), -S(7d9294a5,f462db4e,5e69ac86,427ab556,818a73c,dbc2133f,f6575f43,312d6c8a,d7bb697e,1498984c,d489469d,f4a4214a,4571406c,35b5e88c,f1d11b48,65fb8b3d), -S(54b0b84,e6ae338b,65d832bf,f820195e,932d4e60,24307c96,a8aa8132,53639c9d,330ee890,4596ceb7,28749302,7c8a0163,cd3a52a5,69d41a75,3c099b50,e92a1289), -S(a3331196,8e97db37,c774e6c1,52d5ff75,8552ce30,80d7b9be,5d34f7fd,1d41726d,644016ad,988a499a,70b31577,dbaa6505,7e50a5ed,1cd4fe0a,db31bb50,c9a7e0a), -S(35e2d742,79bbf8e9,80338f27,fff504d1,640cf5ca,30241d06,d388df5a,5d792652,f88cd405,d779b791,f875ed77,8bc92665,359def46,a903d5fc,8052fed9,9390c0a8), -S(e1d851e9,15812c98,a2d176dc,7443342b,3812052f,c2ae183,c8c3aa0e,662c549d,e225ed92,a1d91ee4,2f191b55,f15c9aca,fc379519,ab0507d2,df2019c2,369ae46b), -S(6e99db31,e3f54cb7,cc6e8640,dfc62b01,471ca8d6,35d788a8,e6d0c79f,8de9efa7,176e8bab,4340883a,8380b53b,1e981376,d7f3535d,41429177,bb3a0187,3cf78d6e), -S(ccb520f3,2c671c00,56cfe1fa,17eab66e,7744b2d7,9b5919b4,47a55ef9,bed0d96b,b8a3016c,fa65d9c8,23671498,46379fe9,2f4e74e9,6487420c,38494701,efd9c809), -S(c5e531d5,49e65f4,254541cc,84bfd39d,2279d7c7,98abefc8,cc2cbc17,2e6ca6,4e1c664b,8bec2ecd,7d56db93,66f6a582,2fc70bb6,70c4d3c1,90b76bd4,9a825995), -S(a132f569,c7cab520,d127fd99,9c06d4e6,4a7fa953,9711e1bd,9eea72f6,78430c7f,a81cbf89,b67534a2,4f5ee9ef,8bf5d134,90f73f78,63b3964a,8a81b5af,e44fe664), -S(59242d2b,9279ac93,4a7c99d7,dba4e033,7ba5b199,29a6fa2c,24766c20,71b3c5b3,8824c16f,71126e9d,6bb56bef,7c5e37c6,760c70db,de4b7dc9,e29afbd0,a8d09b42), -S(a8cb72b3,2435a4b5,5687ed9f,bbdd2860,9e96ddad,dfb7c44,d49f528a,f8ba5f57,e8ea8408,eca95aed,f2a6509f,663956e8,e7ced42d,12900677,c86a4b86,ec0b40e4), -S(58888104,903c52df,fd26b72d,4671642e,c06b2efa,44ebb727,e6ca2d1d,616d12af,387e465c,9559e35a,124d6501,715e295a,3d95668b,35335db8,678e48ab,7fe0ff1d), -S(6cddcea5,a0bb7220,f206cbc3,b6ac999d,47f0d2d,728038fc,3b86fa8,61f4069f,724dc303,13aed0f1,ecee0d8,f696c1ae,d00ccd02,90df311b,8611ae43,3664b31d), -S(283557b9,3698a99d,c64643f3,d302454,841eff33,dc110d24,a00467fa,1d9064cd,715b038e,1147a84,8ad45111,8eeea2d2,66cfdad2,e829932c,fce6872e,a99c2486), -S(3f88dd31,95aa10f8,fba82e6d,9d26cf4f,f2ca855b,75bab7d1,c1305654,ccdc8cd9,99ee6e45,76a0773,a8e0a241,a40b073d,78f98b03,33292f75,650a7eb8,bf55fc88), -S(4f0d20cc,acaa4fdc,972e40d1,90ccfb52,c635c438,353d2fd3,47ea675,ad966fff,ab378bf9,c5560914,e5c423d6,f28ee794,eccd664b,fa78a18e,b8f096e9,c7c68bae), -S(4c4f2110,8d32ad06,d60eccbd,238495e,268d2545,bfc5f17f,cdf7a1ca,37c96639,7edf3b15,346f21ec,b3a271a4,bf70813e,c9a4e4db,169b6f36,1d5d48c3,16d7594b), -S(1ba8777b,218e104e,c0908ea,b9ca48d,9145b8c2,a3a0b6ff,95146883,3077f40e,dd385247,7de05b80,6df645a7,646b1c32,90f78fc9,4eab711b,433c915e,462c52fb), -S(4cda5560,ef56756c,f73fdfbf,3799e8a1,f744f497,bab91815,eddbba86,b404e33e,92e1efd3,eedd500c,f4668d78,f4283cf7,eecd6c6e,979980a2,ac8389c0,779862c6), -S(ffd11b85,884b2330,e21d2077,336fd518,a337a931,15fcf6d5,d843b002,dd225ea2,6ab2c275,4d0e514c,bdbc6e24,f3e2f019,8b73b3ee,d267224a,705e0421,4f449d60), -S(fe4a2c46,15b9b000,d871bc7c,af5e6672,a574a165,e544b8d8,bba978ba,ac80bfca,cd15b01c,1ac4e6b1,25b00112,c04d20fe,3afcd997,541f3955,ad60030e,413cb650), -S(c070d79e,dea4a095,a054e026,1c748411,19b7280f,d5cc922b,c2b092a1,f211257d,f7b93b3a,4fdc7bf6,d90ba7c9,56831153,7948d110,a9cff253,f783f075,6c569e90), -S(7820e29b,8a7615ef,44f0639a,2924958a,4b132f73,9e67d58f,ed93f540,934df025,cbbd3f25,b03c0542,5109d5c7,5a409a18,7c117e73,4ba624,3ae7e085,322df8a2), -S(12b4cc3a,ca603277,32fa5c6d,4ffe02b5,eed489c3,9ea67f67,fac3ad66,a20309c9,9ed214d1,4217b11d,324a1c6b,d6edec3f,6dddbe48,2e238376,d3b74a0c,12de2695), -S(bacc8392,e6770551,38b13942,ce2412cf,6e22f959,9f8bd91b,d4855234,d0972261,91263e47,63785808,6c645df6,9b36a64a,8c6a07ab,fdf28a88,6893cb91,4c5428a0), -S(8bf48d87,419b4741,e461ad8,650f2e5e,c93c1e42,cd75e307,c60e8655,8560d576,c38c0513,88d64e1,cb9f430b,5357ce64,c4aa4379,3494485c,4c23e07,dda82bef), -S(c6217853,f15a6675,aab3b7e5,703ff725,eaf68bf0,60dd45dc,c2c209b5,b6255d22,3b5e1d4a,3b04bc6c,665e4ad1,a3a7587,b53f5fce,6db4aba,bcd01f3a,53b342af), -S(ff04846d,7a1309a2,5bcc043b,3a129275,1c5659da,e1377bff,f0a4f52f,78d57c03,5906a77c,f9c5116e,b2bcfbb2,330f12a0,277b211,7605020b,218af50a,b50a8eb9), -S(9d6031d0,7a4005ca,5badc057,34171110,341aa446,37bd5260,9e3c052c,a7833a3d,c505366e,18f920ee,382b6d0,5c71641a,9164c7a7,685bbdd8,6159d981,6990d5e7), -S(328fc8fb,4cfe884a,d6f8807f,5af7f09b,852cdb4a,8d12d6e9,e0a83e62,ef124cd4,ccb846d5,9e5ebc6a,5f753bcf,91ff3e4e,917afd7b,ef3ec9e0,81c302f7,d0302523), -S(6d15ad00,8a21f27a,50545edf,f6259ffc,50b7b42f,6b66daa8,274ccd4f,9968d758,44cf472a,6a9a5bdb,bebc470d,33936503,2823d19b,62f59c50,880443aa,bac08782), -S(a406569a,df5772a6,e881b5de,48a4240e,680b7e48,6487b3f0,6bc10a62,f930154,5378b0d2,df6a717e,b90a9d48,aa9728bc,5fa45468,c997a990,f51aa988,67bf6d5e), -S(a481763,b51b1851,c99f906e,280e425b,833ed883,14b8f84b,ecf5661a,369d345a,95088d19,330668b6,44bd68cc,a7048e4e,da96fa6a,365c1279,47eca0d6,29fb338e), -S(5600b96a,6e0056a5,12160020,7115b198,8ff3fb06,538d6580,f3ba0b57,a9490fe0,a09d1644,f0d14ad1,73b117ea,cfe1f992,2bec2bb0,a8f92f8e,4588e985,4566f88d), -S(95e9d301,fea78bf6,fdd7210,16c7b890,fdf22b85,54870d4a,520756ec,b8d56414,dc2df8b2,6edf5d4d,faf1291,cf2fa41c,d26090a7,499bf36e,a7c5ffee,bf404236), -S(a154b8fa,adc62ff2,ef26641e,4467cb6f,3506662b,8e452518,1832d6f9,145d00d,2cd50f3c,62a43b4a,9bc0c6d8,72efbcb0,c8407e82,39d69ed,40ad56c9,ae3ca73c), -S(f5f28107,77bc1bb3,10c02f60,88a2252d,ac3c3855,78909551,c4602b84,fbeab69a,c23e586c,731e84c6,5a5a0f19,308fce27,ba3fedbd,3980cad0,389e9ede,c1fe6c6b), -S(64be52da,6082fd6b,9f909950,d8887a73,f614cb5a,8e867fdb,3768a0a4,a958c699,4f6792f6,f65ee798,77ca9ddd,3bd4dbf3,3675f059,6d5cfb85,bbd8070e,6f29031b), -S(26d9c5c4,1803962a,f242b042,2fa73750,12c91a17,b6848ab5,af4e9335,43bc8388,f6703950,633edc7a,482f9651,9b638fb0,337b7bb4,dbe6ad24,6a47294c,7f26896a), -S(c1efc973,50a488e8,467d1fd9,ac679eb2,ba011aea,412d7857,e3d2cc0c,19dd2395,c58649ca,c665691f,2fdfdb68,49ef2ac3,4d0bfdce,3927ff52,7a9e3d41,3d8b57fc), -S(dfcc4a7e,5a0ccc7c,f0f76c4c,fa92f075,791a2b05,92f25384,72256905,c08ad084,de18f9bb,28b017aa,474296e4,8ca2765c,8c4eab13,bb4815f,744694e7,697d1618), -S(a44e0a8f,9591b5ab,a051559b,b64ac3d1,ff8177b3,790103b8,db7e4597,6fa991dc,61c41b5e,30cbc23d,e632808c,76bec591,9ad4f050,251e9355,80d9e14d,7116a878), -S(5f094928,fa4652a3,616fc7c0,25b6e244,37d02298,1b2611c6,51265578,daca0cbf,e6599733,a9d0e424,43d3effd,7993510f,15a5369f,6d4521f5,72a85f9b,db7699cd), -S(f9b59ee6,86af9c75,5bb9a4e0,8b15c93c,a787497,ae30a437,bac76831,6f57a535,77f0686a,2ff851a0,e94f28a2,57f05cb0,fe6cc480,39789850,e3f2c7f8,c03f5836), -S(f81d0108,f446165e,46460e5e,5c89d66f,f2dc8528,f19191e3,e75e5d9b,105c0a82,daaf0ce9,7b104214,942efc9d,ab807966,e321dab,d757649b,c1e294fe,4146a6dc), -S(fdafb234,9f9f169e,aac0d2b1,9fa4e2ee,a60ca31,3c544e39,246732c5,61e6d8b7,2b7038f4,9497fc7e,3e73bc8,dd262dd6,9ddefb45,f2bab8c0,770a5515,a5ab1097), -S(bec0f91,eeba7855,9df639aa,6a46201d,9ce07885,85be6bd6,1594c722,79586935,bff92e25,93b8cb1b,a80bf5ca,da923777,56cc1d41,92011377,4f73d461,8b2ad402), -S(41d616f,b05d2050,6a8303ec,e130c5d8,6d27322c,552a248f,2c0dfcc7,1006fc74,1f121fc3,55b81e7e,43523765,80cc3c41,d50e09fe,18dbc40d,a1c75732,5884c42c), -S(e483af0b,fd8affa,423005f8,3d25933f,d2a0c79a,3d020523,5fbae421,51dc626b,31895405,c1d359cc,9b0e5170,b93773d7,39d32681,de3aa9d6,ee635e9d,28abc9a0), -S(65afd96,3c02dd8c,f09867bf,7eadf306,b9dc6146,5b45e138,e20b0a07,570157c5,1034ac39,8fd3318f,44823b33,a140e57b,db8f9cdd,ace4fd8b,33967abd,304e56bd), -S(71aeec22,61b38f9d,1148bc27,7653b51b,7fe98d61,bb3c33fc,b417653d,fb7ac3b6,8344e611,348f222a,cb3c3e12,6a9dc0db,5375d4fa,c1cef432,6008e601,ba2e8c78), -S(ce4a2466,34fb2994,e0af9fc5,a5e8c612,acc30331,81534c0a,640d5fd9,c9b9d208,ca006505,98096923,9973c2b1,c82c6ff9,848232bb,81851f33,cc773721,a97ad669), -S(2bcbcbee,977d3ba,74c81f1a,b1c6eba1,3cc5e48,fa8d9623,35b8ae4c,84fac6f3,bf89907a,8ec4a9c0,44aa6f40,be9e2bf4,a100a64d,3d046c7a,416c9f8f,151db3fe), -S(a745a5c8,3c8fb696,4552ab95,df609910,46074f8,e7381440,e565464,6fb7480c,9b1494bc,ed6598dd,958ffe63,8fb3c73a,d773407a,372db5d8,3504197b,79f3751b), -S(9e0a17e0,33391d78,d168760c,3a31e3ae,f1cbfea,6e13f848,be89b691,11330dae,29bb981c,388aef6d,60461505,53e81a4b,98464956,a69c9494,efd62227,6e0cb5fa), -S(986ffa05,749bb4f8,3a1a76a9,3b972776,e98f87ff,fc66343e,965345a8,608e4411,daf77d3d,5bf42c92,c51f96ce,e78c1436,50cde8d0,11458939,833387ec,993775c9), -S(62720ce,5863fca0,c4723eeb,9f80600f,9a751974,f3c22c61,4bd8ad01,e92234b,f7f18595,97529732,e497344,b7ebb71c,ce51125,78b0bd68,8f2f6b9e,726f7d3d), -S(e60ece6e,c7745cfe,69a17710,c473fb69,9fd6ba1f,1af4493f,2926684,c9740ed,50d14444,a9092465,93dd08d8,3b8df343,5ff98525,907f04bb,343ac295,d8823836), -S(159be1b0,f7579ff1,ae272047,a1c8a9af,2c38354,1ab19a6c,ef7396fb,4c5351f,2ca76b1,a87755df,61682152,d0379ba9,3054049,1f91f57d,1ee1e081,602aa289), -S(79c9c14d,1997643b,44eb981e,1b89a7ff,a6511b81,9539d1eb,ef5dd46f,4c6fb033,2b9b88c0,3dd3e006,638edeb7,1560343c,1a9dff51,b12c891d,dda7f67d,140f1ec0), -S(610f1c50,8012918f,d60ca30,13369bcf,c4bfd56f,abfe39cb,2206e5dd,59827150,85f62af7,722b89e7,6de3ab17,368615c2,9ce6980,4c397580,d48f6f12,5bfbf022), -S(ee26f4b9,9a2285b4,80bde15d,83dd201c,24dfa7,b8be93a,c7ea3bbb,9e46bd88,129379bd,2daa2b99,906b2643,90eecfd9,78b033a0,fc550fe3,b41e1c9c,97671b1e), -S(b9b51c7f,2bae970f,2acc2d8b,fa88b9b2,15ad5289,b92d1f04,92c44804,7e3ca7cb,c5242210,e779cf4f,1f06e9b4,ec92ae71,9a08805c,a16689fc,15b01ee8,d3585a64), -S(1e7530f,dfa5dbd0,7ecbf05e,4c8fc7f2,a44bd3eb,ddc01d27,d83dd25c,c5d9e136,7857a6f6,6d7027fb,b602d8ff,f63ffe5,bae66c9e,ef23b198,bf65e7e8,3fc66d70), -S(f498545a,1008241b,d815e282,d3fd807d,ec8f331c,83669c34,ba126814,56f22037,998291ad,71473cd5,37ce4f16,7bfef603,c144df31,31769e3b,8f5a89c3,a3274584), -S(cba20c40,5a4297b8,2a6b7756,8512c2e4,26e67465,c420e109,b506a37a,9a177d12,81fc17cc,d2363087,ec9c61cd,7b3bd9d,580e280b,354fff37,b43e2ef8,78c338a2), -S(ad4522e7,87c3436b,3406f8c9,3d7f01ed,92c4d319,11644cbc,41c9e103,e8813041,6dea578b,a468d78d,478f3e6f,6233b227,686fe0f8,19ee352a,cab182a4,ec2307cf), -S(e60c27ec,f8dddf6,27ef1c4,e4f84fef,ec2825a1,c57d8a68,dd1283c8,4bc5547a,a807871f,f74ceef0,f647bed6,fe8c2182,e9581f35,465b9c1e,445806c3,428d98b2), -S(9aa982f,b4fa514e,c8f5e08f,447883f1,e49c720,58b6d1a1,d3c3c12f,acb22a64,20886051,e999d3c,f51206a3,165690cf,9d86367f,cea7491,599ba8c1,36ffb70b), -S(607de32b,6c74e540,55de8743,150e931c,6234d65,991e4630,d3e854d,34ff1469,f58fe81d,4f583242,7e8a481a,8b51bc5e,b379ee2,15888e13,fbc770d1,9421b5f4), -S(f980f137,30c560fb,bb4f6db4,c6de3516,2063a618,e1708e27,2f19b23e,af0f3b03,5b7842b0,3ea2cc6b,4d640ace,f6721fec,afefe70a,3729785b,6c2619d0,5162d5cc), -S(c85ae74c,7fdecb1b,52287522,d3c51a3c,4711711,82d089db,1a01e117,706da488,58f96a54,8b03a13a,d15fa656,e67bdee4,ac1ab1bb,d3b91b97,dd35cedc,96d315be), -S(4bb491bb,c05786fb,ad1d2081,2d23529e,5bdc2846,a344f44e,9b914f30,93cc347a,6cdefe1e,abb3ce02,bd3c4c7c,9b384ec8,701d36cf,643e99d2,5c4163b2,a35cdf04), -S(c1eed40e,ff0e2b5,c58ed098,feaa9ff2,7b9e96d7,ddefc1b2,53aaa2ff,ae450542,eb9b0434,e62e2ff9,10ba0dab,8074c85f,9a3bafd1,e6ed1ddb,e158edaa,3b5bfd51), -S(4bef4127,d6566ba9,33881d05,55fdf018,3c47772c,822dbc63,3e6fa336,d06e1c41,1c163ba4,9bcfdcfe,a99702d2,d9bd19db,bfa67409,f4d3777,531beefb,68ec5e3f), -S(3268e230,6eb8d65b,a528db9e,fbc05d6a,1ff35ec9,d4f0bc57,700610d,c9ea902d,126d5546,12de71f,93be584d,38fdb65e,7deccb12,9a5e4e81,b12746a9,cae2cb2e), -S(c4dbf5f8,7b30af00,ee576ad8,3c20f079,cac5eab0,3faf5df7,4d72d9cb,2226861a,badcd32a,d809ae9,7942bfac,a00be66c,80c6c1b8,4b8c7dfe,2473bb53,5bb4e625), -S(8c919ec9,22d79e15,4f1f63b3,5f04db1a,aac7fd2f,911e75c8,b7918baa,a13914ba,dda36a1e,5ada8eac,4aaa28d,6f0285cd,d0011fd5,c46b0e09,1d8dbb77,8b0deee2), -S(1d8b86c1,70366e16,d3c33bb8,247bbf09,cd04fac2,3d9d3b6b,d0fac9aa,3274efa6,ee9196b8,dd6a3e74,697e8834,5f9575c0,80601ba9,d02b9583,260caf8,e342fd3f), -S(ed400eae,debff33f,922353f2,323788c5,29c933b0,e269c091,3f84986b,6e4c564a,35bb3b89,8427ee01,df168a7d,6be85ae0,71c45003,df37b369,2c52499c,85669874), -S(11e79bc0,1c5472e3,3325e3c0,606b6f46,defbf951,2ffdf9dc,8b59294e,e7c03057,e3a588ea,ad8da56,47d42b0c,f314ee96,dc900c9b,5d7fe6e8,a38298f,84812c5b), -S(24a18d50,18273c95,aac1dec9,6d443b92,b980b7d7,d88ef70a,f4b728f,ee718b82,c7bc851d,3e0200ce,16dcf3a2,15bd5322,d9057c9b,df00fc1c,1b0f63ec,fe231826), -S(8349d4a2,fd0937da,1c85e03,c56f01b6,4c0422f6,bdf90415,d9c4ea7e,2bb5873,1557cc42,fb57f4fd,4de5fde7,e4655cb7,fa42452e,1664b328,425bfab7,63ba891b), -S(515c3896,cdf651aa,99e6099e,2d07f0c9,df039a30,c820c6fd,1665b70e,16fb6e07,2001400b,48447b12,391cd2f7,497e1f57,c948e093,6b981cbb,4a414adb,ac928ca5), -S(91251dd4,5a829e00,4c17cbfc,3238de56,c16e8d37,46536392,d5d05134,3cc12279,21748cf4,95c962cf,d28958cd,306536c1,84f8b822,7cc4dfb3,4a8f370,316cabae), -S(659f2b85,6db07ff8,1f10c48f,356acead,cbeeb169,5022f3aa,1e9920b7,896fe684,b7ef27c4,615ae55a,aa576c7,c92bb571,1dcabcff,1bb05c82,359ec59d,a34f53a3), -S(b82012f0,8c209d40,ad21a839,797cac55,728805c6,f139ad02,893cb9e7,3fd334d,76c80c95,ab38d674,715a6f6e,24978fe,5dbc08f3,530a4a44,904226e4,cbe8a808), -S(e6e4fb7e,8e7a946,62ba3dcf,1802903c,fc2cd961,634311a5,dcceb49d,9277e80b,93dcfc61,127c2afc,76a6e097,9033db34,51a95413,a07bed1e,9548d435,88e68add), -S(1e717f27,98ca7da1,268d6bc9,97c01261,6263a807,3874505f,5fad1adc,a56ade71,3093703b,69edc134,20907623,70572119,ff0e9729,a22689dc,8e421ac3,52f4a3ff), -S(8d6c2b05,ea5b29d4,b02706d2,40a989ae,2c3c8b02,c31cfb88,6453cdf1,c33bbcf3,1e27c8a7,25bba645,48236dff,79370ae6,2949c58d,37eac4af,e5977a93,e5ea9394), -S(ef9d932f,d19aa7df,89e6e21e,542bc530,28937f47,7029ff26,45582736,6f207c46,b45714aa,d344a62c,c9348d78,ed4f0684,7424718,784e8ee3,d9b1f857,4758fd29), -S(34932c61,bdd68dac,7957c957,2d4881fe,9e5933fe,65e6c3d5,6f74f7b0,2bd152e7,fd963edc,eb7607ad,a47f716,a5e8564,797c9862,14a1df3a,c6c3e502,86e75fda), -S(ba182aab,ad4a9b4f,3ee47796,3e8c0233,9b416f42,6b4403bd,6087ef5a,f4ad7a5b,178fc05a,35ada525,943ed04b,fa7b10cf,c69f9edb,63dbc72e,5bf8303f,97626792), -S(a5eb1644,c585ede2,59297d94,4ed41664,a4f95c78,239344f0,e6a66020,467e41c6,b04cc4e9,20e643cf,ba8b8dc1,5e4b76bb,575cf1dc,d05a8016,85211ed1,6a98bd20), -S(59ba1e2b,40959a57,a0b41dc2,f7ef4520,6dce83bd,da582f57,e03338ce,cae060c0,2c92f4af,ee3dfed8,3a910194,e548fa54,d4f07bb8,90386017,7394d707,4a979aaa), -S(3f0ff5c7,dacb5106,782f6527,ca891038,da40fe10,7866e49d,106ce243,3b88c962,3f02265f,4dabeb7d,18618e1d,a97700b9,f416e34b,e93da65d,1969eee5,baeb9dc1), -S(4d767b01,8160b297,3cf4152,110ef381,453dcb5e,30af00d9,5bf79971,6656f41,b2c8dbdf,fae8b792,d3a89c51,fd841fac,108e443d,e50376a0,9b4686a0,e03716eb), -S(b3a13e43,1451f086,c6ada2b5,dc38b059,73e014d2,bdb42157,88046d32,efb7cf74,2a0e4560,4cb507c8,6d6e6,686e9b2,9aece6ae,3fb5d3b,7f5f01ad,a8a65493), -S(cd90b032,a7ecd8c3,f1f2bcba,a523feb1,3790cb6b,1573cb0b,1e468417,e52236de,6ff50c7d,354a3008,7907d056,fdb0a4bd,2c34b649,f0f486b5,a366a60b,7d01043), -S(5d12d03e,cef954b,a35e82d0,918cc576,cc8713d5,e77631ab,ab79a0d0,a428fb04,bdfa4678,77f9a637,7bb86a8c,b36d886c,fe09659e,887ee49b,2018720f,6ee35d89), -S(2dc4f368,62d4ff1a,11246119,81a09c25,ecad53d2,e34fbe1,b708695d,7dfcb380,5aca4c06,e92c9327,8d5e29b2,e7af1e5e,f71ac624,ad1977f8,396dd6cb,b676efef), -S(5f1c640f,aae3885a,af679e2d,a3a73b4d,68c3b64b,e7321aa,ec0e802a,66262d54,704c3b72,eacbda85,f425cb4a,6e6632b3,e65963a8,7b26ed9d,770f3a7,81941c90), -S(8cd7d6fc,522eb467,3a366222,5157ce21,805f7f40,3fc2810a,a7678242,3559f2d1,397ddb0b,d0dfddac,bdf8826a,12666f70,d8ad9fe7,f96f040a,fe55e265,bef932f4), -S(b635c8ed,9b7b1858,86c5f75a,d524e877,c4f2cc11,a3ea63b3,7140b044,fb50e692,6c61f48e,a0cc779d,cf746f4d,7b6dcb6f,ca562bb8,5fe244ed,244e720a,648ac131), -S(e0edc56e,e22db179,fb5203aa,2aedb0f3,9f8cd83e,6a1f7449,e33a317e,97b29dab,d3b29f04,818245cd,eb6b3661,8d6c5e3b,384da6a8,aaa60818,ad56cb95,1ecb59a7), -S(f261ce,b12747ce,1b529cac,1d607525,5d48f813,4d1730,32735be6,72db7df8,6c72a777,69cd260b,b78c912,f0bf461a,4d059704,7c1de47a,23a2421d,ba26caed), -S(b6154355,f2b11b93,b69924b5,b450b026,ae63ba72,777c82b5,99d1d0a0,cab223f0,59fb58be,3295345d,abdeb091,8e93d412,c3c5bb1c,b7527ed4,adae9e72,1b4aca0a), -S(74cc74a5,aa36ad6d,42f82135,908b9414,2842819f,9f7b5c89,d2337ebf,af11751f,df890e41,b3253de2,c594c78,18ff0c7f,6637a8f,fd0e13c9,21a512dc,35fb8022), -S(227bf422,28b51fc7,9d090902,a842e78b,a7138a2c,666459d0,16061c08,d6947e82,1abddc56,c5fe3211,7783b52,68f5629c,7ef2a463,40af1fa6,f4edd22f,c9ac684f), -S(31a79a7c,3f1478bb,88ccf5e1,3a220685,845c390c,378c02ba,ddf099b7,7a2905df,a04ad9ec,4b5693be,7aeaf419,2f5c28ab,6ea03c2e,8db116de,7eb055a0,6c6f4a6e), -S(d1b1f29c,bdf6d9db,3d73f74c,df7dd879,14e00b0d,de6c9733,cf7c497a,a355176e,82c6aa29,4caaf404,a5411644,fdb115c2,3c6525ef,f4dcdc90,53d0eff5,6addb107), -S(57bc432c,9fba6e62,35ace8da,4e44721c,a87b44fd,fcb7bebf,610275b8,49b4031a,a75f94ad,19e9a3a3,a0395f4c,403114ee,aa12553e,e168a80d,6610147a,f5c3152), -S(a7c2839b,1c0b8975,2b85211a,e7532018,ebe5f0d2,fee8f053,e6666a9f,9449ab7e,cd2892ed,2bb40ea7,656492d8,40386e97,86919d81,dba6497f,e6f81e9f,ec8b2160), -S(909c4cfd,e85e5958,9384bd4b,6f780b6b,bde85dcb,fe36d8f9,a3f26a93,4c88ee15,f78b72da,b2531fcf,ea9cd085,c17b4375,4263ede6,8dabbaa8,6ecab23c,9475ecba), -S(cb98a258,98e877fa,3ec0d9b6,a1e6dd7e,477b8f7b,716c97b3,1e48709f,de7a3d15,ba6fb66d,502143bb,cc54472e,df00389c,998c8274,cbe8f997,66c90d67,bcc5fd1b), -S(bf5bc69e,81d7b4aa,e4137ab2,6b701fad,a86c6d1d,fd163e6c,4e57844f,3b55e84b,c87360c7,406eecc5,51697719,4eaa7102,1de0afdb,3198a9c1,9253975f,970df761), -S(2457fbbc,767f4fdb,2b5f6194,ca8cdfb6,fd1da59,19e2314c,d809e2e8,6913424a,910877a2,f7707fc6,7b9d3bd7,6408f162,f04c826c,cda46652,cc54415c,30d77518), -S(625e48ad,44703721,c1934642,d72b6989,94550c74,44589f46,33ea8580,e4c20d5c,ef31188d,c127c8b3,67c6b981,241d8627,5125bbc0,dbf46261,4f9b5fd,a54914f1), -S(3d4f45d0,8a28cb71,aafda05c,50a7f534,5b007f6e,ceeeac7,20cadd68,c04748bf,932ceed2,ae007aa3,469323de,fd7e7dc6,deb77872,85e48e79,bfc21cb9,a7bb8397), -S(49f9290a,55e6c9fd,ffe96742,43198574,d81c5b82,1148e5b4,339d7877,ea070de3,f7e61b91,ce217ba2,bd387b4b,8c01e956,3ff155e1,4c8bf553,7ebd16bf,b48cb0be), -S(feffa5b7,78a277de,ae68ff40,9c00b7d4,d6b78b57,b71ac08,f43a5e92,35ce62ac,b90defad,a94dc21b,ce8e7580,dc79073,b4152c6b,441da59b,d904cf6,76219d8a), -S(7b42826,344499b4,5fe3cb54,b8391820,54166846,7806a48a,6221c88c,b0831099,68c5e981,4889f320,cd2818cd,5443063a,4f85429a,5e335f5c,e4731a59,da2ccefc), -S(a2bb3900,e42c4bf4,91aee9a0,bf73bee9,c73a2245,a94e40eb,2f02a32c,760fd29c,6eea2aaa,ef457edc,357c3b54,547ff6b0,8e12f076,2d8a368d,7a9e65d2,d122b65d), -S(ecbf9e55,3bd020a8,196e0b6e,63e8f568,a60bed0,5fb7dfb7,7af48065,ed4c838b,e2be7677,9e7a57c4,3961af37,aeb7a8f1,80070633,617800ec,a407cb5,3ab63313), -S(9d2ad029,2217200c,e3a22d2,62cbc071,9e5fead,6683ed43,8594250b,44e60b3d,7addb679,81dc9504,8b2d98b8,6a4ea72f,faeb5185,f804514d,cd18888e,77acc88f), -S(8cae4651,91c4432c,9c6abb61,438b06e3,d3277b61,177917bd,8fd024b3,353d413b,5615256e,793c6b8f,d96930f6,96d0aedf,4320104f,fe3c7a3b,c7025232,9a10b1d6), -S(2151ca1a,c8b07208,2f765333,42ef886,4a7c9d95,f23e1074,9fc3ff85,bece3336,3a27fdf0,97569b0,52dce8ba,7f22d2e1,325b06b7,ada607d0,7241ad7c,4282e4d9), -S(f6d4679a,a02e074e,3f0ca3a7,95cf91d6,de2b9cdb,d0bbc86a,8e2d14e5,cb4a8908,eb16065b,ab9cbd11,2f30440a,d4540ce8,eb043035,a653e4c3,c8531375,81965fd5), -S(8f8a299b,ade7c13a,2b6ba6b6,f7aedaaf,c36a31c7,bb9c49a,43778c64,b72be2f7,8371703c,b338cad9,acd6db9d,6a840bc1,4bb65328,793ac715,55743a90,f053cf1b), -S(9310f8b4,73347c50,32840e4d,6cb2eea1,a334dc03,b1ac2364,cc0bcf95,e0bb21ac,134d020d,6c2b528f,6e96a9f6,6feddd58,1f4f0ff5,50673620,cac44f57,de0c36c5), -S(a4dfe64b,5f55c497,ec42842a,d2bce748,18f9ae70,cfa521de,255487f5,6d51685b,20b5c707,d8bca7f1,b5d29b42,c6eeb116,6c96eeb2,4201fcb,352e82c7,663164b1), -S(2b880bf6,9a83cf4d,c6138225,733f51d5,ce5b6a12,95b98bfd,e2929b6a,ee5d3863,c21b7e23,b84dfd91,eadf0b14,9649fc10,872c39c7,13b80b81,1d989673,6492a870), -S(300f1400,fad4b0cc,b20fe64d,d9b50202,1105edec,f0bfb8d7,7a1c9f70,73ce546d,166d9e75,ea9a6b8b,cfea2f18,bdf4110,664ffcc8,be29b91f,80d92907,e322a546), -S(7bf49311,d51f9499,6511d0a,70f65466,aaf6cb24,1666b76a,4e821e03,e47cba37,ef25f85f,6dfefb08,c367eef0,c8433f6,8a775f00,464c4f6d,dc3fcc49,7d6189bd), -S(b20cddfd,6f4c3b4a,d9b9ee4a,353d0ed9,9163cb55,83bb526f,63ed9d53,9359249d,b38097ca,9e0203ad,3214819b,b8f4cf79,afe6ac29,cb33c670,2f3cd462,d635ed12), -S(98296e3,83c9984a,b9c06a3b,2daafeb7,32696ecb,af1fdb8,b1d94df5,9149ff2e,fe25c8d8,a72b6b0,17ce8c63,31c3cf1d,dff0ff98,e2db364e,7ce3e642,d3ff7843), -S(ae3c27b0,e32887e6,568abdc0,711409b2,2030dc6,2bb9a2e9,739b5edb,fe4b1a1b,a8513f4b,57f9dc76,5feec2f0,1d7d3ba1,235387b9,132303f4,54fdbaa1,d04fdd73), -S(e0afc1dc,ead8b23d,5956639,5d312ce6,36716e03,e39f3cef,d2d9a5c9,f959dca9,a3a1e6bb,b7fc2373,76484862,e15d89df,8a617e56,b2d61f18,3b79e7d3,d2fd5223), -S(526bc9c6,798711f5,461862f,817b94a3,d66f30a7,bc2aaae6,1da54b76,69004cf1,542349a9,7ace4d08,1022da51,ca2c412f,7c0cc951,62d0c1ef,22d04191,18643b95), -S(dd2a8d3c,8f8bff64,f5acf9fd,6b0d613e,9b149bf9,7c26fd29,41b0c2be,b5419450,6e88162f,acac6dfd,5174d61d,2aa755a4,cd73c440,4b5a83bf,bb79aedd,b7213cd0), -S(d76bccc2,f4079bb7,dbd605ef,ec78a6d5,f3e8c655,c9b38f07,dbff4013,6d80faeb,8776727f,5caa4d38,ba1a3ea0,4a01ede6,5098e470,914806a5,1889399e,c0daa412), -S(afd6332f,27f0bd9a,ea917732,8bf60bfa,4b80f3b5,82319e26,c0fdb22b,dc4b9faf,9595fb29,a8f6df8e,f0b93ace,8f92bee6,f36edc,60b19d6c,968d4177,6582aa52), -S(fb3a199e,1d5f3237,79afbd79,246c465b,98823ca,2851b64e,79aeb1fd,8f90d920,bfea973f,41bf4aa2,f1cc94ac,58e00da9,e4fe46f4,e1d0bd0d,183b8e84,87a959), -S(c4fd8c80,1ef65e97,614bddd9,ef5aac03,3023f7f,1ebfd7be,27f3c4e1,60b14097,2689b9d4,e244e9c7,64b783af,ce2ec314,8ece5372,76c122d2,2fa5d995,9ed94723), -S(6e171334,b59b4989,e2ae6185,54f6c349,26fa1cb1,e7e8b064,61f8535d,cf8f69bc,8064d981,17637f61,72daa8bb,c4604068,624bb0f4,9555f73b,beea8ac2,77e2b54c), -S(e1509f15,8688d157,973361de,6297142d,237535a7,a6b8f64c,c982393e,ff91d6d9,3087adbe,df20cb0c,488b1f61,f12b7e82,f6a36f8e,34a8c1ab,22d71261,d5c2c40d), -S(1235ab12,23b4d47b,e3e5fc37,6b3986cb,941884a9,37d81e1f,991f3fa6,8e529a25,7dd787bf,f7cbb123,e814eeca,45435af1,e2f32c25,8a7081c6,b66088bb,8e560b44), -S(9d70541b,e7995deb,7c9ae87a,b2f085d7,fb458494,f6c4845d,5c8c013f,a7d4a9d5,b1b6c09f,f12d7ed3,9c1af481,3ad135b4,dd0561c4,5a16d111,9bd696f3,e4cdb757), -S(8649ad0c,d9fe1177,8651ed9e,3c2123f9,8ed3b0df,f0afa4ee,adab9fbc,85680dd4,cbb0f8d8,4bc474da,bd1a0b7c,d397e1f9,d9acd111,5847ea54,9018f290,9594fecf), -S(fbae2b84,7685902f,b1473523,2b13f16a,c03d8366,32294d7a,6e214acf,8f8a4e1f,f3fa3a7e,d6cf4375,1f10050f,35a5252e,3c6a20fc,c3d8ef8c,cd393ba6,413f5fed), -S(635dd021,ef74d3d6,762503f6,924c24a5,32c626d3,75ec0d9,279b0086,bff11281,d2eff50e,b28be98e,192dabc3,8b5a605a,639b665b,17fdfc3e,4f339aa0,33d971e0), -S(99ee1d87,4c97c493,f8942a93,8bfbd578,63f8ddd6,387f716,3fd2a454,fd43bd99,81b96b6f,8d06086c,34407f7f,14e2ea21,2fab454f,131da461,7ca88bdd,4026278e), -S(77447295,aa56c62e,d8722ce0,522c58e5,5356d40f,b657ed65,663499ff,289f757b,f60ac045,15811b93,837a0819,f59d6fa0,c1f709cd,2ab128c6,95716590,43373251), -S(b006dc27,bcf879f,92b86d6b,ca0092a1,d848e98d,de52fb72,80081952,34857183,aba7308a,3686ec32,a0a2eac7,47f69f1d,74f9b7f1,60cdb4f2,f8eba9d6,2a9255), -S(41680159,8de643ad,326c6e46,3bd51cac,8c52020b,feb7ca44,6a9c0820,c02cec4b,ad11cf30,5bf184a0,3965085e,42a95721,6a64d9d7,38d9cd09,1dc3a8bf,2ec3b65d), -S(a4e68433,cb81a8c,148b8b3b,473dba7d,c9a1e44e,8e7d804a,519005ae,5c1b7d9c,89668932,7c597505,cd1f0e06,4273e574,85556724,3d257fcc,e0baa643,b38b15f3), -S(3f9b53e,587b01bf,a04a685b,c7d30db7,4f0d748e,44eff028,19192e28,6bf49016,6b927f7a,910f0057,d19f4604,140c7aae,b81563b9,f4c54ac6,6427e50d,11309e81), -S(6833273e,f2629ed1,d95ced8e,e776bcf4,24bc1a5d,284d54c7,d2c3b634,1ec209d3,25607f55,82f7bf1f,4ab5cc2e,c883ede9,8523b751,9d392230,5d98fa5,41e741b6), -S(c7be699,289a091,3021e2b2,eee75322,8cd18703,cbfa7db3,d1d5f0ad,f6d506fd,e5d016f4,2932d594,ddf556d3,399ffd46,c0b677cb,8fd59340,234c9b7a,349cf213), -S(6ef0d7f6,1803acfe,aa62b4e1,cf238e5f,398f0adf,228629b0,65e7c2c3,fa12e589,628336db,78881419,3026db69,2ed2aba8,ebbeda93,fb4f3903,bb8b2e8e,839eb7), -S(ff83fd15,dca2a55d,2ecfdb97,83ca9595,fac1f440,4b1e96e6,dd3abf90,ac857e69,f061ce87,8640d2dc,5fa4428f,75ff93,14216b92,fc1ffc72,29931d8e,f51c494), -S(f445bc67,47a3b7b0,fe56e4a2,db1aa71d,d042b6a,7b09cfe4,bb28c0f1,bc636587,a79a976b,7c857356,2d6131fb,e8476e13,6b6b0863,b8a464df,8e57da25,fcebedea), -S(37f88df9,22775959,94f77586,72cd5894,71c468f2,e6d3e424,45404b16,ab7b9e76,509ebf24,7f83ca08,71fd94f4,b178310d,4fc62bcb,27b256de,22092893,ff3415e8), -S(fc6ed464,1f548b62,a25062db,6b4c9d18,4d5b4b69,ec9fe4a4,db269646,331f6d12,cd384884,28427b19,4c77395,1373fa66,2ca1c771,2cf7b8a2,51c5049e,5d89bd27), -S(675eaecc,5c441173,b405dcb6,256c95cc,70c6ae38,3ba69053,ac02539f,7b6df001,4c275003,664b1f98,98bde64a,6f1b366a,2856a30f,c39fc84b,b6f2d94d,8435c76d), -S(81d9496b,3d892b9f,c4e0b98a,25c157e5,331d6d19,2a7b27f2,e52d2685,3b633395,4b9714a,e69680,649209da,eaa9734c,c611e98f,9bf19099,6f514022,aa2ef5fe), -S(5c6760d7,dbe3dd8f,26bce0a3,a160c8e0,63de688c,e2227bd6,e890e45e,5205076a,f539524e,a8cb2036,bd6ad2b2,3738222d,fe38823,9f03ef10,dfb9d223,407ba175), -S(6c47b5c2,889c17bb,e9f4c1d4,c930a975,6f74423f,7ae9105e,1dac216f,5aec8d3d,55eb547b,d3d60c79,c585b602,dd0f86cd,7d3895e5,b5bb3d13,a44b90c1,edd6c978), -S(da9ab6b0,4a4d3b27,31130717,aeec1123,b21eec88,ae16d3a5,547c1acf,664a264c,87a44739,396a75a8,1f0c542d,2760a2db,944aa850,f61e2fd2,e44c840a,a222a193), -S(cbfc9815,ae28411f,d7056e72,3a4d3fd3,a026d293,f8741154,d9db4ab6,a0147f41,71ed4ca1,e6702d7c,bdd28e8d,9fd41f6a,3879e88,dde652ef,9c639f13,f183d172), -S(2629d332,e3e1ad22,35420ff8,f94d7775,f2385186,a0559166,2aec35f1,623ede43,8e9cccb7,bd6f76d9,d76f89e6,3d8ff895,306028ba,6bc4ddbd,de26f81b,3eb172d0), -S(47ecfa1d,c1e01ed6,111e7ffe,fb44d552,e7a72e76,228914c7,72a80468,634edfc5,c7f3a761,3cc68070,7a1e9778,b0deec89,fc0cf226,14e16e84,4b661766,e6f6b6b), -S(c9fbd01f,ef8da054,7e5f2fd9,c5bc59c5,3e3f191a,7abc3cf8,df5e7c07,ea2adcbd,ba3c6b49,b5b9fc1e,4f433f14,b1a98e5,e20d2448,7fb234f4,9384e610,2035196a), -S(c179921f,24e2539c,9f90d7a0,37d8bce9,bc2741f9,4d7a78fa,a0212d66,f66a0d96,59b573b,9e9425b6,a0232e87,2d0998f2,b1815f68,a2c1ed5b,7bb5bcb2,b4d737d2), -S(a37a89fa,5001ec92,9a93291e,8506c5f9,b669603f,eb3ee27b,5e487113,1ad82cf5,a208d652,6666e930,964ddde0,737c6af2,900b2f0b,5018d814,904e71e5,8f8a0e86), -S(32323c29,2f98e042,abd15506,423514f5,4ea4070c,da493f93,10d1514c,a1895df6,ef273d5e,56e5ada7,2c872483,10180661,a0fd697b,5aad3faa,4cfd1915,fd749ff)}, -{S(6ae991de,18418b49,160194f,a735eb72,c299b987,1981a4f9,aa717ad2,bcdcf13,7ee8011a,40f384f2,e50add2d,97005173,2787cc7c,89dafb66,301bc94d,24b913f), -S(6fe08b32,ab3b1553,14f229e1,138bb09,a3eb4f6d,6629e4b5,903e122e,7ac2917a,4e4e077e,76ab6d54,97c1fd8a,441772b4,36f350ae,ba1863ea,d1fdd05d,f80e6e78), -S(f5ef51f9,13e10480,9a020bc5,37db3a90,3f3e3410,71bec65b,1cea5343,d43cf884,7ac5f6fc,a749b09e,9dafba18,c16bc969,e3d63971,195b92c0,fa8356ea,3419aba1), -S(2e03f430,51968210,a7dc64b9,612b25e1,cdd167d7,f6e39466,9762ad15,571ad471,f063dbe1,3f537e48,1b249a5,67fbe709,ed80c68d,cf8d4e82,53038d90,e67f1de8), -S(8244571a,ded2fff,1a4c9c1c,f3ea152b,d7852596,3e84b90d,6a3dd929,6e0ad9e5,ab14dd92,be3556b5,63cd396e,d8cb103d,cbacfd7,825faddb,1ebe6e3c,9a2e1180), -S(5fa7cf3,ad236db9,db9df632,e7a172f5,fb5396f3,c4df9bdb,d557a3ac,68a97f46,3339f27a,7a6231d5,3e732557,9ab22f3b,49dc29e3,75e08289,b816e6eb,a3ff3128), -S(5bcc702,f5f4a8dd,3f3dd519,371baa04,85b1284e,8bb539df,d8b89401,7206a943,5426221b,2e3fb26b,858a3f27,3d7b67cd,30b7c2b1,b881c285,cb29515e,59b92e8d), -S(96a96f3,79c8dcc7,f87865e5,9023dc63,95224251,12d98ce9,59b610a6,eb7ef515,bd61d338,c84a70e3,545bd8f0,aa0113e7,93f25c8d,d78ec0b9,d5b98d9e,81e16e82), -S(7e491776,5cfb89ff,edc43a8a,c998da5d,cab4bdcb,3b1d6f58,9def4de0,4b976609,7271e990,b7031b00,a990ae0c,86d893e9,915a84e8,d071a235,95054301,d0874199), -S(f9b8be29,8b5cfcec,62e0777e,d916c7d1,371b4627,9d141280,fb8a2767,1af02c8e,c6bb3293,3e77471a,5157f009,58917cb9,4cf77b81,7dc1b2da,d465dd49,711b552b), -S(9f1889b7,720ab815,e6a026e,67be852,980a9609,9e34d570,e1c2a2c8,55a2f54f,9786d89c,4fc1e09a,3bb81830,92df472b,5c1212f0,4ef05a27,dbe9d0a8,75d5e1f5), -S(fc53a56,52d4c07f,3a4af93a,e88cb4ca,5db66818,ab2c874d,63fe59d5,eaeccd32,bdbd9a97,f57136da,8f8dba2d,f34e5d3e,e1dbf1d5,ef27f,11c2c45b,98ef2d38), -S(96a3ced8,ba47f6dd,48a6b320,d88221a0,a5e36c5a,55938018,2dffd1d,3c3c4d00,ee4272ed,b244f95f,54b68c62,2e3d09,b96c7aac,fe77e9af,600a227e,8ec5299d), -S(5d552446,cb8e1882,2aab5aae,676fb3ad,b44eab09,ce665918,6fa6ef31,6f081e9c,723cc3ea,2bb559d8,da986b40,263f5551,25127091,3dbea220,f79711ca,638f77fe), -S(2bd7f7c4,8be5446,86e5a48a,d663345f,bebf198e,d7a6dcfb,da278054,f86d8e0b,584ba0a4,d2cf2664,e9d99d7d,a513b3a,5c06639,5fbc2edb,9259a51d,aa500e88), -S(1caecfd6,26d39493,a2ae68ff,f7af4b05,2373e9e6,8461d254,f9b6d651,9e92ff6a,cfa0c927,ff9814cd,b2af3cf7,4ab5e514,70d70a66,9fe1f353,b0a92182,86bb183e), -S(31ac3e18,ba88bbe9,21fd4834,f9f63ff7,aae351e1,61874ff4,2f8281e3,cd7cfbe9,61d0002c,110f2a2e,19c1b720,a85798e9,e8be1124,c68854f8,b73d6674,4cccd7a7), -S(19bc479b,1637b2cb,2e700f3a,f06b4361,ba1f5d9,7d1e5099,6bbff88b,6dfdabf7,9a59b4c7,deb3ab08,fa5e9e02,4d8bfc2a,a35b15a4,6cd99a08,9fbb0f3a,8770d0dd), -S(c1915003,caa74b8b,51576d17,de53e4bf,c5cc63bf,9c29f847,4981e180,a71fa0b6,cc93116e,500ceae,f045aad5,d9d7a863,392a3534,694d55bb,1aa69cd3,895c7819), -S(ba105ccb,b1c32d83,a57eeda4,2a9bb748,d36370ad,805ba1d0,647bdc8a,1e84a968,76adb37e,53b8bf0e,368a1a87,9a74b6f1,33116144,47134766,27f2df12,602e6377), -S(892f8edd,23341050,7540f11c,9f0ef107,99099081,dbf9e4eb,9bac01e4,94b8ad05,f0451f12,42bf423d,37afc17,74af91cd,7593062d,f22712a1,dc109b7e,f5b81141), -S(389df091,4b0f71f9,70416ec7,1388a464,c0d3d4e2,2c2e111f,f5bbc5f7,d3618bae,e12e51e7,f27256f2,3e8f8935,677aec3c,7c8f4950,712039cd,afa521f1,a88a1f46), -S(383fc7f,86bc9c65,f831c676,2885ba75,25a72886,5d6e91fb,b3ad1a53,d4e64f3,c58d161c,6a14470a,a7be7467,576a3bd9,67d7c944,ae26cced,74089773,b344b2b9), -S(cc4e9f78,9aa3fd5c,eda60c2a,44a55779,1ef31b72,8687ab18,7012ed4a,616fc628,7aaeb0fe,1a94b6c6,4c033c77,3a1fe878,b9b54559,9af6eb4c,a9e79540,faa7ef34), -S(dcf7dcdd,938028ed,f92c5797,6c3faabb,1f2b155b,59a0389f,fe1735c5,ba658aa2,2a008b2c,29290f2d,b64ba559,3c905c4f,46cdae06,ae2b687f,af0b5b91,5422d5ae), -S(75125b5e,f968db84,df6d0253,5108e0cf,df3dd50c,8ca63618,9521475,c02b26df,f6bb520,f8178541,ed169ecd,42a62d42,57ba7d3d,aeba4ad5,e979c8ec,19cf935b), -S(24f1af66,45831b37,bf80d0e7,e6185dd7,51f09e9e,5a71cf,ed350b8d,2c5834ed,2e04d2f1,b0b5d468,b4cab2dd,f0b18467,f8b78304,2b2f5cb0,49d7920c,695f3551), -S(75024c77,150ccf3f,dc677f59,118b4d6b,8749d514,256c1641,e7f70e36,5d99fcee,d36fe19f,442c7739,cc65d1d8,c7ba5479,57aaf055,38497cb8,dab1ba24,d92bae95), -S(4b0b4d7a,51b5307d,69b366af,9a621e30,258b3a3f,affd9a47,52a4a14e,562fbcf3,dffaa5b0,7133dda3,3586df1e,400412d7,6da55cd2,a978e8df,88e23415,9ca43127), -S(83c377f9,13afe5f5,21bb2550,b0a38343,5956fd13,e62e46e,75e77d96,ca2ae791,db64f4d6,6acf0537,f9d60b6b,28ad8e1a,cd9b414b,8f60968c,62a263b3,c8fe5138), -S(271acbdd,71cf48c5,e5048853,3cd6a1f,a49eb8fa,428f05ba,6d7314cb,d128c387,ccf83cf6,2d001c59,a5e6b531,ff40833,4a2b2421,aa75feed,d9ba7878,67323b6), -S(4d41e719,e003cbf7,f3c26d31,139ae98b,a0a24623,f8b86c94,6edb2bc3,1be3983f,2e052d70,6348b402,40e8da52,3b5b3011,a79451ce,41222416,ef040d76,c64a8caf), -S(2599981e,e5b9ec6d,c5da028,1f5ef995,abc78520,32951d1d,6356009f,f482a96c,9560bc0,aa47102e,1488f45f,90797862,3fd9e54c,7467d600,abfc389c,459e5136), -S(eb82b86d,84989f3,68c8fff5,5f801f88,f351e43c,80f145d,4aa7020f,ff057090,62d44ad5,d42a796a,373724b9,f583d57a,d8c19d6f,36f215cb,1c20ed12,320a60c8), -S(8637f2ae,f77485ab,a2871d48,a4f4296a,c84f6afc,b51cef62,b1f22e6c,4cc4b05c,43ba306c,7d6a184b,774e46c3,94c404da,b2acb796,ba239786,d85b5fcc,2c304436), -S(ee462322,f2f44e1f,96643d7d,bbdfe53f,ad268a49,c9a582b3,828bcd2c,e471c1b9,910ec3fc,b9e4479f,2a6d332e,4f809556,1c69f6ee,812b3097,2812079,ebf87cf7), -S(4dcb9320,6a69600f,6d327bb,624d9ec6,24e6d98b,a758922b,b102d159,e6c1c206,da85a8b3,de7b2e,51ddb90b,99f30c7a,70f1bf23,e2c90b47,eac6fe0f,b0d8f514), -S(a1373c2,d15ac2af,2c496399,1db04165,28c74259,6d9d81bc,8004b80f,a68b1405,b7a13e6b,9255caf3,ca4daf3d,21b5739f,65d1e7c,74330404,24911fdb,4e8815da), -S(fbd0d0eb,5a93c0e7,4627e83d,c483b873,96eace6f,fb75acf,ac743e1d,c7a1aa92,bdc310cc,3f420fda,28012f75,e6db4431,d2032990,d4d09a6e,7fb70fa2,fe1344b2), -S(39d9552e,136794bd,76b864ce,d929f2f3,ed4b1b2a,e15b4c9b,485179c6,1d78a846,1565f88f,f2a5c23f,c2110572,c61ba868,9035cac8,ebbc7e8,367c37a,a22308f3), -S(b92576b2,def0f8cb,e13ec334,93e2af06,f2ebf949,332fd038,689dbe3,70700e57,3d7b8497,523e3901,719145,6e908d62,63f752e8,ad2adbfe,13b6267a,ddc415aa), -S(70806f30,e3a407f2,78d59553,fa3fbf72,d5129209,75e703cb,5080627,f30b3d09,c190bf85,9f43553c,6ccacf0d,e33359f4,87b3c406,ea07d424,981d94cf,9e542976), -S(591c877d,6e4c5d56,95152fb9,b809fb97,41a46e0,446b996c,14d201a7,4705914a,b9dc4a1b,e049f291,5c1e6c13,abf19e36,f6560138,9d7bb630,c853b122,9aa70174), -S(f7f3bc9c,fde746d4,fa47131c,195200ff,53c05c09,af87413d,84e9f7f1,feee671a,70a925f9,5b6477a9,f0a6dfca,b49c214f,c219cdd2,213555aa,ea49419d,33f8334a), -S(9505f06b,3a9fa87e,ae289c2e,f4217b73,edb72175,7aa4d7b3,b681b09e,2f651749,231dc38,d5d63d14,4ba84942,67e1e798,973f632f,8ccc09d8,be747810,851c8962), -S(e33e547a,9987dfb7,ae681cc7,1cbc82da,4f3a3a57,972c2b5,10c09548,6c25c04f,55b7c3af,2b3b2684,6ad280e6,51dd817d,b99b856f,409492ca,4f1bffdf,d3fbb232), -S(7bc182cc,598f9281,74fd434d,9b5c2006,e52e864a,90b0b1bc,1634639a,68e8249,2810d2c3,4bff6211,63b09ebe,e77ec622,ad045f21,f9c103c,99089b2a,f0e8f7ca), -S(83dcd3d4,8a18e1e7,353f9b0,76b7ddbb,ddc371d7,7e3d56c2,3741dc5e,c5686edc,8c297536,c3b02d6c,f059db38,791e08b8,2ed1d82a,8cd03186,d2a0054c,862fb085), -S(d4b08924,b8e71bd9,6ca26c62,9c712e61,dc17a48e,bc07e6bd,116d2898,25aa42c9,c1fdad3,1e85fdcc,2f2a0a63,7308c8a4,ef3b31e,a81fce26,21e98cf8,cda3b25c), -S(1b42a702,16d7cf97,de70f734,37a36d38,10f670f4,6a34f585,f9593c50,c6976,f29bd13b,79a7e65,f4f7f94,53b920f,5c751b6,a067d288,82e62b40,7b9858d5), -S(c61413f0,7bcd6eff,ec818025,f792d8da,3643c869,4bf3d582,9a1813d3,cf38beca,68f603d3,db4d751f,ab0823b7,ed050c40,787b003d,6f6e001a,52e3ff8a,71ac0999), -S(5e90173e,8be185b2,16b0066,aa39a73a,350eeac6,e49b4cf0,546bd57b,50ceb215,455ceebe,31e6c3ae,388624ae,fa2e7a1b,fc0c4950,12c43803,c4eaee31,d17122d8), -S(7d0b2da1,8d6416c3,d47bc493,5e409ff7,6b437874,911347a6,3f8add69,8e25c6d9,da9f27bb,82034ba0,64c54a6c,13609188,584f9014,cfeba572,760b23c1,fcea509d), -S(611b1c17,117e25fb,dd62f458,7daa0258,8d9143de,e2bb133d,34377c3c,28778daf,cf1732c0,6de82698,c2531c96,eba3edbb,23aa6586,372cefc5,bb49831c,4c00df80), -S(b43dde41,96f3bca9,ade881f0,5878d347,812abf24,b1a8bb19,9a4a1d76,2f5e243d,1af78af3,acd73de3,dd2a28ea,50b4940d,284d501c,4d39dc3c,8d9220d9,37aa2e67), -S(ba0cf8a,74235782,f251649c,5f6e53e3,6eff1062,fc51f65a,c2a8c83c,e89f4eaa,58e47b3c,467342bd,4202b54,752ada79,a7356f88,92efe201,201af87e,fccde55c), -S(db06d4e4,ca9b1ce0,6d59cf88,da187b77,5e9568f1,da33b398,c682b8a3,ad9e88c7,418daca8,a8e4d3af,edd2de9b,868ac424,6faec0b8,f0b1edfa,e0e9667c,1f3adc1d), -S(8a46cba2,7263af84,80c9ea35,ce8757b7,9ecd15f5,e938f41,aa7d4abd,5c3ce006,6f28398c,eaa2d168,7e6c8427,730ca15a,19965098,7c7338c5,e40798d9,82fc016), -S(705d7e03,b5f0cea4,3720c73b,d6b4ff3e,26d2f8b,cb2f5ffe,6f5f65af,63e4fcd0,4a41f717,baffb579,b769e3a4,ba976687,4727c132,9a30bd62,61df3d91,1472ef9c), -S(e6ed0125,6af3d738,84d8fa5b,361be34,9e2506f6,88b772ed,eadc5c33,98233012,90c4ee9b,aca8162e,2b58406,83a7de20,fb181b92,da81df99,e612e122,8c8e520c), -S(95cb73bf,29e8d04c,a2bca75a,5925ded6,327e6128,e6db16b2,2847ed49,d3ed169f,b4e84fdf,526e060f,7b3d73f3,f534d669,3537babf,3b1ae0b4,c65dc8d5,11917b77), -S(aad1e800,1abd18dc,4d929c2b,c2d59b8e,23c90d56,7b0af36b,2e4bce1d,ea2ee299,a27daf61,acc02936,835d5742,74c875a2,57796038,de289d27,d97bea15,a9d6be93), -S(969303e0,75cf2eb9,551f93e9,43c5512,71bd1a29,b26feda4,cdb603a5,7e333fd7,a8800641,44578fb4,cf16d1fe,3970df68,708e2a10,79547510,f63ca035,616b2f5), -S(6aa570e3,de1b51a0,67e33350,cfb337de,23ce7af1,be879ccd,2b2a4dcc,db1ae9e,98a5f5d9,79cfde0,30fd1ec8,718d2b74,d33639e1,80d31134,85c607ae,d871f166), -S(4e469241,842ab69a,93bc6844,1b6036,578a22e3,c2902da6,1cfde122,962197f8,cc7ba90c,a290de88,e980f50f,bee59f67,ec227323,1db05d3,f11b4e72,34080cdc), -S(772efb55,d4044423,ddf466cc,925548eb,b2525458,e24bdac5,7edc33f1,2cd64bf,df73e64,818bd4e,c7abd07b,24afa4b9,8be7aee1,d115d936,8f4d0fd4,7f40876b), -S(a594e20e,62db69af,4afdd0f2,5a735906,75446d5a,71574bc2,12bf9f24,cfe879a9,1b2fc870,e5f74b0a,994e1d0c,de8ef9a2,74e6b49e,185f9251,417154a2,4f2163ba), -S(c133d96,a51cba90,3afcbeba,40ea594f,3e39a106,8d0a9898,7df1ebe7,4c38d3e5,5cd8c400,989efe10,295ac89b,8891e0cc,be15247d,61ba04d0,4ea018b4,d0fa51da), -S(3ea10966,fca290dc,b77c85c8,232ab56b,afc1dfdf,78628736,9a696fb8,92e67998,798174a7,b4729cd5,67ed639c,9debebde,1538411,94e99adf,f51c4866,990396af), -S(8f0fb3b9,85565632,8207c0b3,e1528802,310d222a,9246e686,6030f9f3,14472152,4fe2daa,d16d75c3,ea219295,661ff8b6,ad9f73a8,b06ba105,80f7f6e2,6661eca9), -S(fc22c901,b93809ac,21e1a89c,8e02093,92e19fe0,8f83d82a,733dae3e,16236a9c,8db62408,8fc9adc3,39de5f57,5377bb32,e3a1ed8,2731b18f,1ecf4beb,914bd42e), -S(7afb17fe,1a4a5e3a,eba9dc9d,c5e178ac,ab9e76f0,d3efdf96,181b1fdd,eb81544,bfbdba94,c3e5d27a,547db3c4,83a09847,3e5c118b,9fb961b4,e78a40ab,84ab18db), -S(38420ae6,13e0eef0,2cf9c567,b0bc28b0,59035e0f,d5df3fe2,d117eae7,27b7eef1,6e21e249,1c6a6f88,e2c96c1f,76a9238e,82cdd6ca,6e9ab090,56e0c1c6,4ccf808e), -S(6b3e232f,1b22dabe,e22f618e,c1a002f,f6aec9fb,361175b3,fe2d48ce,ee724e8f,2530c6c6,8062ea89,24e6a793,6b1e582b,1e630c0b,fa207505,76a6fc24,5e01a516), -S(8f4f70ae,5fc21122,275f1265,520e68a5,e2fb605c,bc3f17df,4ef48133,1d4d3e24,236bd0c4,ef445db6,9a0bd1f7,7ce38360,137d602c,58f8b70f,395e65b3,8b1f18ec), -S(333fedbc,e4a9064a,cdabf1d6,57d5df7f,86114a67,28bad2c3,29a2bbc0,b7e822da,ca491209,173bac98,fab92935,ca8dba42,2583bca4,b7e62ac0,3f805ee5,5f1301a0), -S(d00cbc99,3a9c2c65,b24bfeeb,f596ac8,c925c51c,e5211f32,74145c16,138708a6,5349ca5f,be59a8c8,4ea300,391efa3f,54b3344b,d708412b,a9e6b0ed,8deb8b04), -S(968af2b6,58020db3,e8297d90,c36911c5,786f1d50,7246b35f,86da1cea,f46efc83,453866b4,f19d5268,3ed07612,57bce4a3,173b2c58,280927dd,ccdcbc47,75cda533), -S(fa0adb79,476bea48,8926e659,c8687e14,b769c88a,3a1c1ba3,f11981c0,6934ff7c,37cf240e,ff3a6514,fd7ba90e,687ad6cf,3152f1f7,6d23b8c2,9bc1198a,bc5176ce), -S(7c4a3b6b,3b9c44f0,4f4aaab0,9604066c,3cddd61,996e259,43757c5,a9832392,36a13d10,9ee60811,aca0b269,d42dcb47,aaa0f7e1,7158fdad,50f07e6b,e11289da), -S(9c4dae1c,c6162f5b,e66bf6b3,53b50a45,d1f400db,aff1dbfa,779a94ef,ce7ae0af,2513117,efac13eb,cff70674,b3a9d27,31db473f,e198c3af,59ee1753,f4be8411), -S(c66c125,a04037f5,dbdc4254,70b16cb2,b6318a14,bcd69f85,44ed7eae,346edf13,288a0477,4c2bf346,115235b0,5f921d9a,566c32dc,67755557,a550690e,42b115e6), -S(42f5a4f7,54d8eb34,62c8da57,9550267a,9d73626f,257d21a0,486c043,58c5cc60,fd89e17d,67a052c6,71af223,2337ebd6,16e13b7b,72480373,3fc3a29c,4ecfd240), -S(725051b,43e3107e,2321405b,4f974469,be69f90c,a961e352,7bb8490f,f8d8c7ac,a143d4c0,46ca1288,97633b98,7a6bd28a,81f035a5,e1f49626,1aaad65a,7f68d1cf), -S(358d4f1a,1b94b0c0,9237f4d3,8d7afc79,f1dc3b1a,fae46a67,1a386ea6,ce6b81ff,b8caefa3,86daa463,93097bcf,526d84e,3666a231,97f3804f,3d976ae4,63fa65e3), -S(749bb6b,e9d272e8,8452ec3f,ec83ca71,c15471c0,608a4326,7355497b,27ffc67a,79d588b3,cc607639,4f410d13,c3cab3f7,e635d10b,44e9b242,583b75a2,62136cc8), -S(e5e8cc0c,a1910688,cdf89e82,da4f7a2d,265f63e3,247e5e3d,39d46fee,b00aeff0,89d4d528,60689061,aaaa4c03,469979ef,4c734119,4181ea99,2398691e,29235eb2), -S(62341395,d066f441,60e08ca7,5a9329f3,7581a8da,fb78ff99,1336faf2,407418ad,63930988,431f129f,5933918,e5d23e7d,8249267a,8f0dfbdd,7945e34f,e9e24959), -S(1a4900e6,95118e4d,9f956e99,2f868c3c,dfe8580c,64776298,13da88ce,fc9f8aa9,53bd8fd4,953510f2,72b67737,5b6179e3,e02e12b8,dcd930c8,de94e400,225aace2), -S(b0303fc5,8c1944e8,a84d9bf3,f2102f50,2bad6105,afbe8a37,b09025ea,6bbcace0,d9a29c66,1af8a54d,7b115f8b,52b834d7,e7c2afe8,c7308d61,4e64aaae,3f0708bb), -S(4b51c846,44955e86,9cdf575b,b8796773,d70ec44e,fee77957,c342d491,aac8ae0d,32480851,7180afa0,2d786a90,172ee8c5,75a5113e,ecbff5ea,444ec3e4,143a8d48), -S(c0d19125,b3fea060,45c1b2b2,4febd77d,e3a59da,4b8a8c0c,910189dc,b38d0228,3bed5e0c,e1a5c537,1d56cead,8c2975e0,f420ad89,f0308ae2,95a0c9e1,fd88d10a), -S(8bc96490,25ecb626,131c81f4,c522427b,7f8c22d0,90fd225,ab8bbc7b,50792500,5d2a60f1,591a151c,f0fb3a68,709e1050,21b9148c,5120a79d,100bd319,aad0479e), -S(4acec462,c6566ae9,c17ee177,61822b5b,5ca04619,30270d8,d5b3d342,5e9daace,82832a6c,ed0fcebb,3f40ba27,6e964981,cc0ccbb7,e2a1bffe,6e10014b,c563b12a), -S(6e7b6406,8e3d11de,ee7ccf55,1cf5a34b,168c3f29,d013a5d6,153fca63,2789ea72,72fb451c,f696060a,a82a14ad,1ae636a7,e0f338b3,8aade7a7,fd2599f5,270b55a5), -S(d24b42a7,40563303,25ec4fe3,11ceb35e,68d6b158,689a7434,4cb65ce8,2fbe5104,b4ac12ff,acc676cb,49d5bf0a,7e0a4167,a2460dc6,1b833e,f26083bc,6c7f9523), -S(5ed0083d,2205815c,576c2207,780d9159,7e985b26,9581da3a,2d60f088,1aaec692,2b7ec860,7d94d1d1,7dc3d67f,caa6f499,e3476f8a,d76ae00e,1a981455,85654267), -S(3a2fd05f,4ef9d7cc,6939dbea,a389521,9b1474f2,6fe8cfd4,a2337771,66ee418,5d04893e,6bfaef9a,ee8b9abc,347f3875,2c8cd5d6,d43da92e,be05777e,1b44e546), -S(a0e5e214,53858d31,7aef7152,aff56438,b425914c,d42dc2a2,61415381,30d13374,8ae28cb9,fee0271b,98fcbdf1,66dc9cb6,f0d2ec0,b1e34161,ab8513f1,597e2b9c), -S(ef690072,4a54168b,eabd6285,8c85ed24,2a4c5b04,c4c419,f3586e2a,3ee2a463,49f17e53,7324d9ec,c7feff8e,2f3e437c,d0b01d79,d92189b7,9b35793b,b367fb28), -S(fe22736e,9be9865b,5c1f61c2,a236bdc4,ce37b650,9312cf44,8b536adf,5017f096,bd67d013,5ac42683,e83239de,93f3b7bd,f1d9da45,a7754bb5,f363f501,c3059e8a), -S(4ac35582,84269d4b,cd98bb27,a708700a,5df4e4e5,8fa93963,f6108432,2e0ba4b,91e43c02,ff39da29,289d4c66,6f58133a,5e7ebdd0,1593c7d0,833bc064,d75b876), -S(1bbfb3c,d5ab0755,96cbd99a,cdec6872,4c30a3ef,92162b30,9df08974,30d378d2,b0d34d68,1907625c,726aa90f,d363ca7a,711518c8,831724ab,bd24f082,9b71a9cb), -S(34417402,cc02a6af,129cd0a,d85f6a46,5367b90,baaef255,22622c04,ffa8e389,664ad84a,dc6e21b9,aa5cfc66,fcec0744,dc0e052,3571b1d7,7bc9bf86,f5233003), -S(5e6773cd,613df09,d818af9,cb13955c,f1159616,dc08482e,2737ef50,f3cc34a4,203fda8a,74f49604,b41226a5,40204452,3619c4fd,1c42c8e,1e4c8543,4ba2593e), -S(21f0fd84,1c01cbfd,9998d5be,f2d19830,6623598b,4c6dccd5,28d4f2b9,b0e0715e,ff00f77b,605f8e47,97ecfdfa,9ec4cde4,a9dc3479,3d571f4e,7f9f8bdf,e80b8707), -S(c1ac43d4,7fbdeb41,85536fd2,37aebc3e,b9faf3db,e2155814,e16f93e9,edfa131a,6785367a,1ead47c8,2d143984,c2de38ef,f3689414,14472eb6,8c1fec2c,2b4216ab), -S(c2fcf122,56b2e49d,36e880ba,16f27ec1,adf9779,82679dd5,4ae962ce,62f29057,580b1989,62da6793,9673a54d,41a45486,a80eae55,2de79bf7,9fb63d79,432ca48e), -S(92455df8,c253c53b,6dd44872,9c2c39ee,8f68b260,bb7511f4,b33a5c65,c756d016,c2258438,3f4d24e2,4bb0394f,b05e6a64,552b9e11,7c1b4ce7,a8c59669,b2244916), -S(7e953554,4a105bc9,77ddb025,8fe7f4d8,63142198,98c07b21,8d4c6696,314fa885,320addf1,d0f0021b,5bd67519,881777e6,2bf762a1,2430b17,2f67edf3,edb7acd4), -S(2d57c338,1abbb97a,bc9bdaf5,6ad542c4,4e3aa5a6,2f2da2a9,8c368eb3,506534e2,bc0e3a81,318ce176,c206eb31,cbffe043,8597eb9a,e2c505bc,2c21ec47,2fadfe51), -S(68ff7b53,b4e3dd0e,a24f4edb,c9fedd72,b904075,8ba87e0f,96cc6a1e,4d1d3e5a,7f3974cc,ad1b83dd,9d29847f,d61fb706,f47b1b19,a2993a6a,f885db9f,ff6a168d), -S(2e340edf,431b9efa,cd54eebf,22a4e79e,9ce9de59,b5e306e3,821ceab6,5b11f576,3a5ed040,679e77f,754ad7c5,5de92610,9c863dec,3fca56ea,85dfe104,af228f0b), -S(aee71663,94e2d18,353824d9,2558046,c15052cf,e3e317ac,baa142a,e503c712,6dd9272f,877f5aa1,88c43f4a,d63ecb63,7bce5836,b0b4efde,f980c2d9,778d7375), -S(cf33b265,604c4e51,40350795,baa4d4d4,baa1b136,1bcf63c5,29d5f7de,3ffab739,113390b3,abebded2,667e169,61da10d3,50a3cb23,e2c2aac0,7e72689e,f933b396), -S(367b235c,b5393994,9a034a1,ad476a0f,a3995777,5f933dfb,4493f518,f8ca0843,e5b1242d,c9341bf5,20e7a524,75587bdf,cd571cf0,bc85b390,aa6e4578,69c4c4ee), -S(b133aef6,30e9ff4f,59ce6ab,299eb6ed,ec1ec4d9,5e4e4c6,f37bae90,e80827cc,a9e4f652,cd9aa9f6,31c42224,ddd8c24a,d6f2c8ef,26102aa3,5585d90a,758cc5df), -S(5cc2d108,17007002,9a3a6158,fea4b6c8,3ebd500c,eda5e63b,55e287c6,36d48dad,dc988502,2c2cf16d,6c54d4cd,c5a8d7be,8396f9f0,e78564bd,7bf1f822,bc13540d), -S(2434c516,40c358ab,961964f,62741de3,373bed5a,1db16197,c79209ee,46838156,3376a3f1,8f4998d1,beb23159,143f505c,dd98a0ad,225e7e3c,cea17dec,7d8867b8), -S(5b115d9,e1997333,7f74ee7b,1ab9b177,5f9334c0,6f3815cb,b987619f,e4fc35f1,29afba83,76be4407,d06a8518,3ad236b9,7b967f2b,1ba1bc6,8bcf3a98,f1d36c18), -S(a4c7426d,8bc73763,a0ed12e9,2086bf9a,3f271e21,ca158feb,d6247cda,400ef88d,7beb9c9a,efd02fd4,57e4824e,1f24c058,ad367ab0,d1dac794,58f93031,8cde173), -S(f08ad354,3be27960,41315205,670378a8,9444f336,b1e62681,d1baeb26,f356ab51,24a5ef2a,21eda2af,4b567efe,3c339bc8,1c651b02,25e4fcff,612cbf8a,f17f3401), -S(9c649e1f,c78c4805,7cad2a42,fc8feb93,b93a5c8,a4e0fe3a,3d9c5931,e2e659c4,469afeb1,bf91db88,e49e4142,207cb5f6,1f601dbc,376a3918,77e2566e,eb5f9ac1), -S(5477d1fc,48669d0f,52a4f666,5b599a3,9671f30b,888a1edd,16c4a3ff,b35b0d7e,7fe541c1,b7859b99,528da7c7,ff50c02b,3698958a,b4e96576,684701a4,10b13e3d), -S(33dac142,9de66b17,60ca63c6,887ab053,f315e77a,42fa8091,42d24834,39792355,6fa0d16d,6213a2c,82026d06,57fa1c7c,8cdaa11e,4a92057e,845525d2,ab9401ad), -S(cb80339a,c6d42daa,cf7c1f6a,90074528,6861340d,a9cbf449,4accf827,15ef15a,3f0135a9,3d3d4fa6,80a4837d,e42c9e12,c28130cb,60b9866f,d5ca9f7,2ec484fa), -S(bd7b0bae,e55f28ae,4882cb87,a98c4fd7,bf2957c2,58cc22a7,9505be2d,5c071933,ae3be725,47e45dff,31f4e5b4,c1bfb425,551dbeb7,4d5ba887,376999bf,cc0dd376), -S(654dd97f,29655a8e,12ffd72a,76ca7a91,ae596e9e,2e2e6d05,48157b93,86ae65c6,a6a721c1,5714573e,8cf00d5e,5cdf8169,e363c5dd,fe6e76c0,c26a3dce,f267f031), -S(346dfb52,da33d501,d55d018,70c7603f,d70785ee,1e3029ed,4295ea6d,19d5523d,8728cf28,d307c488,c0acfc1b,53785bc,cfd84e3c,2340dac8,e84db9e7,6739cbdd), -S(4b22265d,70f13fd6,aac7059c,c7f3c363,7200338,28a20412,2168b772,330d73a9,965982ae,f3d121f1,12b4e1a3,a31ba940,ce702a77,1e743498,5ef4624e,ac13f9aa), -S(2336f680,86bccccc,679bc8d9,1c42bdbb,944300fa,fae9aa51,3a5245ca,5f0fcdbf,b0442c58,74e041e1,acf43400,7547ffd5,fc71d5ac,934fce04,65065e07,9b13d8c), -S(9566b5ab,2ca85589,565a2245,cbc04256,5b26b333,b089878a,393f464b,4405922a,2b6ce7e5,b22b9411,a46a012a,6745dd5,6ba35d7b,3304c686,50eeab44,d245886f), -S(e5722284,b8d280b3,a4ea8413,7cb6d8f5,e7107ed7,c1e46b4c,38adceea,8323d731,83492274,77d6d6e9,f19a2166,4fba0027,7c30529f,5025b6b0,6a10160b,bbf941f6), -S(4efc3d78,d30e4d41,e6d7e04f,d65c7f4d,abf51048,922ea858,ced39ac,ff7ba548,d3f3b5e2,3ab945a3,95ead15c,ea221d86,44bc737a,f894d374,f7379309,1f18f893), -S(268b193e,718e2c07,3cb4205a,c1dea8ac,f12b73da,fc17eaf5,b3dd7f74,f9492e16,6f1e00f7,35e4c6a9,a16b0a5e,5ba280e2,20760b4a,691caa82,d959c412,5fe739b), -S(d31e56df,6a0d1e5a,f6ba93d,63a02d6e,a91a6008,8cc6a7b1,ef6240bb,83ca59ea,3693fa09,ac433b64,424162ae,bff3e0ce,b926c036,37266c07,ab6590e5,b269913e), -S(c5103c0d,6b6995f2,94e1418a,21492951,caeb4adf,edadf140,4481e674,247c54eb,7832f84c,f94d55a5,ee865d46,605e708f,a4ed1879,a1bbea67,d01140,e3aca110), -S(f95cdafa,b5578ef8,6f37e978,476c08c6,6e3167ab,73a802b4,a24d855f,39b7e9be,77ae964e,d8a3b05b,8f8a7005,1cc20b99,71a4d78,74dc40a0,e2cab2a9,c662d445), -S(b4b9e827,faacdf2f,6503b903,171fdef2,7398c819,3776d2ca,7d1b4268,e65afbea,c0143786,244ec5e5,a166996e,194dfb2f,54152030,e1bf2fd5,2d33fc43,7f955ca6), -S(9169df6c,e6c940af,8dd672f4,5babdb0e,332b8082,f06ea004,1555b1bf,d269a328,be066e6c,26a18e22,8de12272,a374d17a,307708c0,f05f5846,3ba9a55d,dcede1d3), -S(4ebeebd7,c1b60e42,d40be032,570beb3c,6671ccf5,b7f1f10a,b094da51,7dfb6971,8b8d6022,5b57789d,c91f02ec,81e25d4d,69d85c88,809f202d,2a998460,95361653), -S(8e96e051,f8d7bee2,30209f26,ebbe1f74,1db4bb35,363dcd1b,bc33ffc2,b7c0869b,ccde36d4,c67f2f29,5241fcd9,a85f2e18,c322def8,dd785c2b,232e1da0,3c9dd27d), -S(61b8b1f1,d92213e1,38673287,79bcd83,7f06b24c,331e5dfd,76d91df4,54d6a42,93b65197,a22442e4,5ee12c2c,345afe10,aaefd03a,ad45dc32,98fcf810,914d0d47), -S(3e94ab30,2d01ac20,9b0e8e4a,d7329066,ab3a32c6,b0d8160d,9e2a7b64,8b625563,85ee61a8,643d08b0,a5eb2f82,7ef70bbb,99ca044c,af4338ba,24774e81,b6fecf4c), -S(dc4ae75d,78831a0d,ac87cab5,7c6fed74,500cf2e4,1fdb8afe,7f95e81e,730b9b5b,5daa7147,1fd50e65,9a9845d2,9535f0eb,55f787c9,ac1b595e,da2fb170,b59f17f7), -S(b56007de,d2b04196,b5398832,df12ec62,7d4b188d,beb5f09e,a3cf87c,c414f252,88d29752,eec1e71f,3c72609d,f5a60e31,f485262,b87d575e,83d9070f,b72c0ae0), -S(5d5389c,741446c,1cb8ddcd,48c67a41,580dcf2e,93257012,97a8b8bc,fd20d4d,e79b258a,57ebb0fb,26f08771,d63cc6b7,6d1cf981,124cb3da,28405aa,9217c698), -S(13037858,1413a8e0,9460dd66,18cc50da,f8e93b44,f0c0245d,58950892,1d61c1ff,5374f786,906892b,77d3cac9,df04a393,f17824b3,8a9a8b47,c5adc73,2a7fa51c), -S(d20a183b,1e003892,f65937ab,a19153a9,5c637bd1,8fb1fa93,4d258555,36e334d,c1a3efc7,c1b2c14c,6176dc68,9ecc273c,fc7250bf,d059ab0,fcb068e2,7cb70741), -S(585aee85,4d5fce99,fa00d575,6922e529,abf77d52,3322bb68,7e7d3cec,b28109b,e7f5ea62,cd4e12e3,c2b43ddd,a1f7638,ebd5a2bc,362b087b,6839b13c,ebfc5cfe), -S(1b20bed,29cc0082,5a6fa7f,d1c8fdbe,13cc853f,f240129f,16df04e9,a04e1f1e,daeb1a97,17f5bf42,4972b4b9,ede42db4,7fd36247,173c0e5,b53a6994,8ab01980), -S(c9a9e323,c531bebd,84548b4f,ffe78967,a08b6399,67788ff0,4953a1e8,8c7febeb,d64b4ed8,eda75c40,66c26902,944d2744,503f6017,b8e80940,55adcc7e,b34306ab), -S(6c551219,2ecadfca,bd79055e,d4e45f98,ab4f3a96,15e3b7ce,138f6266,d0ff245d,56aa876d,efa4593d,d1140d14,19f5465c,8a826859,af6a3eef,e2013c60,330df086), -S(e242ab32,5fc71bde,da7da19,686cb1f7,93f38e81,fbb555be,db874200,8ce81571,c56f2ed3,20f7827,cbe76177,e61486b4,cf15a555,816ca48,3a72867f,f27c4ef9), -S(7ab15e09,4b5af61e,3f5b7397,f89f1711,e3c55005,1202b76e,b351cb1d,91998741,27856f9,a77ad2fb,adfd70c5,7099d4b5,8b162f6b,daa3f3e,59f312d4,d46535af), -S(e55d8d3,77e84b5f,626cc6f6,7d1d0a62,44c72dd3,78206816,35c30d95,f7541cad,e78f840c,f8056853,3824602c,3f7aaacd,2de98757,2edda9ae,37da985b,60e1b690), -S(e9a09a03,9b0a0130,f0b8667c,6d7abca4,b3e5c143,d0126565,1fca6216,c2128771,4207a863,dc05cef4,6bc6bb9c,975485f,7c9f876f,3bce673f,f160d714,bc151e90), -S(e2bfd72f,f1af92f9,33ebd08b,d6b70cb6,c1346895,9a0bed0d,7cdae7e1,65135325,afca8d06,74918152,56a53af,b0dab50,91752e09,b44fdb4,cdce07c4,89b00045), -S(656da8b6,83b95ef1,e20bc36d,e64f4dab,7c1ed8b9,261548e0,93e75d5d,525b1bfe,d12b0be8,d382a555,a71143e1,cd0942ad,9f97e771,90bd6a24,5f473204,5d867bad), -S(e5e3168c,51734cb9,c08d9035,d592b821,a6a479b7,61000156,974a8eea,2f2bb902,63661750,8782dc9c,d4271732,68661c76,d2b8bbfd,9d49c7c3,88df9360,e6ea1fba), -S(6676fa5,dbcbc713,920d915a,13d01972,82457d37,514492,f90798f1,dfbffaa1,3005bd04,4d06ff3e,4f06310b,2927b621,2a82becf,5111a825,dadd6e13,bc3fbb66), -S(4f89f4f,523a53c9,ee9571ec,33bd8768,2f620c7c,8257a844,355d87bb,7f6f0d48,131e3f25,cfc2881d,833bfb59,d917d7ea,af2a7336,ee8944e8,6c4a48d5,10d9254b), -S(9f541512,a0f7a48e,a37bdb58,dfd9e627,e775e862,5b8552df,88e5f595,c68cc80c,a8b36ed1,2ae8c2ec,fbea6d33,6903522d,714ce9,3792759e,678f4643,f880b461), -S(777387eb,9e9c70ba,dc94b9c8,f0fb411,ea6017c4,faec6aff,f6d04105,c031e4cf,6bf663b7,ddfbcb36,f833320f,7098c928,22f9b993,3de32c0b,be60b66d,61f94795), -S(b27524e2,ec594848,fc757dc7,762c6396,9938d53,4f90a0bc,78178192,e9bd94e4,f8c944cb,dfe215c,32886c9d,1149dccf,c05a78da,ab759161,22182569,a5858454), -S(c67fb320,4716820b,37dfc400,cf2e934f,4080c4b3,b092d261,b2bb88a4,5136fa41,a3f61aa1,ccd741c,f36e4b6b,1a05896f,3805089a,26961cae,ffd2f70c,b0b2df3b), -S(f4ec97c8,d8a5af0e,d8d71cf9,5450aef6,66a29847,e395d60,7c17e50,68ea9be4,4376c5ae,10e31637,7b1d3ad4,6d224dca,8a83cdc,4e78a9e1,1286b4d6,2c39495f), -S(101fb524,eac89b59,10337c27,48673b30,e24fe7c4,f9beaf75,69861984,d14243b8,d56cb44,6d9d050b,69b986b5,adc3a710,774698b8,72236af7,d4758d29,dafb1fc0), -S(3baa0ce7,feffb71e,31c935b6,ed2018d1,e2a1a694,963f0878,354d2826,17008749,c010829e,aba91b9c,ea31b88e,aa90fef9,3059bc35,aa2c11d6,4cbbf40d,bed2271), -S(3be18f6d,9c8609d5,8b595b57,1ec6084c,650ef42b,9511e1c8,8c879aa3,ad70c65e,84182bf8,9db24dd2,46eea18,639b98ec,b62f8b93,5ce1df3b,f71d93fd,ee3c031b), -S(4249cb66,d532dcd,406767d2,7af9e7e6,2a7e46d2,4a140a4,b01b155f,5712f3a1,e4b5a468,f71ed053,a060130d,e40662de,fa3a87c8,509dffc7,83c7b2de,93c89817), -S(75688f6a,8599ef01,1c89b06c,132dd184,b4485af6,b3410f20,fc2368a0,1df9fae5,830648be,b36c9c8a,8ccd1096,3f2da3e9,e4f03d0a,75b13325,80601da2,3d572a05), -S(c0b7cfea,412fff9e,92e31b33,7e133041,c81946c5,603a3ec4,3f92fbda,bb56f8b8,63a13e2d,9a06506d,dc65bc20,67afbed0,ef0cf722,e75c17e9,14c0ac03,d50ec0e0), -S(777f64d1,c65275fd,6b266e39,5a0eaf3e,df51bf38,336f6651,1140f475,dfed8bfe,d75139e9,ac863e6a,35b495f7,6ca5c554,21fe88af,24cae574,95456046,503f4286), -S(3e7e7c7c,c7cf5612,f44c42bc,51f3243b,20bf280a,8b75e7ea,e52ce30e,2fd80657,e64e815c,fbb6f263,eeb0a21,8fdff95b,19eb8cad,f3d582b8,8847b7ea,7b9460f3), -S(8795ef69,b029ff93,5e9e0e84,5490ebcf,18728b6d,f25152e8,d315292b,d834cc69,86b984af,49c56711,20630233,f30bc4b5,e460ca18,8e4a86cf,5d5badbc,bfed2e3b), -S(f5b01cfd,59a22134,85fa7eb4,d9a7def6,d16b258f,2bdf581e,e22c28be,9dd8ac3f,95696481,42941826,38a4da0b,57f393d7,65e3a9bf,dab06592,87905d1f,5323109e), -S(9453d039,9e8dfc00,763b254f,905acd5d,60b109db,6830d8a,f062f339,a38f553f,59293f71,ea51b918,334593e9,3dedf34d,9dd0c453,2b5c9b35,edf046d9,5137f38e), -S(40011ac,573a375d,7815fb09,8bfab10,89cfd5fe,7fa87734,c257a9a8,9acbe65f,40f2e596,436bfd24,bd88bf33,1e711828,56478565,93e0250a,d7b87b6b,72b5af13), -S(7e0cdca5,50430cc,404cc9e4,e60bcbdd,6611c175,1cf50670,fe19271a,4db4aedf,812709e0,1e5f03f0,dd94e208,992db41c,4bbe8cdc,fe0f0e0d,bcdcd77b,d95cff63), -S(9c60fd1d,675457f6,4fb43af1,3f25173c,f64833b1,48867172,5e1f76e7,3e3f0da5,11d7e0b9,41c428c6,c0fcd00c,fdc4e252,1084a6f7,ae780845,bafafdd3,30a21e24), -S(7251e853,65bccdd8,a493ef77,f22c347c,964b0827,20c84195,5bd367a0,c2eeb752,8df2d302,e0f90ae1,68e84163,d4081a9,b93d0421,52a45bb0,17635904,8efa67f0), -S(da466345,6e03c943,972bfbb1,5b2cd45c,83fde8b1,e22371ae,8c248431,151a6198,6659dead,d0e6dc6c,15721fa8,c00b1aab,6676fd3f,c5f6a834,9ddb4114,b5c45e18), -S(666b5d13,8d5b8169,256009fd,ab4911db,2ac9ea0c,ea7b707c,60196819,6a2dc816,d7486d1c,d50eb54d,22be8156,caa92197,3614604a,1a5c72a3,836d362a,d0973fe8), -S(48f24f6f,e112c070,21c45eb4,59f5624e,e65de1f,ea3638aa,b8b849e6,175805e4,5d2df55d,bce84e37,1a13d26e,f04f3a99,38a9dc58,c78c6c18,4e72aa8e,2ce03287), -S(3518acd8,23ac4b6f,d50f8691,90d14f76,ba22bdb,8e0c5e49,8949468a,30eb3230,e3c92847,a0fe393e,83e101ec,f1b45ba,763c725b,684811db,d2ae402d,a31a7467), -S(105b1aeb,5c85edd9,ad72a0af,cd04ed48,feb975ec,62ef031d,9b0bc668,795b717e,dfb18689,75b80da7,110cc6c5,c845e9d6,6b8358a6,2382825c,2e6c914f,54b473ff), -S(f156d5c7,f15e5276,a9f673df,590b93e8,348407e7,9f6c096c,73b658a0,a630ee70,9d9bc235,b54fc94a,4d34c33c,fa843c,1c67a074,c679b0da,64b44358,14ab5fd3), -S(eedbc38d,d0da0095,a1df4b97,2add48af,a97f2e92,bce8bf67,5ff3c134,73e5c3ac,116d4b18,5a00d9a6,b858d82a,39192f4a,a4e6f305,b2d695b2,e054557f,b895ae0a), -S(14b54fd2,cf799482,ce31b76f,474055c4,60647893,d6b46894,15676c32,3a413a18,5c700720,c08b7a19,7672fbfc,cc7b5223,6b0664dd,f9fd3df5,aaf66e88,f50824b), -S(ede2af57,9ebec635,d93ccd2,1fa74e69,d8bcb14f,d82ef9a3,570bde8,3f6e7f3,e5b817e2,3af1ee7a,38a3cd2e,41b2cf98,c2d4356f,c40dec19,b899d219,e01f9121), -S(6aeec3f4,90b048a2,cf210738,f14d7324,5ff190ae,72234576,e825f5e9,20641002,acd9b1cb,1fd56468,6da61382,cf9d66e4,1fa00c16,d886c9fe,9aee6d13,d1812054), -S(a0df5ad4,8b909123,e0de90b0,669fcfc6,f0e10d0c,28746ac,a260ce19,a678c8e6,3897d22b,fb2ebbd3,e87d6948,cfbaebee,95adda8d,f0654dac,d409dd51,669c7eb9), -S(d924dce5,a68819c,6e840326,5ec20b56,553d596e,78020430,5ffa6d5,736f5317,fa262ae2,f1be924a,18a41181,f417d16e,9013d50,c56a5eec,47244a3a,fe69122d), -S(98add9e1,45dc7541,4271c971,4d6219e5,436e479b,998a4b6c,36ca3a6c,90645ca9,34997501,ea07f7b4,2aa4b6b0,7387104b,4f20c0c9,dc1dc82a,8c2ba093,900741b1), -S(c42f3e37,2cc9cf46,3d76c4bd,e29481af,dddf3040,340baa94,6bf84220,7f9a70bb,5a1ec58,e4038781,3e9ca00e,9c53358f,7d777fcd,4f18b5f0,dd81b9c2,3bb3a059), -S(e940c5e4,1931a103,a4feef73,7e95a12f,346c3855,7a3a7ff5,dec89ffa,ec1c3ffa,5556a9de,d0a5e7be,5440ab2e,3850f718,438ab153,aae411e9,c31d1012,15705dbb), -S(35b105f5,7ababd24,19f00161,262a6a8d,2738239d,418f8f68,8c57fdc1,c8b3afc4,97e93b99,7664d080,f9236d16,38fb8457,28f812ca,9b0d47d0,545058e5,513b722d), -S(15ddbc98,b22840aa,bf698e42,3eabfb3,8f32af95,2969eb06,c24c9901,8b9428a9,33404fd3,2ef62c0,db440774,7fa7f70f,d681c4d5,e042c48b,1c7918b7,75f13514), -S(a00a5eab,1517bcbf,d377402c,d2721d3c,f493d100,3602e251,8882d426,fa69ebab,68f8d86,2708fcea,4022308c,2e391f76,9cd4e128,495aab01,dcb63473,4334760d), -S(7350c15b,8afddef1,4c173893,bf5892f1,6047769a,278c85cf,20ddcc91,125a632f,3bb33254,e5ab2964,f6f401b5,685ae429,7a33b887,99fc9861,75da7e3a,7abcaf51), -S(7d92d2f0,981424aa,6d651cd3,fc1cf104,2f24e71a,29cf49dc,c4aead32,2771f6df,f4f49d9f,f1905e01,f8de9679,b1bec436,ec0bd68b,b24e8041,89d369e,e1a46e5c), -S(2c10719d,6122c4be,8f1ccdd6,d520211d,aceb2e9d,fbba02d5,6c0fb1a8,5b3a44f4,558fb689,90788971,2e5fdb,7bf12431,3ca1e6a7,e8117d3b,8e53ee5e,b7162eb0), -S(5b271fe6,10767158,ef07e835,54e5cb7c,d39fec5a,defb93ae,122bf5f2,44758a61,d82aae85,70af5248,f1e4b784,26a491a2,d5c33c22,c65165af,de42b288,60f097e0), -S(1c3bfc2b,cac4ef22,9f946221,6f03fbb,b2d27e25,9c2e1cd5,c410db50,74be14f5,f3ee7b94,e8c24dfe,abd78d0d,737b89e,962cca9b,8fd47978,c6573e51,2811b857), -S(d43a0bc4,638e36db,c0068609,b7f761de,44303303,de7189f7,99bf611b,dfa1b233,f8877c1f,6ccb955,6e9b182,379600d6,db4bd0e3,83c76dd,42941e24,bf8fe041), -S(2e4d8eed,3e9d1d99,2f08882b,348fff52,913c9a6c,177bc71c,236d92c7,6634dea3,1e994080,635d8ef7,a6401aad,679ad721,56b81cf8,7959935c,dea463d0,b74e96ca), -S(4cdba5c9,d5fe043b,c99da326,9cd6248f,3ecde544,cf617a5,b8c73e47,cf539c92,2527e4b3,ad0bf862,f94b567a,21020d72,92def1d,8e19211a,35f78ad9,dbf72269), -S(477033f6,5abb16a1,7e4b80da,f81537ea,eb39891,d8a2f0a1,5577b1f,999a6473,c986f8d1,3b17239b,e64224e1,b0316573,18c536d7,b00d6f2e,a462848a,389c47e2), -S(2cd55c4e,e05a9e18,9ae326d8,741db193,eeb4b356,78334c1a,48453f56,4452cb72,d9186792,86ede279,dc4fa812,9bfdc308,b887bed3,1b9b4512,1b15c552,ce4f89d6), -S(c2efc599,bf13c184,7906d679,16182ff9,d98cc345,d306975b,a5285330,75925f94,9e6fcff2,981370d,4f4ee530,ab1ecc8d,4f807572,bbdeb533,6157a096,613f267c), -S(4804058a,88482ff1,bc0c27dd,31f53072,f166b89,abfec728,ac77b832,ce24387,ed62ddb0,9c4ad5e8,473c443d,ee624287,e85398a8,dc08ddb2,8ad5b4f5,4e0b990), -S(6c3264eb,7f4d3f1e,5c0c614c,cd8f77ee,a23f77c8,a22d6679,467269e6,a13353f0,158750fe,28339ea1,ccdd2147,466824e0,9c44df45,21b2b47f,540d4f9d,9b57c2a0), -S(5a2e10de,52c3e589,4f7e9807,cb5d75c6,7b8fb61b,6c161f18,661b7bc7,486f1f5,dc191e64,c33a0aa4,7a771ca8,8aec0c33,8ffde81e,3b8025dd,61314acb,e11b4739), -S(57c4ac9a,c559aeab,da34371d,c0088bce,768cc4d1,6423c8f4,daa3ecba,571e79df,5beef57b,97435345,db22f84a,36b0f1c6,7d42b246,32336304,f1f4cc6b,325f7028), -S(46b350d8,326546e9,93e85952,f4fa1b5e,4ff93d4b,2afaa5a1,5ceb2e66,fcc12665,852b0e65,a3864018,62f9bbb7,f284b4b7,e04ddcf1,dafdc616,5b7d2303,395531db), -S(66556fbc,632cd7fc,e3a8d768,b96de7ab,fcd0a7e4,e3db320b,19e9d971,97326d46,45275512,50aede32,9b6713ef,eada1372,69465b72,cc720404,aaad34b6,fcc5c2b6), -S(24e2b12a,798506aa,68b50881,1c555a5d,80984736,5a4e6f7f,b27c863f,8cbd2bb0,fb9aa79c,d205955d,4e9da24f,4798f930,2933fe7e,1cc01024,c08c9fbd,7fdae7d), -S(fb51fa7e,c8d846f1,fde26c,6c14c479,38059646,aead5a8b,7bbb05e1,a5bc12fb,6ca2fac0,20cf7c16,d360d37f,eea72322,edf5b824,3cc3daa7,f0e91a81,dc2f7aef), -S(4613ed89,ffb65026,f0481095,553fd5af,929a13c8,4013bf28,9005aca4,e8e0dc94,ba837762,a2e6c17,4cd4912f,3662991a,ec910c29,8033122b,63396def,5de2cebd), -S(222473ff,f87dfc87,403467bf,9b0f12f4,2014772a,68457462,401933,f6192499,58aab7bd,8e58d310,1849b3fd,96a2b6db,8eab6ac3,d29f9ddb,d2866980,14774839), -S(5e751a2f,988fab02,b974604,b4177076,81dc7332,a2d268a0,4586f231,300552bd,2d466152,4180a713,f6b40571,29bef9b7,bcbc0372,aefb4b07,8707725a,f31d029f), -S(3c94835,bf940014,e0c589b,3df40cc,a53c20e4,f0aab085,d8a79c26,fdb95b24,4cc1349e,212b1111,50ff06b6,927d701,9387e4d9,4d6bc1c,aa0ba14e,57f97414), -S(9fb3ea60,26b6b1d2,d56e6caf,19fea2d9,a2386ed6,65aceeed,aa66c5dc,f8fb51c2,8f90ecc0,87c300e9,3df10082,a3e461af,88bc0746,41e0a85e,4981988c,c539d096), -S(49c1f091,dc031e1f,a14b5417,3831ad26,438e85fc,407faaad,c634a0c3,8d956cf5,6656b7ba,7a5658dd,a78ae1de,74944332,22c36abc,d7272146,80a64a8f,1135e455), -S(eea69d66,68446656,45231f81,f27dff32,83667f37,4dccc3be,5bf12a42,c446e112,821403bc,f618e100,42c45de2,3262f7f9,b23dfda9,9a5532a7,fc6aef36,868eeefb), -S(c251be6c,5c73933d,90bb741b,e87c8b27,909b9efb,b40c70c2,3b1b5db1,956518b3,68f543dc,872f7f37,b8ece85f,acf3c670,bb2e6f00,7df413b0,5416919b,57aeb60c), -S(b1ef747a,4df39c35,4e67f27f,97b150e8,6e138cdd,70846ca7,3479819d,98cf4cd6,7afefc25,a30d6879,45f2b471,20b50b83,eb58b682,b61dc4bc,72c4e368,4f3c01ac), -S(9cb0d6c5,2094f1e6,ff84549e,32ba4260,a93baf84,cbb9516c,68c25c6,4b67feac,3e8e7ebc,1958e60b,cb4159,16f7c903,d63effeb,4955a11f,cb470ff2,e8935665), -S(d11f3d4d,6b18bc42,1692b7be,40589b49,b909ff2d,5659a058,4bf3af1a,7be76be8,cb42df3b,630010d9,fb48f12,e7ab607d,6fa1f829,1543b68b,5e959478,ffb6a8ba), -S(ff6a9171,de273646,9d0c0b0c,5e7829c9,3aaa1ac7,e63a63a5,fa2788b9,888025fb,335b0b06,411d6e6d,7c6d69e8,4a900f80,5077bc7a,248f2d24,2df2c517,a9bc0cc6), -S(655dd8ac,aa0cc2d4,b9543d3a,1c0baaf2,a76f7b41,caba22e7,47c1976c,deb15707,a726eb12,44c2af81,d6b5abaa,c9c117ac,75f2f6c5,c550915f,e005da5c,efcf746f), -S(4ade0988,d4c2b0c8,e303dc20,88a86aef,b2893fc1,80c410bf,d9467bee,a785e3c7,7c2358bc,74de92a5,18d38766,d13d5d4c,2a0d551f,62996105,bc59024b,147406ce), -S(9430a2f7,6f2bd12f,54d885be,3172f512,5282e84b,ab5c6bf6,7120a6bc,1e070db1,e8087617,943aa433,55684564,53d91a84,4a06fdf4,6a587c14,a2695c54,ccc3894c), -S(72b9e511,c78cc26e,f9498e38,9a15ebde,cad6bb3d,ab08462f,f6f19966,d75ae882,3a8345d9,1a0b1a37,405ea7ec,cc427785,607b84d9,d64adb42,5cda786a,fc68fb33), -S(4615999e,29a4f947,83617d0e,2847ad26,f79bca3,b3cdf3e,6a40e6af,f778fd65,5146f8c6,85b10eb,abf0ee65,145d468e,ed4ce176,705b3ee2,cf8e2f66,d3c739f7), -S(bdcee951,41a500c4,8452f5e1,3833dca2,45f94f83,80ee6574,7197610c,5ccb4558,479b3308,fd9ae072,9f97d0ba,622bfd1f,71c30774,c9be1bc7,b6141278,3e649631), -S(8a52a750,7dfa334a,1e285c5d,8c4d6963,5c3f78a4,79cdde18,d057d0ff,9bed97c,d4f40b1b,dadec733,5c264caf,e8c6d0cc,6f7d40d2,6a5d56d8,6a86b392,97f10477), -S(69387f5e,1d2b3fed,1b033614,25486ad,6ecfd3f6,eb85d8e,fc272adf,6d154915,8a72e294,2be10088,f16b74b7,4327ac02,1aea149,84a25458,55edef5,2e5404db), -S(7a8b4d6,982cdce4,c066b721,ca2730aa,5705a43c,84ce54ec,cd184ea5,53bc1099,f4460a0f,62bacaef,67238243,ee850509,d346752c,4a93f59a,5939daab,a654e215), -S(7a32ba53,a2f6c968,56adb025,10d9036,27e945c7,51108465,c88b42ff,e96442a2,213af901,378b30a2,5272dbf8,9b847fa8,32e3657c,1e5af5f3,d49ddb88,f7c9d701), -S(97388117,9d476881,84a6c968,e96316dd,4933780c,1c5b55ad,78c0de2e,aafaca0c,ab2d23f2,13ec96fc,856e6dd6,c73d10b7,5a0e1c5b,b901ecb3,79dc7544,5dcbc672), -S(500491bb,8e971056,380ba6f1,a02b619e,763aaf4a,bd07f9cf,50f86dba,61833354,ad296ee5,b4c32ef9,728c1924,562c0fac,9360a6d0,16f2651e,16f4c49e,ab35e600), -S(1c9c2015,bd266fdc,fa123aea,45428d07,eebbadb5,2fa10d83,7b4a831b,4ff086f9,73b714a5,71eba339,c58d8449,4637092e,9d44ce29,cf039427,de75b540,97916fe8), -S(5a4361bf,44a082c4,4e87d4c3,4173c910,8a3ece47,ccf3d3de,f933e9c2,fe649df7,184372c2,fe0b659d,57ee278c,f3aaa9f9,c6f3e45f,28c8ffad,54730dea,4df0bc95), -S(f6ed8161,c49f7ac4,931d90f8,fe41a400,367d8ab0,ec23b0c5,74886906,86f11eda,6c24c798,f1d88a2a,e2c7b32b,867e930a,41f425b1,ba59b01b,f971306b,a0b6093f), -S(ba392129,6be5773e,a8b509a,408b556c,deb7953d,a5165db8,d52516d5,36cfcf01,4cf094a4,9c06691,bd11a7d1,864ca452,29e91f2a,60b1cf0d,d9bf1162,901cd89b), -S(eb96dc04,ea36d6a,43823477,d4b6e3d4,a89da427,7d959962,3f31afac,49159203,17ce0e2d,6fdf1ec7,3808ff72,aa9d1fba,5038b698,c3f72214,9db254d0,98b714f0), -S(5ee66f18,669dc60d,a3c7074d,c853c51,21f6c584,bfe5c2d0,949d73a3,24714f52,238d8d46,f4143d4c,e7c74edc,78d1fab0,a42e7593,7c340504,e259dedf,4b462433), -S(71979eda,cc7fa635,91767e7a,57f8a1ff,eed003db,8083c41c,ed252c52,438b1e11,94e75e9d,4f3bf3ce,5ed2e8ef,9056d3ad,bdc9f9d2,4e51edbc,9f2b2bb5,90077c18), -S(7a301d3c,f6f6407d,8e62d5c2,4afb8ddf,744c2bc8,d2d219d2,8d912585,51c23351,3578a307,3dd4766f,319d6a8b,190b8a8c,a85ea7ed,1c54918f,73293b5b,5964652e), -S(8b76e056,31f5ec6e,33cc1267,9b49d9b1,16e8e06e,b3ebf91a,a3f239e9,8b188c42,9f0f4f92,a43cdc9f,f1d5b031,44586266,9b65d7dd,707de8d6,23dd8fa4,62c2d96f), -S(7de9be01,b8ee5708,9fa0dbfd,69757649,4d9d2eae,756bb9a5,f9deedfb,d55a6019,8947c62a,fd4a1e7e,dd70af94,f09aa2ac,aa1c43ac,745cd75f,dd1618fd,49251a4d), -S(d0766e37,769689c2,b55a3839,968e1eca,58824760,716c100a,29746728,4f6254c6,fe00274c,f3274a8a,8c529570,8b122d9c,a226fe8a,843920e8,a17f5468,ee2b0870), -S(61e74942,91821765,e144ef34,37c24dfa,80857029,35fdb2b1,511eebc0,324e9523,a641a75d,8917abc1,fb36b5c3,beaa84d0,b4230817,2337f50d,78b71b52,f4373524), -S(a726ab19,5125f8ec,e8cd1952,2facdfa6,2994c4d0,712251a9,8efd73cc,213773bc,2064d5d0,ee2b5cb4,5567701e,a3015c35,f3718700,af2aee6a,22202325,1fe65afb)}, -{S(64850a04,76870a44,2cfa57e0,4e4707f7,eccc5e99,12dbcb07,3b457317,717f5686,7c5facd2,91a6defb,a1837cb9,3bcbd0f5,bc37572e,68ccb2a0,c062a155,46656fcc), -S(fc479625,fda0067e,a75631e9,c79999b6,dbcaf7b,e1b69d64,a75b08aa,f3ac871b,d550323e,54200c9c,393139aa,b8bf3526,45520bf0,d90f6ed1,5187682a,79515de3), -S(a39b8f47,efba84d7,1b781439,f8c144fc,9b637215,26aa6b68,b55d6a59,137dc291,56c6dc,511a8494,b86f9669,504985ef,e88789b2,83e58916,24b9455b,d656cd39), -S(172d5d5,21edbd11,beb288d3,4ee78e86,a1059bb0,5d781bd6,d9589f23,46eb7833,5251dd9,10553e2,d1476e70,c6d2cfc2,397ea7f1,210e54df,d2f61425,60bfe73f), -S(e5f972b2,d1723e8,8bc6ca8b,ed3ec1a6,fce0e6ec,fb13cb86,efd61e13,24d4c41f,2e072ff7,ea3c48c,8653c0c6,595c2c27,d7953185,4e3e1b6c,8c1e7cd3,bdbf9ca), -S(f586c6c5,44cb108c,edd7cb15,6ea36607,d411d162,730170da,51ba1c39,a1e33241,dd5425c4,3f49fcc3,c92753bd,dbfc4de7,f7ad4511,f8b720fe,b07449d8,8919888e), -S(e324072c,8d3b5516,1c32264c,e2287b41,eb8edab8,356250d,b958c37e,555de216,4bb37975,35b72127,6ef1e62d,82608300,9c04b2b7,24655acb,c2d3a06c,ac55e7cc), -S(1b76872f,cf8f2297,ed95552b,17bba313,5dafb896,7f2a7229,faf4a4af,fd416fa6,8c389799,32b146ef,87aff36e,4d6e1891,a2acf7ab,2f362302,d13e34cd,7a34adaa), -S(797e7051,903abbe1,9735f94e,acdefaec,2f2c8c60,13a6ebb,d06a4234,14820bf2,ffbf5cd4,19e47bda,cf59491e,55d3a3dd,97d35b8c,1b824c79,955ff91c,81269563), -S(e3e22849,a67edc06,10662641,d5975a4,ce59650f,e9ced88d,4865d63f,e0ad948d,551b701f,fadbb47e,ad4ad324,ebb01c12,c5ba2ab3,754c9762,cc840bd5,569897b0), -S(50e49072,aa2ff6ed,2c8705af,1ef1b703,903194f0,2c91c0c6,5fdd46e1,2a01e887,b55bdda1,e98db862,6a283c64,e1e813b2,20e26556,921eb4bb,b72894c9,27be1c7a), -S(d1b0abc1,e1164bc5,277353b9,84856cb9,1c55735d,9d475ae8,8cc743ad,b0462739,cf712d30,edf88915,373be307,e1f7e73a,244a8610,e7c6718d,112cc414,4058bda6), -S(62fecfbb,c1532096,583a588e,cd7b390a,7fae6e93,a675d14b,4bc99ba2,546d5573,ccdd7145,780cfa94,7e4f20e6,1729ec09,6ba6d28c,c2a53ca0,65d060f6,1fd9028a), -S(192e0299,75cab01a,5f5a8428,ca2c283e,1b300925,ceac8290,1e134c8f,97698d79,55f467bd,8d0db18f,cb4c8b72,2784ee99,8127067e,bd1314a4,22c063a,4755b817), -S(eb5a94ca,29e28ddb,11907c63,fbf8fee4,e1677ab7,205c5539,b0b3675b,f5fb9b8,6e9bb010,1fdb591c,c65702b2,cbb16061,cc7b8698,bb693c28,e09e853a,fc00ca), -S(4cff025b,579f9c57,c78bff07,115b7268,39a20ce8,f893e5b7,eeb310a9,c738c67b,d1531ff1,a839c908,97afac4,256b35f8,5bb31903,3e8f8e69,b2a9c13a,ff6be9c2), -S(bb5f423c,77da9a2b,540812b0,1e899dd4,a100bf59,46bd9818,ed4c2e6f,103be9ba,d4851c37,afaf40d6,68de6a6c,3a1d9209,f0fdcd0e,98310455,61210c7f,a1a797dc), -S(86066254,59e38927,b90d60b2,f9594e27,5e509366,f5678d35,133bb9a1,ad4b3262,40900453,bd36c557,10f5c8ac,492186fc,f5caa74d,12c69b2b,c28dad4,9e83e690), -S(81d52fd2,14f2d1dc,c386ab9e,5fdfa5e2,99d57284,7f55917f,4468bec3,812cd638,8b131ad8,2f24d27b,87e73419,bdd9d41d,795b9466,9268a11d,c8b87e01,7665f2fd), -S(7cbb1f2f,47f57e0d,20be44ab,2427feb6,18bc6b82,6e5f4909,51e1927b,bc596ccc,bb587bfa,d416ef29,aa36ff38,1f448f46,fb2fc0d0,a87e5170,8313715f,30cf3d25), -S(3c6e6b89,2e897388,157d3565,95ad59b4,334394ac,b33a3a24,7c455d90,a4dff784,b79d7d85,2b62e00c,c340cb8a,d42b489a,bc372022,75563918,fc9b81b2,a1b58b14), -S(dcad5a44,4c6ed0ba,2206a2ac,92e2f0ea,6c5fdf7f,28dc6bd4,7a6a48b1,d32d7e2c,6300d599,63fb36c8,f0d3109d,161ba1d2,9f718697,6694a11a,63377075,b944ba19), -S(c8515e28,b0f7d1cf,6e3829f,8d0d43d1,cb382299,1f781962,b265b268,c09a0aee,f33e0699,9385890,5520fcd8,f06123bd,3429dbdd,cdad22f5,3e80d951,b620c70b), -S(d1f81565,ebea70fc,6ee132b3,79e11725,4e4f84ad,50e04282,ec23afb0,8e24ab,38bfa250,6628029b,721a11a2,4af41f28,7a4f20d6,87a3c4c3,815deffd,bea92642), -S(79c02a3d,93cbfd75,2dc01fd8,a4d83626,2505eb13,92f4800,965086e1,51cea673,aeb43c57,458510ef,202aa9f2,b904fb34,6350d4cd,ae8faa3,d246feee,8da21571), -S(b476ddcc,6a6f785,b1b8637a,a22b1984,30574567,1bce6b36,ed3738d1,8c1c5f88,e71abebf,e2019b3e,99b27560,d4ea4ef0,6d52d300,14c462b8,1daa5a77,3ba73176), -S(937b753c,2d7cd681,b1e48b4,4236aa73,96968213,b57c5af2,3d48b0d7,cf64523a,2d88bb55,e67d4ef,adbae06f,5f93288,2562b9f5,99b50523,e6e05cec,fb7baccb), -S(7e719005,dc42e572,471177bf,80cf531,d31daba6,f2015664,d46c4df3,ee9840ed,80f9dba9,6a495938,74704313,613e3bba,70ef8e1e,83f2063c,566d2791,d79148aa), -S(70d04693,54db73e3,780a4413,804f7cc6,ca1849f6,158c1b7a,9eded185,8071e826,ff96b0e5,4692693d,774e01d7,5776190e,7caab3d6,72cbc1b6,1623e87d,f0f96936), -S(83bbd70b,f2794adc,7bddc8a,ab107e14,d5cc19a2,eedb59c7,71ba622a,53e2a603,eb92141,5fc3f2d,b96bde24,1d68e314,244c9a0f,42e455f6,3b8c09fa,fe3533b4), -S(8f8ffbca,72942dd0,94b208b1,12ba36bc,c324dcc1,dee4de01,ad8dc8fc,ed4f84a,58fc0a62,a5c20df9,e0de3aaf,3944c907,d7c6db11,4976df5,e38ce452,e1901894), -S(7d5fd589,955a3b87,4bec2638,19faa133,9d03ce58,2a64eb4d,643c42c2,95ab2c7b,deed7974,2d442ed3,d70ac86f,ee47bf20,9a8ec7bc,9d9a98b8,b02ff4e,a857db32), -S(19e47a2,323d5a26,fa5c13a2,78ceca70,e46bf5e8,d9d0e22d,f228c15c,8fe4656b,bb439d24,789f26f8,6e5b25df,b40a9cb9,6b3272b4,d85e4a04,e6651443,e1e41706), -S(75708952,9fdc2d9e,ab85a24d,d06a7c29,252cfa04,f2686d19,9fd04ef4,ecd0d304,c7f53395,8aaaec4,ff6e97a3,19ecf7bd,a53a3034,ab504c6,f02ccb24,2a04475d), -S(30f6959f,468add62,636c1bb2,18c2794d,5eb2d907,3b7449b9,eb5c1f7e,a5c1b016,6fe05738,e8ff7b1a,d8527ea,b8ac47b5,35c61dfb,efda4279,382e8dc2,52893c92), -S(7640da0f,4ddf3448,dd21cab9,257e6f87,304afe2d,fef9d58c,93c2de41,e9a7ddf,f1cb4a24,f553505,a660a219,6baf3485,6e8d21b3,6f661a0,baf2aec6,36805c22), -S(1db0050d,dbcb4f6d,e716dcb9,a3a54079,3a8fae5c,53c630ea,aad1dd66,f195226b,50562f14,6f5c2949,3f9e2efb,d64e2907,f7845673,4b7ddf2f,977e46d8,42cb6bb4), -S(2b5a8ca6,f1d94ed4,d68460c,ebf90aea,7506d3ff,9c71de28,908d05ca,eaf08d0e,6cac6a6e,6b8fe9bf,c733259e,7b4a7715,5a15ca6c,94a42a54,be686849,61a8e064), -S(eac0ed60,87593dbd,3c88510a,c27123af,9fc926e1,4a829f01,9fa24686,1b0f9279,5599829e,ba8e5cd6,253cc3c3,8ddd5a30,7e2e38a8,2da09504,4cde7e55,3dcfafae), -S(495c0e20,51615bf,278ecd84,508ae728,72a7e82f,88cbd992,20f2e370,1d46f9ed,ed5a3c18,27e3474b,c04b6684,bc754cf5,b8014720,145ae8b0,fc24c6f,9297b394), -S(c74debae,32533089,35ad9c23,cc038b95,f3f15965,c46dd3d6,df61b482,ba65cd43,9f82e190,4ab044e8,ad645a7a,b27e0f79,e45bb7d0,9755441e,80d463bc,b25ad4db), -S(c6d4d1bb,4b396ba4,a4393403,ced9a8de,59931eaa,beae1f2d,55c1373,77455ec4,c51f605f,101f038b,913300a8,9ad96bd6,d5e60dcd,d7702ff3,357ee1fc,6ca5b45c), -S(a0f35ff7,dfce08fe,6335cabd,c642c2f7,9a4b6e1a,c95df6a3,b4694bfe,91abd1d0,fdec4844,90ba4281,b78267da,b6dd63c6,ad0ec964,96c42407,32834ebf,b9c822a3), -S(ee231095,46b51ef2,547bcadf,14d57e1a,f4682dae,4611b67c,8d99ee4d,ab912004,dee04daf,3adb4d76,485f8e5f,bf9a2231,5e4bcb96,faf63f67,da257c4,5645d797), -S(77fb6478,1d1ceb38,ed04147b,92e46668,bc47fc0c,73c6e677,a56c9fe8,89772810,ae42f6b7,d26702d7,44c3e867,6750cc7e,224e799b,857b6c68,52936846,6a9c35f4), -S(dd205a7c,9a4901ef,3439a05b,56968951,269c8618,ba1638cf,b9949f98,d84ef11e,8a7da4f9,8a628f46,ca39d902,5e994404,dc6d09ba,8cc2d199,47936454,c024a73c), -S(d4225a81,af1ad205,d1ff1555,cd15df81,d82d75e2,7d8b6a37,a7615c32,ffb932e8,3902c36d,7530add6,a88c6e6e,e426434,b9728690,c6476d33,cdca32a7,eee99fe5), -S(237d87d4,2ab0b9bc,ad29bf03,f754d98e,535a3a2b,6a184929,ce65e18e,17eed134,bd7e8be2,8a125d86,adf47552,aaa6a474,797aa641,94edaf12,56b86a9,5057e480), -S(eb9d15a8,76dff407,4ffe6ce7,c430e797,ffcdd291,34b6f737,b2f07cb3,7f2dc8d,8d975595,aa7790dd,d531e7df,77dac484,948d4ac9,3cd1e4bc,d3b7d9f0,4dcbd431), -S(ab6ffcf,2681db28,7a99226e,3fea18e3,5abec631,898d7038,19c4721a,ae341e5c,a93ae653,4ab9ed9e,e2f50552,cce4ae57,1ab80473,38da0fdd,6a203f18,4c4bed0c), -S(28b7ccc5,53c5665a,1daa0150,102a7eab,8d6db154,b575d2c2,33d2ee1e,6fb2231d,a5eea545,a89579fe,ceb2af8c,e67304c1,f1cf936,91ed7b0,4e461c3f,72863921), -S(db7e3299,5ecaadc1,e94ce255,2c04cafc,c10e3ac0,a88edae4,bcdf941d,6a913b60,8d2cc29c,5a23d74a,76d39caf,fc026a0d,58af12be,9202f250,da8e7b6d,f6a701a4), -S(a030b7c8,169eda5d,ccbe9258,30ce03e0,aa89fca3,654e70ba,f9d9cf08,bb2a95fe,4a16e85,3c8efe30,46443cc0,12646aa6,fa030141,1a0b6f70,dafd1cf0,61ef977d), -S(580150e3,ea63bcfe,13b1202a,b31043b,4d581eb2,86b0d985,116d8b06,3a087325,c4dffb1a,4f7190,9807e070,fbd85774,194d7d2,99f203d6,4470f9a8,b8a3c245), -S(d23c6b7d,4c455c41,edf6a923,33fb1b66,43fb00a7,f5f9e0ff,9d96cbc9,af10e6d0,56a494f3,91b77cf4,3a16f72c,2084c3f4,7332893f,de676cb4,3ae527de,eea4835), -S(91a4fdd,eafdc6fe,5630351c,a1d3270f,3040e70d,7c2ff55b,2af7e256,ba853510,59b05210,6c8d327b,24cad438,891bd72a,1b71ac8a,15c9970,334453a1,a8926055), -S(f297dae9,fce4fd6b,decd1c54,72f86b6e,499a6f01,2468477e,316a689e,62c5d5cf,6a8561c6,6cf1c950,9fd21b39,d27e71b,984ef01e,b8c1fbe0,d14a76f,4153f1f4), -S(c8bce284,4cec327b,83e979c8,1c7bb30d,4f5ec633,d64269fa,8bc33ca5,aa4b72e5,71b4a02,e529b17b,6550455d,e5f6db29,59b59cf3,7fb45e24,ab69098a,a71f6bc6), -S(18650112,b904e937,5074377d,ab19db9,88771616,b47c5e90,93e16eff,8d237969,c464be51,dda23669,ef352ed1,e8eda746,3ee2c9b,f56bc33d,7ef464b5,f96c7b82), -S(58e1d8fd,c85f3d28,829cd90f,f968e826,7ccb6aa0,ec8d7002,d78d77a3,76573d48,b76e4320,40359597,60056ac8,6f953e46,6c335207,6e56422d,28d6dade,f7280826), -S(87ca9444,942ca103,5bd010e8,f89ad6da,7158a16b,f5a7774d,84ad7e2b,91130d27,f14dc3ad,8f102cdd,6e192f9e,604293e8,c80211e4,a6b6e78e,fc8e7343,84352a0e), -S(ae61aef7,e240b692,ecb12ea2,b568158e,8da85c8,1c902d79,db82aa8b,747ddf5f,8fa838ed,7248894,6ae75ef7,b4809546,7bcbf668,9e5bb460,2f711f17,6501d3e7), -S(5a91a937,f5a36f44,4a25053a,2bf2a374,aa6118b4,d7f18ffa,1b641977,d761564d,8d2be259,bc22caee,3d0694ac,b70f4a0e,7b7f8edc,b2418486,9613e0f2,7b2e2fd7), -S(8342a29f,f3739b81,f77918ff,d5a74f20,efd76175,6456eab0,aba2af96,b95b1488,5e1280f,3fe41f14,3da73a56,c11df7cd,69f596df,f98204e6,75ec2601,7f7f25ab), -S(bfd9e9d8,dfaa3fa7,a1bac396,45ae27d7,e0a2d2,aa4022e4,6df8d408,eb06c3c2,5ab07b07,1acf15ab,186836fc,29fea177,2c6ab202,a72bbae1,78c4dd8a,7566d025), -S(ae6c6419,ad0fa0e6,56fba661,834b5f49,2299c610,be8f60b9,815f4775,7ea4d9f2,95e9e9dd,ffc81a1c,112d5f3d,d59a298e,6a3fbdc9,c5fa9c00,37394081,e9f965eb), -S(12212918,77ab7009,96eceb7a,b7ae5b7b,822e92b3,e99e0308,481a9936,c3568143,b40c8be9,16637b33,b428f521,b5c4395,6096dcb4,2504bfcb,5780d42e,984f4474), -S(4cb67c85,5964d298,667173a3,3f3bbfe4,5d2f1e07,72eb26ba,95fa961b,41728597,de8164b5,2af252e0,464eefc5,7a65868b,1e0d16cd,f9c5ee7c,7f13ef2b,1f555cc6), -S(b882a78e,a897c609,29c13dbe,b0d15fa8,3b36d895,9ca15b43,d8c8ebfc,cd2592f0,13a114f0,8bc83d53,103a7327,b92e2289,d18b6cbb,39a9571,16b19c8b,77a714fc), -S(7f77196b,483fa953,39b28b5e,464f42fe,e3ee50fb,3384e401,ae7e5a63,70544479,d66bc424,8370ffcd,445f1aa5,38dcb965,68f51a62,4babede2,3f59ad63,8dfbfe36), -S(d04af491,28f406c0,26c8228b,a270962a,7c45c5eb,51c3cbb6,856c8cf8,d2da8959,c354ae41,f03b906f,74b9c259,5a675bfc,7d6389b7,1c181e6b,1b0bd779,b9e47d71), -S(20f6bd64,cde466fb,e0ff2436,4f9d02a1,d7ad2a92,3bafafc,67a1a154,f1a572df,13dff561,a14d7143,369d74fa,c7872c6e,f57d1e78,b0211f57,ad9a2363,19ee4f4), -S(2ae2e2e9,b53d8788,5889bebb,7cb25669,e75ff2ee,ba305324,a2473937,1826365c,6e52daae,1c2a50af,dc37b1ef,22782d72,7a10f128,225eb816,9b813970,fc14c68), -S(2b50215b,7f3489e,c313d5a,14389c02,1c72b1f9,68ab37ab,d9f4896c,6014808e,50069279,8b2a2226,defcafdc,8a8bdd38,dd7c9a13,f5a2157a,4d0942ba,5453a859), -S(d4bb3a0e,7dd530e4,ae3bcc5f,4001686b,ccdc81d7,6c79c131,288bc2cb,76c72717,9c58063,898cd752,23187ac1,d446c8db,c2918fc4,632c1bb4,2278c0c4,48e97d19), -S(82cec682,b714ec75,6d3348f3,da10fe60,885c790,99822f33,d7811cf8,6077284c,c1f14f0e,670e1bc1,ab604e11,8f3c2827,7c86ecc3,79e97e39,6776594f,b4750f6f), -S(b08b799,5cb8527b,c4c976ac,a6675f03,a82cff9f,309eef60,e78ca418,71486c5a,70df1520,c27367ce,53499421,35fd0daf,ba7df181,f66aff88,b83e12f4,f1b57411), -S(44541703,b3f11462,fc2ffc79,b28237fb,3f6d8611,44c66891,e9cefbd5,7f75cd9,e9b53337,162c5629,eabf13c7,f0433cdf,dc41bd64,9238b810,96d2c8f0,77a5f165), -S(5726f775,b5164bc8,9fa8dd60,267615b8,d5aa1be8,540ce3c9,23271a65,8dfde543,31777af1,58e103b7,db7750cf,37f42dcd,6a155880,7f5d426d,1075d8f5,9a83c9b0), -S(c9993bd,7368efbb,c20b1082,354fcece,b072a3dc,a5fb5e68,73bdc8cb,94ca2b98,3a6b4c46,73d3756b,76d0ad69,701af08b,3f4bd359,3c5ddb40,94eb9c25,776063b6), -S(8b12af05,efe4bafd,bab8b73d,830db99e,c3212e17,bf2f1245,86d821da,82a11b9f,32eb833d,79e92f26,6bfe6840,ecfecdd7,ce000f89,14326697,562372db,66d36ffa), -S(c7986b3a,f4992e69,24363fca,fa8b681c,4cf60003,beecc0ed,af312080,d9329f04,a8a72ac2,f76dddac,faae1172,82965c24,d8710ad5,1a1a5863,5dc2778f,22ca0774), -S(b571af4c,b8fd57c6,2ce4b52e,8a38305e,b3c2b5f7,1cba5931,6dcbe676,3a219f07,4c028e68,9d95d4c6,b974fc05,e7a3a264,b1410fa3,2be80588,32986d4e,fc9976c), -S(412a3d77,6113d30f,fdb4ac2d,1be60a3b,bf93fbde,c837fcd1,d23fe917,811fe6d5,d8dccd67,8856db2d,c698ad2f,269aed7a,3c1255de,590c8208,b8611153,f18faba3), -S(33e955e,9aec13d0,c4b8a61d,455f784a,4d22fd0,f935d7e4,69a88dc5,44c89426,668a62cc,9b903539,a26d8de2,44310f07,d8304b7d,2ec1f4fe,35251b82,220c0cf7), -S(c7cb9ff6,4e7c8dd0,4d05f9dd,a7f106c8,a9841fa7,1cd25eb0,2866a34a,74ddc670,d436d69f,c42c21bd,b64250f,19a15191,bc228b35,37469444,717f4c52,a4e9bfb2), -S(9b6fab7f,f701e6ee,efebb2d9,3c4432e0,826560d9,8aa5b0d6,cbc31c5d,190768e5,f01de8fd,bce677f5,5602113b,90853f6,da7f8029,beba0c02,d20b599d,5646d773), -S(48e25e2a,cfad81b1,315385f,25c958a3,26c425a4,9d75c2b2,1a0233f5,9a830525,83a6accf,d0d149d2,b5dbf766,2bcb0bf8,d725753d,50615657,2a0807fd,882a4d6f), -S(14690774,db72e162,667b9033,be102fb4,f1fd648c,858dfc31,a8b17513,74bc9792,d919061e,6c624203,1f0641f5,bfd7466b,ac55d890,a3b1175,12a4517c,af9a6cc3), -S(941b1555,4838a75e,7762a4d8,fca39187,bfcaa3fc,9869df23,93d6c77a,2b956d18,348db67e,845f7133,aaeecf17,ab75960a,954d0d2b,41ea5e15,be098ff,c4a43d09), -S(487eef1e,77bb13e4,821fc8ab,c9f4448f,672d09fe,5fdefd84,2a9931c,477ae38d,eae4bebb,e06b75c4,b6d37238,faf0237f,5b035c2b,cb084825,93053964,33bc4b53), -S(8896a835,37276df4,40f3be94,41267b4f,4160fbfd,51e3f01a,f675387f,362b0ef4,feb71411,db1429f3,5391993b,e461df0d,c3beba79,4b1b90e,cfdb9338,80e5373e), -S(c6f6f864,baa97e54,69407b28,bdb459db,d1af42b7,19da64db,ba274ab1,58da440b,db83cf5d,feb196dc,5023736,c43c1d46,d6ddba7a,44805f36,69f639e8,f2759a33), -S(c901d3e9,1f590c4d,547b5715,dfb1a61d,f898215c,2be28af4,a4d9d229,7852c00,821c673e,77517338,da3617ec,53213d08,9f695c29,2a5ce31,c60a377,428db6ea), -S(19707c8c,3a276dd0,a54e9cd0,b241f54c,470b508c,ae773fdf,20810696,f9eda3e4,1d8832f7,92db5867,73f1d260,39877814,411f502b,899282ee,ff205495,f04d2119), -S(e197c27f,cb20bca5,6c593eb8,7d677048,5b70596d,4f35c504,acc18bbc,49a54230,85995a28,27b2715f,ce2a682,b727e7a0,4c25f412,407bb99,20cf55a,f756027e), -S(5bcb759b,56bda507,23e45cec,4689f03e,d04ce46,497f2409,1c5a93b,3799ff1d,b068ae2a,47e605f7,f9005545,a563ae91,2f841713,15ee191b,d81e0d58,6d68ee9c), -S(2acdf086,f613c0fe,1299e13c,47568fe4,701f5831,1f515c74,32ebbc0f,cb0c5dd5,2496967f,5f3aa9a,352cac15,d3fe9880,a862925,45a2bb5d,7600c1a3,ccdb6374), -S(268c185f,5d0d2fe3,1c1e2850,b3c80f09,f896134f,5f410524,8edbbd5e,bca357b5,2e81765,ab1c4336,6f782895,35a39076,b8501008,41c574df,d6d25b29,707feff2), -S(b6de69ac,f84f7cf7,48d50a05,dea4faa8,9655ad2c,98846edb,e166e2ef,de4483df,3c377b81,ffa03daf,823a5da,e0d4cb27,77b585be,d5fdb889,62c3a3b8,709ddc9a), -S(bc71d28c,ecd81488,5a76720e,da59deb5,f6d4cdb0,36b2bbb1,2e566d58,2843bd07,501055b,52ddb633,74bbefa0,62ee294f,ced29ac7,4398a634,b629532a,3f50f1da), -S(9091a40c,3a3bb70d,d28cb8c3,ade93,910b783c,40b4a2d4,a48facfe,50c524b7,c1bfb69,3ab9ef96,9eaded97,57ed9621,92344389,e62f6c9e,47c51d8f,b75c1436), -S(46a3e416,8ca5d225,1e01eef9,6cc422f3,da56a59,81fd11df,4ba87e88,ebe6486e,e3630232,96c0efaf,f93b3d4d,2367ea73,3d776180,d98abc44,94d1032f,f49dedef), -S(869daf22,c0978d91,20595281,569f2a43,b3afd058,9e2f29dc,c0644dda,fd26ab6d,58f2ff45,bef8eb75,244e93bc,93d58778,c7a1adc8,c2599c04,635009cd,12f8a6f2), -S(1247ffaa,76f92f50,2e4408b3,2d373f38,79a93634,ced87989,c3f666ef,ffdcb366,8dc9de29,3267dfe5,1966ab2,9462d5c7,d81c205c,536c6eeb,4f2246e1,1848fafb), -S(e25575ff,bf62e7d7,aa64255f,8ad222d7,4ce23ab0,934a3c,cbb80d92,7fd98272,c6c749cc,320892c0,31b3ca54,3920afec,90217d17,5397b6f1,1ea201fe,414c1d24), -S(d02c3fc1,68bba27b,ac38bb2a,4fc7ea99,66e8da54,75f9dd9,fa131fb,d2862057,d24c229e,85b30ff8,80b87f6b,ca145250,f4f72907,ec33f51,94c2f8f4,13a8932), -S(28c4002f,5f1fcfd8,d9e13789,d2527f5b,d2788649,72d5b12c,37dc5c13,b0ab243f,259617c3,7c84d212,2ea7b4c1,33118fb9,9cfdbbcc,db707ec,e99b37ac,12380123), -S(a4d02f63,3f6edcc9,88970f4f,e8b0e639,d07cf277,1a6173d2,1e54594f,65b21770,236c19a0,4bfb2a49,98c776b3,2a2dc4cf,7e91293b,4bdb7d4b,a0ed62a,64683bb), -S(f28f22c1,c3ef5444,fd373435,23e97c40,5d3d19f7,21ee5bd4,53087e95,3d2d006f,fca3f966,a264a422,3e861dee,c5844b99,8f245a11,48301797,db141374,128ae075), -S(7ec145c9,7f1bccdf,ab49ef42,1feaa816,e7a6efeb,ca371e4a,29b7950c,ce8b10e4,a278eb3e,1e9b6d14,52f60e3,5ead3083,114ec862,53101724,442482f6,4fe7f997), -S(66a1296f,f7700439,3305a768,bc9712b9,c6a8b79a,a4211d82,900f39de,3cad406f,968f1ac8,70766942,67d06a0d,655279aa,6110ccf7,7ae73873,4a0f4ced,2848d887), -S(f9e2f7bb,6fb1c6fa,760ded51,d465ef1d,b1207d97,660a360a,34be4dda,c5ccf177,48df22b6,c18fdd1e,213d5a1f,a70084df,2419d324,6811f90f,efc5bf8f,24f25e6), -S(f19fcd39,2cffecc4,4f0a9849,6c0920b2,11ca3208,ab312a84,a87bcee6,f6d5f6e,df36cb00,33f564cf,c2e1397e,5d38e21e,460b019c,9bb86ad8,6d4b9e01,53528261), -S(da3bbf50,f63c674,245af2dd,ad0dbf7,7644d069,bfad635a,f6065c52,f6b4b1f,e6babe9a,281a2a99,92b0f5e2,a1377416,e6d143a6,a2de5cd7,dc91eeb5,b3d0c4f9), -S(d5bb7b31,cf5345b7,8c6c0f9d,bf94bada,3d917dbe,2ba7bbf0,f65b2be5,eada38e1,e8103661,6c69aec4,31c7260c,731a471,e236e453,dd0733f1,8e5d1204,bcfabe61), -S(b1129318,36da4fa4,23ae1331,b1adc768,f1460e0e,22331fc1,4cebcd25,85d40d7c,9f8b7276,27200133,b69adb10,ba95989c,22fbb25b,723dfd60,7d1f4815,293e0856), -S(5bd95654,67d6794b,fae7bae9,df0cc02b,a0dc7ccd,cc5d98dd,5ef33d01,99c10f41,867b8536,363dbb08,234d6be3,d8b25a4a,7caf5044,2546d3ed,8f9d6d95,dd279619), -S(cab5c72e,7561a912,25cb65eb,edefc6b5,2e36caa,5551a749,7ac30cb3,149e6b55,f88e4081,3a6336ff,82cd632d,53590df5,32e3967e,37ea5aa2,bef69000,7c683996), -S(f3198dc6,d55fef1a,9273d311,b0365422,ae4a4c9a,2d2e94aa,1c4d081b,2bf138a2,aa2554e2,8ad481c0,d8376221,d15c3937,13f0553c,97b4f8cd,7b341c5c,72b4123), -S(900f4005,d4af3591,a1f518d8,2cfebf0c,e11f6a0c,8ab82367,337293dd,c823d8e,dd729fa5,d0fadbb8,c294306a,e0e2dcbf,9def32a1,1d58ce37,cd318e85,63cbc99e), -S(10f24db1,481336d3,25716449,c08795f6,efd8e3,f49fd445,cd5dfaaa,58a7ca05,ebdfa0b2,75c6fa7d,79751a4,e66b8a0b,f92852ae,bd108f19,a6feb9e4,9a49d936), -S(4babe89,ec5350a0,2ff673e,2b6fbda9,a1e826f7,ef060396,af08bfcb,8da15719,8415f595,ba1d8e7c,e287fcf5,bf386432,5a5a965a,a5ded5ff,4f9e85cc,8a287228), -S(212b485f,e7f39183,1605bbba,6b32cd0a,e3dbef40,a52d1adc,91362a0b,1fc783df,91a67656,9eabb6ad,dd13a646,c07b5ae0,f93c942d,6be6e96d,3d79ba89,5a1ef56d), -S(4aa0d59b,d8feec6b,507dedcb,eeb3feda,ea98fa96,4cd72734,811a72ca,d1f4fdc5,3d487788,3608eea2,dcb5fce9,dc5d25ab,d9bdfc41,ccdf7391,7cde90ca,ea6fde61), -S(dbad6aa7,b7e547ee,8c97e30,d6653c8b,9bf7c37e,679f8ec9,b74ceb24,2ef65c33,3d39eb67,c276c7c4,24b1e367,e71de6eb,dd32e624,b957cdfa,35081b53,510ffb4a), -S(e0495f52,49e4394c,27d9f2e5,e01c59d2,dcffc868,e4be4ce5,1fb114d9,4607901b,e77ab12d,732e11b8,c32a18c3,9c8931b5,f780f62f,7ce0685f,3d921e96,7d21de3c), -S(aef97af4,f923b5e2,3245ae92,9a0baaab,6c14d1e3,bcfaca45,a7c6dd20,58c6e2cb,83e51238,a46575b9,183635eb,cae26493,25acd694,8c04b911,d05c0e53,dd9c61cb), -S(831ebde4,2fa1913b,f4e036ea,73c22b97,916a61db,73918efe,4f94da72,e714235d,60c29914,c09663f5,e6af5b6f,e3b8da4,80a179ef,70da6c98,8ac12a75,10162124), -S(e4db4221,e7ab4db7,e473572,ec6034b3,96537815,2d1d8bdf,e3ceed44,2f24dd2e,359b878,b5bd2f,53f9a275,384f727b,634894fe,a772d1d2,72568a4a,a4d83d50), -S(2f144d89,972800e9,e0ef550f,da814390,9a106ae5,6b2b9dd,cd0f6855,1d824570,269e925b,ab060ccf,84d4c79f,56a557cc,f476b477,9e73a4b3,872875ee,26388dc2), -S(b3638ed0,d52b3292,f7b953b9,7f6df07d,8d1d5c3d,487261a8,8c25a2af,9a13cbeb,54fa96f6,8f475bd6,5515942d,b8d6f208,99bac252,b042394c,fc73a7a2,adae3113), -S(48c7ecfd,5dc8eb51,7827fddb,2430b600,ccc29edf,906b3db,be5151f2,590e56bf,85e43f35,7d9f46ba,8e5a8903,a75d6d36,bcaaea65,1666b1c9,b7e7dc72,487906d7), -S(963dda96,74cd2b15,84c677c6,dd6d91c0,c968d541,1941f5e5,9a2747bb,4f6a69fd,5ae7f7ad,fb515e1f,7790b789,8d2f801b,b764de6a,f5c33fe9,c54ce712,e4c23a1a), -S(6a3c5404,e22a666b,77396b5e,5827643f,ccf4e3e1,7b8b7c8b,6ad35fc9,ae21b1a2,780c9b96,5220c67c,3c8f8e0d,fe57f1df,67ad445d,4c2f0c41,483d9a32,d558206f), -S(14c13d08,209e5619,df06c33e,ee8289d9,628d4ca6,141fd46a,aab75be7,25a79c15,7acdf79d,b5722728,cceb5416,18c1555,4d833aa2,cba5be7c,5b56ed26,7c323bbf), -S(5c83e244,4ef9d09b,d8d648c4,37af0180,a376173d,4b6a23c9,1791d211,f4ba0973,8a041c51,d8001b77,8cfdab74,ebcea960,414269c8,50e52776,61da8c55,2f06d765), -S(824300c2,d17d63cb,131d489f,63c914d6,75120933,667be49d,e0950587,13cd17cc,94cfb246,f97bf2d6,e9de7b17,fbbe864a,521614e5,1cf6eff0,9f949657,f60c522), -S(691f9af2,1a0e7506,f16acfdf,ef22fb51,fa16e068,86d4ce5a,82bfd069,7fed7406,33d1d8da,91b28358,913089ff,dd0dfe0b,1cf5c3ca,1b4acb43,5223e353,5be8af3), -S(a0014691,2dd02b0,bf8533d7,60cb656a,eaa87ef6,93959f13,df81028c,82025aec,644e45ac,2729f6ee,22388317,a18381db,e1675a35,23ab2820,87afb9d1,48f777f7), -S(7c8f565f,228c2015,f1624956,146fa45c,945f6bea,b69e1b9,bc8401dc,f95d3331,2491f474,81df8eee,6b97f82b,48506dcc,fbdba731,44dc6e9b,29a1606b,22bff452), -S(bae86f26,301c873d,2f5cb288,7b2dad60,161410e4,db4b1a49,6477c58c,4817c582,65eeade1,cdb0ca0,14d50596,6549039c,a0c6e43b,4514de9b,fc222c93,180a7bbd), -S(aecd8a88,4bc42d87,b1c49637,ee23c3a,364c04b7,c16ec871,11c9b447,81116c69,fbe871f6,bc384cea,b894b0e5,837a6da0,98f8ab45,72b82a15,b7e7a058,7d93350a), -S(51388726,2e51e2d8,9c5f4ca4,7a6d2aee,3ec63b6,7ee5515d,4bfbdd82,6318278a,319c5fbb,2cc90ee1,3b3c980,3f2ccdf6,18d9f3f7,d09cde94,12779499,9ca87b3c), -S(29826f1a,27d4f62c,9f891a35,82ede6c7,163bdd5e,22f10325,6eea348d,cc4f5cf8,3f473cd2,9041dc75,6afcedde,34fdd6b2,82e3ebc2,baa2948e,774965a5,6d5c6b5e), -S(2d36c3b8,f293d2c7,80792a15,89895cb5,9b33d8ad,362469af,5777f0e0,225f2941,bf0f3c33,6ab29ad0,1bb693bc,249cad79,63aab00,97beb92f,ff1d4dc1,cf1885ca), -S(b7f1fe36,faf18532,34cbaef9,a45d47fd,26a6cd9d,2cbb6424,7f0757ce,3bc0338f,f86de831,ea68826f,925a8401,5ebffdcc,dad4fbc6,9d32b264,767ab067,c7b1b6b8), -S(d254e76c,41359c6f,521a898b,d55ab42,208b583b,59761c54,e9dbab37,fef84285,d504c24d,7955bf0,2bdfc187,bc8eefc2,42b65db7,43e9439e,3f5204e2,9cec288e), -S(88bdb44c,6999ca3c,8d3e8fa7,61f343e,7a9a5f15,577e514e,809af06b,354b8971,c7cab922,69bb008f,cfb1dd08,b6576959,e0593f76,b5aa45b7,899b305f,e432cc7b), -S(94f19750,6ae279c,772b1c5d,17146012,cf8582b1,973c140b,7aeb0bf9,3cd21ef7,1e9acd37,9e7f2dd5,a6df7a9f,f4b757e3,369aff72,341ba963,fd984259,6c615de), -S(f5b2f65a,16322443,a4ed65d8,7fa21983,25f2d3b5,523cfc11,39f676d0,8953680b,7f6c8197,cd730769,2eb466af,8c63e35b,1d4eb84,fc83d22d,d5d1217d,10e06ee0), -S(58e85669,c5f76dff,9b5f601e,3d1a15d2,c022a5c1,389dc15c,81657f8f,e3eb1be7,4fd07587,429bb7ce,3903f7fc,f3356282,24e17eb3,e256fbb1,32f1fcd1,e1048f05), -S(29bfb3d9,d116ab87,407376b0,f8fc607a,ba8a9da1,803479e8,a7ca8fd8,ce96a822,de56238d,93995238,bc6c4b94,f03823d4,a7b690a5,24d01e06,374ddf4a,2e5589b6), -S(78e32283,983fa295,f6fec0cf,e34ee0fd,83541350,e50d5948,8760279b,dd54cc28,8ce8f6fc,d58a5330,595cb9de,eaa7472d,9cc02c4,c7dad678,74af6,e4a20f34), -S(f70d3534,ef29e626,84b84023,2e69e806,740b20ad,ea957ba4,41cc06ae,cdd4ce39,5cb415c4,7812684f,971026ae,21f8d1dd,377d7c27,a91f8d49,90c96adc,2d570c36), -S(4dffc775,38cad4f1,2e87a8ea,44ea868f,ec9ecb0a,a79d26aa,6db46522,7244f006,7afc7426,9d4a76db,2c243eb5,a89735d7,2d91305c,2d44acae,335fc4ec,7cd5f81c), -S(3fc601db,563c119f,9c3fcc60,1005f3d,63c92315,5bd786,9092cafc,237c6c15,4ce31449,bb975d34,5898d06e,6d2e463f,e8e84835,7bde361e,eca2c999,6982735c), -S(7a74384a,d0423c88,4ca797f5,1d62a152,4064db4,c0b5c925,47739139,5bd9219c,2b9c87e9,53965eb0,d5708dec,58a5d0c7,d698e51b,b6d2d45a,b174c9c3,4eba7f76), -S(76dbd3a0,2ca25871,609eace1,6ae2f814,8b256a09,8cd74d21,ae6b0344,16d542f1,c95914e0,5971f888,61800a05,ac946af0,99e0758d,78cfd058,9347ddd,8000bdec), -S(ed159060,2d63fe28,5b88813d,a6930f49,65dd3290,759b677d,ceb9b213,2340475e,894e82dd,1415a206,f3cbe2b7,3b7043b7,1adff71b,58b74c6b,2297ba54,2e1cccd1), -S(74fc673f,4a41d30b,d3ca4b63,b850d23b,8e1b5f2,6c37fdbf,12a83b9e,9c896ee5,8d341f30,c67403fa,e23b7502,91c35064,ffdde04e,ea52b3aa,3003b169,68f1c95e), -S(78c78ab7,5bf6ae8e,d7836957,e8258a33,b88b9cf3,53feac8,e3a8abe,59307600,95c6d9a1,3c9b637e,35c301d5,78534af5,777dde51,6396b017,6155927f,11db8880), -S(4d694817,ad756fe4,2cc21193,d4e707d8,ec458304,291db1bc,c38dc6c0,52f11194,869b495f,49bda0df,b0b12c00,e19c7cf2,14e457ce,66cc8e6,d93c5db2,7a91e1), -S(ac23df67,801e05c7,d283aa5f,ee2dc366,b02517d3,559123f8,d093de6,a9d61a10,e7e7d4a2,1bd85ae8,c88aa4a1,c5cf91b5,6fc2ec00,f54d6ff7,89e10103,7ceefad1), -S(10c1e9db,43b60e88,379b2ee6,566a53a,3341c12e,8d5d6490,ec5ae5d8,eceb1675,2fa61b2e,26557d26,f496ac8b,aab81dd7,16983978,35abd7e4,4d5b11a8,8d7f3558), -S(55ac4cab,1aa3465b,584aa94d,bdcb9eb9,3cff7159,f8a139a4,2504bb27,bb618854,cbe23bc3,8c553ad8,fc9fa619,b96b5de5,90463240,944d2906,41a14b56,cbb28844), -S(4afd69f4,caedff00,601225ac,9bdb192e,6c17fb45,62a28164,15929e64,249da79d,d08702a1,95f9abfb,47296d6,c24981c5,db62e8f2,96ebabc1,1b4b1612,c9478a55), -S(d70b4279,b68e2135,844a45b1,814f1c74,7eb8a5cd,100a6d8,8b12cc79,bc98c9aa,2728845c,c3e20846,a7088f35,9a08add2,4997be96,1327b54,a26ebb1f,95641efb), -S(ab6bf873,7d0321cb,bd2548e8,b81e8070,ad449761,af21a945,9ce2e17e,bba82bec,49bdc2a4,8bc574a6,9577cc51,91267c5a,85fdf00f,ecc5c538,688dcd86,f9d039d6), -S(2e01933c,1462cfd,b8c6f180,c7d633e,1b684ec9,a3011aff,573ac22a,aabff3da,f7c0c7a3,36e576dd,96b83111,9e3bc370,3b94ff45,d50306cb,4acdf9f7,d8126ec6), -S(9ce6a2c5,cd9dda93,2fd291fd,30e8e846,63720189,4a70fb34,9361bcab,263b4e18,f1d503d,592be1ea,98ec3218,8e61ed8b,c2c94e76,5d42c72d,4fd404a3,83412251), -S(626aa071,a774d04a,bfe7cd21,448392e4,a5a3d2da,a2e53dc0,93fd8cee,78f82bdb,a666518c,7dcbef4f,a0915a66,ce331a4d,46867af4,3966c81d,ad9d2dd2,43d30fa5), -S(a6fd685d,4ceae2b2,e1de2177,dae1ba3c,41822896,22270c76,74118916,1b51ea7a,73c90eef,ee517cf1,4f4afdf3,b0f58c8,b66ff7f8,c59a83f8,49b9153e,e29a5ac9), -S(ffc5a16e,cd27880a,bf5f1931,ba61fd51,57396ea1,1630577e,b5e12eb1,e9fd9826,90abe5e5,e312ce4b,14c6548f,bbe2095c,4e146bf7,c25d4022,c017242e,2b057afa), -S(848ee3ab,8e9bb2e0,745ca530,a6231a00,7a41d685,466bf798,9ef900ca,18407854,e1b0d35d,9f44e0d6,b1c8b148,ae5efecf,320bec28,32aaad80,5e1c7812,993afc41), -S(28d833af,476daeac,27559042,f7e352f3,4aa2f30f,b7ffaef4,26e41e28,d11971fd,d0a0338d,57c2f186,c4faaa78,eb13e931,8f8f6d7e,1472ae68,40668e17,94d31802), -S(40579821,9bc06e48,88b1056e,270b19c2,4ef1278a,d415d3,47c7865f,98bcc237,cc9ce014,f853d620,83e18c0a,2fd36b0e,9eb7d265,b711fd5c,6d3f809c,b86f34d4), -S(98470fbe,636eeb22,7b6d425a,d7077b31,9384ad8b,9327d1e7,139a33a7,cf5765e8,92d4c695,5837771e,9d69826b,1445f09f,bc610387,d23a90a9,773113d1,78d471ba), -S(a9d28158,a84ea778,63c7dd75,5bdc6b60,3d6a0d6a,7cf88e9a,b649fb32,44aac2c0,5d628cd5,38824a6e,25477bea,12962465,dbe281d0,bb7f5db2,78bfca90,e5d812e6), -S(7dea83c9,13fa2478,fb03c1f,459cf002,98adbc39,4dedcea1,c90dc05d,5a56ae02,19306ca3,7f768ad5,9e70ea0d,c811adf1,a1e593eb,42bd8d9e,de0c0673,afc1260e), -S(2ab32555,3df0405e,e5576b5e,9965e488,dfccd677,63b03dfd,ef3255c6,7000ce2b,4fbd0086,10d10040,af8a6e80,a1525d88,d8e44ca2,6a1ca8a7,d6eedd35,c5d26ef4), -S(d59e876,ada6de89,fa87dbdd,43b2db0a,e1c1ed01,cb0a5d3b,5fc5cdec,ea52d069,b7923636,a2c5d928,7722673f,f759ec4d,3dbe9484,b470e14f,e28030e2,f37c3bd0), -S(8a69a111,7bdf0752,13f53f00,1101c594,2d2932ac,789c9b7b,15a57640,c679082d,5ef32f62,103c59,8ce35443,5c26f1f1,9ab21ae4,ee8e4350,60aa910a,99fe1633), -S(1aee31cf,451a516b,24f43cd3,71a1b93a,6a04bb09,74f73855,1120c6a9,d27d4546,f6767dda,c1204f16,e31cab5f,ae5b9357,4a2d8b47,b3dc3229,95c0afcb,c4271d7c), -S(7fcc179a,9a2ab1fb,10f03d6,1e936985,91ac91f2,f49ac834,e583f991,365efa71,c69dda71,c28efe20,3ebdb28d,70d0718a,9da3aa5,255c7c60,6f355961,3841ea7b), -S(bf75127f,46e4e90b,3bb81277,13641056,c75f78eb,3717425d,54df396d,9c021a21,640e202d,c28d9d72,c6d1575e,9d672c57,d64610e9,93983585,10eaba8,61fa86b0), -S(4c1248b6,27e5cbd3,5f93deea,44070e7e,bd5b78d,97f27961,53cb63c0,c18feea6,15e12929,f7b6b8df,bce226f4,6f2c73e,7d473833,18fe05a1,1f8ff01f,5d42dbf3), -S(584bab22,79395635,883c483e,abf11ac9,6e97bdd6,b9a0fffa,f30b9062,37520da6,2e7e69df,570afb7c,a3e594fa,7b23d00a,2f8a7e64,c02cebd7,3fe718ea,458891bc), -S(68ae6eb8,fbb41532,aa8e8801,e7c1334f,571ef1f3,92ad014f,9637bb46,b18ada9,aab3337d,550f07a7,20285869,72781c30,4bcc2d81,ecff0fc9,c27fd09,5c41b1df), -S(21d7d1df,17e3c1f8,65ee8c63,f16b0e60,c074501,334a601e,eaa803bc,2b1db846,b6c847d9,a4992f60,c9dd1898,708be183,41f4999,a5803b4e,7c2a5677,d3def3af), -S(63b70ee3,eac6f6db,36b273f2,2f919be2,6146d19b,bfa217e0,a3389ca1,f131b6fe,38accbc1,28b57d42,ab2ae5ab,21997cb3,5bfb42d0,71059542,6867fe83,14df95d), -S(6981f1e5,ce35b49e,b511612b,22ba76db,5884e2e8,819832d0,1859e993,84d6e8d5,7261f896,810a30d8,53cc24ae,40f3f36f,78826bd2,49141d57,6b9bd900,678e0b79), -S(e30c73e,fcbfb24c,882df876,b878b5db,31f0a78f,2e476d3f,850f6b2c,e1d3d548,5821f7f9,7a2e568c,f0f03bbd,c5e43e2c,ffb1a55a,4d6d4855,49f7b6eb,f9a6817a), -S(e95e8d30,316e97ca,70e8d602,89c5a43d,1c698beb,f40e1ce6,87d0d017,7e922f4a,cb161116,c64f6a66,7fa6500,294fdfe1,f5f27cf8,de2213c8,97c55144,2a70137), -S(f0062921,2603da15,6e315036,ebd10c56,477eb7e7,5239f2d8,a4fec336,9e956c38,4086b08e,a3d16b48,a0cf712f,54a7547d,e732233,69030526,c10ba827,eb85793d), -S(ee8526b6,a932b82a,c4645a4c,c5200e91,ac1a8ca9,eccecd29,1c83cb02,bf69ec6f,d5f40396,4f593b1f,d6b130db,65a45c32,241be6c7,d0faa091,bf8f0d5c,41bc41a2), -S(6209df6f,a66fb907,70c68cf8,81b0494e,7c31ef69,38fab171,cef2156a,740ce435,ed1a499d,5d7712ac,dcc39dd5,512aa71,4af5fb36,f53c789c,7eb53d10,7ab415bb), -S(f1f7899f,7a0cf14f,4ed384e8,e55bd6d,8ef0cfe9,895bea58,ab80715f,7bfb6fb1,679f0e59,705f87f6,b23a008d,69c9e145,c44637e7,69326445,68c9dfd2,631a0e32), -S(ecaabf0f,890fb84,a23e6b2b,11822f6c,62ddefda,7def3d2a,816ea029,2d24d93e,b5450b41,29c8ebcd,f3aa0def,bf091346,6ceab1d,874000cc,527e071b,6e3c420b), -S(42220ae9,3b056efb,66349955,402c6b93,31706ce,c5ac1916,494e523f,10959fa,8272973b,a0c30376,a3ad6d38,f007e1de,c9f74fad,f6621d6c,cccd7f55,f9293477), -S(a5b1cb9d,ffbe6c9e,152304e3,c195ab6,1904fa5b,661b097f,6838e33,fcefb7e4,f933eb70,32b9723f,250b861f,1c2881d4,fa118f20,2f16d0e9,bf41844c,4bb6936e), -S(dc460969,258cbf33,c327b9d3,3927b18b,eeb2f2b6,db477491,fe1b0f8,bfb274ed,383db155,3ec0da85,62038810,653c06f1,f573065,4ec029b6,1eac7f75,85bc7ddb), -S(546afcc3,d5e1002e,f7531c4d,40284782,7690f7aa,a9b7aa65,80070700,9642647d,ea4c5ed6,31cb86c3,c7710671,dc26249,13fed4ef,e2bb56dd,fa4f21f3,478ec442), -S(707533d0,61c5c4ed,387e30d6,69ddc3c1,de0162d5,48c11cd2,8daeeebb,6fd8eeb2,a8f2c219,eeea9182,16a5722d,b9fc3f44,a8cae2c8,8e9632b6,dc9350fa,6d6f08ab), -S(4480b923,babe395f,9b21ded4,d7f3ddc2,b9044ed1,379ff4a1,f417bcb4,ea1a1bcc,14ca822b,e0cffe91,42fb177f,712b5c65,6e650c55,24bbaecf,26450356,c7dfd4e7), -S(484a7a43,c88ccc85,9bd81923,a0faf130,f44e45dc,cc43545a,9f7f18c,184efda9,8b79382,3ab0435d,6422fdcc,8a3272b0,1b326ae3,4ef2992,65693070,45fc2388), -S(df247ee8,1936fb3e,9a4da6f,ad000c85,f7c83171,45097f9,ab4b94f,a2c8e1f9,4955c099,d857520c,633c0b75,731c6286,7b5d43fb,506dfea7,9800ccda,9a4962ab), -S(95a936d7,c83a5b13,e0bf865c,22155aa6,71d8f86a,3c518cfb,58e73ccd,f23a141a,be6ed058,5bee36b8,9f2d8921,58bca498,f87675c1,9342df09,f23d62b,64a6533c), -S(89e0cab0,118c0f6a,58b22a3d,fb66fc48,b19c059b,6b5e2958,6c7f7487,61c65b2,cb77eec3,d806dee7,b11c5552,16dcb2a1,2c00233d,2461887b,6897618d,e8c4b0a8), -S(64ac2ffd,67fe55e9,5d82b26a,a88aafbe,5ecd6b25,12226ef0,e6503aa6,a3fb4ecd,41bdf623,644d265e,be30bc86,13a6f084,a44f1dfd,a6f1ee8e,16d84e4a,fc51d66a), -S(60e0f0fd,99be1c5a,43866b76,a7ea8890,a7077135,43bf4299,e25ff15e,e35d87a6,4ef82895,b158d4ea,d8ed02cb,82e8ecf1,df795d20,b3692951,a431ec81,78479c22), -S(49f0734c,8b89d8fd,2b349b48,2d5b32f3,b7d5e68d,532f76d9,753503ff,de2a3caa,4e1c2858,9b22009a,2b4d143d,94fe44a9,5697540a,48a2fad9,100110c3,ca0b9548), -S(ea29d84f,41a54da5,f0d9f7cb,ad239ff8,91395e85,5cf2c86e,e00257ee,325993f6,a0bd6636,dad5c1d7,8d65e18f,c36b00d0,96d9379f,1e650fb9,cd072b0,224d0f4d), -S(92edd00,f9dd358c,6622bb73,ba4f4760,de3e5727,2cde54bf,a8a6d0c7,bc205f56,eacc8aa9,b85829fe,391ae7b2,a747c122,625b408a,c97f1d46,cd0c8891,eb0d4eda), -S(29811533,8b09ec4,583d1702,5a0b0bf6,b8a322f1,76fc46f2,49430c74,84b7b6ac,f7332c0,3b3c5c4e,bf5bfd9c,1e87d668,8347b315,7f0acc43,591310fc,5792ca4d), -S(b5a4aaf6,8a97958,86540199,cad47d9f,86cc478c,ec43a24a,84722a13,4dd6d20,bafca1a,5c9d99f6,3c986ac5,9e432a49,7c8e5683,331ca708,4326978e,1db66f8a), -S(4e249e10,981f8ee8,b3f0e5e6,c2e67de9,ffc811ee,6d9776b,4cabdaa0,98a8b430,955965e1,7ea5d179,4b293db0,b750a649,429833a2,7c317a24,654806cb,5ab7d709), -S(1d10268d,abf2f72c,2769dad1,dda70fe,879c650c,8ed3b285,8583cddc,cc02ffd7,7d31408e,499940ca,8e88fb4f,1aeadace,fbd288cc,c35699ab,8484be00,1acec27f), -S(3540f96e,fe965c34,dc608016,61bbba18,386b20e2,ccf75f8,a0fd6e62,65b8e62,b0d0399e,35c5c376,7773a848,34cdeb8a,cc7ff651,ab6e2575,1ce81e9f,628bedf2), -S(b1e45c76,35de0135,21274840,8f06efac,4550291,d3151239,f8272640,b7354cfb,aeff7dc0,665692d1,6fe0d607,c996ea0,8134b150,317df1c4,afe97cf9,3630c3ce), -S(9fddcd30,734ef7be,aab9c040,f1ad782f,5a67427d,e457f107,b2935caa,d52ea1fb,5c89b6b,36e26147,38599d97,2f4ceafc,d3dedc7f,79e482d4,478e4cec,b7c4016f), -S(17a4abe3,99579c3d,8504a0fb,427e521d,f6034e48,115dc864,b8ba4385,63d692e6,df5128f7,aea1f8c7,214db822,4738dd89,24e08023,36fcfa9f,d4a49a8e,c09056ca), -S(a7d67392,27d93a67,e7eac9b4,2f1583e5,633c7877,56ba7b01,a983d8b4,d4cd181d,1f10081,e72a50fe,b95b829a,d5c36349,be13e45c,f9722108,8ad78dd0,c7b5d9a9), -S(87b2dfbc,e4301a3e,311d8c9d,23c8bcf4,950f8fb3,8481689f,905d6bc9,be1db1ca,4dc9f93c,c4c25853,93f10a45,31c6cb0c,9607170,49192ea0,9ad09810,3c078463), -S(d2fb6a94,adc47e9a,e68ee0ef,24a1ec07,742f3307,36916c3b,8409de8a,2b546ab,eb44e5d3,970cb849,a797bdbb,438bfd0e,6e6dcd64,83bb11f9,10be2dde,978b7e1), -S(7dd84bf8,c7070b5b,d258da10,e62146b1,b5408b62,d7154cd0,45ca4cd8,81623bc7,cf07575c,a02b6ea3,ef2d4cf2,9ad42689,4b30f1f3,689f6a82,31c63515,6633fa1e), -S(b13fb14f,8fb7bd9d,c2a26c80,aac1ad3a,3d10116f,6ec1a7a6,888bfeba,acefda26,b5314ee,2048c766,af47c814,592c3d42,b143ef88,3470eabb,9629c4c3,5fd70d27), -S(b58f21e4,4061132d,75843ebf,74126a4e,25def37e,1f30759c,1c1d461f,95c29dad,737399d8,b9490cdc,7c0a18ce,3d33d340,c2cf7fbd,78a1564e,1115306b,247feb38), -S(10d3dc81,14156a53,f58cbedf,207026ed,6c74f52c,e62cc0dd,68189a6a,bd577fdc,fc4b7c5b,1f1288aa,698032bb,7b8ba84a,10819479,c616c00b,145f9996,8a4588e9), -S(3890baec,2d7505eb,ab767f3c,8b6ada03,3505a329,791920e5,acd55a6a,ccff5fd,a5ced26c,24fb642c,64d292e,2696aa5f,fbb234b0,3d695e83,50f5b101,6074ef8e), -S(3344cd50,af1eae91,f94eb7b1,168737d,fc8d936a,1fbaa3cf,14e9bac9,9c85dd49,b844c82d,1ef06c70,e7795dba,ae1f1e32,f8ecbe2,6c7d295c,b96433b8,161a0fb5), -S(968d92d4,5b6c2adf,376324ca,2feee09,9715b56b,6038a3c3,c51182b9,a2ecfba2,3e014876,6e32cb,5a1ba838,a5d3c64,f954c3ca,a6d481b4,3c660974,92e39d4c), -S(3f7a1811,751e8bfa,2740371f,27e823aa,c2a23c07,d1f5892b,ac2132b4,c8be745,5d475208,6cad8b6,58cee187,f692309c,4c01f335,c4a561e6,6099ff83,18cbad88), -S(2e5d840d,5e808361,799353bd,a2edef2c,4e686735,f8161382,7f98d94a,a4a4a522,859d0019,a0d7619d,89025f7a,6273d98,25acd521,ecbecb75,195bbac1,6d1124fb), -S(5536c7c2,e29de995,e3ad73d1,6d525d3c,5646a96b,fa931bab,5b96dd,ece62eb7,710b162,6d690586,15e54f97,828f7dc5,527b20a,3273e318,5fe9c64f,86ccc206), -S(d29f9ce6,d0758df,c4025af,7097b53c,163493ba,5e16d5d1,d66414e9,a75fa6a0,af5fd2ab,36975272,bd4eb8f4,83e37b01,9772cabd,fe863c46,53a38906,450cd77), -S(8fda2d0c,79aaee8,fbbf2e24,c9e2a98,e37651f,117df59a,b9c37d62,a4538ca0,dc0fd47,aea5d11f,c64a0aaa,d0a2953a,2762878d,6608d513,8b911d40,e679f238), -S(2e17903f,6b00a556,a3492c2f,cf52ed69,58a53715,950c3cb3,f99ddda7,fec950ae,73c72ce7,6644e080,a0fa570f,32d4bf41,ceb500bc,c328aee2,a9c2b22d,56419e5e), -S(c5ec2ed,9ea6c3fe,5d6021f7,bd475c33,3899edbb,7562d91f,4d0028ff,7a07709,7015d790,a6c3f25e,b9cb4bed,f3bcca04,740daf14,da1d3008,463a8f28,6bcad698), -S(b8deae8b,299a5a56,24dc2931,c9d4b63a,361ba102,c5e4e2d1,fdc17262,e10ea72b,40e8ac66,b37a8bda,5d30e794,977b3d40,d2af7b0c,276ad346,a0c10273,359fe18d), -S(66e4daa2,5442fd81,500071ec,51a2843f,ff19b706,8a8a387c,744f295,6282ca65,16a75c2d,bd9d5317,e2b2094a,a85c95ff,87bf3c9e,39101a0c,1bc743a3,70b09380), -S(237df4c7,cc475cfe,7936c17b,dcbddde8,61f37e34,93e4f3da,40d9466d,eb2c675d,170fa5e6,156a8c60,ced37da4,c929fe15,e6d8c691,ff99850d,bdfa8844,38968873), -S(3290620f,ee694bac,64b4af07,25beb94b,9bbbd0ba,bd9c7340,9129d1e6,d5d8da43,31455278,5f416fd9,5bae000b,9b5eebab,65575fa6,9a3b6ddc,cc2c5163,455438dc), -S(a8eadd35,4d5ecbc0,cde50b55,c7e21304,7a548291,7d979b32,94fc138c,d9dc4cff,94dc973c,962b25e3,9aa324c5,8f1c9349,9190eae3,8c869896,a0e62dfb,222255f0), -S(14cfbcad,83d44db9,4194e0f1,bc7d8650,c3586ea8,a362e1cf,f044d3e3,8a5a3ead,348713af,acdf1749,bf27a162,9baf1992,2aa62412,ca2e84ae,85046366,95acbec), -S(99df52dc,8f8daeab,5bf8a48f,fb8c4368,7f4ea8e2,b7feb3bb,fdd6e1ee,59bcda5f,3c6a421b,d7631546,d3fea7fb,6370e823,999c6a58,c8d4f60a,6362e590,c6114825), -S(4c420d8d,7d734ff8,220d9335,ede52153,4673dcb2,c4af920a,aaa691d4,777e0e61,4ec2028b,811fee0e,8937dc37,9961ef93,d7a04147,72a2a45,1e3f64f6,ec5c37d1), -S(485b4e1b,e755e864,ba0b7505,20ef3fcf,a58e2fe5,5b6f736a,6122ad9c,160a6ad6,56adef3a,b8d325c5,c4b30910,cc7a85a0,5a326195,a39a3681,2838d5c7,e3dce17d), -S(8d698df,4acae452,26ee02c6,18c04d33,4e11ec3,f0ec73b0,6365b46d,2e61e478,bebc1c0d,285eb1c6,bd132d29,5786198b,57650a92,f6eb951,a99bfafe,b06454ad), -S(d0d4db9c,4f9b50c0,dd8612c5,43b9d535,8027c081,cf27986e,cc4326db,16526a12,43bdadb1,b7e56e62,2f10f5d8,169a3198,30523f7,908a679f,1c78bf26,6c699c53), -S(b4aaa39d,50e18cfa,743e307d,8ad30f88,3f8a86d6,9f040d03,de008e10,b66b8060,ebce9bf6,8be9bc73,29e1ce4f,ae1a904b,2e1613a2,a45c8095,ed8e346a,6a1bb53e), -S(28e6c590,5af1bcb,f3a81492,37011af4,2e46ac15,fbe0f2f7,a19ba76f,e7104f98,82ba4bc5,4b20238,12256511,b1335079,b21e97d9,7698ffeb,723605e9,c200fe67), -S(b002b5d4,2a2089b9,fac121e8,eea8e240,2ac5b8dd,77f8fb6f,68b59c2e,f2b45182,7eb16bec,99d2249e,22f89e48,11c51324,99f2b7f,e6df592f,7ebf0fae,36130449), -S(36e9cd9,8d1335ab,90d58af9,83f7736b,e317c3c5,c1f0d702,d43c32cc,916719be,df8a57d0,19c19da2,8fa517fa,749f6cd9,21e19b53,dd97e255,1eae0b93,fa6dcdd9), -S(f89c103a,bccc8040,3684beb0,ea56ba57,b447442f,bf3fe918,b25be9de,9bbb225c,7fb1eec7,855ff2dc,9029e712,ce0b619,a6809a7c,3068acd0,1d275dc4,41a55847), -S(5f164591,cc718471,7f23615c,ac67d055,268bcde1,bad2e211,7e235699,4074767e,99aa6bc3,3979f79c,9765a053,66c82dbe,6c067ae,539065a2,4ae37579,4c5a0eda)}, -{S(92133195,a4fd0c59,7e0cf65e,8ce1d939,e333f7a8,441523aa,31e339e1,2ae51e8d,556a388,7a7d579e,87de7f49,8c54bf24,2ca4b8a2,8b959e21,ceec4555,b8fabccf), -S(e3b58edf,cbd6615a,dde1978a,30160514,80e9a335,1ba66cd2,a4e939d4,f4cce6dc,8d493750,a60f61fa,ed9f680d,fa8ac946,d765ab2,1925675,d535e60,b124b12e), -S(d7dc081e,9409bf1,ae46ffa3,5f9eae76,8a92faf3,4a670d76,487b4334,50c2959a,77737006,f0021115,9c81a55,b58da8f5,5f056493,6d319eb3,9fa1a9f2,9ffe1696), -S(ad4d72d6,768dabac,d7c40d1e,b88d5978,46e2f335,8721b980,f1f4b16c,bdcbd829,151a1ed3,ed7f999c,ab836e2c,665212b6,fa08a716,35ee1061,d650735a,3020f89d), -S(325cc8a0,c03e6d53,acebdc12,265ce043,13d69ef,ae00b17d,84df58e0,a3005759,2effa974,b24c0972,84f2cb82,b48c7460,3268ef06,a117aa4f,66d080bb,20ac77ff), -S(38e08a95,fa799d10,23d33d41,e5f305a7,eed9cf69,5151099e,cab0dd40,861b094,3e2c225c,e2c7d8f4,cd27e9bc,50015cb,3714e4e3,2feea2dc,3d275a24,997b7c08), -S(d477d862,f7572311,73fc315a,35342791,319b0185,4acc9ded,6bc71fbe,ac866aa2,c869f5b1,cb084021,d2379b27,d4e5dd7,5e88ecab,765a1808,4664ee8b,74b23bc8), -S(56a5b347,f304a6e1,13dd27ac,3ad1260e,8e65265c,31a95f8e,6d58a893,d2afed47,43c3a208,c6965fb3,397ad3a5,3d335b11,647af4cc,9ca1f4b3,1dd7cc3d,f11b4b22), -S(7755d5e8,bb6c946e,d5a9bd6c,1d3f1675,b0bfa137,3f69f92b,8f0f64a9,baa72e69,1126edd,f0f0d7d7,18128faf,3a988899,a7e2caaa,901e92b2,312f2658,f24bd0a8), -S(f010342e,3b068db4,79325185,ee3198d4,1cfd61ae,e1f2fc3b,e9552b30,ad5a1767,132b3929,a59718e9,addcd814,99ea1f69,941bb18e,f26b3ac1,50b9324a,eaa58001), -S(1f994727,6e3ef21c,2eee65a4,38fb451e,bc87028d,31ff0769,f9935095,efd3e347,425ebd7d,4d6a6a1a,1b32ecab,7be89b36,1f333206,e1526523,991542d7,b23cdf81), -S(eb0a70b7,ca8a1289,e57b3a86,9f21adeb,1ad77d21,9ab64d0,10716f91,3c5fd2b9,dc03531,46af152d,b78813a,bc402c76,93baece4,e57cf68c,ea05b6b1,ca6be07e), -S(b46e930e,36eba93,11248490,4fe0504,91cac0e8,5caa4d76,f35384d8,24f8637c,8f2e844a,29cb90b5,580b74b5,b16f07bd,87385834,23b61485,e3336286,1817c92d), -S(bdf5b431,db844804,70eb3188,6380085d,76c89d00,7bad9990,f28a4e04,e1bad223,9b71ff3b,8f13cd83,b493c150,67d91f38,6341cba7,5f711276,bf768f3e,229c1e55), -S(a4aec29f,3aba4188,e6c73e04,14e8c538,e482491b,6d1d01e6,9801c580,fdefe920,135980f3,b38cddff,e9f7c0d4,87f1b44c,c83c393e,9fe3f8c5,ef6d7840,85a11013), -S(4664f7d4,58ed1845,33ff308f,6389282e,ee336d05,28dee862,2ad54d31,9d1bd536,d774ea2c,9346db82,edef5940,264d2f47,da810925,ec1492dc,5f3c5887,e0015f58), -S(1732bd76,99c1b718,654ca447,5a9851f0,f46bc444,541239fc,54b9b053,e6cd8d61,db1d259d,15dc772b,608957e3,cf32f7e9,b076ec05,3be1305e,c2b8c9d9,7aedf5fd), -S(8e33f8a1,22c90484,7303d6ab,d80fb29,ff84bb43,eec9ded3,fb643482,82f9d4e8,5d1b2f19,30758a1f,d35d3993,598db1e1,d8514855,c23ab82f,245abb78,77f0eaaa), -S(4d96af74,6c067b61,3dc07f73,7eded3f5,da106daa,8910d37d,f9d8beac,962ea02d,74939d7e,c345a59e,567f8046,bb400efb,54107096,8fa45412,c327e10b,3db50b1), -S(478f6fda,3e82c5f1,d65caf64,f80a8341,54428fa0,90dd3833,c2a58cfa,dce5d32,1cb8ecf6,2f7cd442,8b9b3f6c,b33a42b2,bd7c8a94,26e35886,4e1a73d4,65294226), -S(9f7b432f,c89b4f8c,98966a60,34ac0218,d02cd505,f888dba0,55688463,687164b,9d18be19,871f002a,b4518835,9730000f,15446136,f8803657,51987e10,571e681a), -S(c3d1eeba,d935773a,7f30d379,4e5405bd,6bbb9990,26d3d745,78294c0d,c32a5e2e,8857248c,674c01f,4124bb99,3d5b261,def62594,7facb651,f6bb5385,2f5e5674), -S(40a419f9,180b3e76,dddd489d,eadefab3,b3a53abf,8898e5c1,63221606,d7384ed2,53f5382b,a73b7d00,a5afb12c,9345afbe,9c5e5134,cbfe1d9e,81bf3b59,4dfd6b95), -S(ef7cf180,fac500e4,32a70987,989efd6d,d527ddef,779cd09c,589b7e19,747b5572,7b540c7,c2a008f1,8d5ac610,96743cc1,56e87270,5aa2dba8,ac891ea8,bd6b755d), -S(402422a6,8b33b370,aa5f4d57,3a92aad9,acc9be9,2e304de2,73aba72a,d2a8c4b8,351e81b4,4a250b81,5abd8a73,f23ba0fd,a624970a,59076ed2,99667c52,6f63e7cc), -S(1b101d88,9f802cba,396dffef,4eed336d,24138432,12d21fd1,dfd56765,befab1de,b51691ae,f6589bf9,f1d47e2a,c29b6e95,ba600e4,17e48801,aa8c1c36,fac8dcfa), -S(1e82a9b2,4458de28,97110749,dc63f744,94dbc6e2,1085afbd,15c9317c,e3b0bdb,72ff3c57,cf1c18f,64127651,2959762a,83a77db7,2f7b261a,67b1f64a,bad69db), -S(3e5f2f47,a3b6e9f1,69d67e79,39ddb4a6,3ff4d6b,e85e7855,9eebb19c,ba5dcd88,208bd01e,5ace2579,5ddbf6,b57ea49f,aac3aea0,ab3160c3,62e1436c,c545c7bb), -S(e0aba818,cf81f784,ad2656b8,1576ab4b,91a4d0ef,1145b359,393b2bf7,5e798cb3,52f41c6f,3f49e3d7,8031c7cc,c2d4197f,51d53167,7a2b3034,20f2750d,f85dfef6), -S(115d9e1,1d6ae4e3,7a28e641,4704361c,f6422288,a3044b19,7dcfb54f,e76293dd,81c06f64,28931504,21f74c52,64adc217,9c9839d0,9e2ad42,8680b289,64d7f8b4), -S(b742c7f5,60adf44d,a8ad0f43,30c110df,488fc072,c6029911,bb60196,6098f26b,f683d248,d6ad0724,2d1187ea,109f89e4,b231331d,5867a009,26496d34,e7fc2b7d), -S(d8d686f9,2d5b3e5a,90a6b33b,f6e22fc4,e4dff29c,c8e2abcb,cc03d1d2,89d8ac,817b0c58,8e768884,6570da24,12d4dbae,c1649e4,e87b15f8,fb6ca41a,dc90ef8b), -S(a2792c2d,f53b4f8,c4d8da47,1117e7c2,19891016,14e6f8f3,cd40e74a,1f079bd4,bcd3c49e,fced8a89,c5a22469,8360d91,e55c7752,b3c0b798,ffeea98b,373bbec4), -S(2aa4ede7,9b0e39e2,2108d839,a1a3a280,e69cd9da,3ecfc71a,b3ff89ee,f921feb5,8568355d,eb149d39,8d4ba4f3,bd1a36d4,d7e0320f,8b3d8c6a,c81479d6,702c5841), -S(ab965917,6927e9dc,20ef1e6c,60349cda,947dbe9b,79dd2402,f5fead7c,509c56eb,2cc227d2,68174216,abc20792,12eda585,2a91aa1b,e5e141d2,a510a165,405fd059), -S(4103c008,71a071b7,f628d6cb,123c0c9b,2c91fc19,e52e747c,a35846cc,71a9baa3,8aa4e7d9,ee8493a4,ad092826,1377f4e1,397597b4,f63dee00,cf379bc6,92ba589c), -S(972734a8,6a5fc831,6745ab81,5487dabc,51dc150d,4747ee8c,b96de185,4552d1e8,64341946,6c2ae001,49ea0ee4,9dc92692,9ff80e7a,649bd30b,89030606,319a6fa2), -S(9405e5ea,569e492c,883a5035,ba768b83,79fbd706,bb4171af,b0a7480,7069c796,ebab6dbc,4dc6195c,f0fc9b24,82cf324e,3b00fbf7,c4773677,2f55c2cb,60109c6c), -S(c9152518,b43e2f9e,7565f8f0,322eade9,83c5bddf,dc85a120,8b18c6d4,b53e2cff,33a5001d,26ba5f94,19602e75,a0cd39c,c6cc7648,ab9338c6,a796f68b,250f8bf7), -S(1069e550,becc5618,5bf3b627,9e70db17,5c2b98ec,8796dbc4,ebb393c3,95fc23c,cfcd8ae6,b94cfe4a,b3856627,4896faea,ac4db81f,3137c2f4,d14bcffe,26255ffa), -S(e1d567cc,7a7e3b86,ddfe4143,ddd5ebda,41e731fa,68e84445,3494507d,642aef46,7c6355da,fcf15ddf,8b143c1d,542ac5f3,da67225c,d1eeefba,ed24eb41,698af892), -S(b12d2da5,72556701,4915f7a0,f19d0483,452626f6,d03c4829,9bd2fa9a,633d2ca3,5b3af65c,1ee45b4,51a1be81,db8654e9,62b81470,2f162b9,5b02bd2d,313da49b), -S(b8bf7426,e023d1f8,bbdcf2c8,cf0d1ca,3bc14c46,c25ad34e,30e37538,222aebb2,20311608,cca061d4,7daf2293,ef087cb7,bafdbf51,b6fe17f0,f2c676b5,596120b0), -S(30e2ab2b,4d4416f1,56eae97b,15df3e89,8313bedc,39e224e,2875def3,45ebf7e1,a9a5c2f5,bab83663,463a5ac2,38d34f2d,942f0864,9f013068,d5fb43e4,3aa9cac0), -S(b51a0245,335f2b69,ba346bca,6e262ae,e3bb9483,2c4a76e2,cf1b0a43,24398a06,381aebe5,9c57447e,e48a5615,2b8c1ae2,36e1216a,eab9fcf9,f4608c3b,d5c1bed5), -S(16ff6ff9,ea6268bf,fa04d0d7,697f08c4,1717ce6e,6956c14c,bb1e7088,32ded621,a30c4501,a9791b68,15d4fd1b,9b6c943d,8af81feb,b995457b,34640389,eb312a), -S(75a9b34b,80f56b8f,843fe73f,f0a522b6,b32941cb,a892948,be3a649,ab644ada,55c90f2d,e8ddccf5,a896fedf,bd1676ff,11e537ec,fec1e99c,3d880705,93794d9b), -S(e3d207b,fce3af45,7c93e30e,fa54e879,dc00b005,481775c9,1d2195d8,3c0be4b2,ea97b4fe,989166bc,eb7485d8,50829a7a,ce306586,a34f812c,5f30353,9f46702d), -S(4c133100,4af7bfb,d9b25296,64c16012,aa5d2000,167c5ec0,4560c44d,5f424139,4a68e2be,d1509b05,9839d1bb,1e96e953,cb655fa1,1da92569,8edbd940,5758296d), -S(cf6da6f4,eadc1ed2,c4e5c161,541cd6d7,6c3187e,2ca791b8,2fb20f9c,4f8bcb0b,c9fab960,ef26fed,75259616,ae18156b,3e5c7ab8,73a08a65,cd199de7,f743a492), -S(70348438,bfb71d5c,c0ad51d6,d6dd5b01,1694c9a6,d759ac00,72c1f3f7,8e6064a7,1c825ebe,cdf3f546,c731df,c03a7bfa,8101f864,b8428461,36beb2fa,a1d5a916), -S(505ffdd9,f57bb5fc,1e32c035,6bb7f655,793f3aa8,1d34ae77,68a0fcab,73aff902,7ae3363e,36fdebc4,f5d91f39,cb92dc58,a772741,c0191eb8,ab95575b,ac32bb79), -S(a3f102b7,1312ca94,748f0364,1f3e15b3,bb41d1c8,8bb9ea8d,b51b4c9b,4fdc659a,1b1506f7,ed9bb787,7e65f94f,97b400c9,bdaeb208,5944d4aa,c70906b6,6b8e85f1), -S(21f0e0cc,35288167,6cf5df32,fb7f1d9e,962366d0,ed994a35,5e95d68a,1ae73664,13b8d4ee,c089cfe8,ce0fee41,67f25dd5,bc165cbe,c178e80b,d4d7b57b,b0f26f85), -S(6cdead78,97b40a6f,ab7c0e79,66f930f,ef8a2ea0,f8b8e20d,6c832aa0,6476da10,aee696ac,24106a15,2350a75c,aa45a230,c55e3eba,413e2251,719ed8e4,9bbedce9), -S(ac3d60b1,c5f1d942,17c4165d,45efe2eb,889917c4,8a9e650c,e2528893,ea23d48f,791c1b86,6e072f43,78221fc5,b62c5c97,4a601a97,57f130c,787a3401,8bea3f6d), -S(74b31ac4,5ed0eb87,36380b35,e711c93a,1ada56d3,f4d878b5,ca04033a,2673e0a0,818c0254,b96ed496,29724ffd,cf71501c,f37d57eb,93df690a,4c7fce70,a100fea), -S(b4ede440,f1561150,4e25aaf5,e415030b,3542680f,45697539,6c91c85d,aeaf2be5,92ac0c65,d90063ad,793e78a5,6e94211,392b5a72,f417fc5f,d1763228,4ec2cd5f), -S(b629a62,2434ce88,6f7e340d,d3fdb0f6,b36f06d7,cf4657ac,aa189793,5e46c413,f927a57b,8eb72443,bf2a04c7,65ba56f6,4c9aaaab,f28fce4f,aa1fc964,2b8452bd), -S(2536ca07,e67d4bd1,2a3e0c56,77e0b83b,35f03ef4,392efbb5,9a08106f,5e7468a8,4eec6714,c83fc9a5,5bede8b4,206affe6,68d84316,b88f65c3,a7b1b002,9cb23d94), -S(30a68c11,93764521,b72d251b,dafd608c,eaec6052,89ca2a40,b3bca114,117667f2,4a79cf91,e5938ae2,31516a5,a6198cf1,531c9824,1eff5f2f,519a9038,76c21b6), -S(aaf6b23f,bc200102,ed92dd61,a8a853a0,7298b004,7699d43b,ee706ba2,15daf366,e9a15558,d984695f,fdfdce2f,5add6499,644c1d91,79e910b3,2d8f5cd9,6df9a78a), -S(aba17c14,424f27b7,324bd29f,b3a232c4,670b56bd,71013ea0,14942d40,c55cfdd9,5c0265a1,963f3679,f4bb7e7a,60919df0,860adc26,b0fc502d,830c81b3,d8000999), -S(7dd28211,82eff020,ff58a4f3,393c6fd,516b52a,9f78b823,9ba92f08,6fe30fef,6893b183,1c0402ef,c162c99,87efe669,58e9256a,54cc4048,aefb5ff0,989ed93c), -S(822f080b,76a98334,55635b09,2fee11c0,4abd6018,73b83f82,fa761d68,5fefbaf1,fba007cc,b611b2e7,37ce918a,ff26efcf,92a17d1c,4e90849f,ce058397,4128de69), -S(e47aa72,50e27d84,ab7e2e8c,a566424e,646640f6,c1b458df,3eaacf89,2982253d,e2a109ea,5e1854ea,951edeb0,bb8dec1a,8adb05ef,515b0bcc,40774196,222a0e09), -S(6fb6cc,902df4a,34a517ac,5feb8d78,33607701,1d5522c9,9654dfa5,ab5f4872,6efd6a0b,f55f98d,9a1872ec,8a4102c0,e7272e62,9eb6e10d,de6f5b80,aa4bc44b), -S(2cf349e,34205e69,79ba5a1,83032a05,76b5fb8a,961636cc,4d1e0cc2,82158ce9,b75d36f5,94df0de8,6cfcbcb4,b4ac7b97,fd4b711,b48f132f,961b0642,a123cf1), -S(9cb540d2,f8cc21ca,d4fb1b,7e2529,389f6a2b,ac1a71ca,d73f5152,483017f5,65bb5abd,91d3c759,924314d6,f9925b47,87413c2f,1023a6b7,8a7bb65e,d43a48e5), -S(b008d6d,24acd10e,aa0f129,58045da6,4a858f30,44b47e6a,1caa37c3,3ad7efeb,808a3f6,12773a98,59342b25,e479b2d5,d28a8c1c,b2597f7f,72fa0e9f,8eab294a), -S(24bef8fb,9a3465bc,63868e5a,74293e70,3eac939f,99bc1fe0,8263e324,96a171da,efe5e06,9018bce2,bb92fcf4,29efe63d,1d624acf,d732fd47,f6b82c81,db028f36), -S(338b7660,385e3d4,65d5cf89,12473b94,3d1cc1d6,98a07910,8a3745f5,de300277,6c419d49,f3df4dd4,b87178e4,3bc2e9d4,9a76c1a,262d9d0c,bda141da,78fcad0d), -S(a53c790d,d8756046,8446a40a,cfe6f890,21f64328,8d4bf979,99a5fa9f,51f4bc22,444ecb6d,fe9cf442,d34b643b,94bb73d8,7fd9d5b6,87907c62,68425c57,e43e1158), -S(185852e,f02e1aee,10d6054c,796ec263,a33076db,26a997f7,2ef01fc0,ea6ece3f,1b8ccf90,fc573d34,b0733ffe,f10c1346,2190860a,f3e79c16,863a3fcc,add7394f), -S(5894b2d5,476f40ad,765bc171,2bc9426a,df05dd54,31b0d89e,b164258f,d5ec603a,27bcb2fe,ef2d1ae1,e2024ee4,b62e6d77,9d4930c2,3badf2e3,84241d74,cab8beb4), -S(56f1ebc0,345c7d51,c0e58f2c,5e4414c3,a264da18,73e1e898,e3e7d526,777b77ba,1066de15,7ef9ad2b,a07dff34,7d430525,528812c0,2593c14d,a0d0a7ad,73cd1d93), -S(5a271684,5903bd72,89629f8e,c8b99ded,6e20cbb2,9d20001f,9aaef99b,c6e21ac4,1b32158,4e2273d1,4f9f2fd3,9f5b5813,526577b5,af221538,91feefff,ff1a86eb), -S(7cae9233,8cc38ef9,a84e10e8,2281463e,303f8b0,44eeb9b7,fff51d2f,5ad8c8ba,69855baa,a2516e72,7a516081,821f2f68,988a50aa,eb9aac08,e2cd5e74,f2aed0e0), -S(31659ab6,1bd1376e,e989ced2,7d22ef10,d6e48cee,5ed1563c,646f00ae,5f7049ec,2634891c,bf30a25b,fc710d57,9b0e2795,dc2175d,5c7552dc,c0bc350c,cb240797), -S(e007de0f,96522c6,52f49b68,ac817746,27981ecb,72f70b80,25a4ba,efbb871e,6cb6eff3,dc6c9c4a,424be741,f6769eb,f325f749,b12cd512,d6d82ce1,e142b12f), -S(5c67fa0a,604b6b0c,19997329,aaabb82a,926b595,32e10f64,7c519cd7,139aa06c,7b5e99c2,9c49b426,e1df9233,d0fecd34,ba5e2c75,e6bb2b2f,8397c00,18d77b71), -S(40f1a163,f1046ce2,3d46cafa,30c3f1ce,a0b21da9,5af03f72,e7e8e006,7f070563,efeccb57,6a86a01,4ae4273c,fde8a661,3850ea8b,658aaee9,d3058ae8,9df8fba9), -S(bc34a35b,303f885d,d3d2f32d,81f81b84,fd283478,16d56674,89750253,9abe723e,79e3b04e,e93470a3,5c8848e9,30e3a963,77fc0704,5a0fcf62,f41f5610,1b6cc670), -S(49695da5,ff006373,2e59e24c,6c2b8b57,b081dbc6,8438395,282c555,ae9545d6,197f0bca,b2bae828,669a3505,e1790b60,134eb70a,aa85c7b6,82210c4,f6f2a024), -S(cb73405d,957090b,9eef27db,62657d6a,ec058e08,e9e51513,a63780a7,15c3c77f,80ef26d1,deb10417,a2a430ba,4501a722,8eee85de,c40c863b,a88ac3e4,814fc645), -S(40f1a629,1a37fba5,a9992ce7,a9af16d3,ca57625d,1e72c218,bdb71efa,d6ff819d,fef17320,d4f318f1,e6536f75,c104e7b7,fd5d23c7,efa0ac05,5ab28aa8,9861c05b), -S(adcedea0,47371dd9,95c2d169,e84df39,7b91b051,aef5ca5f,e759afe5,e30fb54a,986f4ab9,dcb46d,676076f5,46ae4f8f,55393422,95d33c0a,d4177ac5,bade6dce), -S(56f92765,41af201c,3e9f428,e7e23b50,7dfc84f5,b36e40ba,41f1f3eb,610d9e0a,c1b9bc04,c9e7412c,c8f6efaf,c4c8ff7a,59b76a40,d2717a5,ac6d9270,12ed62ba), -S(208efb63,23799f9d,a69aae92,d7921ab2,31ba1d9,1b5d17db,f6f061dc,30395e6e,4765abc8,177f4765,810c0fca,a125d72f,aeee8889,637b169,6d843d97,51e0e5c0), -S(271893d6,a36b984,878c40ec,45459e3d,932920f6,257af8a8,a5a11b9e,43a111fb,80ce0758,847df058,1c7d4db,6c62eda1,c41e3b3d,33d6f2ab,2efa949c,36c0fe0a), -S(a6ec4e2f,4937a358,91153a45,254e22a8,dd5b812c,1333500,321a62b5,af4be98e,db55a35e,575d81d1,41da4bcb,12a5813,65c12f37,f8ff0164,feb847e0,e49dd86a), -S(1f5a1cf3,8c4ddaac,d12deac4,efcb280c,6d6cbac3,901fecaa,a64d570e,9ebc68d,12c7fda6,5997f8e2,b4b85d96,9d9ee069,1d084761,25a221e7,cbea891f,6993153b), -S(bf41a276,99dc209f,79c80dcf,a5812086,38c7409d,cbf4b842,21869806,e445303e,d375e246,a1bab103,3a89c999,ab89d82b,7bc50961,ee500c52,4fb6eadb,f4e04104), -S(8375c69c,bb4249be,77bfcb40,8ae97e2c,db6cef39,7e265ec3,85987a60,6b83d8b9,3d6e1864,8f105178,7817858d,791938e3,7b6d8f98,ef9f627a,789574ab,c5bde6c3), -S(4872571a,c44368c0,2d0ebbbd,a82ecdf5,b451d428,f3f9f848,28046f01,19d8c41f,3ac201f4,cbaaa772,c7afd2f,1d942d29,2a0c705,90da811e,789b7aad,ab49a7f), -S(2c24eb5c,124db868,235f333f,c3453e49,5dbe9215,5b6de64e,ffcdaaaa,4be86b86,6f520dcf,35dcea5f,86edd00b,7b7e4903,6e414e2b,f643ece9,e22431ee,9b3a9d29), -S(aa70abed,8c5e973b,a21a038f,37d36ab7,61b0da01,636e9cc1,67cf95e6,78c07330,b4367401,7226b35b,1def07e8,c02b272b,8975ab77,7e8d7c31,10a78db9,94fcac34), -S(ab317750,1b5a627f,45a57b2b,38bff161,aa8869d3,a034a5fe,35289a60,e5056b0d,783adc21,9b1c0173,9977568f,234a3cf,4f05e91c,cf07fee9,71bb55f0,e379ceab), -S(d8ae6ebc,fde52d4d,c482acfc,ef231d62,637f4bde,71c32ad6,8205ab30,9d66c013,f75f1efc,2883bce6,ce06d01,1dd86796,77ef971f,22a1b5ee,1c08a3b0,2ecf9cf8), -S(949dc802,f4d797b3,b5f40cd6,a5b3bbd9,c98e579b,7a4bbc20,2770e4c2,f737c1dc,a1d1dff4,7b86235d,b16a88a4,59596ac6,6634bfcf,ff92736a,7b7aa081,2c10ef89), -S(8b0fa15d,59e05495,47dfd98f,5366571b,91355f8c,c54d78b1,b50ac4bf,ed31e633,4b0215f2,65267379,10855e46,1d8abeb2,71c7baff,170667f1,962c0954,6480baed), -S(98707fae,93b85fb,23f0fc23,c953ed7e,68fdb5d5,c7d29c5c,1b130193,400f3a47,bda56a3a,97c9d049,78bb228f,2aa3b6af,59fbf9a4,b0ea2f29,48304fe7,47a654a9), -S(df34cdd9,cc111a99,66690fc9,a79cd621,66075104,dbc40423,69a817cd,8e94500c,29ef5a11,91ae6c3a,f9b959e2,423523e6,5a32e254,c924a416,a41361f7,df7c4351), -S(c23fd61,b07e8fb6,a528733b,f4ab486a,292901,eb4f6af1,2b940af9,49e80811,a749fc6,7f340cc4,71056f0a,ee59e08b,ecfd98b3,cc978477,1eac93fe,1e2831a8), -S(d8be2fba,6d2970be,cf3fca6d,3f3ce70b,a4eb5e19,61f07223,c60853d0,bdd99e21,b03144b7,7e6161a1,a35a01f5,2474872,6ec44cbb,cff5daa8,53de1524,3d5d7c48), -S(beab3690,382f0fbf,e1ae999b,1c12a04b,f421e94b,ddbe0d78,a287c8f7,9de0a903,91168177,fa3af115,e75a4e5c,b399c136,41793138,4d22a85f,982840a7,89d59082), -S(72b16aa2,6df7b6e,9b6381f6,8f3e153f,da872dd7,16c91f66,d04539d4,bd8182b6,73ff3867,2b5b7008,6db53e27,2d7e2969,c6522666,cb544607,52aa6bd,f6a6a28b), -S(b25f6e67,169d5375,3b3c0e43,a8a1dc67,33ced5b4,95902ebb,4187277f,cb754f9f,88657428,cb2e98d7,8ca80ab3,a52cb043,cc50bda,3e0d477f,b12aa478,dad14016), -S(c5d724e2,1eeff913,fd3bdef5,10c963e,77fe49e0,18890a24,fa2832c3,a8b61905,f06907d3,ac8982cf,63eee75b,b9ba739d,e80b819,32a3e978,a3702a9f,256e9f9c), -S(c2ebd113,ad286a61,fd8bb092,ec4025da,67a1606e,31e023ad,f0f7d8c6,e18b5e61,f5a5e5c,defff7ca,722b9fae,e7182953,3191ccdd,cdee5536,f2ae31a4,48c6918b), -S(d6e1a1,62047343,aec39c67,65f07f2e,d0bd1b14,256370dc,2c90bf11,7b54a82a,75864f87,9f5bc30e,afbcd624,71816e3e,fe9c3aec,ae631dac,e0cc99f9,702f7ddb), -S(bc4fc591,c3869b15,8401713a,e545061b,94675162,8757ff17,a52d200,f6f490fb,8188af48,51cdafbb,a85fc8d5,5129dbaf,53642f19,c0ad555a,8385b0a5,c82860e0), -S(1748e74f,610d6d00,f299527e,9f09b30f,271371d8,7cea2ce5,e092416e,7823bc5,5ab591e7,4cbe7756,9fba9944,b84d8f60,268d4824,f73a05a4,9103817e,5c15960c), -S(cd5827ff,853b6997,b3aed60f,829c5fa1,5a6c8482,f4ab123,eff27af0,3e145f6e,3e7863ce,b6101b67,243b1c22,73824acc,212d9123,882310c,970c6f4,9936cbd9), -S(d61d636d,1d5db74,1cfea51b,59d7b870,4566c733,e8bfd023,a152fe0f,bcbe9c95,fb94fda6,36a9c976,2cd6e1ee,81bf6fbd,a5f033ae,1ff7db06,3c31b045,5674e021), -S(2363f1d0,735814c2,8ae1c637,ba838c00,601cf14,d99dfbbb,a1e0f45c,75c62726,f340d59b,44924783,85235374,729d4773,365943bb,21c78b65,c8d7a8a3,f1de05da), -S(45013f55,3e53c6a9,aba8d265,696ba61f,45e15c9b,b69a578d,57a2559a,cc7441e7,ea2ef736,8dd1868c,34b6a65b,6f451f6b,3342d2d7,f90fa2be,93ccacbd,6e6f5d0d), -S(8fd98d99,6bda42ab,ecc672d2,521921a,4c838e9d,760f0f06,25523dfd,2dad54c9,ce29f650,a59a61a9,5955f9c7,c4e1505d,5d795caa,4cd5f81c,290175d0,4e48cc97), -S(d9af8b8b,3ce2f4b1,70979639,db524cdf,a68797a0,dffeae55,e0bb9e60,9ddacef6,898eecd4,5ad6bf9d,55e2e658,2387fc69,d1acffe6,8603ff56,68a06597,bb0186fc), -S(f3b40480,1e1588bf,fbb524ca,9dae6d88,c96634f5,aa163adf,ccd9fd9b,dc78d8d0,4951b9c9,31a7f009,92c808a0,cd7d6c66,fd6dc868,1836c577,d61b3783,39decd99), -S(feeb0e91,e310b9e1,b8c68885,b6c1c728,31a6c29b,f93a733e,c8c86b43,2f576b27,c43851c8,46c3ba4f,6b84f039,6cd4e20b,3a8d492b,57970b8f,2df52534,ba1fa2a5), -S(8aa75b71,79cd7941,1c45f803,e0e76c01,59972566,b24d7566,3fcd1a17,8a0af8c7,f050d1a6,fc082a7b,6c342cc1,f7221042,373dce2a,2b055638,c49c5900,85b97fed), -S(44e9ea01,b7f3058e,f878a57e,8a9ed638,b6fb5730,aca25b8b,e92ea856,611e3b78,e28955c5,2a5ec160,185a29a2,28b587a6,6ab207ad,70236a25,35d0df67,44b48d7b), -S(7533e418,ad594d1,2cfee794,8894a09a,1e440b6d,335d9019,78416aec,5be9915e,312b4709,605c94fc,1215e513,ec13d2c8,e04cb150,bfed209,e848e247,485b4f5e), -S(682d72b9,e5ac04d8,23d7f275,ced51d52,6f8441bf,2b290c40,1e31e6d2,91392bd9,96a37870,6c3e7c3b,ecb70,dcf3aa02,902bb466,9db00db1,39a5e8da,1cb7e749), -S(79aa4b03,a9cfbe13,b7a9bafb,2e170b87,7dc29832,ae4c33a4,6a4e8957,ad2fff11,403a3f70,b165471b,b120e22d,a78d964a,f40b6712,1535d44f,769ef4ea,ab0827cd), -S(73f36ec8,1fd92ef2,f7a7974e,9bfabd08,2e8af24a,4589336c,9f9d72f4,e903f164,9e351dfe,ae961e77,8f617b33,4faa021e,db206599,84ce85e1,53b3eb24,bf155584), -S(c765b554,2a70148d,ca6cb008,12364451,236cb8b6,f2f389da,8325d283,1385555d,c7010bcc,54c1cdff,8cb53644,59916a7e,90dd5c52,e5ec450e,5bffd621,352f9aca), -S(e3b41ae1,42c61c16,b798aeed,8fd85c8a,1ce8bda4,c7378511,b595b1d2,1ca13278,319a4f8b,b36842cc,b4bca0d1,f30970d1,491f1191,b96bdab8,c460230b,4d79ad87), -S(e12d6ec1,6db77af0,2f6487ad,2e07348f,f09e0db4,61b65a48,51381bbd,c0adc704,8d5eb2d,5dd04fd0,a0a62c1,4dfde904,9345fab1,22b9fa08,d54ba78d,fd362179), -S(222174f1,9fd39456,30239a89,1555950e,c10fa208,fb2699ca,311a383e,a92fbd6a,47681f6e,517eb688,c1c5e6ce,ede55387,d6073d3d,3e838121,1324e7a4,e7a9919d), -S(91686e4d,30b99146,e67f23bc,5d0c2e56,571fbc55,2bde35a3,33360ec2,8664ca33,49792737,7b52d9d3,7fa3f737,898895f2,dc6b5cd,e83c034,8876451d,671134e6), -S(ddd308d,5e6de51f,4618dc3d,5ac91e2f,bf449a6e,3e613d47,5419a018,bc88f5ff,9956918,ba5f5ac8,cc155ab,c617cef3,3173fb42,c3c2ae46,e4ecdbee,9bfd4379), -S(ed320f14,1431b13d,b683a4ec,e2b82554,b32f8c8e,fa626ba8,dc9769ef,f5aec648,90d63300,1b6feaca,db963593,ed87f370,63f58a93,1712d88d,62ea3cbe,1ad502ee), -S(4a6fc424,aa5a3dc8,5e3922ff,bb25593b,a74202bd,c8a3aefb,495bd516,54fdd47d,8f32c810,59df5968,8c96d558,64df667,b1e17252,4f48fd10,801297df,325d0370), -S(409c3ad0,16237b76,e4f61caf,16788c4b,f8b8f994,f82435e1,c808a7f8,e88a0e1d,3a2a5354,b0e8d2d6,4be8004a,287e27c7,ea1d1b8e,d6b7e542,4ffe878,de81dc8f), -S(54cd117,bcb57ddf,67ad286e,fcf49489,5e5351de,95011a8f,2887967c,a2d89b3c,c4967891,b75792b6,ec631929,8ee79bd7,79f499c4,7282805,dd4270ce,672e3c12), -S(f31e127d,fc904fcf,9f38aa19,e3d797d6,83cab4c5,a36be0d7,73e69267,785775ea,1c57ef59,42b1046e,1ae1b2f7,d20f3330,1441baac,eee11a40,905315be,165caa10), -S(a0260e45,b9fb584b,1a82262,cc07a5a9,67dfa2fd,f3e7d748,705d87c8,f46d4b65,8e519cb1,1c634aec,67f682a5,72a93009,a11e91bc,e7182c47,19af78f3,bc171806), -S(f8613bdb,882250c8,8f755bd3,86e31331,8cfb410a,ceffd9cf,7b148ed1,c19b6ddb,aa36adc,3d036a3e,4188eba7,321845bf,26350925,392a9a2a,763e6d5c,da3264b9), -S(9cb8fddc,93df0048,eb5919fd,52e29385,597238f1,d7eae596,583727e7,439c0de7,c9f3d25,5cdeb940,c8cbeed9,92ae5bfe,f9be9d7,d81b32e8,a2948d2d,7014db9d), -S(4543a84d,5dda5cd6,af28086f,ec4b916f,9ba8ddb8,d6c1a4d4,f1e242ef,805cd5c7,5ab700d1,a4a4052,a137778,f5691683,824c6596,44f4b206,4f1f58af,9fbb34be), -S(a33279ff,9fa4e088,13d36e4e,e6be8892,7bc36723,cea3ae92,c059a7b2,cc7392c,b47fd3e,8dd3edd,384f98f2,572d6020,21289abd,b05a0d38,58f0c557,15542fe5), -S(2831c5ae,a01f60f5,55763206,9b0e11b5,e88c01c8,7dc81d6b,c4da8497,f8d34d26,4557f90f,2bed0c05,87bd7ea6,92db50b0,dc12c8ba,a9ffdc0f,972e0e8,9481682f), -S(f8b84c2b,18aeb807,5c001f20,e55fb13c,bff76b0b,fe7defe6,9d985f32,abef4127,46258945,3a074620,df7352ef,cb5efcde,23982c5f,3e706272,52cdfa82,6b2c127e), -S(c47328e2,8dca9f9a,ad9dd5ec,1c9e5038,f362a491,46c39de2,dfc6eaa6,32602264,4e0d731c,834a4a3b,6bd5b3d8,66c1ad,1afb3627,c641fc29,6c1adf2,13d6b313), -S(24980a0,6f177e94,7b00373f,1b7985d9,88d6f715,3647090a,31efc04a,a6fff347,62d80bb6,a4841b41,4d6c8ee,bf626629,2b2a505,15fc158a,7d00d470,63efdc1b), -S(c1c03eaa,ac9c665e,cc4081d,fad9bb3e,a8f38453,c4dd54eb,885d198b,5cb9fae4,ca769550,165fbd81,96af4fd0,82ac3a42,5bf75be1,312f7d05,f5cfa9dd,d20c89ef), -S(14cdaa50,b4ec0bc9,5f609133,4698395a,c204fce2,62fe04ac,5f010826,cefaa818,52008b61,3f289f96,1298c773,2938e44d,2607b5ef,8ceef7fd,8f89566e,5c5d4ff8), -S(9914f9d5,f45c50c5,fc4c11d6,d2aa2751,29880d53,7c0a3618,17577886,abce07a6,a4d71a54,3e5bb9e0,664bc22f,86c146ee,3077764a,fb5a0017,41405ad1,50098d84), -S(5ba84c73,de6b3cd0,df8aff3f,c907de14,b73d21ff,dd0236ee,1eb6e83c,b22cb97d,759c472e,55b3c84c,5a677fcc,19dd56dc,14f88be4,4df9b18d,c0395648,487ec1eb), -S(5f0ebbee,3d20d7b,bdf0681b,ec525604,e95ab69c,166a5ed5,a3b38790,7e2a1c76,2ebf4d70,652ab5ac,a932d68f,7687f284,8be58123,701e6e78,1995a10f,c49a0c32), -S(ac1b8b80,3d168f58,f7498d84,d771ab77,2af1c5dc,fce17fe0,f024409d,5a3735b1,57232c98,5f2b2947,82fa66f3,5cfaa879,36bf2fe5,7cc16e43,3f2ecc1b,508329), -S(ffb18dc7,4644086e,51a6ed2b,b6756b36,69cc9e05,e1599ed7,5678437b,816f8656,3dc8b95e,213dc14f,4ae4576e,80a07ee6,5893720a,62f3d45f,bbdf2946,9febfaec), -S(f80b44bb,1a268d50,66b0aa33,6f0cce05,ac025e05,6bb167cc,c3ee3256,31782edb,10d80583,d4288202,a1c7c543,90373965,bc67191,948c4833,1c629f29,2abf2c02), -S(20131423,d27cc837,a520a922,f5638314,11a73ca1,ce7b5442,c557a341,c0fbbab2,7b6757db,16d6c286,44143884,b76fb2c2,8a2a0811,5cd88e7c,c07b72d3,b91a3967), -S(92343611,cf9abf9d,76291f5,7e00c0c4,868d9f28,50e24c85,3f302c90,4a3fb0fd,1190d25c,b8e776fb,931f47ee,25ebb7ee,7dd032ec,c30bcd5b,d48e1049,6ac9062f), -S(27a0148b,39981959,2ad43fd,bdf913ab,26e98ff2,8bb5d33,d74eef9,c07c49a3,b8322dde,2f0aa07f,c3c95e85,88ffc410,5c18e236,7d71c7ce,e8287e33,80addb88), -S(b336155a,ad266dbb,a52bf3fc,e3b681d0,2f1bd72f,2a3b020e,d1a34e76,62fe00b9,bb997d81,4c915336,117026c8,f0f7baf0,a4a3d63d,13477748,ca4b5228,b32adbf6), -S(27752e08,63b8dc92,c4e63ed4,d2acf880,365ccdd0,f83d3ff7,ed62fa2,a6a4bf9a,a67b60d0,81dca9b4,ccc6a192,4a6f4734,16af822c,c939ae01,dfa88ce3,6d4c851e), -S(c9d2dac6,93e0f9dc,7124c6f,7c256b8f,f99a1436,8ccdd33,6cc9f421,e1b1d474,a3ecf256,9ec4e99b,e04cbcb3,af36851e,44d4f91f,b945e59d,7c76e3f2,288c32d4), -S(ef56ff2d,e27a5853,64a397a8,88204405,680b00a7,6c4943b5,1ad02915,a321be5d,1b2c1be4,5f2f67d0,6cd9851a,9c6f12d5,d4dc7fe3,27031b01,76cebc1e,bf8674df), -S(1abbb10b,d34154f2,d28928e9,6f2719a1,d6674ac8,5c078e2a,bf6167e6,6723d972,7bcbd8e,4c01c5a9,68696956,c4359776,e5ce3cf6,a7faef11,7cb7fb3d,19613de8), -S(e51bf6f7,73d2b22d,4dd57e4d,79bafbd4,94f9d6f8,65baa712,97d8596d,dd5b9c83,e7a565f,d8f0a273,3bb72c84,1d283e0f,d6cd1738,af58f6c2,80a31873,9f70d9a1), -S(f61e0619,2acddda5,309a29e2,43b3f597,5b52914f,5e7ab14b,45047d3,76530c93,60bb1329,705d072a,12cbd305,35ed2f9,b530e967,45e34ede,885ca32b,ff0dcb1e), -S(f91f0469,da8630ab,2134c23a,e892ee57,78327bb5,2b2eeca6,11719330,ff163b8c,c216fc14,88bcc308,e4cc5df9,42b1df51,92c2ab24,e0e6630c,38735932,f941f7b2), -S(c6ce13aa,ecbbdc54,6124e467,e5e8f966,a5cdc609,8e2c77b,37ee82bb,df5da173,eacbe9f4,9e21a930,99b08a1d,1e5e8887,f3cb59f0,b9c79e5a,1e26545f,879893ed), -S(522cdbdf,20b56337,e5062b1d,24c8c347,6335e380,4aede233,daba113f,3a174101,b8be6e5,3dbc2cf0,4373ff88,79a4d847,70255e9a,1c9e46cf,44dc14a5,91f6f659), -S(4fec5311,496a5626,341f22fd,b72d4078,109f6656,347c4a0a,6ffc2757,683f50b5,71235dd1,4aa58ab3,6a5fdbe5,71be3f,c76e68ba,9cc32ff4,95bd2166,b6c88737), -S(ece25d,92d12386,1b8b7a20,79548c7f,71f05bc4,5b37fd63,46f14cd3,8d03cb46,ee6c9e60,d7dd08cb,f3fddf35,547ccecc,5d7c95fb,8de3bebd,f77c529b,317f3b60), -S(b160e499,105c9f7c,5582071c,fcdadffd,bc3be684,74158120,50fe69bb,e090df53,702fb302,77470032,3af31e37,aff2075c,201841b,f8ff4589,fd1faf45,b265e3a3), -S(f578953b,a3e785d0,ff9a0c6a,a4f1c1b0,718024c,c40832b6,fec24024,dc65c23d,46391a1d,9a0eb7cc,40b43b3e,6f234ec4,da5d174c,fc22ac49,13d94c2f,87fae285), -S(43fb3e79,fc0b7a1e,a12e3aa2,78fce929,46f1e368,ec23d157,4ac404c9,347a2468,fb902d9a,1f4fd892,6f622169,b7a9792c,d6cf9071,e0efe86b,cebb9274,be62537e), -S(322b8b20,a86183b1,47e01e7a,1a204e57,b5261b6,3d0cd615,5716c2ba,2b7ab42b,dd36d5e4,82e4ffc7,f16ffba8,dd409cb3,217fb763,35810059,a8bf3534,116dfde1), -S(cc54be01,33ecd8c1,c3bc6031,b8e9d0ef,e5483bf8,23c604f4,464cfb5f,d3bcafb,588f4d9a,561f0951,9fbb5f07,1f0f75c7,530caef3,fda4b815,bdbc39f3,9a93e3b), -S(64ca8dec,26f3a2e0,11929ed,22074fee,f9b9ac00,296ec54b,87fb54b7,184ec668,d1465642,dbea26c1,391cc7ee,4380983b,55a54f6c,6886348,dd394b4f,9fd8056f), -S(3bf7a76d,281c908d,4e9b096a,38b432a,2aac8b63,9fd69561,18dc54f5,8f563cad,2867389,d516089e,d6e21add,199ac238,c239743d,e4355602,14e9e570,c060f268), -S(e3e6ae01,7b23ecfb,acaf4c15,b3068e5e,3c1b7b0e,808dec28,15646d59,3f84b011,88ca8e0d,a307bf72,7aeac25b,49fe536b,213d4815,7d229cbf,3944867a,6d90753b), -S(9569f3ae,b8258e4e,98e2243f,da75fb1,ef74c3b1,58f89f42,8ad3f884,7b40bb6e,751c6fae,979806ba,fb81187c,69cdcafa,e13b4657,1785741f,c10bbd3a,71b8f7ad), -S(f66297ec,a2526513,42662205,286620a9,a2a30926,4023e1f9,98c5ba95,702e3bee,9193d0bb,b677a6ed,68be4f01,8c7c3810,23cd7190,bc7be65a,67e633bf,236262d4), -S(d867329a,1e6f65b1,7b6d1bdd,23c847fd,3cfcde18,e0527696,b282dcee,3944094c,8f31fc4e,43597152,ae9e6749,c16b4873,c678b55e,19375d71,228bba75,39182518), -S(356ac12a,743ae734,81328cd,a8469f86,e0e50107,6bb67e21,e77b2f24,8b4d8bda,585efea5,d6bf41cb,fdff2ae9,9b3c8ed8,cc3d6381,bf5593ed,4efc09c6,f3c4739d), -S(c6d16443,5641ccce,bf033261,510529a9,8d5886af,35248aff,ed516ce0,e8a0cb57,3f9d4a08,cc77b5,32f8ed9,e401fc4d,39f59876,41503c46,42077c9,57bd474e), -S(cd895ed0,d1aae7b8,ede22bea,b3d39045,a3e6ce5e,cd8ac7d8,4b74ba17,ab2a67ee,1e1ad565,2d0eec45,4f9c6801,358b05c0,fa96e34b,796a293a,a2f986b6,a920e6a4), -S(1779a75e,51a56cd0,b433fd5d,5b138c9f,6d42fe24,676daadd,7f0865a5,c58c7d97,ed7e5245,445fc6b9,33032805,b4d6c02a,beb7caa7,b6a4f51d,534f2181,d7a9812c), -S(5c1cd955,73d0ffe4,1d06ef6b,a3aa6f16,f275525e,15e89142,cbd043ad,901bffa9,489f6af9,1798dc67,c71159f,44f4b3cb,b3ba9cca,bd9af2bc,a2fa6e1e,d693c7fe), -S(637d236d,8d9dc670,1d78f88c,acef91be,a05092e,44e2ab08,2f057ce9,ccdf1011,8dd1883d,303dd21b,6de832f4,fab06158,ae9a7043,b6fc026f,88d6981f,46476547), -S(c3c046a6,d0ba702f,72f3e1d3,d7af46e5,5ba2581a,b1efbe36,ed20b96f,326afb97,d9d3d813,88bfbf02,9662d022,ce0fcf38,c5442a6b,426a852a,ac443f4c,c0b940da), -S(f224c5cc,249f2879,92d6ad0f,c9556628,b8565431,b0778364,44521b76,1e220e71,4aa9dfa6,99c5eff1,209ad9d8,9c26df9b,4a7942f8,607d9f86,deacc85d,65637dc6), -S(50c0ce65,6f95aa63,946b66a8,da465882,19b856b8,8f2cd78b,5d85040c,feb19a05,b8529304,9cc46692,b2ee676b,d39b6c7c,d2f465c,f4ededd7,6e7f8655,654c18c), -S(925757f7,d66b084e,61fc08a5,cb96d115,86f94c5a,5979d09c,ca34a07c,44133c5,66691d64,5dc5db51,bec2c2e1,e398fa11,84209850,99ccb6f3,e6467406,256f768), -S(a1a7a197,c8067535,df3ff670,2363c366,988b3630,7b63ddec,a48e5c7,35a5338f,4936dcc1,b186ad2c,7f0bfcb6,7792337f,561a378,e8508206,46e2d8ff,21296856), -S(54ba4a9a,877fe4e6,baed26e7,307ff40a,ee662d57,7a48828f,eacb9bea,cb7b614e,696eb116,b1508f7,547463dc,a93cf778,1a4842f3,d7b120ac,89cb0799,5b06bf15), -S(5af3fea8,2941c9e7,bc3423b3,ffd12df8,2b560441,dc3a2851,9ead7546,898082ac,e33fb5bb,c79b2fab,f1755f54,c56b67f4,c1ed9776,1580cf38,3b603dd1,e6b263b4), -S(f383a835,81e8d9e6,1e9c6d31,8fdfb6db,ffb26137,367885c3,401e1b93,33ad37d6,dc6eb905,bdd1f81d,b27ce843,df578a31,bacbb490,bba9adaf,d0c4cf30,c2e858ef), -S(ea01281b,1aa98a60,5c4a1d9,bae8e45c,a9e67ce0,6eaddab4,4decc473,5a7a51e2,3bb44d94,b07c483d,da7e1f63,eb8dbc9e,4f9e4a59,3ff722bc,816a11a7,ab0c4cd2), -S(e5d489e1,e3d0ddb4,9a1f42a9,e928e2a9,b1a1db09,48a59fc,68452a35,c52fe7e8,90d6cc3d,b30be1da,a8d3742e,bfdff07c,f8bc7c31,a3c4e166,fbd1c3ba,9c6507b2), -S(26133aa9,17fa7770,102a229d,487c56ac,1f531d0d,536043f9,8d25d6b8,ba4bbf0b,57c2eb26,6ce9169f,8b0f0a03,cc9d7b3f,25e1965,91eb66fa,247bb5c4,213ef5f9), -S(447cc951,1e20b173,5cf546e2,809140c1,ad248474,51c101bc,40e0ad44,ce791f12,9031be0f,bdc5de93,5539eb8a,dfbdffbc,b5550e70,613811d,dfc9131e,4550ea6c), -S(76992362,e0ab0d3b,b4ba4552,1197fc18,e355b161,bab8b080,a9b849e6,c32f4ae1,c73b4930,47dad2da,c9eba540,5955da52,94b9a184,fb1dc60f,8cc94d6e,6fb1bec3), -S(e14ce3c5,831c8464,75ea238d,46e8e7d4,ad77f14b,46323bf0,aa48d958,cba69e63,57b2b465,8947875,a26c956e,e8b53d83,2d8a4c10,87170d78,ff751fd,dc82762), -S(76375016,e26cad9c,c194cc1a,fd2a5464,5b5450a3,e93eb3fc,c973db01,d367fad3,f86a87fe,5ad93797,6a96323a,e4261db9,6e176488,3f389165,3aea78a5,a3b3e0ef), -S(99947ad6,27bd282f,60eced69,6a6bc741,e338f2d,b905fb2,85e170e2,9257ef3f,6167d7f0,14605150,2e226f2b,6c8320e,b2338350,9962b6c7,e8945f81,4ce1ea63), -S(a68c11fa,497edb8d,4798408a,f2c0c832,f7f70ac2,45188bd5,df8caaf5,58292b66,1007690,df500ea7,a2e80c7b,78162a27,2b54c93e,1bcaccc7,84218656,8f24f590), -S(559865b4,fb13de16,268fd4d6,f2e4adac,6fbe420d,1c7db6be,cd09cb58,a539edd8,f61bb541,17750264,94d479f,7919c6eb,9198df88,3c195399,f3bbcc5a,5f43b52c), -S(7e88a6ea,d32b58f3,5e76431f,75a0b1c2,848b79e4,8226fe18,60241685,e1e349ab,6b070306,7079d62e,747bb6ea,85d7fdbe,1df8730a,7a62615,28b5b20b,341a5d72), -S(a93b9d40,c0b8cee,3a094e19,a181cbfa,d4ec38ee,f12b3fc8,d8e2fd05,70029b05,8c55292a,a8a4ef7d,4a69ede8,c55dcf57,e0247625,85efa9d0,aa22d6c3,ff070370), -S(26afd318,eff92753,1727fc74,5d3bff1a,9b433c23,475059ed,a6065375,22c0cc49,5f03409f,e8a2e649,7b1deaa2,5c2ad40d,517fc985,2bb306cb,86b0a16e,4448fbd4), -S(c0b61efb,ddac8a75,3f32e885,df07e071,a4250886,4657014d,de4fd9b,aa84be93,c30a6285,e838590b,dff89275,a1f69548,c65d7478,52d57a6a,aef16450,f73569e4), -S(be39b097,6ea0302f,8350a663,1ca366d7,7eb108f,ad8db45c,dd679a5b,68e7657f,4528a809,88d04fa0,b4ddd4f1,10fe8948,ae1f6c37,a13d7a10,81cdb4a3,4b83aa84), -S(267becbc,72ebcef4,95d64c5b,3da4bc2a,3fa2149f,a554bad8,eb20bc47,b43c055e,5c5cf671,4fcc1923,9bba9e52,fc97140c,3037d95f,2aa4b828,2f019854,63e89e38), -S(683e99df,1246557,2b88fac7,914c6b15,a819be55,f7415348,a59aa51a,2f08d99d,e5bf288f,d1a561e6,7b79920a,7cff1563,e22528dc,c0a56996,1e87b84e,98210f18), -S(984d688b,cf2a0f4b,b5972f58,f996d13a,c65ddfd2,35247aac,9c983aa0,ad61bd89,b31672e7,ea2611e0,cd3f9397,3d56b8f1,78ceb2d2,85f15a8c,55a4d514,e8b9296a), -S(a9224213,7882e7a5,5ef1c35d,12a6cea7,c0912746,af66057f,20a9835,5dda38a7,532992e3,630370dc,bb4490c0,76f81e18,b9b20dc1,99b0a557,4c600947,5f05cab), -S(6b6cf051,d4311bc2,6a878a11,f5d755e8,dcfbcec7,ba63180a,6c1a527,90c75f0c,395f012a,fe1f6377,7266f20a,d3f1b47e,552c1e04,fee7cc43,bbc94206,1ade5147), -S(df30d2a,fd1a4145,112b2e25,1943fc1e,3c251d44,f67f583f,793d1f2e,da10e3dd,e6753f83,edcb12f1,e29f688,a555699a,aa361a11,afb94832,32849cb3,33bb66ce), -S(1e09829e,89fe1ef0,54ccb6ac,eb3787b,291ebefb,c4531e5b,765090ad,49e9b4cc,db2bbe7f,57c81824,515191e3,7718c75f,63b6abfc,ea51f397,b4a6cef1,6cb49a58), -S(eae324c0,88d0e213,ea0a5e4d,9fe3cc78,3488bc63,22fc4733,d5a2509a,e9fe9f91,5bd9f44d,bf33e894,7572cd8d,41f7ffe6,47d1e194,b4d27053,4f3da5a2,df55ccde), -S(ea64dfd0,aafda3c,e15d6fd4,d4fd87ca,a050e0e2,9c581b86,dc0ac4d2,9396f1f1,f448858c,36b44a58,fce7d720,b8f577b7,d0888751,2569e473,eba52a94,ffc0b33e), -S(22bdbedf,7b4bbc51,a95efc63,8ddf782c,ef33cccb,b112e866,61e7e47f,4eeb4b3f,5c9703d3,84f23420,3eaf2139,9e2f51ff,c02fda84,570af857,e6d51377,bd837e7d), -S(57f7a357,4787394a,d3577667,99126aac,593d86f,58801919,b1f8ad06,d92f97ad,edcedd28,23618851,ee897866,44846a08,5235a60f,d0e84dc8,7ac22ef8,21cc9bfe), -S(38da2e5a,f6018763,89c3b2de,1101c202,390048ab,5e976c5b,b1d0626e,27b5e684,ad71092d,e3c12d55,496c5fed,739a8007,998bf851,8dcf7937,1e1e5d00,cf05286d), -S(129449ae,79439127,7e336d44,34b40d7f,6e649931,feb5be64,b2e59678,1a9eccb6,b7c99b67,a2e523ed,9b52110f,e5104056,c6410ed7,1c91382,c4e5676a,3f0d568), -S(34d6ee18,c82e63ea,6a795055,4558874,6b93d52b,295b52f4,239cd98d,5250a099,d8a9bccd,2d8e6f2,54c25353,996bccb5,dc2ebc48,ae5e6f55,eb015ace,e111fd9c), -S(d202f4c9,c114ad97,963830d8,1d15018f,ea9fbd1a,37b8b818,3a504b89,5925ff3d,f250110,1abb223e,c3293e06,3dc5d2b9,20b5d0c,ac28ef72,3c3ced74,6ec25def), -S(753d539c,82d24f0f,64fb7e90,fb9553bd,90033df,770d7fb9,aa6255d5,f598f611,340d2ed5,7f4a7d9a,d0f94be0,d7c80fa8,c3d42eac,5536382f,76568caf,ccc86226), -S(a440e28e,e1bb9c91,c03b0664,ffa79f2f,c645433b,59ea44d1,a88c73c6,1536f480,96387729,9824b3a4,d28f1a2,7f8a6f78,60407412,2d06b028,78a31c79,85354247), -S(aa9a9ae3,3ee7de0d,5a1785c1,75bfce5a,2d353344,3c32c5f8,94f7248a,1726a0fe,9063cb03,350e55fb,dec53691,4d1dd16f,34d3631,f7d4a56a,f2c6601e,1eba9482), -S(61b60b17,1d406619,e612c5f0,eeeeee96,a7b02b6b,13333f29,3a67e9bb,996f4dd9,e5093ce6,f9eb8b4,4cc2b835,404ac312,2c62228c,b3f0780c,3d995ffb,f92d1734), -S(7fc18068,b529b15c,86180482,b33b7b7c,12b6cd49,79f46168,58cb6084,c92a8443,49aa8a81,a8d66fe4,b4993097,da735768,a2a64f4d,21993b5f,e6e45f25,7632d775), -S(8ae08ac7,6d8ab6c2,a0eac25a,8bfdd54a,1c383b06,84d99005,5f1cc3fc,ea2ae26c,1b463b39,549f3095,14e22e18,e51c4af6,c3e4f5da,9050b9e7,e1556c2d,9b47c2e1), -S(de680d6b,9e75f2cb,4482e3c6,37b03f25,1873aa93,d4af9641,a3e0efff,d10d10e1,22fde416,c2cbfe77,e27fe7d1,190896e6,64da63c1,f89793d7,1478697d,e5cd9108), -S(6522ca17,8d6fffe3,34a8dc3e,83a7c9e8,566d4d61,aa0de5aa,5623982d,4459f553,cf0033ba,988ca9f4,7afdcff2,abb9a069,62f1622c,2b3744d0,cf7533c7,9e5fd425), -S(bec2be0,2fdd1e26,699cedb6,92c46054,57317b30,3e2ddc2e,bf8c9b12,a55a52e1,f03d1203,e013cac6,5b4fcba9,6ff28834,b6dc8539,d38c8053,4d59b5e3,ec3b45e1), -S(71e3f913,cfda601b,1d9c0d29,82dde7c7,970123a7,a2c9c25c,548995fb,6d28d488,6b30b817,2785c0ee,82eeb3ba,1f3b6f64,95b73a61,990e8532,aec482e,19992f85), -S(901223af,65764264,da7fee9d,fca46c4a,d7ce95f5,1c3d3b59,554853f9,20de36b4,c15ac0c1,69b718c7,9bc06ba8,6bb180e9,f4a45c4,1b09a761,67139e11,c3cf220f), -S(bf0ca457,8cc9c676,e6ccce5d,dd9139ed,ef3e2a92,6d4cb5e1,34db0a96,302ea422,b067b031,4a8cd0d3,427d6e18,6c12d0b7,3eed37a2,b7f197c,e2359dd4,6854456a), -S(8e4ad808,c2fec2de,17595149,4cd176dc,1197c18b,b6d31f18,41501c96,fb96293b,71b0086f,f41aa674,e21802fe,f44ada5d,99b5d7e5,47c60b1a,11c4cbbf,42465e6d), -S(7c682ec,732238ef,d9226ba7,9e3d0a21,d3a23d34,66597af2,4db38989,d06464dd,6a6e89a2,fcc6b55,c9d0562f,2c58819d,b7b59177,fa16eb5b,4f6995bb,64546301), -S(36f96e68,ae6603d3,4da2736e,f76ec4db,645c26c5,cdac2721,29527ac1,9378ae2b,6aee55fd,87741026,362d9c02,1adaf833,1a85623f,d97981d4,d0ef82d0,87e83ed2), -S(3cee56be,a461cbca,53cec614,3453442a,8b7f314a,5a79e004,6ccf2363,7b867ed2,b43ae401,ecd4dd1e,4741fc78,cf1853c2,97352cce,853c50cc,fa4c9699,7b063228), -S(6ebd223,be2b4d8e,6fd3a2e8,cc6d899,9b8f571a,7f5e9905,f45d71b7,7654ba84,9cbcba8,3fce430f,41073a92,a90380e7,73faee19,b2c08150,949708d,f49d23b5), -S(112aada3,f4ae50ea,cfb050b6,52ccb99b,79524b9c,4d7821f4,d67b4fcf,b992e64f,4b4cc764,ecb5698b,328eb0e0,7a242e0e,b69821b2,38231446,964f1f01,b6c59877), -S(54e622ff,ef55ef5a,8bbb46e5,f7a98f9a,4cc577ce,ef87fcc6,40909be4,8b0ae6be,1442f6fb,a55ba6b5,7344b4d5,5555f71b,4e77c10d,442504b1,64f1d948,a38a14fc), -S(247497b8,1e23728,f7dc5d0b,8c450eda,fb6eb9da,7eb90d35,e5939440,8705301f,9a5d529e,f38de912,f5c7f58,56e02285,32c6a6de,702244a8,6bc1990d,6144b46e), -S(720cdf82,bf44e211,b71d6fe7,52ed34b1,c9d7f88e,5c4042aa,b3826812,b45df62a,2a05003e,1b36d9f0,b76e34e7,66feacc6,2ed49573,a3f6414b,f631f32a,9d79817), -S(7b9a28c9,8f5260ba,18db1c61,5656d2ba,3de591b8,90a9cee8,96f60bac,54cba095,8a162ddc,95ca8565,d00530ad,d8d338b4,bd62760e,4f185963,60de82cc,9b543e57), -S(cef8910e,534f2fe1,9228ec86,b903a1fb,e6056a5d,2cf7ddb7,f2dadb23,6e2952e2,deda80a0,305e27b8,e9cec5c3,81015929,202fbbcd,3e84340d,3172e0ed,70666b1e), -S(1203af6d,116f7b3e,4926c3c1,f9002e20,196ab0e0,1c6b2b5f,adb17142,8e2f6ffb,6e7fc524,23e6c744,52d2b6cb,4d659fa6,6e541df5,785cc666,a4779429,7ea3a842), -S(c265725b,f9c43ae8,8ea01292,9d0e3edd,e9bc761c,54316ec3,47adb51a,98eb4590,362a5d1c,9f0ce3b8,9a6c83ac,b30a7e00,ffa5bf70,be1490e3,f1e643ac,3ac65019), -S(5044578f,e3d7c3c5,a70a6a1e,dc6686ef,da027c91,a9bcb7d8,5a14cbff,6e7eb943,18d64743,78e2842,b6704760,d8c68b0f,5caf61d0,37fa4b20,98046c88,8a3e84bc), -S(3d278c7f,c4644246,1b324f0a,f666803e,5e052d5a,80dc0755,9d067d1d,e32acc63,a242e218,d1449f64,20417ab2,41406756,e94d3aa9,f4ea1c40,192015e7,3f3b74f6), -S(e89ac46a,382f58ed,982973b7,6569c95,c23c7ca4,4c893317,ce3c3a0d,934b4c93,f8db1b16,6bca5162,23b6d397,3a7d429,9a99a1f5,1c9e82d9,96e00103,11a9c696), -S(d46d9244,52ed46e3,5868ca93,35c9f14f,158165af,f6a16d0c,f31e90dc,569b8acd,c26880db,bd8c2308,5b2995e5,7a40773d,e692799d,b8680a29,d01fc51d,d92bad21), -S(52b62ffb,6989bfdb,ea671d22,f782c692,aa99daf,f6afb854,a260f6fa,3a5dccd3,75d15e76,a21b03e4,7adf5c27,3953584c,9067450c,343f026f,e0dea126,6d6a4a52), -S(b3db1f2f,9c3e602d,5c32a28e,85079423,3759c3bc,3ebaef4d,485f1e00,817a5f30,cd336cbf,7cff0f29,211b9c6c,3b811eb,1d49dd23,c03d36b1,54b43c71,91dc62db)}, -{S(ae5fb021,e9256cc0,6236d667,b76b9bdf,304a4683,d2916ffe,489cf019,6b4c5683,e768366b,5c8d36b6,18e45550,d57493e2,41fed17d,12627e37,b29b4b74,d3603696), -S(d6f735e7,93f6162d,d540a255,76449ae8,edd46e31,d8f641a6,dda76200,c0d33e4b,7f8721f9,23fecd81,b153eb3c,eb2cc58c,c21f3cce,56a1d750,7f99934c,4ade221c), -S(84254df5,b28af43e,d4aed5f7,4e104d1f,2fb371c0,a2adc7f4,21415ce1,ee836c51,b07204a9,260540d4,8e29fc23,e254f378,a49a2cfe,fa21efa9,a2657342,3be3ffa5), -S(7c329ae8,269aaeee,fc01a25c,d2e9a15e,794c589f,b3ad0c76,d51c8efe,4fed9c87,a31b2006,b54e5b13,1e5f4997,f1eaa866,77aa3073,6f6b808f,249522f6,99373dee), -S(922c5ab9,b3938aec,d8a89bde,ff2a803f,fa6d77bc,d1301d76,3f8aee6f,608c8976,efaad685,6ead7c1d,adeb3f45,988af445,ed6701de,1e063a53,6d8b76c7,64be0ee7), -S(3b3b6d42,b662a8e7,44e218b5,4e8c7ae8,842600d4,dc8ff55b,701ae392,512d2d88,3319f63e,5e72d98e,21b23c40,fba11751,cba6756a,68dbd747,f5ebf054,34f8ea52), -S(7031413,ee20f2a3,c716ba79,39882dd3,74dcd7b3,c4fac819,10b856bf,72edb957,20fdd866,33755d03,5ec21df0,39bd4c33,e4ab4bc3,4adc6e7e,f95c6afb,980daf70), -S(b924bf9c,93d735fa,24f61239,83aa798d,e6745852,cb1202d4,db74ded6,a9ca4d67,c8800807,c30e88ee,6351e5a6,547705b8,e29f87cc,4d7166ea,c719d0e3,3f156cac), -S(d43f2e6d,a0f105eb,e6fa058c,c3e98099,3d878f4c,40791188,80a8c5dd,a775f798,3c681084,a8a466e5,34fe34f0,f533f6bc,7aba722e,37af767d,30519272,4465404), -S(d6fa6f22,5617d2b0,6b35249a,eebdb016,517b7ce8,f2f52051,385ecd1,e987785b,1fb064ba,ee45eb8,b7ee88e5,963e290d,6bca04f5,1edd9623,a94476d9,83d60fba), -S(8584a76f,1b641da2,e3645a14,b9b0beb9,9e43f4d8,40ee16bb,793aaaca,c212f1f2,9d3de317,5cdc70f1,35aa3b81,e8a31154,15a65855,510a1bc7,d980715e,5af76d1e), -S(67f50f74,1508598a,c32fa77,8e7b2ee0,3b24b63d,7a48c12c,5bebfb4f,8af63e2f,f35b00cc,c14cdc2d,a088d8eb,b2b39878,5fa46ed,4ce966c7,8acac1d0,a59430b6), -S(34bac85f,a0bae27,e443336f,c6e6df4d,252e5586,f0dd898a,afdec4c8,8a57239b,756a85d9,71dc0296,8f7124e2,5edd877f,d8554377,4c8dc772,ef22f698,5d741a7a), -S(1d2bf603,120749c8,c802441d,b3021c02,65364a0f,6a162d41,f4dfb347,a425a8f9,4cc35601,ac8bb504,13e3a3ed,9d67a55a,fc5cfb51,d3caa73e,73300b65,9503f351), -S(26b9ca6a,aa72fa3b,68c0c995,52636afb,d0f6e88,e540dfa7,a5955952,af5204ee,b2d6cf87,1e017775,152ec88e,155e7ff2,5c04a631,92df5074,2a5e546b,6e15cd89), -S(7dadd65e,6c658083,e82369a,bfb1745a,fcc94247,54db92f6,3fd00d25,23172d06,655ca6bf,232d8f85,e5d0ed6d,5b4040f3,c34e9589,6be0df98,2c65ac06,ff50d51f), -S(98667128,2950f125,a399c076,d9eff5e3,ab8eb85f,c5a496a8,ae8c740f,cd4853e1,949246a6,b2b17c2f,2ef08455,590d4076,a26c508,6a4043f4,18f2d2d7,2dc42511), -S(efa70ff2,4042d4cc,5215b450,703838fb,d274bec,204df700,72a014b8,33d3bdb3,62fc11bb,bb1a6d7a,b585f05,c5da598a,f59b2148,f31d293f,17280652,c8743380), -S(97ea8025,12bb4141,7a2ba994,8456a498,f66fffb1,69883e3c,970d4c13,834c9f61,87cc181f,6a83fc47,c1ba6e74,38104fe3,1627ca80,6b4efdb3,329c62aa,d5cf9913), -S(1353da1,849ae275,84e55047,e8662ff,2a2361ea,fff847bf,17dd5c8d,52b46942,a380a7c5,2ddb6241,cf7cd12,87cc89d6,96a7b3a9,5a198785,76bc4039,b9a913ba), -S(33329e8f,50855274,5598448a,d07e36d8,85b9eb34,8f67b10b,a8b7d04b,b71edc4,be08cacf,ad6763bf,92864ae,3afebab1,a6b19992,b1f0d9a9,436f42ee,b96c6c90), -S(863827a2,46421930,553387d9,46fc1b4a,7d40549d,dd470f6c,75569887,27fc2747,3fd2c6d0,a9d5a056,95c25ac7,8f7eadca,465176d4,fee49512,72a93d33,5fe7324b), -S(8f2c64ba,637543ac,67a7706f,69ec59da,9528be29,7b1be5e7,ffb4fec0,e16d25af,7cb53924,c47605d0,239add6d,287030e,9e8f33ab,4a36aa56,54f1a729,e3dadca9), -S(8ce26953,8fe8a9dc,ded83d07,717e96a5,c95eeeec,e6af2b92,14ae0811,b315909b,9277f1ea,33861808,36545b6a,f467c0f2,dd96ac04,28ea8a0e,e32db52e,de60207e), -S(44274f51,cab44f1e,3e527e95,e92156fd,1cd2e363,332876d2,d3ce75a8,e96c034d,fc4edd64,5e2fa7fa,3e0a8a60,36af7a5b,80424f09,7203774e,489ad68a,5a0c3b3d), -S(ac9170a2,a320f19e,211c2cae,b827e87,d065a9e3,15e11584,d074c328,b38dff24,5afeef29,a8a03e49,45009c9d,e41d354f,69d8d974,ff0f6b08,d0bdad83,5bb8fb5d), -S(eb21ae48,cc5aad77,7202e145,e7178bac,af1899c4,de96aee6,ef2560e1,a13e898a,5726d1a9,1c897a8,c6594022,e139d2e3,e23047f4,99d107fc,9f3ca9f6,aee95d9b), -S(b6b842c5,bb0ec79c,36c0831c,b87f8eb4,8234618,f5d1b888,678d751d,be61c7de,9dc3deb1,6eee7b4,4f6d29c4,ed170cce,2fc78db1,a5485dd7,85fa6de1,8b9d1838), -S(281f770b,e956f478,26529137,e836d00c,5a5b55c7,4158ff32,79b96ef,7b6f17c7,33e0dd6f,e4610a87,c703f4f1,9a7f2b14,3756ee8f,e3e6fbf1,a36f1d28,88a2a836), -S(3520dd8a,8df2555f,2a404ed2,d2766080,302a38ee,14cad37e,a7c575cc,18334cd8,36000e77,7a789b8b,e3de5ef9,71b345f3,3e08f491,3171df2e,ea41e07a,cddbeb92), -S(4307f2c6,db337087,5e69307f,73fc13bd,eb70f5ba,8651e507,2b58ba8a,5945c07a,198ad388,9d9c5b9d,2e050e69,b8b0ab53,8641f4aa,98204215,5262143f,2e513bbf), -S(3f69e90e,4be15f1b,7a3e0518,d2173143,8fa2d0d5,31617b6b,390cb3bb,6dd3e130,2c2eecb0,fed8c40,a0e158ed,44c94f07,61c5c288,d525f12a,ad927235,cda29dfd), -S(487638fe,525ec3f,fd34fd11,6ea6629d,4c15cf03,fb581c18,2c14e0a5,526e9b99,464c0ab4,eac365db,ba6aa562,2dfab02b,93ddb339,d790f875,f8e98a6b,6dc1677b), -S(9fba06bb,20600712,45795836,ba95a91a,af40c61f,c9c83511,8bc97ea2,1428981a,97930e0b,e2b4fe40,8bb37aaa,afe5b66d,6b8c140a,d4a0b0db,a39abce6,f35bb8bd), -S(fe0b19f0,dd103ec7,cbd3d605,dd1e6230,dd4dfad1,b4dfc2e0,23b8463d,8710a27d,167d8e8b,4595516,1daf03be,99d1dec,383d4c47,247c68c3,8927515b,dd388621), -S(a935d63b,16467a8f,41657e49,2c9f7fb3,c5da37f2,3191955b,7e73882,5bb3d256,7fbcb19,2261cd98,ff7b5087,567c1dc3,635b544c,d9f43d02,8d11a94b,94812623), -S(ad28e247,18f124ca,b1377df9,f3f78fbc,1fd4f8f7,74925d02,2f11f56b,c08bb8f2,e3205a6c,5add373d,4893fd23,84fab0ca,525f87ee,ea5b687a,b1b60550,f090bc1), -S(9fd9c788,2172b1d5,9f2c57b5,746506ea,9483fcf1,5cf51ecc,70fa4a40,841f7e9c,900279b8,566e555a,ad3e1318,dc890ad2,6a0c9e4f,36ee4e01,d3a6b046,7b66f11e), -S(85ab8716,a347ffa4,fa4a9807,6a7a1e4d,8f887dcb,7b758212,5831cee,5fd755cb,ecb83ee,e3ecf915,43460350,39e2097b,ac9f0000,2855ff37,ddbbf6f8,6d2f885), -S(da34dea6,49f6db93,c4edb612,c7872054,d78b9e13,4614502c,e2db2c3f,1445d2a6,d34bd4f3,d65a7b20,79510648,3b41c2ea,5ecab70,5fe961a8,a3844e0e,95b5640), -S(1faf535e,2136c3f0,e5026f42,15ee8d0e,d088dbb9,81ecd469,b5311a1d,c235462e,ac1e6f90,a482e42,c6c4cdf2,d8c33dab,b307c39d,c3745cfa,db24810,94e826c0), -S(d1924ae7,ff945ae6,5c1b41fb,398c257b,cea8bcd1,fe6c6e8f,2bf4118b,c6bc9fbd,33d6d54d,237fdfdc,4536abf4,1bfe6681,173a3b42,5652aa1a,9f605f2,8c2cf834), -S(5e30dd95,dc01b76d,2eb1876a,4d0079e7,4473f4d6,acf88f,4b1a7ade,81ab4a44,5edefb5,959759da,4c39c9b2,8ed669ca,7e96b937,394f8cf9,109d99f2,8ae94e9e), -S(1d1b3ebe,aaf21685,c590efc8,5def9bb8,4b5a6e74,de93b34b,b9b169af,3d1863b6,9c5230b7,c41d8d3b,9512a817,34fd101,9d98856e,b916fc79,2806e377,2a75fc93), -S(b1f84efd,e53a7f4d,4cb66989,876f9521,9922fb16,65dad292,a342ef77,f151a7e,624ba3ee,f1bfd30c,81e905f6,fc9a17a1,1c0cc014,acd9ef0,25620277,3e95e849), -S(88857890,30e21565,c166d64,4b14a4ba,9832f99c,764f34dc,ee2aa79f,60f3b4ba,bddced24,35da5a76,79c207b0,e5713ded,b73cb088,997e2ecd,c9cbfc43,f38bd096), -S(f4b8fdea,a8a4a630,2d59c0a0,b34c2998,a7a72c6e,911cf7be,7adfb44,63d1a213,f78d9aba,e80329e9,f02c4f9e,d1bc524,35114a63,884709a4,99925c8c,d06963f7), -S(7f85e0f3,6a03b7c7,47b9cf89,55aff917,df60dd64,f35e14b0,4e9ba8c1,d647393e,f3b23489,f86e10d9,f9f542f7,49df5ae6,d50f5613,481564f4,b8842869,6e40b72b), -S(b5d3138c,6fee7f5d,68599558,b7f4dad9,948d47af,98abb02e,369fff57,bcb9deda,e0d247f5,2e097751,fd33df86,627cc172,5a26eac5,4a6782e7,7c42cda3,b9262d58), -S(7b13216d,bbb83d60,20b9d45e,5b202538,ff22a2e0,e0358147,22344248,d352f2dd,2eff7c95,77819e9c,aa0a762c,ce70fe9c,f0732917,46a2c8,250b0a86,77563e9c), -S(3a79df59,b1f3ced5,70628491,9aafb365,59c757af,efaddcf2,164dd3f0,73e0b85e,5afd0066,b083d36b,da510974,75d07f24,28ec9d25,5ccf79bf,49e059d,cb637a1e), -S(318610b6,9f525ece,4c7b4c28,14cd0fff,d4729929,56872cbb,3ca350b3,6c0d5aae,8dff9296,62ccc6a3,af202f73,4825ccea,362d64eb,30fc187c,f8db26fb,6ab1ff8b), -S(e411c5bd,ea470bea,188e8e26,f7207bca,4f92c793,ba34c1d2,d1a0ed70,f441d836,d4d40b75,f46aef9a,b17afc53,efdee46b,50217b2c,93058fed,838fb17b,4fc33be1), -S(f363388d,497316bd,bc962af,270c591f,6d5868c9,69a08003,1ca021b2,f218792c,6d29bca1,5716584a,8f13a69d,498ffb53,f37d38ec,d7703e92,d55f2dd7,14b860a), -S(79852af7,34689490,a5e7be06,33f973a4,5f1870c7,aa5912c8,8b121a6,3a6f7aec,ce1bfac3,f472d348,c5186160,e167d840,426a4be3,7a58f56d,ed651eaa,15d14053), -S(353357d8,c93b2dc3,3e091ea4,fdfc99dd,3d235074,1eefd250,70215e03,7ee9f450,85c07a65,6bc1389d,9065abe6,a896d4b7,953aff1d,f918827,dd0b57eb,918e8297), -S(d64e1ec,704e979b,5cd19df,3ea4845d,8161f348,eb9afe89,de1c22ee,6fff6236,6772ac7b,c2224a28,dfad9639,3b9fd942,6f59d6bf,7e4a94d5,4003d24f,6b1cb2f6), -S(4afe8fb,9fff7ac5,3a0a0689,24b5961b,4056f190,27fac3d9,dd493338,180e41ea,efb6bb06,ea3ed1ee,c5e7603b,2cbe1d11,e32a1602,19079b9c,a04f997,8ed42f29), -S(bb42b5e7,a047ca7b,eaa52d7,48c763a,3ccb8ca,38f252db,f131d123,90cefe5c,65f8231e,f9bb6ac,4adcd01e,87b99dc3,b2dd30dc,4163d84,8dc0faab,ae035b87), -S(cc6431cc,e7e4ad45,a0125326,6a8114e8,ac9c6896,56cf6e75,ae8cc4dd,cd810a29,498de8d3,f8194a03,ee8c5db,d1d39826,6e09563f,9d5253c2,a6f5ddbf,cd41dcda), -S(624b81c0,b8f558b6,6b19afbf,76b1b7c2,9ed964a1,b53b6ac,6e58acf3,4c6e4d4c,d8429386,43d28c7f,f0e79a55,801a989b,2c923c36,d84638af,686cc637,2cc3095a), -S(53ad6cd8,b0bd0b5d,2742bd76,65c0d0dc,25234c21,a68fc9fd,da85b2d4,a9efb4d9,d886b54c,9dc40ae,40f57f4d,112da945,46c44b26,8ab08440,d027740,8264d5a), -S(ed7a10a6,9a2a65b7,7f3bfbcf,2d8b2f5,57ce675,5334f13d,615f85b4,7bbaacc4,d9021ae8,e1a0cf99,ba539b6f,52dfa141,ac6d2d48,ff71c1f0,c2cdfba6,845750e6), -S(b07022dc,5d250d6c,1464a03e,538b53f6,72470792,da6bb28a,9eb97664,a9797d9d,6e1dc0e9,2b112d0c,520e3fa3,7e90f7b6,36959a43,15a76833,ad935237,6ce4a96e), -S(f0cc2567,eab35314,d0aa253,681d6319,cb016a81,c6e683b9,51e151a7,98b3ef22,cad6711c,1ae440a4,4f547afe,693d199e,4be0f8d0,6a13e2cd,4127e9fc,c99da815), -S(1a71731f,232ff7a,670c81a5,30b9868f,eb59fde4,6c77a264,7357b84e,51917b2b,1560cb00,13a3bae,23983028,4be74589,ece8016d,8c6a23d2,9b52faa8,e907eebe), -S(b8e1e4c7,461335f9,536fec82,30136f2c,a348baae,bb3a6cda,fc8a3a9,bcf72df4,fe85e36,e956074a,26f56f8e,ca1f4fe2,81b0a682,508ca1c4,d6c3249e,21f48cf4), -S(63eeb2ee,ee187fe0,b80d0c2f,ba2222d,1a763aa4,776b2679,b14bd541,f566bf8,56ead5ac,84ae0964,c728b87c,979557b9,c44c13c7,dfa3b31d,86a7e31,5a920c99), -S(862e7b7f,9bf1cc99,8f0a3cc6,3d873eab,228b3977,8bf3aaba,57ab16f7,32ba9d0c,2d69026e,f29ac9a4,151d9f98,1c4248e3,2c3e4789,72c27811,68fa2c4f,5fce4a28), -S(e0588c62,3f65c421,e12cc7bb,d5842e84,bf46c00b,3ea3c38,9ef98056,6cd1deea,98dc9056,d105607f,569aa79b,6d6b6cd6,1b42f749,4333e255,35c220e3,15f9d939), -S(9a6f0406,7e3743e8,78ba2f1a,4b4aa09e,bb8b5bf5,7058128f,bb0a573b,1c504689,6ad673a6,61c9dc87,15cf81f9,3815b32d,6c47879c,c831c549,5a17749c,80003838), -S(6f4bcc03,ed655fbc,be383009,5fa5a1d3,3d4be203,9380ada7,d53e1ba,248ff68f,91e8f700,44126d04,ac2cb1ca,7650a287,e77b2a9,8cc22e9a,b36b4906,5d03b8c5), -S(66b32a92,23945f66,ba2f7934,43f5e31c,8d0bb858,3fdf9db,6d1861e1,fba5e0ec,74d81838,3c0aa55a,16242a41,3ed5f9e7,6569d041,e668d82d,ff90f6b2,aaa9b9ca), -S(c1acd55e,cc4b6743,3aeb6a4a,6a920dc4,626a4219,d70cec1a,1fa4ad6,87696330,6b14fa02,11b63493,ccaa9c6f,e2c288b5,55a4b851,d6a20682,d7aa7039,6c21b156), -S(2bb86341,deda561c,99dd59b2,dd2392e1,4a5cfbb8,9fd49d9b,a35634dc,3274bc61,3662d431,b4403678,a9d59758,dbb413b4,6b48bccb,f3fc9fba,801fe7fa,8d9da0f7), -S(b94189e1,9fa60eac,7b1eaf49,be80b0f5,511693cb,a0efd3e9,70cc0036,eeaf851b,26ee1cfb,ce3445c3,c217bc5f,5ed12d1c,59367ac1,80b65b91,a52d1d8f,c091c8f5), -S(8cda78cc,fba3d6e7,869ad44d,bb5447cd,718be851,df976c1b,ec65be9d,335ff879,cf2cf6e0,94f20682,505bfc56,8f537acc,b2289003,c87c5cc4,23cfc9a5,f61acf02), -S(eb447748,ca42bb71,71c6183e,6ba0e9,a61360f5,b9b686c9,246295ce,c8dae15e,586d8bb1,4dd7277e,5aefa348,55af5e89,55e56526,df89ba4b,575911e7,59f6cd0d), -S(73beb803,c18a68a3,ee1c945f,6031c646,b08c688,6d5b4999,5641181b,c6ab7b0,5fecd8dd,82e3f515,d7a23cab,26949aee,afb1c1bd,1cdc6853,90f3d081,ffd51157), -S(4c3f9e89,e5cc661a,ed4ac704,f37cac28,42afcf38,2c4d51dc,fcc21761,d87311bf,28547fa6,8c661209,67ba52f1,3a13ce38,33ec41,402cb743,49d82e38,2973f615), -S(3e19b5bc,93c422f0,42a2fccd,1595e7d0,d89a2655,fce95a02,56802460,a3ba5b11,edca8ed3,2758daeb,f2649ad8,80114b84,654c3b72,d7ada177,2b84ea75,ea7079ed), -S(7f4b2fb2,6934a60f,50fb114e,b382e0c3,a432f213,a57124f,6cc23e84,27cfe1fe,d0ac243d,9fa8daa2,90efc550,af03e5c2,59d39ca,de0e8779,d68b5880,c74fc874), -S(daf46145,a53b5aa5,ff26bd5f,e0b1c880,835e04ae,9dc51caa,ab37f168,6e57db0d,6203be50,dc56e59f,adee0012,d1c8f24e,afb8caba,88dbc814,f6c127f9,efbf956c), -S(2b339287,f9760403,6bf7d2a,5dec5ac0,6ed9d23d,c2557b4,f853ecf7,70131ad1,6cfe12b6,fbfad32e,b7b100fb,7abcb7e8,cd990d72,d5e7d10,97ad8a45,bf056c1f), -S(2b42fe3d,6a44b1d6,8077ffd8,d3eb700,96afb615,f70af414,48ba4e88,32791e4f,1a8db3b8,50293439,9d31a512,9272096f,6e913775,ae89656f,da79c425,90ec01aa), -S(36c5c074,76246100,bea82171,713bdf41,3d8ef2b9,5ed50fe0,390a93f7,7756614a,53842c42,37723b9d,24cb4666,9f587f68,fb14601b,f4d7b05f,24f9533,2b6d41ae), -S(6c82d0ad,ccee854e,b8ccf077,4917a92a,4c8f4f1d,da784312,2f317ebf,8e8662bf,be05113c,2fba79a4,14442305,f8773526,3b909e30,95a51853,4f76a666,7be28f3c), -S(5019f59b,48e6cd5b,bb394dcb,3b8798fa,bf13bde6,20916ea3,ee9fb32a,53eb2503,4b2e655e,9a09615,7d64ddba,49d9b337,a84b6b1a,707d8896,93211e51,6829a07), -S(301d16ee,7f980c8f,98056bb0,6ac49906,f2f5f404,f36f4f7a,e1b93d47,6e6640b8,d73660bb,d9bbb41b,8f0cc43d,d203ca79,2f07d10a,a60904e4,8d2e3905,e207ecbd), -S(23078318,53146a67,7e03cade,15e9cb41,d3f516c9,4762abc,8a6d7722,1f5557ba,bd7df729,10f0a43b,74a27c80,5bf3dad4,7751af23,9810d9aa,3f4ebbb5,773732b0), -S(2b91a10c,bc666ed3,e7449d2,bda7793c,d6ddc1e0,59c90e19,b85b80f0,50e2a21f,a9b18e39,5154dce9,d6da961d,dea00c40,c58a9cbb,20d9829e,ed4f246d,e7a4af15), -S(73f25213,23e97715,c726b678,cd8374e2,fa7fa140,ec0f9de4,ca25ca02,277bbb65,8b1ec6ee,85ae17e8,da8f6984,c6d6f2df,fa7d2fd9,440904cb,449c227f,b3bd13f0), -S(b8971801,ac6925f,374a5901,2b19e8f9,f2279479,70d070d2,4e097e04,35b4d196,7329d3f0,23a5d418,68e576f0,39b7ed39,8e0fe209,25f098d9,ffa1c45c,8c805fd4), -S(15a6be8,52035719,da9d99e7,9971035d,bcbcf637,d73a37b0,ed8a0113,7500f8f0,3512f517,b5d07551,2f1e91b5,79ceb942,2b807bd2,6be8c336,c124057c,8f204957), -S(6a814e7,c5267f8,182b46aa,a657ccd7,508a468a,dbd9a8a8,b7ce315,2fc672a5,87013b76,ac1d422c,41c8413e,884feb4,bcb29c4e,4639f65b,1962eec3,25ca0d1b), -S(d5ac8a12,2c4e2e37,4145aa10,d5309658,d5d8dff5,7a246d8f,59a4ffd6,43a48d23,683710d6,6ee30017,a07ad2f9,8c12110d,f794c8b4,d92a89c5,6b509470,ddc737cc), -S(9b2c7eef,f744c46b,6e080539,6abb4dfd,6309458,d65185dd,d72a3c2e,ed301b,866a08de,d9d8598,c90fe692,f195d40e,e7a294bd,13f113be,b32323b9,edb35354), -S(a1d0ca41,dd26772b,303085ea,6514331c,57dbac2d,f7129d3c,94a14b56,64dbd1b1,828b9dae,dba3a32c,e72dce2e,e57cba96,7b3a8001,dcf4694f,4e936cfb,2d195c9a), -S(d775ef1e,c3e03ea0,be8852d5,50d30e2,651f2b6c,1b88cce5,8726d66f,e0f73334,2abd706e,acb8e68b,3a3b096b,4517912c,61fffc4f,8bd6c0af,2ba7affe,f3446c8a), -S(6c4b9a00,8c0cd988,e518536e,6dba0027,60e43d4f,e26e7a00,632db70b,e7701742,79d51a,905d04f5,75067ed4,8b22de92,3c25c98a,f14d2955,dce9021b,9aa9950f), -S(39af331,36455357,e7b4a48e,d74e5b0e,182363c9,aac8ff12,545e7cd4,7af66101,e66eec81,736f055f,7325521f,e349d4e4,3faabfb9,c73f7bf8,7c9a791b,1635f16a), -S(ecd4f3e5,36ec00aa,8b4dcd7a,997cb470,6fc83e55,8635c241,5c03807d,16f6916,479006dc,de668a08,fc4d3bb4,628c8b23,6deaad8e,9f75e99a,93e464db,4bd96a8), -S(d26fe1cf,b13ba752,d76d09d0,1ea6204c,8e90baa3,79ece72b,80e6f7a9,282348b5,db4d5f6b,c63ebd68,44735571,a0f43d81,df9d5661,471a1050,11cf4801,b182d80a), -S(6d00c0ca,7c94bbfb,dcc30c47,1f5622e1,afa13179,8b0fef54,3adb02cb,296faab3,7705f197,bca702e1,3ae1eb4b,ff6d8ad2,80c43085,ae5bc7f7,12fa75a7,aa65e6e4), -S(5a77b624,b3949a1b,16587011,cf9b251f,90428c1b,6f5a371d,f2499c28,92c94982,928036ba,b113a731,65760dc5,70562398,f23d1a53,126ded37,6370178d,37ea3db1), -S(e92f3c46,b854d695,455035b4,fae2d3ff,83ad6f62,5fe9e8f9,fa9f3266,898d063f,9ddd806c,683cdd2b,430677fe,89a7a603,75fa8923,bf72c196,cd0ead02,e1d9fc8f), -S(c9d99f0,47ecc29b,5892fe3a,9a285f23,eb7ea82c,e7ffbe2,2f0596df,14c2f8ef,64c0ead2,269f8833,a7a16d8e,d0c3acc1,56309197,9685467c,f4b47420,1b6e74c8), -S(85359be0,9d8cdce,de34edea,1ae82ecb,51af02ac,8294ac59,868b7972,c114398c,6e6e163,3b8101cd,5d3b4264,26a05f69,3aac26ee,c5da1d7e,75944fcf,710b15ff), -S(a1fb58fd,d1283e1f,86026dfa,4e29ff12,da8d9c7f,d6e75e9,6fb31706,8c9f34ec,9429b8af,a89a0031,ead59b83,a9796219,aa8ecbd0,a7875b79,c9fbdddb,85f1a3bd), -S(8ac4d467,6390b97d,488f7943,5e68c47b,eb7c6cda,f920cfc9,dcd6faa9,593e1185,5cde9d0f,3fd47f0a,65b9d7ad,c415872b,f860e1c4,74471b6,c57d464b,9395ead9), -S(1e1cdc12,96067717,2b3776e1,d61a872d,a65c6a99,33596409,99ac16b8,f836237c,f9fae2b3,49d8e6ca,57911ffa,ba411fc0,f80f45c3,a8ff0bd,ac0d6dfd,1b4fe271), -S(b96841f0,b49538fa,7d14c6c0,2cf08242,d6d21ea7,333ad720,9a0f6156,67f6feb2,fef3827,23554c52,6fc37f41,7baed824,17f163b6,e855af0,51e81cde,bf8a32dd), -S(b42499ab,a8a83591,3be09ac,504c6c47,3214f31e,fbab7573,67936d9e,216fd0f6,a2f6a202,e1a97f1c,cf083e26,c84ee6d,7d57cee2,266246b3,c4b6b56c,5f4d613b), -S(418c2e28,7875dd00,6c5760a1,1c72ec31,f267677,7d27a4f3,fc03cfd6,803d85dd,5e727ed1,a2180e35,4bcfed5b,65eb44d4,f045d3d9,ede9fb67,beba53d3,cf8c9ef7), -S(1aa9e157,cd261a2d,c4a00e7b,d119968f,5bff1084,4cb9c835,62b7218a,3d484fe3,d13b9646,a6f1edb3,777a526f,a48353b4,eb06031e,1a2327cc,99be4b06,836a3bb8), -S(2e865670,19aaaf33,c7833174,333e3f9a,bdd63c7e,d25f0af7,49f2d7f7,a69bf7e7,69da2079,a30f2791,8966aae3,b3b9f8e5,fc150b3e,e71616c7,ca845174,36ee5c24), -S(ef7a8374,943df2f7,5ed67507,df3c1a2f,abe2042f,d66e97f9,4f6e3490,1dba9ce2,6b93d053,481b8395,c77dc3a0,6abb3125,7951ad9d,d9d76190,1e218bee,8bb6b4c7), -S(2d097904,179b400c,165cd596,f57919d2,2d7b0535,8018d528,aad0d3,23583478,9f9a0ecd,6976d6a1,6936816d,95283e18,3e94cfd8,9f384bc8,3573e695,35e15380), -S(35b46f8e,231424a2,314effda,3b610f4,5fcf33cb,799b5db1,6389b880,93ab66eb,5e97fbab,a0b89500,d9dd3e4,2cb68439,ec7eda2d,f1a5d6be,24186be3,212f8648), -S(eaa55e55,c4e410b7,2e599063,f4cc976e,754c43ab,a0df3bae,825a4563,fbd27711,13966980,3ba07091,faaa131,71437472,67a75d15,3f5611db,91d4f27a,80aa6975), -S(310c9ee9,ead99f8b,fe9c711,f93357a,e2639181,176d4a6e,4ac84cb2,2a52d6e8,300e5486,deb90657,dbe417cd,6aae423f,bfb00e5b,b3077fef,b6b8a166,10fbd172), -S(de1383d6,2eb93ae9,81f87d12,7811be58,fc373b38,893f0e7,6a417a82,95b27bef,f86aaacf,8704cab3,f0715f93,3eccc9e8,203396e0,636a55fb,ecf76440,7a2ecbd), -S(f5bfa7a0,28beeef3,1fbd817e,5ef6727d,5b81e76f,179fcae9,f271960a,51eb954f,ec3fc89b,ded5bac4,72d79d7b,19db43fa,ade10bb3,cc43d38c,f38efb3,f9ae9f66), -S(5e67e65,80b858fd,df24ecbe,f0f3100f,4378ffb0,7e382ff,f4761ce9,226d29e7,870a1da5,663f1be1,4cd642fa,d7eae191,d50fc6cc,1146882b,5b6eeec4,f1e80123), -S(68cf070b,60e1778d,7c9a2f66,b6abe3fe,23c2e090,f4c59618,a37eebb8,e7108ea,f09cd61,f52305c8,803a2346,65f76a14,49d2fc53,8a4122cf,8462ec5f,b64652bf), -S(427d23db,3ff49c5f,8e693ed8,d88a9ae6,339105cb,cbe2195b,13f39e46,172abe8e,25f4ab41,24ce76a6,a59cd840,de87daa7,be30fe64,59829f80,2caff723,efab49fd), -S(18c3c0e9,810d5353,7963dea1,820a41ab,3f662b0e,ad0fd5e0,8b07806c,e3bc1110,da91ee74,69e89a86,eb9d4ba5,558d9f77,d3c41201,e0db692b,8f7cb583,da4b41dd), -S(f16661c4,dc6130ec,79c47737,3794193f,7538ca5f,2560ab19,23929a75,ce4a74ca,a225ddd0,d3c3fe76,adb89df3,9987d46e,4b404343,6cb457d6,c3a13583,3b41e05a), -S(e467d2da,4ff404f0,5a1fcab6,631ff889,b8f5809d,64328225,7c228589,cab00ccb,86c1f60,ef5aa2a9,5b262e4c,d539a3cc,6839d704,f20938dd,7b93f958,9f461645), -S(ec69c75,520581c6,4cca16db,acbed064,20df5851,b3b13bcf,299aa02e,4473dc92,7742d8f3,96aeec3c,b27d066a,fb640236,ba38722d,e1ee4d2f,d0c9d810,3dd14d85), -S(21c0f26f,1e5a08e1,3db7581b,86fc8869,f7db1689,c1137223,7305f875,65d3c5db,e799f72e,24aa785e,13de622f,224af49f,ba408dbc,22a935c3,2e3909b1,2da7d775), -S(a49694e1,2feea444,ae028e73,e7c56924,7ae4c7e4,fd7cda34,425aa039,c4c13378,de760a14,58c508ba,f8889c90,35478a55,a8ffdfbb,4ae61802,a364832b,5735b599), -S(1c49af88,e3dfe13c,69e470d5,d8680b17,b2f3094,6e94a5e9,5de05936,d556eb71,3466dec,96cdc49,54957fd0,3bc9376e,7b53b222,ae5f5765,a6645110,c04e8f05), -S(e445bedf,aa503c85,c98cc507,86724a03,d6bda967,ded1752a,3b688844,485c0829,2eb37e04,25589c02,a1531e24,ac1c2df3,497cc81e,3ae51641,cd57db8c,f70f2ae4), -S(1fe3fa90,70496133,c6ebf718,8a076453,91c67d39,6d88f09c,a8244c62,242b494a,35a8b8f1,20503992,20568f9a,c5d0d90d,4a5d1d3c,b9a7c2ea,a17561d8,8d40e61a), -S(658dd6fa,63d1df2d,c9d4045f,c9726e55,2eef2721,90c3c437,29f4a01e,4b775b43,442b482,b77df6c,727f58fb,51331d0c,7604f8c,3da01b77,40f71ba2,f6219bde), -S(57441b8a,6787c3d9,b87b58dc,a66da1e5,32a8e8a,267f8961,fd1fbe3,3859fae0,fb065a85,9675effd,307fba28,226f1276,95f6ee27,389b6959,ea9ef704,ac460e9), -S(432449e2,51582cb8,ac8d232b,901d4796,63198f92,43c1ac42,f66aadfc,a79ece53,d5496156,87c64c16,c2bbf07d,c94e754d,af680ea9,47beb11c,94394c11,a27454af), -S(90db95a2,b17842d5,37c4aeb,42aba933,be6a9cc2,fb23b9,457e35,c2e6a77c,8e10ba44,21a6d262,a4129852,d6f1eab7,2e885bc7,1ccc8b5e,9023e504,2bd751ff), -S(9a7c6aca,93149860,cf4bdb29,fc8dfc1b,84d30bfa,13728f67,ef3bc6b8,1492fdd8,48beecaf,c66ab57f,9e5aa39e,76887725,3ca4a8a9,b464df58,3d86e8a8,f8b126ed), -S(926c02c8,cc70f343,9522fc18,29308f6a,3a1d513b,f632d3a4,cc56f7fd,259de58,229378b2,6e0f48b,de2b0bd9,8364599a,bbd011b9,918e1e55,cd7a0bae,a8cccf2f), -S(264bd086,5bd54674,11b22adc,f02653fb,d483fdac,1682a210,54aa810,9c9cfbb1,75032c4f,a101f117,a042bfbd,5b0fcd3a,3991875a,d3444ca8,5688e3d2,1d2df64d), -S(a2ef67f6,ffacb94b,9f28432,f27bf1b5,ced82580,8c46465a,69e57f01,c070bc1d,2ea53f94,5c1227c7,5eab61e9,a508cbd8,7730d9ae,73831322,80eb90ee,609130e7), -S(940733b7,46fa83a5,4acddd6a,76ed1e31,80daf833,7e014783,93641ce0,3c9a3657,c5a9ddcf,b2202a32,34f736fc,996cb301,9bfea0b0,21988946,8112f5e4,7abe6a11), -S(95e6b0a,eb191afb,10eb0ce8,bcc7c14f,5990a9c,c63da64c,c7bce7ae,1a0d9b48,80698f50,f7ac67c5,4d55911b,cc88d764,83df654e,9873c039,d854d7ae,14a92980), -S(edf7e7dd,e79ad130,1b7c8d7f,ad000004,298a799c,7d08cd94,38b0fecb,cbf5df2c,ae1c98c4,1a7b068,57786d39,169ebf92,ecd60d85,795fe484,707970b5,e7c33fad), -S(f6f75f2b,c0fe2cb7,8be2ef4d,e728e06b,e17f6350,4267de70,1a9dea54,736b804f,11d046f4,efbfef4e,9029f632,e1603dc1,196b710a,32173f07,94dad87c,f8095c84), -S(185ae081,d470ff62,7e73bbdd,3a7fc5d1,df1eb46,733fda26,8e4001ec,fd7b7b94,cf57835c,3a69e46a,5a58ec1a,2c0ff80f,4d8020c4,eef5e1d6,dca1e260,4b2e22de), -S(a93647b6,1342281a,7fa5a92a,48c3379c,4e8fd29d,2113c07a,792e1d75,ec4abde4,b2260a18,e6a05f66,998c3aec,201ea4c1,545ccc98,606d35df,cd671d7e,5b53fc9c), -S(27028628,171d1083,7d713e7,8011a818,81125514,dab8eaf6,846595c,d99cb5e7,99b0fa18,eccaa210,29e5437e,6d561f2c,a5174f49,42ea2f3,b640ceb1,50ceb025), -S(d560c4ed,f442947e,5a99d3,f2f8e519,b61f5243,322aa725,a3a68249,50318281,f403247b,70998349,d5eb3d38,1041616a,ad8697c,6a06643f,8d3b786e,707f12de), -S(b54c07da,a18196e8,33173c51,68d5cf7a,1cde555c,80621501,bfae82bd,2043406e,ee83b25e,300e532c,b09ed563,5b1e1a80,48fcea5c,5b41ed38,97cd2c32,8846b3a7), -S(5e43b2c2,8365005a,fb52b971,ac372448,22ed45b0,9cb6d829,f18fa481,91a5780c,6b3d5dd,951ff60e,4533f783,aab0276f,aab00898,4a4899f4,a31a00fa,a34bc760), -S(3a62aa88,99bf76bc,a23b39dc,d6008d4f,a57e9b1e,3bb69a90,88b77407,49b3ce9e,d83de010,f65c8320,810f7079,8de4f3c9,6e293792,841e7178,d894ff76,135c0951), -S(69ccd9df,9cfe0990,440ff050,7a35ac47,6a0ba786,56c775e2,7677bf59,e5c37594,73a97d37,48f1c24b,6d5c814a,a5829f0c,8589212f,485ffe5d,d86d9868,14bb537a), -S(9b2e9201,51d8b063,95823db7,83e33a7e,e35c092d,265eb440,bcd0a6f9,c9f89c5c,ab125c05,dd565f17,93033058,cc0a0ad1,f6b32ad2,90d129e1,6032c781,ffc2e331), -S(9af6ad84,535f84d9,4d80a592,943c83f8,76360fd4,787ea16,c6f6df4c,b9d92eff,a443e538,895046c2,9cb80270,7777ef63,ee18acb0,fa028a16,d7be8bfa,c0b4e5d0), -S(e7fc44df,cf4eda5e,c982a8a3,1a72d69b,b2b39f83,3dc4e621,bb002fde,2277f4b1,64fa8e8c,f2194013,8caccbe9,8808a47b,bda56376,d9b02ce3,33e36558,365637b4), -S(c820365a,3c6cbff7,273c80b3,f7ae7278,f6f4e282,dca68586,1fd23693,a0dbeaf,adac7864,cca90280,13bb3a68,c3d235d0,dfb3b99f,749b9203,9b03068f,f229310c), -S(3f97b6b9,235afad6,a4cf1eb3,dd3be029,7d67625,ec18972d,62ae4b2,a1b0de3c,a652fa0c,7fc89c54,e11df8e9,7650fae1,7cd51674,dc44be18,26e70b90,12089f2c), -S(74f315a4,d12dba88,1ef5b14,14bea596,ec386f5d,5f6e1dd2,f5e777b,c8c3370f,fc994b03,bd5a0461,9ce52114,4915b7e4,f9380a77,8a15407c,9b8a96d9,e7999c0f), -S(db546b02,795e2435,e8e6ede,3a45fc8a,1cbf311f,d0d9784d,dcd956d4,79d37b40,f16a6c,ab9dfb8f,1374440,86f1e513,79e54030,db4153b2,d2c06602,302ca383), -S(e1ce9f95,c8764028,b707f2bb,ef2b4d0c,88adeb47,f0469924,e2659195,6a53183d,358014fd,987f41cc,8f31856d,25a509f9,d406a68e,82a68fdf,1e1d4afb,99de59d7), -S(38f1e3,e35f77d,76cd5847,9b9b2c92,e90bbb3,d8793cec,509b29cc,c0fe13ed,faaa8e0a,a9a943a2,a5bf0e7f,a2a95079,ead33f72,8e1a3547,e55c6d63,3e908264), -S(143da00,da92138a,609b62da,8e90c19a,44b89be6,3372913,fc8cda65,44740ed7,2d042699,25782d78,8f6d8f4e,7dc63ca,570fb79c,ac2e5691,65a8df5b,38089686), -S(93819e60,23aa61d3,f015f747,d74ff5ce,d3437f2d,9c25d9a4,dd5ee0d,e4bb413b,3496f668,113975c2,4cee563d,5a5fe406,5e68b1d9,afc95e8e,2ebc949b,5779955e), -S(247bdc8f,abbe756b,a35c9f77,2c00836a,51cd8c5a,d2182e56,81f4f79b,2c0fbfd4,39dee166,712fab57,95edba10,8ac84b0,3ac90b43,7e22290f,91f0899,7ac3233), -S(282c681a,c67c8ec0,7c399e8e,a3198c41,a7993d37,b9bc4042,b0226d45,353034ad,8d5fcf2a,d66a9266,788d77f5,5fe4830c,6025c26f,e9468d95,3271d2a5,61634ba0), -S(e0e0229c,b260bfc1,a5979371,5bc7d226,eb9a8989,89edb9cc,5012a2d6,c05657f9,5321fb39,ca241eb2,94c69885,502d8d25,b85e414e,f540b713,e9fdbdde,ec0f50b1), -S(b8e62275,85d52f64,88a76515,e8c62894,7b9b01fa,1a7bcbea,9124dae7,b8a05447,84a564db,e14aa687,4cabdb11,7ccc7e20,706a7a54,c4c23689,4660ea5b,6d0a189), -S(77f3be41,2e08ecdb,b8443431,8e71c69,e6613ec9,bb2ec577,40cf944a,a3e12abe,39b45913,a90e014f,ffae3a15,a3bf44b8,7ac121b9,fadacbe7,19af320b,b9d35124), -S(350833c6,8ceebf3f,b0e5d4a1,749838f8,c60a673b,a7015eac,dd1050f8,eef646c8,ae37f219,cae837b0,bdfd2899,2625868f,3906564a,70ee0b90,92f2b24a,a2631de1), -S(2ee6a70,4c8083c5,3f88dc2a,aa39258f,2833d3f3,600b1a4f,61101e44,bed8d5f,589a8a8a,d8e32dd1,c7e54ad,d2b6952d,62017da2,5e68dda6,aedc696c,77b4dfa6), -S(156af2de,75e81831,2e6eabff,ffb82dc8,b5fc207,4fdd6341,b98597da,b22a6473,dfd13542,36d0407a,e0659ccc,b7eaa304,10bb4afe,4afb4221,4e70909,15d4fb18), -S(396d53f,5a488086,9be37006,e07a4638,496ad4cc,80c7554e,3f4b4939,5ba18d38,a7a6d320,39f05345,f41e2792,77bcefbe,10983280,f56c17bb,943c253d,7c094b0c), -S(15407e62,684b2d9e,4a8f08b2,31010bc,fe42c9e5,f85378f8,904e649,a759c7c0,54ab28eb,1b91562,ad8551f,47f41c96,2516fac3,3af933a0,75c757cc,e381d3dd), -S(80fbd75b,1538f0bb,96f29ebb,3c50682f,de0cd2e,e9615f1a,4b8c1b76,3b2090fa,cc3613a6,8608dc75,97870658,3d478a33,21c3677f,516cf6f0,6fdfc253,3bc0946a), -S(c795f08f,f5458042,f6268079,36fdf08,bda3ab0e,5281fc3c,447df53f,25aecc93,1524dee6,b98b74b6,616509cb,77a2a5da,2871b1cc,78a7b217,3185c187,223b88e5), -S(1c39286d,1aca3eb8,36bd90d4,e46ade42,ba8c0b1e,43523499,ab151e3d,7b331e6b,4f81e790,e66df7af,b4725dac,b506bb73,4c299afd,21dbbfb0,a60055c7,ebf119fb), -S(e778e362,f5f67d32,73c861ab,3cbafbc9,eb03f7c5,e862b5a9,2b7a51fe,26daee5c,1035cc76,9df9e120,7a71a13d,37693edc,19fd6ee9,33fae651,a145cc60,37ccc1dc), -S(d71b5cc5,56ba74aa,a0ab5775,cf0acdee,54e5c48e,5cb08734,6e510e1b,18f9a914,f3c3419e,84b4cf22,31975aac,e31b9b36,9aeb4a3e,e2b2bc6f,feffc3fb,538e8e5), -S(819e3ba3,6f5b1011,64f3e798,764e01af,5838ecd,e6141690,971e562d,a99d0520,da38a00a,838d85cc,f606c440,b941f128,a66b0216,544008b7,a4904094,7d7557c), -S(3c726a07,740912b5,560bca0f,f8d827fc,a9f2b1f7,1596f922,218a95e5,db2c7048,b9e52f48,ee2d0944,3c5c5776,eef02a78,47cdf47c,b83316b2,220fbf00,4b3d72a5), -S(e2b550e7,189f0fcf,a897fe12,245d6912,e6743828,b0ab0d78,9faf3865,d90d1d1,11dbf946,3cefe572,f45a5288,55c2a257,43dbd70c,3db6d012,34821a0b,35ffb115), -S(4cd65ffc,23acbe0d,59471667,44ca1194,f52dfee9,ba532725,508eff79,61130fe9,9af3c41,97fa257d,79fcbe93,145fefb7,96bfb0a0,3914ade3,c1127b41,9e321a28), -S(6fc537e5,4f7bf705,bc4a7a1e,a7cd365e,ec36f190,dd4fc7c1,ec8f5f3c,8dc63c21,d06a12b9,ccf770cc,f8504b97,ae68c61b,1872d500,54db9cfd,76a55c29,58eeff4f), -S(33bdc335,cd76ec99,db66b3f4,d90ad5a7,924f343d,836edcbd,847350a2,10366223,2761ca74,ae8bd215,b74fd37d,9d6527c2,c10406db,fc5932e9,d408c2e0,ef554987), -S(a4ac1b95,e9a8ce4d,da11a1b5,c21401b8,b92d9bc5,f7bbcfda,3b1940cb,cc331dd7,8f630ccf,30f68759,174b4052,8082050,599c29b2,4922c1fc,e4a5952,61c2e239), -S(6f34af2c,86f06702,4f720e5f,89d45fae,f44a8976,2b0bb390,e9a7ee72,fdf07842,785c4f09,d127954d,d6e6dff7,e342bd1f,5540448f,ca390d72,485b2967,b6ef1825), -S(37ef099,8571efbe,bbfc5350,43d0fcf5,758d78cc,3ebf247a,cc7b4f59,480aae80,29a3b2eb,fc41f793,66bbee1a,cc6fffba,76d37631,f10136ea,4a47a18a,d9263c78), -S(3d815c75,6c6d730c,b3d7ca6,de486159,f0035011,851211c8,25bd59f3,624b9056,56e109c3,e6ad3198,48b2e00d,1168806a,f0a22c93,81d8a243,53850c4c,1c486cc1), -S(d3143ac9,845ed52e,961b9fca,faecd1a,ec6e8554,c90357e,ba2317c0,c832730a,f4276188,6db140b,4d9b8b96,1e6555ea,a80dfebc,8d37ddb3,a21e284f,50b1dc73), -S(5b0066c9,221d1b8a,3bf660d3,ef28c3a6,8c611dcf,943824bd,ba4f2a8f,836b03c1,86a24204,f40de381,21be77db,a23a6e3f,5c8ea5eb,7138d218,45d8003,cc8460d8), -S(62461176,e6bc9c4c,77f8636c,3ffcdf24,45ff5c98,935e4b76,1c4e50fe,c00b606d,5431f12e,488bcede,ac9822e9,5797c2c4,5a49167f,6989a6cb,601ed3c2,860c28a3), -S(8efe7f7f,482ab457,4a7e56b7,77a7b5ff,dad6e208,2261b9d6,bfd6c647,c88a757e,ef5e2083,ceaebbb8,aeafa383,d188f30c,7350f484,eec83262,8d9fbabc,522b072f), -S(4dd8e450,5ccb49bc,2ffacdeb,53bad1e0,362df309,5756505b,33eceb64,34ebe715,9f801ac4,243d720c,eab5def4,7a7e6d6e,a051d3b9,783a2b80,aacf087b,b575b58a), -S(3a345a97,85c7db9c,b5661c97,3c739949,c48253c7,bc36ee32,d4d74878,3b0cb734,4bb7a957,d4c8a2c8,e1229e1c,d29af780,ba844bdd,a0251134,5da7fd4d,30223818), -S(d76335f,3e14a6d8,b8d6a87c,7f8d96bf,ee171c24,276feddc,a52f17ec,74cd3ed6,dc2d6c21,590edeb3,a9014b24,fb8a6ffe,e99c0f0b,d8fad1b5,2175f647,d5be53ba), -S(25fb12e6,2e05fa71,57badcc2,ed5c53a0,89a55b1f,4f5b508,f89fee83,b309727d,c73cc2fc,4021d267,7821ac82,f5803218,d4ebb736,6fb22f98,62a98f9d,6e597928), -S(6ec69e2,970df6a6,52e50e1c,2682e39,66e60120,6ac7fd61,12dd1446,47a11783,e9d08d09,1148b329,6a8c7b7,f9e4588,8fdb1179,72e08c56,41908b1d,127b7a87), -S(f72d2f36,35701d5a,a19309f0,12d8c5a3,7ae0784f,699a200a,bca89cad,57b08db6,5081bc4b,16c53997,46f2a35d,e7d59b53,8956b57b,865a99dc,e8bd86b0,259888c8), -S(945fab90,e970531b,766f939a,8c1a5cc3,c43a5c7d,45b96983,ade1d042,13d2e46,d76f827c,1eb775ec,7d5946cc,aab05b62,97173b32,54407669,4bf194c7,c84e612b), -S(fc60b8e4,129df265,9c335842,a099edd6,182acfa5,b74110e7,7880281c,4f582b77,69cc15a6,11c54e60,72db1bc9,9af6d289,f647aa85,95006a83,8b3a91a9,da33557b), -S(a4e41222,f9643671,390a7213,e6d0f5c4,9722d41a,9d0102fd,818f4aa1,6e03f5ec,c1636af0,55a67855,fc6a1827,c9e3e463,88922c7,c769357b,4f4fc4b5,3af2307c), -S(b1749fc4,8c935c8f,f2dbb7a7,2a69524c,83a7d551,88b48ef2,30f0306,a156a002,43efe91d,ee498afb,4f47a4d6,51ce132f,fe1fe875,da143682,c56d936b,dd7dd80f), -S(407b881,6141cf62,b8c87b3c,439290f5,6be1c590,41c847f1,f127c8c,c4b913e0,c3c90c06,afc5bbdd,7c699eca,5ae24594,69735dd9,71bd6b0,e48db6bd,6b77bd8c), -S(b0054fcb,94060a29,f983b713,79ec998e,34e39d5b,c5e0c271,ef48ac4a,e12b3a18,e2b89e84,5aa2f8cd,8ff2d240,72c0491a,81be7ad6,1e8166e5,6619e928,7d37c2fa), -S(4c202cef,fd6b69f2,33efb265,77e327a6,b47e722b,1b8b6477,2372f4fe,7559e5a,1a04446b,e69535eb,3f10d334,38049fbe,e0374b53,54f2f46b,5cc1de16,59c3e726), -S(451ea6f7,c1e9992e,b50c5ee2,90784052,a9974a8a,101da027,753575d5,1f306ef6,ec8cca1e,a21e21b2,cd0fb48e,dd14609f,733b32e5,42cd1c,a1ef2acc,6396cb81), -S(1ae254d6,686a8a2f,135fd775,16de17da,5175a82,aa8599ce,45b1660c,b5f65d78,a2595603,71a24698,626cfd82,7efe6d46,d8c4e31e,1765ca1c,e01ef584,4a5780a8), -S(d358e246,514e986,b0b8a192,53e07db5,5a635c01,85d7f39c,666064ca,cff640ac,d4b34eb9,30620b9f,eb1f94ab,8f88f3c8,8d8a9a5f,4ff35528,df0266f7,d4481c2), -S(fd4af649,5415092b,e61abb8b,ea2827e,3e833f5b,4653a1fe,7e9886bb,ae454b54,9743ed9d,d30ef4ef,31ff9df4,e5d10272,1e5c7609,b539630b,ab555559,88b56965), -S(4286c7fb,d1b785d5,a778f72e,2574bbc4,2912abdd,ebd9f6ba,15bc6c23,c7700cd8,3b0c1d36,2f62cf4d,f5dfdd78,1414fe1a,64a5526,cd36cbed,8e41c740,56525e71), -S(2262acdb,7dce598,ec0b2419,2d761dad,8b413bb2,58444c1c,bebd1693,a1ed597d,c6bde565,87f6e506,4882d86a,6eaf0314,20107b26,9b57dce,e9ba48f4,d9a220ca), -S(b8eba19b,a6057f98,519c319b,cd3566db,8a4a53c2,f3d825fd,9646dae7,13fe7b5c,7bc344ca,fff215eb,cc8f42f6,6b711406,7a00e881,f7e40ae7,253fbba3,bfab8273), -S(d49b8d30,2d8a1c2,ea6e8302,33ec1fe,371cf035,57c2c45f,d0148df3,1a43b11f,6f1052e1,18fd6180,1694b106,8e1d8cea,f72b3e68,ba84d0e8,ad945fb5,156dba1c), -S(56db7750,350da2a5,c6a73239,13f987de,9b4ba04c,9f0c0fa4,67d53abe,129116a3,e4dc5c13,9b72462c,bc5b5200,68d27c73,9599b40,d17c8581,1caa69fe,3a429fa3), -S(1c987244,7d133050,8368960e,7f63a52c,ae56a840,cd19a359,d8e94720,b3f4d54e,9d8d1dab,8efaf90e,f2bbee51,b0e9d369,abc06979,48bdc1d6,efd1c18b,26dd0ec4), -S(e9bfca61,b09d2298,3f1657f1,f303e0ed,f9650830,c3151ccc,eb7cce77,7865568b,6c06c996,48a3a164,a57dadbb,304d9d29,75906d64,89e42292,63d4a86f,b4a82642), -S(52f86eba,9c3ed139,83704865,ad0ec3bb,e54dd2b5,5841fe8b,826da573,213dac7b,59bccd99,a53fb65f,1df73e8f,eb8f4734,67f1d4b2,715745e8,693589b8,d1f24d9c), -S(ac02234a,412dff76,e01f6ff4,a3bab5b5,ff3339a0,4ff3fc70,eac1bdd,f0eb88f3,768d7219,782584c8,e16818a9,f8ce5aa8,18228c2,21a7dfa1,6e9da56a,61227843), -S(c2e5044,2dc773a4,d0c3d1de,d9883be,dcc01c32,c83b2a51,3e946212,8551336c,30063e65,133d1c40,607c2cb1,50f680ac,43195e5a,8ab68add,5ace3977,4242b689), -S(fa02cdca,e19fc987,a7c43acc,77328914,741ac5a0,e150e9bb,cc6aa0ed,9c16287d,ad7e7b78,f566a226,99e27510,2a03ddbb,de7a5e57,58fa52a7,f198dedd,7f27f72b), -S(805110bb,99a2b8ce,a8dfa8fb,e4bfa353,ece63c67,22adb161,9c696d2c,5aa66939,aa0e9a9,df1a2a11,72fbdd30,6ec86d84,e04ec973,79e16505,5273bbda,4fae3c8e), -S(6472c6a5,55be3145,476b3cbc,9f1d5459,be137d1c,c4cf7a11,6d28a722,f1b8960c,d28a0da4,2cc3ce06,fa16e4e4,dab04b2b,eb74d8b7,8b09632,1d02ab86,b92b0afe), -S(a659d5db,dbb45d5c,af7a9893,7f82e6c,c37646f0,34411e20,e361d595,28c4fdd4,d064e26d,ac724089,90947031,27256e35,745ca0c9,696da250,adf2df91,1a3a05a3), -S(882a7c39,56bb7ba3,f3d20df7,d0645bd,b13db6e6,2ba58f31,82ce4efe,2a0846dc,627c82c8,82437a35,1ebc003a,4035af13,63de299a,52924337,a4162a0f,c5bb17b8), -S(5556c236,9f7c003,d5fd2451,8c4be1d0,9b11b2e1,8961522,68e5cdcf,a6282db8,384b8cbf,13d9adbb,7a2fce16,38b71729,aa70d754,37dd7427,8cf98135,bcb0f1ae), -S(f268a877,472c9305,e3c2b193,303c29b0,a6fd2ff0,fb1563eb,ec5d39c0,def431b4,5dd08bbf,c1b8cead,9b45f164,e6323f7,c1bf0b33,bd9ad8e5,c553dfa4,cb42a634), -S(fe3438ef,5cdb0229,2c5d392a,387c38bf,87e453e0,596c5546,aa27940c,7686a90c,5b3baa2f,76647870,95c3453,64f59327,415d6aae,9fce79d5,85222afe,8304b998), -S(51216a9e,54a94c50,f2c2ba07,9548a51c,8345dcf3,b38a7e70,1a3de47c,9d5422fb,1046f888,360c5de2,95d63e16,93463bda,e3714f16,46f74ab7,3b6d68b0,15df71ab), -S(326d2470,700341,9ba6438a,b7ba4498,957e919f,f748590a,130857f6,d46386aa,7e31c242,cc2f3ea7,d5579be1,8e216b8d,9f69e360,c03af079,636bc03d,2090b770), -S(cd5abed8,a071a8c2,4d379611,4d81f490,5e644884,82b2e2b8,3eefbd92,a98947b1,f3d6560f,e10eacaa,9a30cde4,ab852b49,3ef0add2,f6d83db3,5d12b0b6,705292f1), -S(4482b5fa,c39560b7,7550b621,238fd8a9,5252e8f6,25fdc8c8,42382845,8d2e27fa,c1d246d2,145041cb,ef8d3fc3,8b5a1237,fe400256,e4d2588c,ee320733,f6884933), -S(1eb303,74179ee6,76a977a8,76ce0ef9,71ca88b6,615f3729,cab3cefc,6080caa4,a9293fd4,a0a156d5,f8f735cd,a60b9ef2,bc6004b9,efcd12f3,a0f5c16b,5524e421), -S(542685da,a08f407,71cc90b8,bce723cf,d2f6e616,133adcef,7908fbb0,ea29a4e9,df4076d8,44a4d3a1,10126bfa,344fb3a7,79f7455a,a9abc99b,7429eeaa,989b5d44), -S(bf631fa4,5277594b,c425882a,85a361c6,d62c50e,aac20ba7,ebaa596d,d6801a54,69995b4d,f20f336f,44681ef6,6a65b54f,88d43953,6458ee9c,f7657389,94e53bf1), -S(27be809c,5bb70530,ee629628,18a4ea73,540f1e6e,75990926,3269a205,604e7b53,a5bf709a,caba50ab,ad939c56,1abbd0b3,fdafaded,3b82d9af,964727dc,bcba7b3b), -S(40126263,3f3af376,4bdd2a6a,c1c6adb6,fee285fe,1171a29e,af4d71c2,5f03b849,2ffbed36,47815c25,5d5bf7d0,a7f09dfa,8eaf79aa,df9e95ae,57024960,ec98fe8c), -S(a634b11,bf441eff,6ae8eee6,dedba52,6377cb96,e3c36a7b,4ebf02de,42146298,57c555ad,85f0e194,2f9701e9,1227e0f7,42763296,2d0702d9,e81e025c,c411d379), -S(d6130997,fa2259f5,bac49b16,38d224ed,f30786ab,c7321e10,d593b932,27745905,ed5a448b,c2157699,b436efe,6725f8b2,8df8282f,1a588692,41ca7db9,6c66821d), -S(4a313361,bed4a94f,b7d9f1de,a1feaa4d,3d957379,cc24d880,92dc29df,5c503d72,2e4e6930,b8e33e50,d166f862,a4f73520,63470e27,f9d9a3ec,3382d252,e42ee20e), -S(6be34d7b,5aff85f0,e731e6bf,285b2f79,eb241c67,df9aa3aa,c2574e5a,d8b146e6,a9ab3f20,dabd0073,5935255,925676f5,799d14d7,75c896c0,de451057,f0112f5), -S(2e42de88,38560214,228691ae,26a0a26d,fd96cee7,9416439a,e771891,3499898,6ff846c2,72393037,a2d0b2c,da38539f,f8d3a6ae,175fb604,55afab50,8454a419), -S(d65d003a,c979da6d,9e4b077,3ee965a2,f33e512c,5c20a9e7,456fd3d9,fb5b0b6b,fcf12ef7,6fd89385,5ade4bc9,4984d7bc,63406649,d4525f1f,3c9f35a2,6b357f0b), -S(f58d02ec,d136eef,67ec91a2,6fc5097b,74c01db1,911c2685,4941f56c,af6b10b8,14169b8f,aa3a5512,55d3eb4d,25ece18f,d802606d,f1259504,64f79587,518561fa), -S(fd13b1c,d189e832,e3c06cf0,6277474c,3e388979,e0a7e925,1799dc9,a9713b9f,a2838fe5,4a07d539,5392dee5,dc2269c5,9fbb222a,8541f3c0,7fb28cd8,1ac2283f), -S(bdfc6941,424ba1ec,88ecff53,c8da31d1,ee6ac442,c8a1e58f,5171f4fe,b808d41f,a0533200,4e7582cd,a824600c,20864fa9,b8286c7f,2107ff82,9b5c964c,dc4a3531), -S(a390ea29,4096bf15,e953986b,86893c37,e2cd18b3,5a0df983,5be6ba2f,8a5769c3,1b432110,1c37b5b3,147029f7,aec437ab,cbe82b5b,559e9446,a2cd4067,9a9b5b9b), -S(40a61a44,a356f623,968e386e,319bee22,574f2f41,f558cc5c,f8a9b6e2,93db0ea0,745b1083,a9e9e080,365f95ab,31db5c6e,9e38c2f9,62bc4e8e,6a879768,f21998fd), -S(2ab87f5e,83538093,e99e09e,468a0056,5db6e308,2bb072bf,b7f5522a,24977f87,49a22c4d,790450fd,f31f8199,1084676e,7cdafbbb,5656e2d4,bd03621,bf50cf68), -S(656e91bb,156468b,821fc9dd,14c3ee76,ea8016c8,92133d2f,189820a5,81a964c,d8d153b6,870c6ce7,a4db4eb9,bc1f75bf,22f6c3ff,74865118,fabfd336,c7ad73), -S(d2c9e2ed,7cf8c21d,8c078e70,73c8ea8c,88e7169c,abea0a44,5c6c339f,82eca7d2,2db2942f,ee70cb15,56fe1d30,d5bc94a2,3d748e0a,7ce8735f,876e9931,90552a5b), -S(a5301947,cc6e0053,7cbd19ad,db91d854,67ab1bac,1a5e9862,bf46ebe9,a2d14710,c36d3b1,d62195a6,18f5bc12,61680ea8,1000f37,86f3ad28,3f516d16,f45e7cb2), -S(1f61d637,80113793,5cbe0dc5,34042617,932efc37,c3a95ea3,57575ca8,7280269d,24dd91ab,4adfa0ed,9369d30b,70a25b1e,df9b4383,37d83464,7fe064c9,e2ba5de4), -S(14efe93,49750c63,81d61000,4b80c733,204afe5d,223ef3b1,e45bcb6b,177c633,d8e284f0,ee2f4826,9c958271,3caf5364,6361294c,a0aacdd,a9aef70e,8fed2bfc)}, -{S(782d5c9a,d970322e,deff2e7b,57844184,c589a4da,c042fcf3,86c1a9f8,26c1babb,27bba565,405cb392,64762d97,cbaff552,1bc38b20,56afe313,556542d3,f200eb06), -S(1c000fe,9372bdc3,68d4d6df,832c0396,3701cefa,bee1cdc,3965e183,3476f636,1792668,89cb19bf,39633363,98df43b2,9d2eb378,a9a30531,9d33ec1d,a571eeb8), -S(17688e97,d3dd0dff,1f43ced0,af969ed6,d0b53f3b,22c1f1dd,240f4bbb,253770c4,bdab9644,b7047941,f42ce962,4800d25f,54dd194c,6fc74eeb,2e1e9779,3e4890f1), -S(c9e92b0d,e85dde86,8eac6f6d,1eef4b4a,8b25974e,7b77cb,fc210530,b595cdb4,5aa94a9a,7210e6e2,e04dda5c,8250c8af,16bd5081,f2102f6e,a9d09265,8b4c4ac8), -S(c9efbd02,5f6aaad,e30ec696,e5e6739f,ec6e89dd,9bec22ca,cb2a9142,d7bdd284,f32f9e4e,dbaa0a73,135fc5d7,7d2cdcc5,80c357c3,144bfa1f,e05e70e1,c8888744), -S(25cf39cc,ceff3fac,e9ae5cb,e6e6db7a,586f1fb1,8b3c444e,28cb2d19,ba08ef4e,d3b55fe5,3f11624f,f6c25252,4928226d,a82128f2,4649c140,24fb1f17,c9ba9742), -S(262a25d,36253456,cabab430,5be8500b,e2fcf871,1c580d9a,a76202fe,9e97eb39,873e797,bf2adf55,dbb3b0a5,a2480c30,1395cc6e,477f39d3,520e1a1a,6e61440d), -S(3041bc09,6dbe8a9c,9e436f15,bd88954d,b2e1586,5de92c9e,8f8df7f6,456665cc,f17d1d17,e406001e,1aae6cb1,ce4c8889,4a502e40,1a0f7f04,3f8daf4b,a4ed4345), -S(d0fcb1f3,8d32d3c1,5a0d984c,f9eec4de,22e0f400,b93c0343,337f98c1,db2afa4d,de5133d3,f7920fb1,4d34b28e,5058d81e,e9e312a7,17590c98,aa242e98,92f8356d), -S(65f5da86,cd13e857,f41a7016,9e62e05c,628506ef,d1739ea7,5308b75f,510f247c,5e52e176,38b22cfd,8f1f800b,edcf0af2,1efce458,e179da1a,d046e0f9,5afad4b7), -S(a4ae6a21,f07f51e9,cf635714,e0cd35d1,d31fe32f,22d29ffd,16af4bf4,65c859df,41a69d4c,ff1abc12,8831efe6,e410a22d,80790640,5f319692,46fc3bd5,2589c094), -S(d92d5f09,79a47bb2,e995693a,e005c266,54d6260b,85f41806,89407c47,69b2c5fd,1ab29589,87b2e4be,6ed6eaa,fc47a9e7,49349e9d,1eb438c5,735dfb9e,d77f2e8e), -S(f0f136b0,787e1c0a,e43e3c34,66d77cc3,64282ca3,4b686a23,eb30622e,c50644b6,1fe70372,b3047ab5,242190cc,6fbc18a6,4dc0797,d51b2ace,1eb208cd,30625ebd), -S(52cf110,c8a81a1a,f6ecba15,7b6e2748,9fade773,20b22880,ac023ebb,3ba95119,eeb4e114,2762e0d3,42ed393b,c3b01a2b,e7534b34,c7466f91,224519f6,762da31c), -S(dc1f1041,76019cb9,e5ba446,f1601edc,77ff662d,e69a560e,2795243f,e3635bd8,29fff9f1,d8aedf11,5f518298,4b82186c,1c2b8e9c,8d80bf5d,c0a8b0e,9598700c), -S(dac7cde7,dab3d68d,cdecaf9,3b4a1985,ba099d97,eefb84c1,efd5b103,1559bd5a,53940d9e,785b017f,9142dfb4,4157c250,7a8543e2,c52150ee,8ec1910e,caaa36e9), -S(42500318,5ca69e1b,c4413ba8,ed3949c0,bc39ee8d,10b543d,c4035f57,7f46abca,5c187b2c,936e589f,66ecdee7,dbafbd48,b184a1ba,4ee9bf01,f70327f8,7b80f384), -S(1a8728b1,3cf2ef6b,d122df7f,ae11873a,fdc4aaa5,46981212,616f7a35,73fb94bb,3c6e1732,320fa8fb,7bc908a1,93204afa,aa22e138,571bcf1b,b0b31285,2cb76d21), -S(9963b507,f4fdba39,1312782d,35446a4f,a1247315,29a1894e,cfa86138,22206031,1b7feefe,36616571,f904d548,4673322f,4e867016,b60527a0,f0e4ffe5,97b7021d), -S(5f98a8b,93016cee,48a8bac0,6553c0c9,c3f0af5c,4ff969db,237f5669,ae7c4f12,ef144971,69e32124,d0ce4525,c2ad7857,43a62914,ac21c954,a1f0f6c2,4cc2d091), -S(ff4d4fee,875ebc10,fa6db1ab,19941a6f,b934ef14,6b2f7299,cb7ccd74,5c6be029,10b3dcdb,2a753aa7,e2464ce0,b021eabc,3643134b,9acb6f55,955dc471,8a5bf46c), -S(ff159279,11c229ac,f5f0aa9c,67cb98e6,309d16c4,94a95808,91bdc404,e2a1636d,5ae15340,a7e94020,108e0a07,3e775a92,a7eda92c,ceb6af56,cc91ace,e8991e1f), -S(652bcc4e,a1c2f450,10273043,2cdbf01,3e07aa76,7f5d8d00,a48ff9c0,b97d73f3,de96c171,173cfa8e,66174a45,e8899d12,f5ff50e9,481f6310,8293075d,cf5d524b), -S(8d33a9db,ca44ca87,634d52ab,c325f892,14330c84,d6adf84a,3a2e5ab6,ace8089c,6ac0fb1e,2324dfdf,546dfb42,37a523b4,1d8dd5a,81a6c398,2ff14f6b,c68348e0), -S(b7356428,d0f718a5,a999a4b0,cd55332,b812920b,26b5c5a,babf1afb,3c1ef230,60a1a61f,17e4a054,921d9187,30807530,3c0c72f9,1ef469da,743c8a55,cc58f62a), -S(bf32c76c,c733c2dc,85299812,392a2ee6,5b0ce661,93cecfb,ed2ae522,48706aea,961e28d9,a6dfc6e2,3b7a1235,4b9551e5,bd1da617,f8a4d985,467de1dc,bb2b6630), -S(68760c7e,1b0b625c,bfe9533b,fdc4df7,cd0acd04,de4c4e5,cbbda233,4d2394ad,b0ea6bb0,f9c5c9dc,91af54ae,718c3ff7,5bbce1eb,ef353006,3809ab3a,4432978c), -S(abfddef,d56b2944,ba1548f6,dae0e65b,40e19431,b6415380,3558d497,7a373aab,ab40ea01,23588781,882e332c,432177b6,15023347,b76dc121,be5a0a71,f55563f1), -S(73800767,7aa92884,93ace49b,60923a7e,e3adc2de,78c17e28,3ae967f3,72145ad5,fb1552b1,6fa17e4d,1dc2bb35,95b1b1d0,5dc7e48a,ea07fde6,7e6f7c75,f15f5267), -S(50c0bf3c,6e3666c8,a1a69544,90590b43,996e9a75,77c87e0e,5bb8e927,5caa4ec1,d0f80c96,1b75680f,8264fddd,31b52c28,48a769bb,2976d706,b922b46a,277ecc24), -S(879e4cb0,47b3138f,1a5cdd5d,9eab5b47,a9a8b542,83fc488c,f82ab22b,7dbf2f47,5f607d08,bccffc0b,27c2f0f8,f8a80476,52fdc19f,eeb62b02,248447ed,d5743bca), -S(6ebb3735,465dbfcb,32bde807,471e19af,35d5568a,ea6f5286,4a382596,df623bb7,e2801ff0,8e04b574,414d4844,b7b1efe,8741c0f6,4af13080,ef473397,3aa0bdf8), -S(5997354b,9b77dda,f34a9ef8,649904fb,fc8a0223,1e8cf882,7a8309ab,b209f420,d42f55c9,4d8054ad,7dacca4d,8d7553e5,355db690,1df155,5bd07574,25e9580e), -S(41e392d0,456f7aca,f62f8c96,37881d25,8b316bfe,7655ab56,61413f43,4e428f87,20481bd5,36bbd86d,96600911,1da82106,2c55ae0e,b2f12d81,a8b8a1f0,4309af91), -S(5c3514be,60fb6a05,2303b2ff,ccf81ebb,5734ddd9,ff2b485b,429ce68f,3b16ae64,573f787,958b70d6,36565295,b35d9e73,7ee46c3c,d1d1ef0b,e37828bd,eb80e579), -S(de9e95c1,220bcf2c,cc2acf7e,ceab12b8,239f5531,e2c52949,29e30daa,c340ef7,2e20a50c,94476926,ded26edb,72780f78,81f01cf6,bef5b1dd,5051a27f,abc2b181), -S(29922283,6619c2d0,402ff634,ee6fe671,b0afb7ca,cdf4d109,cf98814c,af69adac,ad3f5da2,7b1785c0,b958af5c,7e9e7a85,f6c7002b,3000c25b,f7e82207,fa9ee9d1), -S(82f8b1d4,b50025d,fe960c1c,600eab7,45a25ba0,ee052eae,2f3e56c5,bc236561,97ff7a9a,a3fab00c,54f8bc06,fd59e050,b854f7d0,53dd2df7,1e93d75,60456d29), -S(4b883553,72c3c528,b8edd509,b8eb2b21,92e8504e,da5087a6,d2a3f9ad,256cbeb6,b0ec67df,a34acd1b,a3a68b3f,79962c17,11c0bfbc,3fbed2f3,345cc097,c221aac3), -S(53cfaef7,ff6b8bee,f6264a1f,f4b796b1,a5d3d1e8,471504c8,d6ea5d2a,5362644f,35697dde,1730762a,2692fc5b,1db386bd,1749e07d,a67ef310,47deb9ac,394ab691), -S(c4d4a268,112c2adb,d862b32b,f344af89,4e070db6,2262daf9,244b5c2d,758e1cad,c109c651,2ef251ad,9f9b55b5,10c973e5,dd6b2746,996942ea,7e4de0f7,cd8a18f8), -S(13d63ba,49b043d8,ce6a21a7,929745df,668a2497,5a57895d,704b4f9e,3bbd0aa2,d52dd90d,6e418aa6,afe2037,80870e15,78ce6dfa,c1a73879,490b57e1,c1f06878), -S(4499275a,5e03c1d5,2ee69082,9bd53365,6dc44a6e,6584d2a4,3c27ef78,fa3475a3,4f51bc3f,56fac2ad,3bc36d35,b47bfc56,b3885e3a,9c279c86,83762bff,edc952c3), -S(e526f9ce,24911c8,30311aa,82e8855c,575c9e2c,553f7392,2285fbb6,caee91c3,e56c2c38,28c7432e,20b490e1,3f6c2476,47040253,7b1d851,31690263,a41ced87), -S(723260d9,c31cf302,acafa19d,ac90ded4,18d5945f,e5fe302e,e7fa8e84,b3fb2449,bf7b11aa,b5603f1c,89a8d6d,ecdbc47c,9bc0d229,937cffb0,8e4bb060,d932f6ff), -S(5895fa08,76ae7387,41184045,d088aba1,61be9802,33f8820e,7eb1f9fd,dddbf76e,a4dce1e2,d7a60205,197a8458,d566e8e3,720edaa3,bfc4d946,f798e438,ea3b3c65), -S(c358ae6d,c1565fcb,623c2c2e,a575ad86,388dc893,b9153135,af4e787b,17c64c9,f5a5852e,e3826ec3,e20a0d05,c330338f,f28699e4,ebd749ff,3abfc3de,edb3b97b), -S(efea41f2,599d5357,5314ec4e,7f36b564,1f31802b,ad030d6b,cdf8ef63,4c1491dc,5dd25fd0,45ee4019,c2d22619,e47da1c8,1c4062e0,d6a9bc4d,fb37c6b6,7b9c52ea), -S(8e939129,e1547a83,c73900d5,4adb8bdd,79f98d70,3c9c7689,9a7b3f35,8eada2f4,47b19f53,433c6b75,f8f33cfb,3aa91908,b8acc5a6,a69bb533,711cd84f,f497ca86), -S(e5f3fe2e,ddd45d3c,745baa9,fd812dbc,dad77d5a,aaac44f1,20f92515,53681f79,a450e661,a13cab2d,758eb49f,4e49907c,f9ec8207,bece14e3,e3e80eda,cafcda1b), -S(727ceca1,f1985b59,e3b1abcf,400972e6,87f83e1,ffe30f64,c853c8f6,35f4a3dd,c451b046,44e83ef9,d078367c,3cb44374,ddada9d1,9416ac28,db60a12c,fc526fe9), -S(a98a9e68,da05a375,80c0633e,216d76bf,151a7921,32ecb2a1,c114c001,3fc095b8,26aac75d,f680f14b,ac3cc30c,5c14e782,3b7be308,ff8ec2ed,1551737b,2e213c33), -S(2dc1bed0,a25f6024,3ee2e20b,90158ae7,102b43f2,c781f91,86dc6d8f,768a0ba6,85b6b3d8,509d7c9a,ec12d44e,453456b0,c881212a,3c056d0d,827f5488,f02e581c), -S(90cd9e84,5fc1e7fd,28f28544,8b9459f4,e22be67f,4caeec44,2c96d77,3f6932bf,63c92e01,1cba5199,3311487,7b208922,1cc6a651,b160a049,cd558e90,3ed560e8), -S(7ad554e9,61e1084d,8be77d43,e8aad732,5725a9f8,3ba29da5,6ee8e21c,8d6f15b0,9e13367c,d9b38a18,6b8306e8,714cb709,12619c2b,56953ffa,9c538383,c7b36e3f), -S(e39f4f35,c68f835e,b84acfc5,dd5a9c4a,84263b85,376ee9a7,e72489df,c96fe3e5,3f06c83d,60b5eb27,f6d8ed32,1d38630a,8bf822b0,1eb97f0c,90d2d9ba,c1fe81f1), -S(e732ec5c,6d2c9f2d,17ce26cf,99151e74,31aa7c07,87a9cbf8,65611936,5458124d,51d3e77,e75c44b5,4576bdfe,36cd28c7,9131d0f4,b1cdc356,dad51aa7,253e077a), -S(5cfbff88,130d394b,c0ab5ba4,b79ac89f,f78a2c0,fb3f7f35,bb3b8c60,3eef9596,18aca6d9,58e733bc,12ba085b,bef5173a,6990eab2,59bd6d4e,e3cc7c5c,7bb5516e), -S(69d1998e,3a0be330,a6341161,76adc83b,6d2dc4d1,2b985924,468790b8,25b182c9,5d8435fc,6cb17de7,65b628bd,2609a81c,a4f8d081,337be0d7,89cfd817,583849bb), -S(4fa189e1,1aa8d445,aaac9fe,b8bb0fc3,a615ef8b,5db97120,b231201e,1622d7a1,ae8130c4,164090da,706a5f21,1bd3389c,8a08418b,36c7b248,a9ce1c7d,7f62a175), -S(5b8c0419,17905a9b,7f6683a8,ab52261,bdccab65,9d70db3e,daee62bd,a0647a44,ec7c14a7,ce63910d,4ce729cf,e1c30a22,3c74fb05,eac31e8d,876487f0,cce4bcbd), -S(d8911bb9,9e908660,34a55849,84a7eb49,2f4e2ca1,c1f99d3b,35fe4d58,8813df71,c479c2b3,4d9d5bdc,c82e1f76,c2aff35d,cd71c0a6,fec01808,a0d35ef6,e74631a6), -S(9691f765,417f4841,22baf14e,c65afb44,8337b915,dc85d449,c6101e07,9ec94981,d3f163e1,a69a968a,223e2ba5,145d0dd4,2a8cf4d,baa6d247,4ac5c965,3cdf7049), -S(27299a8f,98275592,39b42976,bbc08787,30025475,79c6eaff,4f959156,61a47ca2,cdbb9fc1,bf25ee54,f5524fe9,c5d70a59,3f849ce6,b9ef2b72,c9d85c57,a0f54974), -S(ba929ab5,abb7da7e,be263049,558e3e68,397811fd,9346890d,ca890f2d,4260a31f,78e7195a,1d6fa4d4,a73d3b25,125b9a70,1346492b,962f3587,7e5b8a40,7b94e610), -S(5d065bee,93ed86be,f4d96ef1,cb1584a3,7723bca0,1c696602,ad27615b,a0eefe84,592a8fed,16b03476,ca7c695f,3e934da7,c9ae43db,6db95bdc,e313ce85,8d6efabc), -S(89c311cc,2cddbba,b5d183af,2d6013ac,f3682f24,7c51a9b6,fda419fc,5620678d,a3c6ff3,9bed892f,5fe084fd,18e7ff3c,4facd6ed,38afc3ba,becbf4e1,67e086da), -S(85d1158b,5ece0b13,97a5d9da,35880f77,fba762cb,58d05c94,ea27a97f,8b84daab,b8cbaf1a,b3f392ab,f70830ad,b7bd69c3,69384f9,4c2f11f1,476ac91d,f171c46c), -S(9905e022,d0d9504f,f9acab48,49be95e6,f95e1c74,f28a8281,7c6e858a,602f65ec,a1552c6e,19467331,f78f6fae,71de8604,504b11f9,66ca5dd9,8788597d,b52b88a2), -S(2cb38e47,c18dda23,10852993,6a668f2e,aa5ddd2,b1acbe2e,8d772c00,18a0b513,6ae910bf,62e0d313,fe326bf1,55e44d88,c85c61f1,35862d96,57237a8b,42310ffc), -S(b98cf874,dc156aeb,f85fe931,af406e75,2e4a7738,bb22db42,5a853949,e152dab8,bfd9ea5f,e8f9fac4,bda888c3,7e37e2e6,73d3262d,8cce54ab,f923fe5b,6afa964), -S(b907808b,678f8eaf,b29d69f4,5f62d8e7,990be642,1f62087e,8002216c,5f75d851,8e01d556,f9ab18ba,711596f5,61294f50,432b429d,5bcf101d,2c7db554,7f2881f9), -S(158c96ad,32e36ffa,1b67a345,a650d15e,e3caa5f8,eb9f391f,f14d04d4,a3299700,f63742a8,a8d39d2f,da081040,748d157,18c9bbc7,f228a768,afabc69a,7897dfd8), -S(cd62d2eb,1ffa09dc,e6d5596e,fd6627f1,a40e1d6,46e58d0a,99fdfda7,1e1d0665,9d0d6f0c,3e02d85,b99b723f,90acfa03,38c1e021,bc8bef01,9fb0deb6,ad41836b), -S(1616a7e,c92bf575,713bf433,e6788774,2ffb6c2f,f9ce2db9,f0df6149,fd7acf66,baf4dcc9,574957eb,aafbc4b9,cf6f913d,198cc26a,d98d9640,364bee25,6c76c22b), -S(e7ef9ff3,6e86908f,8cd68871,838ed08,2873771f,2df1ee9f,a74f8943,f2f46a3e,ed95ed67,65626e66,8cc8860f,b268b28,e9e4784f,4d704af9,3427f645,4f65e081), -S(9d91f868,ddb1beb2,a986d7ab,2e6c8da7,65e2605e,e1cfb07d,f368a30e,239b16eb,55ef3a1a,284bbb2,d73e4fbc,2f92ed35,b332c77a,fb19cc90,ec98d964,dac6f8f9), -S(609af9ec,3804a542,833fc7a5,bffd7bc1,da753dae,2de2e9b8,296b7327,b04da33e,fe876bc1,8fcd4c30,5bee3437,77a27231,c4e1baab,cd0afb37,9469c085,c416c8b7), -S(871a8cce,60560ca5,83896884,9bc3c7d5,3d9dee7d,ba988495,16258f64,23ccce06,2b557be2,d08dd1a6,126c798e,ed1cfe84,340aa979,c38de116,dc01e442,39418023), -S(1475a480,e6da65e5,ff84f5fd,d926f302,6ebada5,6f32c036,c7cc1375,db1df8a4,1e35a8a8,b1c38922,555357d5,69ef412b,dd0338a7,54e58ca8,87d09cd4,7e9fcbee), -S(4e90a94f,cf609448,27b69ac9,7c758057,9aaf77,54e068e9,db68f50f,6d46f68,5a7532b,13f4224,b51542aa,6e94b984,651caf84,37a16c56,1583d227,8099cd22), -S(bf8f311,7c4a9500,8fb70bcc,2442cb8c,bb5be275,f1631dd2,e86edbd6,6e239845,2f8cfd98,1dbed87f,4c51d621,8b308d4,76ee4e60,161509d5,861ff2c0,72a0cfb), -S(ee46cc95,d118b3cb,6c37dd09,31f42988,ed324ceb,9a6cf226,87fdfe13,1bac0cce,4bd94958,867907bb,4823a7dc,9e3deabf,a3ec504f,a4efad0b,146ded5f,3fdc67df), -S(76c7cc03,ca94b2fa,ba2aa8f8,b571d57c,6849461,5aac6385,11e28d0a,4345d4ac,89e964e7,d0c2bdf5,de3be34f,886d6b2,8955cd32,5e92ceb7,b379aed3,b216624f), -S(ee37e6e4,bc5616e,59748645,72e2c350,d43b1f5,fc6c672b,524615fa,e6a5e14f,8b721572,f7fb8c3e,a108c05a,1214ecf0,4443dee3,89fad7e3,86b054f9,1f0c3d5b), -S(e1c7ae02,561bd2f0,1e64844d,ee3df837,eb647df5,db64bae6,96c1312f,d9a0775f,932381c1,1bfe3926,37921d4d,7e1ffc39,8aeb52a5,b113d01e,1b78d0ff,106f4213), -S(6aa0b3e3,98f6f75e,f13994d9,91cdd270,c025c754,67ddc374,9fc530c2,7edbc255,5282fe89,2d97a94a,e4c54bf9,94d9db69,8f629f58,fafcf7a0,e18f85a6,574ecf22), -S(a4c83267,3ea49743,16e3aa95,e5d9ad46,30818d04,58c6783b,5f305e04,71b7e980,10eff981,dff167b0,119286f9,453ec889,a98ab7b9,4acac35e,f8a39745,2df75661), -S(d5b2a546,81726474,55c45c43,a5e900f9,4bdb83e8,8196e3e0,17cbde94,c2f2cfab,d0a76d60,dca26b92,e0a91901,d9b414fb,eb90155c,89ab67c8,351e15e9,da1bc7e7), -S(c7ee2daf,b3d220f,8865a578,6b070507,533d0b2a,3ebf9379,da04c68d,fc5bae5c,ed030df9,e07b915c,ef0dffc3,d2d24cc3,55a0af4c,f6462786,7f322b21,78420cda), -S(1327686a,b3a0cc7e,59a8f6f,c3cfacde,ff6c17d5,9100470b,94f04bec,ba82b09b,1ca32583,151c8774,6a84b527,313c79c9,dee0cb5d,3043f584,6799fd7,abd0d07e), -S(1b245c2a,3e49e7b4,4d35701c,f6b69597,9df760e2,e65df3d2,b16e8a5c,efd065c3,7ded9046,3a7b9073,c30fc599,eb8660b,f3073166,4fd147a7,d5c33903,ec3f046a), -S(d48820d4,c768c172,43727ec1,8b7d4824,ff214bba,1f079eed,828377ee,e386d651,7ccc1a18,5b0018f3,b7911938,21a30185,c18f3586,9d34dddd,4da1f76a,a06ff703), -S(7dcdd09b,ee384bef,55bd4591,82b7560a,aced0ef3,9037a661,317d911,38562054,19b815f7,c2b8370a,e4cbb9a2,facb11ff,b970c050,26ef5aa6,e92713e6,f5cfa3a0), -S(19b26e20,cb023c5d,f474cc3c,12a80528,aaf0150,bd90a19b,9f7578b3,c9624a85,71ef67ed,d954782a,a3fb9bd7,c7b747c9,e9101ab9,2778c401,18c96ddc,d1458273), -S(9dd490d6,f1ae170e,598c17b,3acdd8d6,f50f32fc,9f956bcd,8e2497a1,5af3f29c,e62680d9,4f21d3eb,4ea278d2,66c4bce,ece6c1ab,e6fc068d,ca9d72f1,21bf3903), -S(6f12b9a9,71263232,4c15a533,3726f032,2f634d81,964e0b15,b20dc998,b085998c,34fcccbc,b4177216,24471698,31fe129d,a90ca8d8,d95a62f8,cca5da0b,505d0b3), -S(b011c854,19c89036,77c6023a,bceb8a0e,496c2021,e0448993,87880eed,9f5c2764,afc0603f,aa87d081,5449686,d9ebd182,1f33f675,35d7ab18,5231e8f9,6c5cfd8a), -S(c7ebbba4,5d2c4b92,b71b0e50,3f4c4e99,d9b61fd8,e3bc100,dc3b6b42,53444c10,8c042323,c7a16c9d,32654e6e,240f5c97,901fc2,2f6e0840,de0ad053,7afde378), -S(95d1bb83,27dbe838,bda8e60,7f23f193,f43996bf,5a548270,fd296f9a,7ab93eb0,d15aebdc,f5432a03,3ddbd8e4,42433984,d1726068,634fc49e,ff0dc9be,e843842d), -S(94897726,856037d1,3e009a99,cc799006,388a0eb2,d34541ee,f548ec75,585abb64,7552c109,7343f999,9d97f0a4,ed65910f,f1d7ca9e,542d9b4a,3ecec791,3abc4920), -S(77b0dc2a,158cf2b1,88a98be7,d1b3c1c9,fd9b2c94,a2bdc2f9,c3597e77,e8572823,ff3dee13,5d130bb,c5c12bfd,73f73aae,c510ad84,cc9aee31,f28ba147,e99554f4), -S(47f7ddb,bbba408f,fe233d83,627582bd,a4d8915f,4bb5386e,b0b039e2,ed3706d4,63c6280d,be656fa7,81389b03,1d70ae36,6146f7f6,4fd736a8,8d9edecc,a45d2710), -S(b6561d0d,9673a6b3,4005bf53,20f74c4,acac0fab,d065d10f,8a61d5d5,25145020,dbf3f35a,9bcf58d3,ba3a5534,5229918c,a4461f1,8ae692a8,aeebd8cb,1e66782f), -S(fbff78c9,1c67bd4d,75d62a12,b679a4da,ba352a0c,73ab0d91,96ab06e5,c7e7052c,e2266fba,7e71ecf7,a6862bb5,84b1cc9b,6bef8697,fcba312e,649e836c,fa0fe837), -S(fc7e1250,3b630005,f488c776,9730f43,f5a4848,edaf869b,68bca480,22f85ac7,f8170409,f312edee,fa00b1b9,b62b463a,b7e0ecfc,563bf6f5,543ae7a7,10885247), -S(84f2f115,9fdc3a58,df6a2971,9e2dfd7b,165d1052,4eff49e0,6ee53a9e,6101f30d,50557807,24376a0c,215e44cd,ae1d1dab,619c324f,fcd5e766,89176f71,363d7998), -S(41f89dc6,3cc4169e,e6dd6317,d9aeb671,c5e0f0c4,c29c1621,b9fc1c73,9edb5a14,29d608cf,75a44457,82694ed4,32924d76,79a33233,2e62b4fa,cbad3643,e6ff9e36), -S(2bc495ab,ca4e5879,fa277a14,6c07a2fe,98a07db5,ee5a145a,e042b578,bb4e9c17,87b9ec1a,79d3d68,b822a80e,721238e9,c2a75c2e,aca94cab,2fb731af,f964de60), -S(4b18ea46,1f6468f4,f1f6b709,a00934b4,818032ff,61297f0f,6a4cb057,8cc4cd90,4f491b20,32837a07,171da3d,2acc4191,11eaa82f,db36464e,fa675944,a2c4f986), -S(ecfdc56e,c44009f,1206b7c3,bd3113e3,178e3909,68d6d2f1,cb85ce3b,b951e61b,5085e948,5b4a00bb,9f09efa1,17f83987,6711a043,1c3dd794,611b2c8a,c795229b), -S(6e97a5e4,2e911bba,c5f7ff6e,1c4fa9cb,9d12deac,2c13e8e3,1baa9cd1,3463a8a2,a86f92d4,709c635,f98dcdc2,e93d66cd,a541e49e,aec0ddb0,6b1c90bc,e692ccdb), -S(265226b4,253a201f,bb7db973,5558a4fc,e07c26e4,245e4743,2ab0bb89,e99a804e,51e617ba,10b8b90d,67f565d1,156557af,a967f03b,85400f9,975864c4,f5c2daab), -S(2ad97868,5a488eed,838560e8,b071aa47,565c4bf0,67337584,c20f8cdb,b2534169,8cfd2d8c,4d7bba3a,9d9afcf,2ee1d594,1c3aec8a,8e532e1b,def7e232,b3ae542), -S(457eaad,8c46f083,56a2c593,a65b3d7,74ee3292,bfc812b6,526aff72,8ab2b495,3bc3068b,26008298,5186ef55,7c9c6731,795ff1a7,34657d65,e97dc564,cad5a019), -S(dc83dd36,3ece98e9,636fbabf,96610f56,c74d0518,6ff0658c,e1e96aa2,8a488c7,ffb4642b,9f07e134,a3daae04,a7895645,ac49d6de,7cf95131,a9847514,786b4f76), -S(36962a9d,5731fdd5,379870f2,6562feb8,38f733dc,cbd6726a,41112d3a,c9df3cb4,efa15b5a,bd55c577,82e95c2c,12e54992,d9728e70,31566878,85e19362,8d55af3e), -S(494fa294,b5ac0d72,fc6f7f7,6b7e60d4,f8ec6399,dd1f4465,e57846b7,32210ea8,e0b00b97,71079c11,2a5a6e32,613c5d0e,420d1a5a,3212b52,71d0dbfc,4e6d16a5), -S(4989c175,23783475,36a6fe53,a6f135c,a968484e,f7305e4,f80b6d95,cf41b30,75dd93f7,f04f06b8,88a19ece,4811c5b8,9992825e,9be07f8,c212b660,13cd7017), -S(677e82d2,8b74f3db,73a8230b,98729acd,6b010356,5ba148a5,2438a5c5,436b6fb5,1ad2444d,b7b84e6,c4e2f573,cd2fb644,f3823c6e,81a574dd,bb4777b4,e26ff10), -S(c379002b,e70b8de9,80af55ee,bb05eb6b,ef0beb5a,102e2172,687f85d5,b9984d21,127b0907,fc511741,77cc7f9a,9b36c334,c23d1d72,20267878,391644ad,dbacf331), -S(39b33368,5aa7ef10,fd223b41,3c375334,38d06cf7,5b27ca06,3fd5c8e9,22cca4a7,88aaae58,acc5c41a,807e644f,6cc1bc3f,1f147174,994e0440,ce678f78,d783433c), -S(825be64f,b35ce8ed,85cb6826,79ca7677,5a40bc3c,105828f3,a8b30595,ac3b6b21,976a3b6b,dae0f22a,e33f3d36,7d3fcf21,29f2ac35,e8239df4,553a869f,18650183), -S(47d9d5a8,8bac6136,ecf568dd,ea7ececc,57f26b88,6fdc05d6,4c5b7ae1,113d3a7c,c6863fd7,e05f3e16,c0a47eb,6c2b0581,184b8d8a,550da1e2,370928cf,4d7b2804), -S(bb7576df,abfd677d,6545db2b,69af7d62,20ba17f4,f4ae2881,8ec91a0b,23487df1,b5df0436,9d7227bf,67953da0,ef410f0a,a7cf80c7,4f3c8c89,de6cf1b8,7c65d16), -S(6febeee9,251bea0c,d43eff7a,da9dc5c9,5b86db1e,b0e09bc0,4d34fa4c,4ead4508,df691ae,ac9bda8b,496aa808,949d348,97166b32,3f99c9cd,a851f68c,26a1e39), -S(25fe413a,59744683,ef244175,a8021b6c,62e7c2ef,c6489261,958167e9,10716fb4,8be281f6,2df1bf49,8823c080,69849a84,b1ce138e,2326db32,cccab7e7,8c8a1ab7), -S(1389327f,be427f53,f219b978,4faae37e,8337f5a3,1c377bd3,415596c3,e72bdaf5,fe33fffd,a7bb26f1,34340613,ab692eb3,9a24916f,37b66df3,194ac53d,1f9c1a99), -S(1a3221f,30f9ca00,9e9b3e7,ac40dd45,b7b37b5c,1cff9c34,25cd5375,48f6fa52,7a105b3d,25b763f4,15fc1ff4,b8b3b964,9c1f0317,a6c4fa25,d731a120,562730a3), -S(ece7fa3d,55e6b94,4c6beb50,b6ae339b,69ec8a46,679e11c2,7c703056,4cda225d,68be5c5b,fa975326,e5bd41fe,7187ecd6,b83ba698,ec98a7c8,9c8ff6b,d207d5), -S(9fd0196e,91eba507,74f75e0f,980c4737,ac7ede54,4be0a8e2,c1a852b9,4799d10f,bdf3d80b,fc7ca162,76417e3b,b9caf72a,6e94c84f,c42e8091,d3eefaf1,ea790dfe), -S(db89a9e8,703f23e2,13300b25,f952df32,853691f4,6fa6bade,c7ab775e,21a80fad,504c9ae3,c9a9e7ce,ccad44a,8f97502b,5577db41,510b3e13,8ccfa64c,2fbb0a31), -S(32e762ff,a1b84c7d,c3aff832,a838d555,a9ceea5d,7066ae6a,efbbf96e,5f5c5eeb,ad842a97,ed1f274e,d3bb0460,309ce41b,f7e9cb55,c7bb5d3c,3b2b662,daf4c419), -S(8e7328c9,93fac58c,17d2c9ce,8a3959fb,2c0c8c7f,a4d583a6,c4428f9d,98f5d1ca,b5370e52,815ba519,3fa02e95,d75a7168,e1906ae5,12cbec72,4bcd1a9,b897b8bc), -S(dbb8e270,d516fe0f,470e325c,37707a03,3607ca5f,92c6f2c,97c32f86,1418ecf4,3da4b926,7cab86e1,7bd9442f,f3bf2c41,52aef531,f1d028ed,e801215a,7204fa86), -S(5dd9b4a,bc618666,12cd3344,2d8e068a,fe624850,1cff8c33,87af5881,c3523544,51f5b,a9a010dc,6e5aef1a,138251aa,dd75c5fa,caa222f7,db2d4218,220fbf44), -S(50a74f67,90a95b14,67eaa018,9409ba38,7edc5abb,4f2c408f,5bc6a5cc,6724ecb4,d32f7031,9f9162eb,861255fa,42495a6a,fefc8949,d36150b9,c4d5b066,7b41031e), -S(11721064,55ae2391,2c2e35fd,190ba29,6bf1d580,fc76cfd9,1fcf6a02,e77ac992,158165db,2865,968604f6,3fbd298d,3a079619,a0c161f1,35879f14,5091a41c), -S(570cb8ce,d29b407,f5e4769c,57c42796,b1c0b111,684c5a7b,fe9ecf8a,20b687fe,9826e697,97573a61,26d7cada,c636530,ea747b41,308874b0,a4fa578c,b984814e), -S(5adfd4e9,142a8f6b,1ea6aa3e,14a83fc0,7e1df246,279082e0,36b8e2b7,dcc30637,82314ea,36edc02d,c489c36,c2b0d808,d64167ed,1cb33651,418e3c08,7732c97b), -S(b26f96ee,37d49fc2,e4e76f4d,257197a6,f1c667bb,748fb69c,29d9f033,b94419a9,bcd2178,aafa4409,329d735a,60bf2fb5,60706e87,295c6d7,a7a7e0c9,4b280542), -S(dbbc5fc1,ea84b079,90bd1af4,fd244599,70bff024,835ae3b7,129f6caf,290c4bd7,78612296,2b62b621,6f43f734,eab00121,ba5a5b3b,81090a4c,ebe2cb8a,5a02591f), -S(e4d32dd2,710624c6,94120041,36639e21,708cb3b7,a15682ea,57e80ebe,a13738b9,3aaf833,3a7f31ac,6d6c8b85,e0831fee,3db67209,f35b0362,3b153677,6d7a4098), -S(81c6fed1,b687970b,d3716384,5c35061f,e9edbb33,bbaa609e,53a835b0,c13d6a15,934cc11e,e733fb68,1a575c98,cace3279,7a6fff4d,6bcbed2e,89836fb9,3b83597f), -S(28a654f9,58003817,95793,46ddc440,13c07f78,79c3b247,e52dbe27,97a02852,10de9cc6,571f24a3,6a08fddc,1ed27cd4,a9a0cb11,5d275d99,ceb60676,43773965), -S(532c99ae,cc7305db,5cac0294,e25c0a0e,45e270dd,4f621f2,d1e36ccf,51cb7a48,8ee3619a,61df9f49,84259ab4,744f563a,bbb45462,9eaf0670,5240d67,6b3240dd), -S(de02390a,37ec8a18,2a5891c4,f8041ef0,d548f367,4e8a91be,9e29e0ec,2b822e8,8ae501c4,32e81681,844fac5e,86bcca09,aae6f862,76994d93,7074c1ce,c3a04b33), -S(877916bc,6880f1b9,530af368,1ad44238,dcdb76cb,ef1d3f61,6856566f,bb6da5a8,807bc5e4,5c400875,42804d76,eab0f291,499622b3,dc9a7e81,c1db7839,ebc5a5f6), -S(5980d5f3,4b0c3684,a3381a84,434436fd,e0a0d6ea,1c8f16ff,b8a35793,74c30e9b,9d20e10,5e51e720,95d95766,7f479f61,34051c24,b09c8a2,125fb9c3,6a0b4b7d), -S(5246fb5a,4fb10bd9,c240b274,93abbfd0,e404f444,13f0a126,5d8fae3c,ba805fa9,8aad021b,c7317328,6ab78e8b,3e3cd613,9d881233,d1f62cd0,9a3d6260,88886c7d), -S(9b5ded4e,dd6f9c11,c3e9e760,71a7e257,74d2ea6f,c87412e1,a918f2e0,fe2075fb,80fad92,396c0f77,216187be,66619a53,d6a6ffeb,1ab70ca2,d64b19bf,2b0a95bd), -S(d2d4c183,c4ba3336,2aff6d81,263a5845,b76d1e3e,6f5a0a0c,928a1887,da2b03c7,ea15aeaa,b602f360,f3a7faef,fbf2725a,5838d041,70455d50,6ec5e1bc,ca651b2), -S(222241f9,b3408b3e,a8f7bc96,67ad4928,183557f2,754b3972,d5e938e6,36ea7857,cc2598d9,4621a8e0,3c8b444f,bc6b68e,ea584144,c770d095,b2152891,e6bde708), -S(14cc26c7,c26fa386,e29204a6,99b24119,c8642d24,256e9fa5,407bca7d,4e69c32d,9b125adc,dc2150ec,5181d2b5,5a862dc1,4de72a2b,7a04e912,cb2f6503,24101dfc), -S(292a1480,959eeb3b,468d54ff,2944786e,7702bf4c,8ebdf837,edd65177,1d5a971a,e7355cf3,e1c089b0,9362b68e,83825a25,39c88058,8dd6e1dd,ecae9447,ea4b6388), -S(6c9f4196,a35d0a9,f0517c9b,2c04a420,127140b5,ae9d2274,cd5eeffd,140ce3a,854d6c38,df5604c0,1d65c8f1,9f5e89f7,4c6b1c9c,2756fb9f,8276088c,c39dd80e), -S(fbd63ec5,8b3e0c43,4033ea2d,f4a8cd55,b4b4d24d,d1f8ed5d,6d8b1b6f,a14bf30e,e3770f0e,7b29f62e,9921f8e,2a78d2c3,a62814f,97caf2a8,304a782d,b72c6b50), -S(df91d6e9,b046fc63,d81d94b9,aad17096,a2c7fe88,b95e423d,edaf12a2,4a2edf87,2cde227b,ffa27e95,ded3f142,41d26599,da28da39,16227b43,e665aebc,f67a9fae), -S(b2ff741b,8b5d4cc0,aa987660,59652337,6ac36083,e784a181,63f653c3,667fa2fa,400a34a,e6990fc5,7e268eb9,ed2ee2ff,dcbb27a1,26f0c7a7,937617d7,19e7b0be), -S(d156797b,9de0ad57,41b759ab,38e8f935,d352b464,b01080ce,70e22376,8d6b5e23,b7e64c4d,fb332c98,9d21c2ee,67a5d5cf,d728bc07,9b448283,55d9e6d,4b0fb3b4), -S(a3814ee5,e242a6a4,65ad0681,a0193dcd,16538d6,1087c6de,fd362a8e,671e7ed2,3be12033,59d441ba,d59d88a5,64d03ce0,c67a5d18,4f883388,96f7caa9,e3dc96ca), -S(6aab0cb8,b46728b3,8b78d386,d45122af,c95bb1c9,9298cc77,299f2fd2,b5d72586,fcdcf718,caf0c93d,1f3ec76b,b4060f8e,a3863736,a5d966d7,c617fac6,6f530753), -S(5fc6e596,7b508698,4c99666c,22fc7316,54b700e,55877f73,169241ff,8b759937,57af0c61,76ffb00,626a98f7,ecf72762,9746b0cf,dc8a8914,683cc49a,6d568505), -S(7f3944e2,bcb3cb25,e36c8479,ed51019a,a61b1122,ace99dc4,82ac38a8,580c6d2a,dc039090,54244e0f,6acb6d33,fc4fee58,8e5e25f4,b23cbe55,5a330779,872f2062), -S(5485c8db,86078936,14fb7a19,73651f6e,66ad843d,e92db2f2,c4db2d5a,bb7316f5,ac39c239,b0fda325,44bfe05b,1a4ecfab,7ccb84c5,db2ec999,6d8587f7,d15bb82e), -S(e52b9934,910510fa,3611dba3,8630853,d0cfa8e8,ebd64a2c,7b59bde5,edcedf2a,cea4d745,64e8df98,d47a3ca8,7f1e45e4,728e52df,f383e391,6dca08d1,326a7e38), -S(92b17ef4,fb8f8dd7,e0307a,672b37ee,78e0dfe3,e19c094e,44a50c9d,3ad7faf2,5bd53e68,dbcb4e47,18266085,9d12a34e,943691ee,dd034cb3,1eef8a29,e35b762e), -S(7f8b2952,70f6b2e0,84503f9e,df24fb8b,e91393db,64a90971,5e68b009,aa9c3b6a,c45f0d84,d9407856,19a87d38,296f70d2,41ddf1b3,8f421d12,fd2be1a9,32d2b437), -S(cbb90912,403439ab,8d04714a,1a5ee460,70202e4d,1d7de375,36754bb2,4c8bd2b3,6966ca4f,bedcb6cc,64d72eac,fa1a699d,977dde05,5d2454e2,9deb220f,e2f51c11), -S(7d4ac2b0,6d1810b9,a3e823df,ece821c7,70c90d2e,ed0bc324,9ef1a43d,bfab3043,824fb46d,6afdf15a,7979b032,28588c23,4a9add5,6f512253,780acb93,ed7ff34d), -S(36482902,2ab638a1,df90feb6,c20ed6fa,fa81ddde,87d069d3,7cac4a6f,e92a9b32,af6530a8,1c62e72e,409d1308,d07fb227,63afad97,8e843672,b241ef60,dbb36aa3), -S(73f4eff1,ec95095f,be5d307,8a9f6db2,23e9b874,bb2d077c,c58fbdd1,d03e1f62,d7c0f36,5ab93ff1,999c6f95,d5c6102,47341004,1ed97e8e,9632b845,527078a6), -S(9a88fd12,af0611c4,b07ae62,59767f24,308d1aba,529886ae,6ef7f5ed,22e98ba4,a16e8f50,164ae75d,9712b544,ecdbada7,725c2144,3e8044d9,f3aaec64,367169c8), -S(265e4dac,6139efd6,a7866385,f0bd1cd5,e8bf205f,344ce71d,3c0ce073,766a6619,ded5a75c,ff4de7d5,f33bab64,d000b65c,e5078ff6,c01930dc,17bfc64c,826d103f), -S(6fe39213,baecad17,f8b82f25,d7621cb,3f1b1a07,2333ae38,d2d00a6e,ed8aa1a0,d6b830ed,f36775ef,7cd7c648,180a6edf,be65ab25,7304de39,791733dc,f561172d), -S(671f82c0,ac712083,8cc32fc8,85ae272d,4bc59e46,2dadae48,b4dcf279,707776ae,4aebdeae,2c42a80f,fd433d38,ad4ecab8,9e4dbd3f,d73db0b6,ae72e78,6eb7aac), -S(d83ef3be,4630e5d4,edbc6628,828b40fe,45806e60,83094433,31be3042,814bf4fb,ce89b788,8c93be59,bf0bffa7,adb87c4,a4fbdb78,73de3d04,c62b5a58,18e1ff92), -S(de2df94d,78cf43e4,720da5de,7f08de15,4b271731,8bf450f5,667956d5,596cc60f,61c4585e,3557c10c,8d22671d,8389c508,195b0ea2,e9150ed9,ca93fc53,3892283b), -S(4bf44266,3d4c7de7,872aa7c5,e5ae22a7,30dce19f,78d92abd,1b7e04ae,fa3e5dda,ea831ab3,b59eda4a,8e959003,c4a6266e,d4f691f6,1514dbef,18409b03,5b2a6594), -S(4912c91d,38722c4c,f00aec0c,895980fd,af4c6351,33021e52,ddf0ad4b,89b67f7a,f96d3a36,89e4838b,116b1529,55392373,1be5f0d,30b1d541,6c0b7839,1b24ba5c), -S(8c0bf82b,d2cdc2bb,49b2161f,9f0a528f,79f8f8a8,1b919b70,9fe5a46a,c26d417f,aa98d79c,1869d92d,251d322e,7bac3dc6,5f166c56,28250c29,9be63e4d,ae430dd6), -S(83eea34,4eb8bc40,2f4ee569,1d89214f,dd3ae674,d60cc0ab,9df0fd42,7559e0d7,9d7f5834,fe912c9f,23790306,3aa41b6,33085264,e6621a9b,9e87e151,dcb2562a), -S(754addb5,a1b21e3f,609416e5,5792c265,76b90660,736d0d0e,364aa13e,74b0a699,3145763c,c0d95a33,5e443b3,5dacc8e7,bdb2904f,b868cb27,3a505475,511f3dde), -S(3e513f87,e381efdb,14dc686d,14d85d3c,bf725e63,9d934de5,647823f0,c4eafee3,360be751,d3f097f0,b09c7d0f,1d425cfc,88e400fb,7a0aca3f,9d521e6,e79eb87a), -S(ea4cea76,f7478452,7364965e,546a7356,55d203d,5a92c3fa,336816f4,983fce7,a1b664b,e74b830d,8a49eab0,165e6945,69ce0518,98007000,e8094f92,6b3ba536), -S(eaf39608,61712ea1,88c9a2d0,c025d56d,8b52e59c,ea35f298,41f13759,625dd824,96ff00bb,eef7e8f7,23f2c7bd,7d6c3eb4,16827208,d3a2ca54,d40dbb83,4e13a2d), -S(34d3a7ad,a590d9dc,2547b9c4,b99a2e10,9689320c,61105415,c50879d,4de223c8,49eb6d27,eba087c3,1252084a,d78e187b,89473be1,1032e032,8a944e48,ce0a7bd4), -S(22f0cd6e,9e232e52,d82d70e7,d1ad0df9,3638bea4,8fa0bf16,4ab3c7e6,a1d961ee,66d0990,b57c8e13,4e2818b,910c27b1,7eb33daa,90ad5b2c,427b91e5,51514068), -S(27a48cff,114f4f76,bbce0d83,458a949f,c80b8821,fdcd35c5,b3810fd5,60d179f3,41690918,b0599515,f913db47,37083743,4f62321,72084ad6,7a730af5,b32d25b9), -S(2d845701,6ecda7b1,3a2a72f1,cdf24c12,8f4d85c2,c4b72881,45802bb4,603093a,50f1e7ed,ec9e2dd9,55678abc,e5ea06d,12ff61b9,baeb1d56,79055c32,d8654315), -S(cf2d9ab7,92247125,b0bccfee,f77a5a37,5e796957,75950d0c,af401a12,c8fb9a9f,8839d0a0,850df254,3e77dfb6,cf06f424,dd16c26b,f3aaefbd,aa3cdb5b,d0ad818e), -S(de85e4d3,75463ab0,a198a6a4,1d5f1fe4,c56af2f3,786ab9d3,705f540d,6b5a3770,1ade7a8e,1f9d595d,b67cf482,4c8e11fa,561b3625,4ec5631a,68d73907,8a9d8eb2), -S(c18e2092,299be419,77e40102,c9d4388c,84d602f3,770beca,50c03008,55ea3a66,86b9b3ed,786a570,de95e947,2fb0e61f,ac4aa85e,47792e99,25738e5c,3c4af6da), -S(df9ad184,a9e3b41f,ecbdaa0a,a48e2252,944e0384,538300cc,43f9ce48,6b224422,c4061799,db92d160,de19c4f6,a1280ca1,b62d675d,b7fca41d,ca838bd7,3d082fab), -S(fd846cbf,66ec362e,4d10a783,ba60c734,d9577ddd,18934ef8,81ee755f,d3748a95,d6db4def,d6c742a,e50ff8a4,43336754,d4244a42,a851ff72,7609a016,d0c84d32), -S(5e86fa96,c29e30f0,7b845438,5f39ac6f,43d120fc,df10d891,ef60e2b,141791f9,39f5ad4b,2e86a92f,3b38e286,5d7e1ec9,2782845b,593d1d4e,43ec73b9,2dfd6440), -S(8744ac1c,1b16d65d,daabc8ec,d6cfc40b,109dbd9f,c19e4439,1e2ec486,ad27293c,ab30e186,e4f2f48e,51ffed3e,46dab701,ba78b9af,b6987166,19c642d3,9491f1df), -S(9c4bcac1,c0a0ca58,debc6c0e,71238988,607dcdf1,415045df,83697282,84a31c1e,6467c5b2,32947b2b,30c32a18,174035df,d813d42c,593b37f9,2a8a05c5,52d2b7cd), -S(3766aac7,b9a2ee6,27691923,ef91cdb7,30a24727,2da61421,955ffdb3,5125cb7a,22b7d930,94110a51,ac72dc5,9d2bc66e,45349a1b,90a7c655,4464713e,6d2833b4), -S(e7f2d315,ea0d0f71,be63c896,3c6ba75a,2122e650,fda59f27,b4ee627c,54bdd30f,41cec687,9e6c21cc,99a3aaf7,e4fc75d7,ec163a4c,6aad8a21,22da269e,1e342d80), -S(cf50bffb,bd4aff61,80be7e75,e9004d85,2234fdd0,7b0b3e13,1b883359,7e96f40c,7c9eb80d,7808d937,eb5215a8,4ec4d330,565b2aa2,162fc4c1,b46bdb19,b93fc159), -S(5aab4d81,a4eca88e,e9cc0c20,94ced3ac,912ae932,2834a67,324aca30,956805d2,64d622dd,9afc799a,eb495ad6,dbdf31dc,7156ee66,d8a5e67,c44bf50a,94fac52c), -S(a4f6d781,9dd34aa7,18166000,79d8d7d1,eeb5b971,4549cf3e,a472126e,3cffe8c3,4c87eace,b4e535aa,36ce839c,336fe9f7,d4b0680c,e61fc525,4633d38f,a8c395bc), -S(3ccc6b5f,8188f3b8,b5805bab,c95f08d5,9b803e03,febb6f49,84dab325,1f6ce719,5b4987f1,7f9e2610,e443cb1a,2df24752,72655670,e739f0f4,3ca9c3ab,2a4dbbcb), -S(2d0a94d2,5bee2c99,1d8b312c,251e305a,5f44e1b9,29bde36f,a973e51,2919130e,f9cdc9ee,528a45e1,5d1ad338,db49b3a4,2db74785,d84cd12b,59391140,566636a1), -S(ecfa1649,da1a0bfd,41ffc294,40ad7a91,b6ef0d97,115408e7,3a05f506,e1aaa6e9,7f8a0b16,4b817533,84970c00,3c497414,ae319090,7481fa22,9a920004,8e2783cf), -S(4b97331e,38aa629c,14c37220,b6c3241f,603bcb0b,6b07a66e,c74ad1bd,bdc25d7d,65524ca8,ddb85804,a2111e69,17167d2c,105a58c3,321c27c2,2cc0256d,c30761d9), -S(acfc4bc6,99f3af13,ac70f25c,ed729ef0,866b900a,6c39705a,5e0937ba,fadd2a90,70ca7ebc,923aa022,85f91b19,3c550487,172f2f0a,8f10f0c5,29384cae,20167824), -S(2a984810,805a9eee,d24d1ba5,46825c6f,aea09889,132295c2,b4ec7e64,8db9826e,b56a531d,7fb7e8fa,ef957956,747015be,dc28da96,eccd66c7,c2727529,c2a45ad0), -S(76c6568d,551abc3b,f6102d02,17a440e1,36e80776,135dbe60,7581bad8,2aabb2e8,81e56168,c16473a9,bdadabf8,339c04d1,5d3cc74c,56465bfb,2eb0b2e2,8bd4f82), -S(6476831a,3425f0e,e8ded7b8,be239bf7,7b16d271,eb1d4b36,ba7f692,a2f155fd,90cc74bb,88acd0b,cda7e17c,48056936,9dfa8ba4,ec8d6f85,eebb19ae,f35ce085), -S(b2b49ada,50eeca27,881c3b6b,656df825,3422e3b7,1c145401,e92c5ed8,fa3dc51b,4f3f9fdd,41d2669d,b087ebf9,883f4f9b,383c4241,eb87898f,1e916392,d6838820), -S(75448fb9,5c0162e7,c3892300,bcf070ec,dc49560f,8c0f1665,f0bb081e,dcd12e05,b0b84014,c73db3a5,9963812,d99d6d0,5df7d46a,6a646929,9868d874,6308beb0), -S(643e795c,1c158422,24ccc0f0,97c18b11,dbe1fcbc,df8a4e2a,f234f465,f42cce3f,a067acf3,5c7f2e05,4ee6c40d,1c1f1eb,2850c9f1,8138642f,e6becd29,46e3d604), -S(fa200bc3,6ecefe8e,9e5c82b5,1f380c2d,a14b0478,6329dcde,9dae0546,4d109dec,8c6b6cd6,a676bf1a,c7f43bfa,29d6863d,87740099,d5a06e9a,eae4b885,44d1ecff), -S(851fe9d8,e47b0186,ce001821,59c674d,390e5481,fadf397c,67a2a35f,8cd7b1c8,e6e7b57,cc25bfa,8bb93e2a,f934e154,314dbf3a,37549659,8952de0a,3ae55a71), -S(4e462e9d,d2995148,d0091e2d,94f5660e,a5a994d,6476039d,dc0bd812,cc47ef1a,63c80573,dbba650,5ae95b0e,9c376a2f,78fb0d86,889e0ae8,33e0b823,7932cf00), -S(3e46f7ea,4606f5cb,4a8d7386,bd0fa2e6,89f03985,b9ab7cd3,1baf3cb8,24e928f9,a4d3c20c,9ce14434,2fb14481,41a381f9,fe4263c2,ce955e7f,daef45dd,97c3948a), -S(c650291,432ea873,473dce0b,c34aafbe,24a752,fd54ad97,5da33acd,66c48bca,795e9965,74baf74c,2fdd9e2b,a917f02e,aead569d,9a5069d0,73341203,772ded96), -S(219416d7,52d6258e,c69ad11e,1a2a7552,4b327412,c9431211,7b57d960,d1e23c5a,916c79f5,97ff454f,b93332c3,d0643652,73861c82,68ded6b4,9558d76c,217278da), -S(d97d3e10,8f3eb83a,9dcc03c6,76755f7f,ada5b761,69859e14,bcd4e7c1,56dfd7c8,a2f0cb2a,2fc680a3,79aecd75,1cf7758c,50398624,8381a5dd,ac9c9902,65b18a27), -S(dae2570e,67a3dcf4,ffc0f56f,ae3dd134,479b1e03,8faedb8e,2e84bc1a,3847223f,817af757,125d14f0,c9841d34,f885209e,e2b79522,53663a6a,a3077e2f,43da2c7d), -S(6d2b21e4,33b168,a6eb9eb7,496533fd,b6ec326d,e7fc7556,84547cc1,2c9c3143,9ff9697c,514175f9,6082783a,a2bdefb6,439d6826,af9a61d6,5282884d,4741262), -S(de577780,8bf5caf,428cf519,9487a81d,8fb8a2a5,2bde22fe,2f72598e,3fec4495,8ebe9150,916a70ed,1c6384a5,d133210c,53e205ec,d0ba7a04,5a6434d3,e32df9ed), -S(d04f1378,7bbc4e1f,8b1c548f,4d79fdd2,8a0f8199,49d81b51,3c63ca6d,c5c6d3,5cbcc339,3050eeac,677f8382,8499c8bf,b3d43b1f,5ec98768,ec0a71a8,d81dc3ff), -S(4353b53b,ff906815,d6a58b36,ae02cce,cbaa3fcf,a2bdb5db,7dcad258,4fa18e88,850b08e9,5714b0bd,2fbc8f2a,4ac5980b,ad30ff76,1241a5e5,5a5f01c8,a221fe83), -S(8141ba70,fb997010,1ff2ffd,865ebf7,137340bc,9eaaf3ad,279eefe4,d80953e7,ce0450d3,aeaade42,e4c66c30,2da0fae7,595524e,debbe419,316a1d89,d238ea5b), -S(8676ba13,25c85d1e,af93f424,755d17c6,70d2694d,2d52b890,540f9826,f2a1bfd1,df0c7ba7,8fbc592,46b5fb7e,8f98fb1f,ce1bff80,c23cc2fb,c1caffad,213a51f5), -S(c55ac2c5,1d918713,804abb83,e2109412,4494f614,109f32cc,62148706,98afc8a7,44e56fe6,6aa7b14f,44c6bf3b,1974e6c,dd8c7b61,73fe0067,952f0391,49512132), -S(72738507,f0b3244,e199409e,20eddb8a,8ffe7fa3,18930f45,ff0b1c9e,f7a15b90,ec121c76,e6f5caf4,7912cec8,4ae5c8a5,d5a9311f,a7f383b,d2e8622d,62e6171f), -S(f6a7158b,4dedfd94,6a4ee001,cf55ed08,33a57284,cedc4221,58cda87b,a0e1bbf8,2f37f2db,45ca86fb,b2fb6af4,df82582e,28e1e33d,bea3cefb,906d15e1,e7442f25), -S(8cb36d0f,40f21951,23ab2ace,e1ed08cf,de216970,ef6c6c96,48d79a1e,7760e58d,f397a565,d5eed2cf,427ad4ad,52d5d748,2b87bd97,ce31fb53,ad05cc57,2989819e), -S(c5cc35fd,5575f56f,6c050c24,769f4ae1,c0427e01,b953ddbb,4551ad36,93fa385b,6b5210a1,8e4b1d7b,592cb2ed,d1a66e11,545cd114,8541aaab,cf781d29,77551419), -S(bf3bbf0a,48711b91,74e120e3,b977a572,712271f9,842bab34,db42d1dd,7da678ee,6c711317,4fead9e7,c7fb5ee7,9b8f862,a3af320a,d97cd970,df12c0f3,84a3f3e2), -S(35534e77,c8dc6f7d,425d430b,b5cf4743,f3fed959,73d63a3d,771e5a5a,bf7da645,d22f018b,81b8f8a4,e2d297b6,f233e826,8fdc6168,4166f72e,2d89998b,4124159b), -S(6471c07f,de641ca4,b118958b,8ff9a9b1,27403eca,32a849c4,1b0ae1a1,b2d9ae23,ebb318bf,edcf26de,5d4bf68f,56fb898d,8c2294c4,7097bf9,2f34f3d5,6c535807), -S(9b8d568b,4f2879c2,1bfc95d8,1e97ed73,9bce2444,ad40156,7438ae1c,4b99c2ba,752531b4,92245df6,19251bb5,7071301d,f4a7f681,ce5ea509,18924173,7d00957f), -S(8a8673da,eb675829,cd5f3cb7,2c7434b8,d42c51d4,2fdc7a97,1681f7bf,4fd04e37,f2a66884,bb5ed9eb,f4e16864,3573135f,f65ad9f4,2203250,60b45cbb,1861a000), -S(b5048475,f56c6a46,db949469,2500bf4c,49b226c8,83576872,9524621c,c9807bb9,4727efba,45050af0,50b7847e,f5201101,591b5432,57ca917a,b9e6a210,20036cdc), -S(7d207c2f,40b9b31f,be509744,c325dfe5,c958c56d,92f43a15,511888aa,9deff6ef,4125af38,1e3f9562,64089375,965274a0,30ce04e3,9533b3bc,bc742b21,e6ee3582), -S(f6c8baf6,b2561144,47fd3cf5,a018b31a,846eae1f,a1d8f74e,59f315b3,43182edb,bf8137b,3aada7aa,7d582791,11d5c4fb,970669e7,2c160ed1,da9e1d1,4a2e2bc1), -S(9c67787f,84a714b,89a560f2,b876e92a,f8b2de18,6f8cf416,f5bbcb16,2e59d27,c0262b77,becc9f9d,378051bb,d2705bf0,92fd8a3d,b53cd131,aefc583a,b98e9402), -S(54d474be,7b58457a,929b9a7e,39e97b65,3478eabc,fde384f,681375cd,6896ff47,b8314502,4c1c2aa2,586342a2,f035baf4,ea086434,52ccf444,530b1c06,3e4ceed6), -S(e4dffb62,4132a5ff,6eeb946a,35f98c01,53b607c5,40811043,d1baf243,3bb23467,a580f3e5,d8d8e685,47e0c259,5e9c4d6f,a8616067,b3a437f6,ed43bb7f,a695edab), -S(d572f1e2,8f3eb14a,afe3ece6,585ee6fe,f49fce12,a2adcbde,d5f4a247,97c4a7f2,d9d268fb,2e80049b,b9a26309,69bc1692,c96b2d5b,dccdffc7,93305aa9,7011f88f), -S(bea4242a,5a5eb8a0,6f5c0cae,f38c3b81,4711a7ed,780e607e,10512d32,fb4aba82,601c583f,25936e03,ebc2406c,b248aecb,61f7ba27,894e4f17,46f34aa8,519546b), -S(e3179e2e,b6b92374,9c8f7ed0,40ff053,127a7d78,2da166d0,4639f55b,7cb74459,9a22f3ae,8df42fab,4b3d01ca,527c967c,7cf43f38,6a0d5751,8d47e7de,731b21cf), -S(8a973494,c8cc5c5b,4d8eb9a3,13bc9feb,fe6385d9,27112399,3c78e2e8,a732d4d1,fd2d15c,c9aa5128,c505fe85,786c55ee,aede07b2,94bf2466,d9845d3a,1596d8d5), -S(b87bfc57,7d8decd,3396f6,43200d10,946c0a7,f2d4ef92,4de7741c,e8acd653,62bc1f4,e3c0760f,82d953a,5d02a10,8ab3d0d9,53c463a0,295b063f,77f434ec), -S(aed2bbe,8ea08b0c,fc49c4a,4c92f63,2bebb84e,53027958,5b249cc4,c0ec61a1,76296846,a5391c5a,69df4e6e,44e9718e,622392b6,63a4ddf0,54b9e2e7,11a35bf5), -S(34fcdcb2,655b0405,2758c3ae,4f0bd15,2965dc47,9d7b63c2,b787adf5,6852835c,8b87ed68,30c88383,8eec48f,89a375f1,3a846f3e,ff0e8729,c1ad8e99,32cd4786), -S(f9586aed,be4ac742,2ad3b9f9,b8cece5,a52678b0,5b8ab318,1c6c2412,b470771,231f2be9,7b81431c,12539d6f,d247b4f,3d0dc8d8,15c2cfec,4526ab9f,e9cd6b79), -S(88125579,33848e15,f6c9d813,91e5eea,cf8ecdb2,1f55f4d4,1ff34ad3,a80e093f,d45c6727,c3340e79,a5256df0,41b4d999,e8910869,9620aa9c,bce6c3fd,7c17283), -S(ce1b52c7,f975a37,25f904df,9f602b82,52573170,96d4adc9,8043d35e,6773d354,17b65d8c,cfec6748,2a3c6d62,99dcc47,bfecad81,bfcb7d83,5f216f76,1ff9ba7b), -S(7e6885eb,5c8a5faa,6cd47921,54b2f5fa,4aa292f7,5fb16cbe,87c1ccbc,57501542,16a0e969,a212ae5c,6b4df92f,b3a510c4,c0b9ce27,c4f0f389,e77e4038,8c3cd101), -S(37589935,89c37714,3467b869,c366af1f,2d1566be,1ef950a4,ab1491fa,ed2ce425,2ab4eb91,cd533805,2020300f,b83a46ad,bb846863,6fb2a9c,c1e7c7cb,f3e56799)}, -{S(ebc119d3,8e794efa,85fcbd,5affac35,f73c7428,590ede0f,6365f1ea,87c65b4b,183a9992,3911b1b1,cd9b0fea,3667b6e1,52af7499,8d32beb3,d2ecb91d,af6e8a06), -S(28740562,ba21e3a3,69d80ec9,17b36013,8119b6b6,77b64cef,5f84f278,2fe5b3c2,2298a60,779ec4ae,86f9e0ff,7f981f2b,ea69e782,20927aa3,da793a10,3eb3d307), -S(12f64dcd,310014ae,81a7f6b7,fdcacb7,e8a9ec78,d28531d9,71ef3dad,af946fa,dde0755a,af7081cd,59da7725,e8246e97,2340c01d,eb76dd90,f0890923,54fb2d8c), -S(76134d79,133c485e,87a081c8,ce365757,f3beb361,c764220f,b16c1924,787cdf2e,2a77c2ee,b1cd5181,72101ebd,538d2f0a,10af3190,118da259,e4a53dff,d7a7b0c2), -S(89c5073,fa0877c5,50911355,475c24d4,bf8b8e38,8e9156fa,93021ed6,21429c8,40fe8b47,cdf3690f,63b3af00,efcc2aa4,b29c705,d04044f9,bb910671,b6ca995b), -S(bdcab1d6,157ea793,40f3bd0b,13365b24,b68641af,4e222d7c,b4efd8db,47b8905,b9d78e27,96820c87,850257de,746c6a05,5be5e595,aee8ced1,1dcdbca5,d92c5ed6), -S(da509ebf,2b7dfd80,d00c4c25,4b2e3b1f,df021d5c,cd1874fc,50b24141,2444e666,c3782467,e1606722,a76bbd84,dbdfd6e4,2cc41a10,cf50d921,d1bf916b,24459c50), -S(45da8013,3e8ee0d,f0a456d8,bad2d285,ab401f36,bdd520e3,c66b3d6c,925a17ef,4fd239f7,bb17c84e,3eebf9ee,c352fe82,652af898,f670dc5b,e1b9842d,9e593938), -S(d67ae553,58ac6a9f,cab9bec6,8a423738,bf7340c8,33a51cb3,2528893,24cbb1b8,d0b6ee57,e131ea57,300e228a,e1feaaf,55f1eab9,67a3ba3c,c403bad,b1dc663b), -S(6ab4478c,c8bdf1e8,7bdf566e,c24f4e46,a689459f,b002d0d5,715eb22b,62cbf077,331f13ba,e5be2960,97f8326d,1e4d3147,fc3ca83b,f4b3a4,56ae15cd,83d176b9), -S(e5d02a1a,3bae963e,9410402a,40390ca3,53d53a56,66ec6258,e82510f7,f72cc2c5,80379b63,2b5d4835,170bb358,c9040fe7,fad6b2bf,c7fd26f5,38acb1da,ba357453), -S(39acfbe8,48db640a,c2e7ac,86a1333a,ca94060e,fa88f0fe,f00d6273,74d79293,70ea1445,f7ea5f8,1148f42b,a37b2fb3,fa09f42b,9d2416ef,7fe0bde2,6e1e8f50), -S(1f8ce5d9,a815f4f5,d52c4dbc,7faf4f0f,d76a35e6,c2570632,6602bfd7,aef3b51c,3a2ec9d9,9ad3594,b223afbf,4d292f0b,88ef9372,18dc2ce6,e53df212,cc548e01), -S(5ee148dc,f4fd3d7b,b43532a4,8c782365,f944910a,eb235d67,f36642a1,b15a4581,898252a4,64cccca8,bc958dc,363cbf6d,b044492,248c0a96,aeae3bc4,26c67c93), -S(a07ec6d0,9829e04e,135566b2,d0d677ee,7e6bd606,21474cef,3e9b512a,753174d2,eb8dda9c,f3b44412,ae50c684,18453765,42697a15,33c84e78,fd75a8c7,11201514), -S(9069843c,36cca54f,aa3f5ed0,3c1d803,abd12955,4a5f8729,ced1352f,ab628d44,7140b7f0,e955a45d,aa2ddb02,846bdfcf,85163b62,718c9a51,3380b3dc,4ead8950), -S(69a98f1e,2677c441,86720bd,3b1cb073,9f06a16c,e43f7e0f,680c14f8,6540c36b,d52b75b3,a3005ab5,69041e3a,398549df,8f432e5a,c0d7e268,463b9190,191767ae), -S(c9297581,bec70b7c,55abfe17,95337b68,b99fb132,1d203a2a,29b82462,15e29633,36c4eaa0,5564673e,8ca1f783,82070d49,b8151afc,ec6c982f,2950a371,605f14c0), -S(53d50d91,1977cf5a,da1fdde4,7d44f6df,98d66efb,c858b92a,c490ee97,77c593cf,84db77c8,96dd1607,2c45c058,cf5bb2f,6435bd45,60bdbcf9,b8df71bd,404848b6), -S(ee15471,8e67e1c4,89d62145,5291a5cb,158d8fa5,84f7a134,bfc00357,ff578ed5,d9d90c79,3aefe401,c7017ff6,56d02ead,12318503,37659baf,f573c9e1,e4c65f0), -S(19e16e0a,ae3a4e80,ba0f66a9,7d415f37,784270e4,69e16560,7fe3632a,4bd8f1e3,6aabbd97,55c15f11,5a2e8287,b6fe91cf,659371f2,de5c86c2,a8deb96d,27037e72), -S(e93d52c6,12c07b0f,4f2f93f1,4b37bc92,3c3d7171,fad16472,146fb195,fd92f33d,933450e4,30e9c8ce,5a5948e,63f6d0b,40fb2ccb,adf5376d,4c076a63,9490ffac), -S(bedc3252,ab1e4676,63def49a,781cd7d7,98d01f3f,7cc1228a,9e396d86,7e8af12c,445c8bfe,9eac928a,b2d1d143,adef019a,7c243159,23a7b190,c763cbd6,dd305271), -S(28fd28e8,723d5c98,d978ac74,b070402f,3fc2315a,76d6c2e9,cd996b97,bad6375c,3ef59add,897dd001,4ef7441d,a62a8ceb,2c62b7a6,f5674ee5,b916851e,efdbf0d7), -S(7e8fc198,22ce5d20,dc04a61a,d33e4d66,c17ef03b,7fd53acd,e9c3e01b,21f3f646,ee5db413,637b4c88,d8cf2e1f,5d1d3be7,1d924962,38bbc30e,1769343d,9590cb3b), -S(b891fd94,36a14ef2,43f7ce7c,91d30887,34d1aee,8ace1fe8,ab3b29e9,2aabcb5,8af06c1e,ebf9bdbb,e1ad2f06,fdee27a5,4dc1c0a3,b08b17df,8e6ef7c5,5937c215), -S(236a16f0,21e85cf2,d5d62763,ef051bb4,c532dd26,cfdcc64c,2429f15d,8082d6db,bd24dcf9,f41f4c07,4fe6b6ea,450e3b9a,fd9c711f,b83ad683,43e65b13,3e654f3e), -S(d15acc35,21f6c40f,e7272e60,ba7b41ad,36351083,37683d43,4f9c576e,604b255e,7669301a,144b952f,cffb2e90,8d1709b8,87cec28,e7766930,eea8e753,2afb792d), -S(3b2c4a9f,cbd14308,fd612624,e5236b7d,4c363e3c,ab30aafb,a1092169,5beb3b78,69218228,5d7ebcaa,43db5109,46b93c22,ffcb7781,9c0de27e,3254ee33,3f9ed9a3), -S(b9f6b09f,a02dde42,453dbe34,b2388f55,4d042646,993ac018,5e7a6a63,2374dadd,7ee30f24,51683425,b8597189,a053a181,400df517,5934d2e7,cd00b504,484d9b3e), -S(f65baeec,e811aea7,a83f78f4,8e6db3c2,76fe63d6,11b4477a,42df67b8,4995758f,372ef8b8,9c75c669,7bd45ac9,68680c8b,14e4e558,d38e453a,2bd0c176,f6218250), -S(1f9d4799,d02782b8,f35db2db,eddb1715,e75779f0,82fd59e4,766067b0,6072bda7,86680af8,c57394c3,d50f2d5f,aab5d475,dec645fe,c02279d7,9366c450,bd3806e1), -S(c753e7d6,3dd4a9d6,384148fe,ed1a5f7f,1234182c,918dea50,2b44733f,d3f0c813,d80602df,ea4d0507,3b311a9,74be42ae,8e832f13,25790319,cf1a66b7,ac04c2d8), -S(6e294116,8eb1bc8e,55a0f2c5,e26b8b81,d6ecd829,5bb092c5,d0384073,c294e8c8,870f2e47,e00b9980,696aeafc,49adac42,32e77a5a,f5945f2,2f148d61,a9d4dcae), -S(eb2c36bf,298f419f,45fbbc61,7ea5738c,872df682,f537f965,3a58cab6,e38d2570,4619e86,3f2b9923,9709557f,932768ca,284ccf53,bdb9ef10,582d11e5,3e1afc31), -S(6ec36131,e3a55bb6,7b95712a,45ca3c8d,fe85aeb8,2746457a,cded305b,e9ba4607,6160727,f7b6db03,ad31828d,4b04a023,b07f1b41,209f4689,f126048e,21e0d9c0), -S(6825bfa,13237b39,277af3e2,1814e510,8fc51e84,abdbea42,8675ff6a,35881541,9f03c24d,c3bd1c1b,c45098c6,8f2ae07d,ccf7239,61c6a2b1,a3466d7d,1afd035a), -S(c8757c03,ce5f4fd2,2fc61bb2,e8f699ae,a733d64d,145c6fc0,58a68368,801fadc1,6601f2a7,e08e1249,5509bf1f,cf149459,928e5976,d7469e0f,e2e625e1,d9c99b0d), -S(5c1204d6,f1ca66fe,91b4cc5c,f2895ee8,2edfa489,a5b97205,808d9912,1e24a6b3,876a2e11,d790214f,d52fb598,ea7113f9,9ec08052,ff09035b,4169316c,82ba7122), -S(e0c03a38,9c612205,6b9688a7,edcc3869,5cba30ba,9038545d,33ddcff1,5f9b697e,4c0ad413,7a6e9b87,8ca914d8,31aa0371,d1bf770f,b73f1cdd,3d4dbd9d,d8fb4b21), -S(79c75424,ba72a99a,22802f65,56110084,e8adec17,355b2e8c,d2e7f8d5,13170cce,129eb5da,2ff02b6e,1fa41283,39ef9fed,3f12c606,bd55ccba,5809375f,dce59f1a), -S(8d73db65,e37a52f4,fc2b038c,56d8e371,450b65a,58614369,e1dfba92,2dd451e8,84458df6,859fd26f,ac74fda6,e7105d27,25b64fce,c4d86e9e,1dff0284,1d051d15), -S(41320642,e7de949,fc8fd03e,1b22a2ee,421bca4c,ef0e3ea,40411de4,962daddc,134f4f62,58c35358,cd33ff69,69a6b044,b36faf4a,77fb64ce,63289922,cff7d38d), -S(ae1b7bdf,21f2fe17,8a510982,f1d69a28,2f565cd4,9f3e6eec,d9412995,7b1652fe,6f6e9f98,45ad4699,a84d91b,9fd41a78,30b13310,c7f7a71c,9cdc4796,e1b33aad), -S(1d31ff82,2fffbbc6,1c3007cc,dd133dcb,624d612e,5d74acb5,f8370a8c,dd332d24,9fc68745,ee1f3a80,82efddc4,a01b75e8,6ffa49ed,698ec087,a9373623,61ae9d35), -S(f075d743,465437b,ccb185e3,c5456d2b,5546009f,79b3c591,d68e7c30,e5ddda1b,8c864d4,af8e89ea,8a1c5806,2c97768b,3e5b4c18,5f38af10,dd5a3d78,9f6cf73), -S(f9b07e9,abefdd37,a567598d,a23dd08b,7716c0d1,94cb24dd,3c6d6218,1f5fd2ed,1ca40c2a,69b92115,68e093e5,14312598,92cac6f2,c4cdfe41,16f287c1,71b1ead0), -S(14695d33,c187b712,c5f86b69,c0816fc7,cfd31486,e4fc0cd,b7042e37,cacbf5dc,9cdd12b9,c39a3237,c980047,e239b1c3,2b6145ac,853d331c,6f635efc,5cabaa82), -S(989cab0d,803b6665,33b78fbe,377d8db4,e1477f7e,6d962a93,7822e811,cfddb013,12f6454b,e88fc235,cb5f2de1,92404327,8b03c574,47c14fec,94538b54,68014a92), -S(88d1da3,4b47fb67,cbdb5eda,a463da2f,372f9605,dc0f0754,4a746ecc,a8409f4d,c2f2ae0f,38594687,7b814e11,333065b9,932cf4e4,1a6ea643,e6496175,4d46aff6), -S(2c6d9e3d,67e3a096,687b6c5e,8607293b,883017c5,35ff1594,aa8317ef,5e2fb573,678732ce,d618d76e,4ef02ae2,49485852,349cafe2,c9a78360,8a3d2c43,ff6a5d1b), -S(e0115fd9,be5488a2,e8383774,bf52b761,d75291e0,ce3d3fcc,aa642c37,66531cf9,49d36cfb,80e6ae38,d21be55c,3e885db1,fb773a3d,5c6827e8,7dc95ebf,9ac4cb3c), -S(1e994028,eb203a9c,da816a14,b08a00e9,7ec4cfeb,e6fba4c4,37dd1e41,68ed7a34,d7f4af61,ad4768af,959313d1,b5565c70,3581c4f6,b04cc1e2,bf27f202,36a6c94), -S(da12d2f4,1d60af63,a209844,1e5deb8c,1af51989,7a6edeb6,b8033621,1ac738c4,65561894,467e391f,c7de310d,fafa2ca0,c2d475a9,ddc506aa,a292d809,3272e70b), -S(aa3b79b1,4c5c6e67,ebbb8f7c,d1dac8a6,da3df0f9,af7c548d,ea0dc6c4,70830532,27a74ddc,79f6cee9,3bdaca0b,833637df,bb426cb8,58ad93e7,4fc1e285,87857cb9), -S(a25e2e8,942e3353,4a36ecef,62c71508,6f1e959f,627287d,f0e7dc67,6457acf6,3383132d,2ab2de4f,890fe37c,74b3253c,fee9265b,e2ef62c5,a755af61,abe00463), -S(c8ffe7ba,62d8ece0,843bd801,6c8043db,2e71d0a4,f91f2eea,7503824,1a3e67eb,fb507024,6a0e3286,8f6f6e67,7161b822,ac9d1aa,267658af,895cb9ad,4d94586d), -S(3352b6ba,380ee90d,d846c6af,ede2a9d6,de4d082f,46bf3a18,dfab2943,409ffbf2,fd6036e5,d7b2ff57,376967a8,42bac428,203b2784,4196fec8,64d8ee42,b7248472), -S(2ac42896,c815a831,a7b2d28e,af6a8c3a,803977d2,661fa36a,11143a43,7d179d55,2cc1490d,70b9f5f5,96cc8294,41fb5c43,44566d5c,77c651a2,34ba058f,b4b05823), -S(ac5917d7,64a4dd2c,a5c1db3a,75cf56a3,4a695e8c,ddae8c0c,74594857,cd48986d,5958f85f,f6794368,294d173c,14937aa9,eea64dd6,80dbb96b,c3e7b855,a87c92df), -S(c79122be,5424c0ff,728368c3,a0ef6ecc,3026bcd4,12ab1ff1,e3443d7b,dc2b46e9,2abca3b4,be4d53f0,40fb7d0b,3b28f4f7,44e4a96f,1e1cdfd4,cdcc7276,30332dae), -S(b3015fcf,1577fc15,337847a7,2b6c9bda,a7d6649d,711a156a,499b5e67,4e6a8ce0,2e826388,be577c02,f2fc3f2b,ca4f1ecf,546b75be,3373134b,1e440319,b78fa759), -S(b857212,b941cdd8,6f80063,3167a5e5,7d6fa385,c7ed08fd,9773de0a,4a481af8,aeb5aff7,329b6227,f614b8ee,1e2784a,ec5432f8,86d29e35,916ca3f5,7b901ff), -S(18f3f92e,a869ba6,9f64ec10,6e42e4c6,438504bb,709734f5,eac1a97,a418c23e,a9d95cb6,dbc06ba9,cf35b953,b0426ca5,167766ff,a533d47,bf40e55c,9e5cca00), -S(b6cde393,b06eb82d,ac45aa40,b094dd08,1a7b4bdf,f4a6caa1,7a1a2d9b,de336e60,81816d39,5db23bf3,9335c483,a50ee3c3,710217f8,9365a04e,1fc1cd49,20fdb244), -S(42ed0806,c78c2d5c,851f134b,341fdb4c,949c74c9,7522e681,81423a0f,64a6f1e5,fac85e8a,7151a4e3,b7b24919,828153c,237bbfbb,4a49607,a70f595d,9535d66d), -S(bad68afb,e1931a,63231202,69b4fbd2,a5b84ba,a951fa56,4ca07bab,d3160199,1b19d063,7e89fe43,894a2c4b,e8203e1e,cda6ac9f,f7e6989a,b1581d81,8c1f7ff1), -S(74c6a877,29197f39,c253450d,ed7cc4b0,948f1c05,3c91d120,668f09ed,f56eda31,e3a383c9,b0bc99ac,1eaaf1e4,47d9a088,e772095b,8a30bd75,dbb70622,44f46d29), -S(ab75cd77,a5800af0,9a2b4ed2,fdcdb6a3,d6b32076,ef5d9211,8dcdb4d6,acc25547,dabcf737,6f03afe1,6d2e8dba,e7634bcc,1cf0302,7545c57b,dbdc97f1,6bb1491a), -S(1951f597,1bf190de,295cd417,1ed7fc0b,6938e031,8403dfff,10434dca,9fd7b7c2,321f12d6,b8790ad8,2a956947,ef0a615a,76b6b678,5c765d8d,e9f04cf3,9961604e), -S(3095615a,6dce993c,646b7e39,1fd86117,82ee418b,cad9c9e9,413db342,45c76edd,9745ff66,fad21c00,68699f49,158f578d,b1ec962e,d288e008,cc667a95,95513fa7), -S(9b2a6fa,60b7fa62,f0cb6c41,91f3b7b8,fc0d549b,98520472,86abe23,4cea3c1d,4763f538,6bcc3b22,4bd2299b,92a10572,7a761b3e,709ab6d9,dc875615,43baa2b7), -S(df52e023,92e2a319,cfea1f52,c58a1039,27c14e64,8eba846c,faac077d,13493c3a,eaf8a802,9f682f59,295d3d,d44c11ae,537442c0,ac61e6ad,1971e975,5f1856d5), -S(3cf08be3,65e6164,6dfe3e73,83ca54bc,ae2e1b36,522da9cc,accd5ea3,4de03f45,d2eaaa72,8b2cc3e3,75bb14a4,4f52aa90,40df35b6,282c0b0c,df8c3a7c,8e75b435), -S(e7d92472,23f321d2,9a327ad6,4d08549b,e38a216a,d9ee8e1f,7dda5956,c65eaef1,d0cd5049,fae4996e,362efe1,f6019de9,2b57c8a5,fdd17a3c,a9cda468,e6a5e5d4), -S(fe851c52,f05568b2,ecbe964,bd80be47,98414ab3,c20fa0a6,d0b114c3,8ff6afa0,3170ce7f,99584c1,82fa6cf7,47197fe5,7f7f252f,e21a38d4,cefa09e2,697427ef), -S(993a0c6b,10fa1b82,8a3e72d8,89244094,cc60ef72,7f9f4758,53f09161,fda8a1c2,51be5ca1,3539c2c2,7a1d395c,3d89567e,cb218a99,3432a424,96ea7e69,95a6fb51), -S(ec46aba7,a6af89c2,7689933,2910bdf8,87362c46,a2a3dd0b,e1e6419f,8b2a2036,cca7634d,1afdae1c,d764d553,80190aa,96a5f444,70db8f07,fe59d460,c2a04380), -S(ac7188a6,8ecba28d,59c786e7,e127335,c332697e,2980fe52,ef3dcd2b,f8227c6c,e7ced64c,99c08050,fbcec989,89f99a7f,faf89fcd,2651d291,66f40c6b,3fba82d), -S(27e6baf8,f83129e7,14858346,ea158821,c474fe2c,fec352fa,61f00808,e662502b,84fa023d,3d371686,db30f0fc,65491b6c,d7a5043,73a08a5f,8d63f94,73f2cbfe), -S(4deb11fc,8f4610b0,c9875767,704d48aa,d55c06f7,2712d577,22f48359,38acb0c9,1769af84,c88f65c5,70df086a,e07abe6,b1a5b2fe,95da770c,ca57e11,4c6dedd3), -S(e2c30e5f,a831d62f,ce366bdf,1415fed6,574f12eb,c4ad36b4,d558081,eab8ca7f,6b76b320,252e2b24,a49da21f,f51207f6,cf2621be,992fe9e3,758e2abd,adafa7e9), -S(293bfb9d,d46baba6,8cd67e75,35e944f5,79690edf,4d17bdcd,2295d044,be309644,8c3777df,a3f4188f,4643b137,4cbc8d53,6fae283f,540d18d,514c8162,4b7af701), -S(adb8b1ad,d80a6120,e90ec376,14f08f81,b668cbbf,db85bc8a,9fb76881,f3feb2bc,7525e4c4,56995383,c9d5b8cb,b920130f,b9225012,a441eb5e,f6ec960,2181b070), -S(a03cc251,b299ce99,ced67920,11eca35c,87ecccc2,80ca61f9,b35f4fe0,8828afc3,34e992f2,9a8b7e71,804c5bbf,680622d9,536c58d3,316138bc,77adaec1,1f0a28f9), -S(e370ad9a,8a78dd7a,e7631e25,bc5ddef7,b5ee9fb3,449cc56d,3c77b12d,2450c42e,ff2d4db8,24f0f626,4f8c61c5,a3ab3cd1,d731ac1b,36503024,61f7c333,d939715a), -S(e7825767,be268da0,958756c9,c10a7f5f,a8b90b0b,f9279530,d5d60cb9,3cf9a782,e8a54111,66446979,5ad4be94,31d267df,9e471de8,9c2f386b,ef52c14f,85193030), -S(67768f1b,a78c76df,4f0e0ea7,ce2faf8,4fce8e5d,d43707a1,586354bf,77c5d369,a33cf627,c206d44f,79e3a473,a07051bf,202dbafd,cb74735f,1af2c8f1,27e4eb4c), -S(3c2296d9,a780ada1,a795d3c0,6bb3cc74,b00a7232,5c244ae0,57cb18d,5e0b8aff,bcabc5c5,2e1260d9,b14f9ee9,70b098f2,edd5163a,65b204b,fecc6a00,cf6c7f62), -S(c3ef3a3c,da7d376,2b128546,c8402603,7aebc362,c2a4d869,f2583418,2d8c8109,207ec4c2,6673447b,8d899e7,62104c68,3d0dba18,ca98c373,432cda8a,a6ffd6a5), -S(1d97f529,2fd92440,7fecb4da,a0baefab,15670b03,fd635cc0,66c078ac,fc35b80b,4457ef24,3b6c9e3b,e99d7a01,9d95b706,fc2530a4,7a88d11d,ee4083c2,fa7a9e69), -S(22bd1fa,eb1d343f,cbd595ca,f80a9128,c7b6371f,e5ac920,a31bd2a5,990a0a38,e2157272,a9ec6919,6ef17add,1855bdd,31097aa7,4e332779,9dae90d9,75155910), -S(dd8b69cb,a32f727e,e5c7e09b,5c152bea,badfec40,8ff36c66,5a95f572,82dd7b88,f8024917,d1678ffe,52ba97e3,48e74c0f,2ccb06d6,8ac7914a,378b7e5,a86dc3de), -S(2b3da42f,b0ffbe4d,69143812,a221f92e,496d381e,a420efb7,944fc66b,ee5eccfb,9299b809,47c26fb9,b5a3f004,7041f494,ad665c1d,ff304479,9fe0dedb,4ebdadfc), -S(98d2a44b,fba2fcf4,5b33a605,513d4c0f,8c036bcb,555f9142,3133be23,7e616db,70f5bcb9,b499ea99,aae3b8f7,f33169c,5af06f3b,55dfb8a1,623d7a2c,d54b556b), -S(37c7450c,933b1e12,8d4572b8,deaac8e0,80bdb588,ab90ffeb,f0d6fc37,2feb2219,ad0cab20,39622393,5d8a8ee3,2198ae9e,950be80,12b5448a,bc030b42,71920b32), -S(d8a2d303,8a0b0bb8,c85b0a07,79a88840,166babff,ec651b00,15c37f89,f11067e5,18200caa,7e7a67cf,e5c720c0,ec1f8ae0,ac083011,9ecced1e,b78802ab,30198d13), -S(c27b256d,eca6b591,c1e0021c,3d1da818,8ed96783,11a90a0d,41396932,f9214a5f,d30baf5a,3c64f47,4ce7d705,fa836a89,9161e75b,a0cdfee9,5f03c559,78024cdd), -S(b00215c5,b93cc894,c508a613,20debae0,58a3e4e1,d826e3ee,cbd168e0,384f82aa,469355eb,844e6608,7a390fcd,f43372d5,37389f99,33d240f0,3dcb0b6f,3476f0b0), -S(da646c43,2f525192,efe9b58c,5e41d190,f5ae5e36,9d8353e0,21aa9ff4,15a663ad,742d960a,863eb936,50a84bcd,5d4a1d50,d1243ccc,77698fa7,9135a351,fd5e9864), -S(381abcea,fd9ecec2,897a543a,d712bc1e,39a76062,b2d34ba9,8c06e7ba,6694a9bd,813cfc4f,a40bc405,941ca90c,73648d66,790e7925,31a6e64e,d432287c,24fd7891), -S(130361a0,1be7546e,57ce8b7c,c97cd06f,db4d2498,635821e5,d05cb8b7,46e7ea7f,448b60cd,668facba,4d56471d,d492e529,b7e204fa,778ed89c,b9ed021b,bdadd193), -S(95df1d44,7739e3ac,7e958445,1b269507,8f32d917,b512e4e2,fdb143fc,465ed004,5807bb76,184742fa,1745feb6,b3705ae3,283066ff,fbd0457f,720d2a2a,4931e728), -S(d9b612a4,a3074698,e06b2c4b,bd27b668,8c71b874,6808d245,188eec80,73292c32,b7e771af,3ca2ef2b,e3d82568,203f0a6,3e8caa73,d6f2fc32,17ad4b53,bbf6bbf0), -S(c882600,f804cc50,6342436,10b79f56,7c9d9276,948413f8,889a6bb3,fc16cf79,835220ee,694bd660,ff321b3b,d931d082,f6efba84,dccbef51,37492ceb,3c03e11e), -S(8ae9f886,4415cfb5,cbb8b67f,8076df4a,19c0aecd,82a63f66,ee5d1a76,1ca3ee6b,4e24aebb,1b507a13,fb1f3f33,7059794b,e81c5f13,4825806a,e7da3723,8be7c7e2), -S(70558a7c,756dc54f,337a3159,aedddee5,fbe3ffcf,5ebe648c,9d6c4c42,e56de4b2,67959da7,f775ca30,c942b87e,a5c7e2aa,5ee64254,4b600134,493fe07a,47a3ea82), -S(ec4bbb6f,6d88f798,832c4b59,d6e1ab57,fe559818,a2ee858c,e4273770,81c46b46,55933669,59789697,ea826bde,7929720d,6887bff7,4e910b3b,44bf757,a2cad075), -S(e7f069e6,abcceb3c,30d28256,50e8a469,3ac693a8,6ba5b120,fc827400,9f737e9f,2a9dc479,b3a7627e,3ca49295,7598d942,34f4bbf0,304c34eb,cfbfb662,1fddac1f), -S(54b175ab,7c18c090,2f0f97cf,4444f362,3916122b,1767fcf9,ec576ca7,5a2617f7,b5cb03e2,9a829c80,81f16888,3adfe85e,917e6525,8cdd4f0,cd3fe571,7adc6436), -S(da20f8ff,2b64cee8,7572fea1,21f98044,57bafdfd,3b1ead53,6fef24dd,16e08c2c,6e1898d2,b7482032,6b299591,376525f1,700ddcb,8e2c8057,40ff9327,2cee5bdf), -S(55244d3f,e177f889,3fa2e982,6ae89927,1b0bb5e0,f3764941,95a9e90a,8d1367be,abf46ed0,93f617b4,85d7719d,b4878968,ade00c3b,7c8dbc70,c21561f4,90dd3b4a), -S(a2c59a7f,d001bd82,48813d66,2c6ccc24,ad815cca,89ef749f,891a219e,956e931e,fa61c08,4a0a648b,5307e771,28a58d14,4d1084b1,58f1f824,f3d96d,d091346d), -S(d94e65ad,9f2cf491,192e5d1b,ce9d42f3,14c0a724,5c3b351c,f2ba3a3f,e70aec21,3d503a0b,df638ea7,5ffb2886,b3a9d723,2c427fb,d4921c4b,b1eefb86,2eccab8), -S(eb24a84e,aad08175,13705448,36b99c05,adc0e7f6,ae871a70,b42d24e0,a6287c55,3c4e2230,208b5750,fdf24d95,83d94db0,58e65604,d555a0be,372a5f4,a39858de), -S(69ca3107,a95583e6,c6b76b73,56b6a65d,2c45f0a6,194b69f,ec56efbe,289f8141,594001e4,46916b8a,9f977542,281016a0,8c8290e9,92e5e87f,fc16d49b,ca9f7155), -S(f7b24587,a436adea,15f6cf87,bc065d18,dec084ff,6f6582f0,3782a977,515595b,30391228,a155358,4b1f8b74,da91239d,89a4fbbb,93635cec,bc2453b4,9f355331), -S(16bfd7d3,572a6fed,c10a6e8,f6ffe3e3,9090448f,71884026,f6a16688,5f0f0d92,17a933d5,f2b3ed3b,f09927da,25331207,31a30a81,93681cb7,3bc0b2a0,c0b7f436), -S(dec8fca7,95baf9e4,379aa5fb,777777bb,178e086,1a738053,17f8d676,5cbbe9cc,99f2da03,32b83f9b,b712732c,e9b7ca53,b7bf6086,46c7642,620fc738,6b74343a), -S(f6b5b4ea,ba3f1b89,d399f6c0,eac8abe1,88a9cb21,9a9d4d3,7b578447,62f3956a,6cda2c16,8211c18e,8722e689,70fb9a23,54d09606,8e104c7b,5a6f6812,fb854a25), -S(2f547664,916072d9,2754da2b,556fd3cb,d9b67045,4bece334,960875f7,df57559a,c3c27849,64cabd54,6487f05d,45544b4b,bea58b16,e2a2e3aa,2105cff3,c8d0a5e3), -S(b98cac11,e194e80,83d39bde,8b28103b,d09bcf5b,bb163b78,33e00be3,3f52779d,dde188de,3763488e,7ddf8bb0,12291cf,848fc21d,25ad040,6217a8ea,e1fbe6e7), -S(1fc36f4c,99b540d7,a74dd2b6,1fd71f1,b095343c,3d7856c6,6febff21,b5c61286,6d165f6e,ed6343f,36dc761e,63f6068a,1a583086,cb76ad6d,a6996fd,8fb303f7), -S(13cc7352,2006a383,356e7378,cbe74e7c,873e1a8,c96f437a,995f5549,616dfa5a,f73ab51b,639aeff5,ae8deaab,e5fe7dc9,fe8cc203,ec66f16d,dd789031,6da8f614), -S(a42b8522,d7b620c2,8011137a,76719fa1,3066761a,7a612946,60c9fb3d,e37696e2,e0163b30,5f5500e,74bb9e98,c7f8763d,4cad602d,d01ee3ef,404899e1,1df9111d), -S(ad1e64b2,63b364e0,477657c4,33601197,61b2efc3,87c5b2f2,71befc20,279ca300,52e1f8c2,80ce5c76,70533ea1,4a8d75b9,e4e0ad6,199cdf0c,c570daf6,469e0a17), -S(b25ac32c,4406382f,6c28a12,f4e1b491,d7cb9a6e,2f03cbbf,46c26d95,d70b6295,db173a50,1d02a785,ab98ab65,2e814ec0,fce3ae92,e3948610,3141a844,93113f11), -S(507ddbd6,2908f782,9bd54ac7,948cea3b,ca3f5551,d5fa0b8,736ff2d4,a38440fc,76e3189,b588462c,93de2716,b5d79d42,8339a81a,1bc2d8b,e512e33d,5de5ecf8), -S(c300e40b,425d9391,4e2a8624,830f119b,3adb2e8e,d90f4873,46dd02e5,1ffe7006,b588f4f9,e9a315b4,1bc6484c,3b0cd1a,de816262,80f14767,9a1c3b31,1e48df17), -S(19d029eb,114bd8ff,952307f5,1e04593d,a4936127,dfc72bd6,8767a462,36b31b6a,e56c64e2,b1f14ecd,1f7dc29,be51fdaf,d859d6cb,78c5dd7f,5fa0f221,bec715fe), -S(b972dd3b,e3531c85,f1d9580b,8ba77429,747ad431,4c5a7947,3c54d647,bb93ba63,b1076055,6464152f,c5477005,fd6b4ec0,e8a73dc6,63fd6622,ffd31170,5ca7af0c), -S(148c6a57,f606ff5,2489a1e7,df84b1bc,11ef7b68,9cdbf0f4,f583be09,db595b9c,308e0362,2a681b0b,308f11a0,71742e4,f501d089,9f190e9c,239689d,2de198d7), -S(f8eff5a8,48a0b184,768135b,8c159bdc,ba86397,c38a2255,dd6bc746,549521cd,9fc518c5,d2bc6749,8fbb9ac0,8c22a070,e948321e,3b11473f,b96a67e1,2d788e5b), -S(61cb5332,ebb1b0c6,badb58d9,c15b8b1b,8c5b0a95,601220a2,a2fdb007,325b4442,fa90f15b,e1636b62,72ae71b,5711b43b,53580f04,86b6472d,e14737b6,8267242f), -S(9ad91194,210d4acc,b4f2fa3,f69f9fe5,707975f9,99f3e40a,9b766e7a,ae570b9d,bd770b3a,e6f6ccac,9d0dd1b9,bb5c451e,c27a8d0,ce02b491,a6c40afa,86067ce6), -S(d6985c89,71c21dc4,723540e0,9901194a,a898c0aa,33c4bd7d,34d74164,cb46ee8a,3c62000c,c8969f08,2dee7159,df6ce660,89e13b1,9c71674d,fdecb469,5e4eed89), -S(398e5cc8,4a90fcbc,1af56815,d56619e3,74e30023,9f95ed2f,3b0c3d32,fd0657d1,f82f5fe9,99c25624,9ebae25b,71946c98,b16cf462,cdcade65,ad22c608,7776fd49), -S(d5b3aa26,c2400d25,7032782,b35cffcc,902fee32,a28fdda2,f36eb3c0,1b19ea86,3f3fcae0,a7f0956b,2ab41211,a8941be3,358b22d2,1eb18b0e,c0afbf38,95e8e17a), -S(6f6e1cb2,3e212a5c,91b91407,7c90d465,eeb3c46e,74addbc3,ed228a1d,8fa201f,c11432fb,60b782ac,9dce6e69,e8a544e4,c5676f36,7c959239,c4dbf548,610b0f74), -S(23eaf533,24bda09c,ccf5edb0,8d0b5904,6c42f17f,12f64c81,54b884d2,239239e3,87aa0fe9,c37c0150,95ba3f68,96ea597a,a38f5a68,d8fdd6e9,a9eb4aa0,b6dedc57), -S(639f2502,a5f0073f,95352a3b,63982bb7,f215e0b,c80d3f7b,fc37d1b6,2ea89e18,a93481e3,8d78e490,6fe37f44,a198b85f,c6246f0,50d17193,f01962c3,c9351b24), -S(1e78e21d,4f696d89,b0b43eb5,e5d8cb03,46c9d030,65a4ee15,5f81ac27,b8fff65c,3a8103ce,e0d7e645,69e22332,911728ce,20793c12,c7d45b0f,3d840641,11221f8b), -S(1ece1fda,85a726ba,49bc7ac9,23e1599b,b070e8ce,134858b8,cb4d714f,2b539ff0,dbbc6f14,fadb9d5c,559b3b2b,df070bba,11d8777c,b5526bc9,ac951dbc,9815863f), -S(e49e79ae,f17ff1ea,b81e3c47,97310952,6dac7ac4,ecba2a57,85696de8,279af373,92b0fb30,368189ef,dacf5e40,1ec4dbd0,a4ef28bf,512167bc,42f63cf8,a7f6ba73), -S(ce0bec53,1c1eaeeb,868bd283,9b37c225,fdc90d0b,d6d82e58,20516b7b,9c9b81fe,9ca80cac,80100d58,68fd1bb9,b174b0c9,54d17492,12ebd194,5bbd526f,6f842b97), -S(df282fc1,b4fba7e4,fd75af57,805d93ce,af88590,3b57cea8,38f5edcc,2e7efb52,27487ea3,77eebb18,699eff2e,66909c2d,9daf7f0e,32e13ac2,17df0d1f,b8701c33), -S(e82d0d6e,29b68dcf,aa8ebfb,4d8d5f70,2d6a91dc,b10c5c3b,c7363360,6c937510,ce1dd596,232791f3,7efdfb4c,7da518e4,c98e8f02,d36c7230,3cb3c52,69bdab85), -S(cbf085c,5316258d,6cd5e721,b613f97d,7e22cac6,2b832bd7,e2830f34,2f748f20,a5efaf98,97cfeebd,b07bc80e,417e73db,bde10972,57684543,151c1940,a92f7e68), -S(dfd983bf,84da8670,1a475a89,66569aa2,59c36fa7,9a5f5142,fa62cf34,105817ff,91973764,28e0cd11,11b8ad8a,5f41d6d0,3ac5b930,5701d1a8,d621da05,16e6083e), -S(e89e41cb,5dd179e2,ecb2a48c,af7f3dbb,d4d9fb3,78eb0822,6652dfff,593266b6,7dcbd3a0,765dfc52,8244c19a,df657719,6ed46b1b,2bf62042,949f0f57,df872d01), -S(20b45025,780c01e0,e8bc2899,7f59aac4,ff9434f6,bf4ac433,39096769,f3e360da,4bec5654,5409a944,c68f0942,a1fca7dc,aa89a2a0,4ca9d6b9,b325eb06,9f7bff95), -S(ec4820f2,955c17b6,81381e12,8acbe1e7,75669f02,8517dd41,f4723d3e,64d75bb2,41ed16b7,5dc65672,eef6166a,b86a419b,ceddf23d,d365e63b,578388ed,bc6bb8fa), -S(b15cf70d,523695d9,48dd1f7d,2f2a12cf,aef60bfc,93a79410,2678ce11,c4233424,63b11e19,1335490,8eeb94c,6bbf1875,f867cc17,a599e83c,2aaa4553,47d549fb), -S(d9e85a98,5cb2dc07,790b0db,1e5a43b2,a51b882e,846bcc2a,8c2930eb,efb79f6f,482abc51,54846788,1b8551f5,e0162ba8,3ca192de,1ca4ba97,19ffdb18,57583b57), -S(6d8dbc0,cf0b7081,c03e9bcf,16dc7445,3c9eec0f,d21f82c8,d05c70dc,bf61db91,ee91fa7e,4f5f59a7,5841d903,ac0a3f0b,68c837d3,aedeac7c,bb9576ef,a7f7ece6), -S(b12c9714,2b5a8ef1,cb2b0cca,9316dd0e,7969a2bb,f7fa34ab,4cd412f,dbc500b1,690c027d,e9327f7f,3f761509,c57a23b0,b2d7cbc9,e5392472,8611ba10,7e5a8e61), -S(970d6bb7,2dac2f5a,7588ac62,31a7425c,aa120592,80f4cc54,19b55126,ed4f36f4,3f541ae8,2186eabc,562d3e1f,7492a8bf,68e45210,9e5d9ed1,ab59aaff,9dcbc58d), -S(41605872,337e0cc5,f9322c5c,a4dc3e81,40b8bef3,b99c1285,e0b5c53a,d08d25bc,3a52bbfb,d18d532a,53187d3f,f9140aca,38058be8,ddcafdf3,83f4204,780fbb56), -S(4889a88b,7e9a5d65,bc564fa1,12a6318e,564c5e39,4be6c4ef,875e79e,f33358e,e0757939,a788755d,c54469d1,3e82d9e,a9502478,3dcc51bb,8856c5d8,629b1da3), -S(90ac2fb5,a463523f,ee81a501,510874eb,ff69456c,3670decc,2d14b3dd,a1bc284,b6f10a6a,c316af7c,dfbb3b7c,6aa30846,10b2f44a,1e415fce,d67245d9,72d2fc63), -S(9286dbdd,9477d600,ba2a941f,e467ee8d,9a7b114c,dc42e488,8648854e,febc5a1e,5ef9e3d0,ce7f522a,c5a1e46,5281bf98,a63623dc,f300be6b,d01df5ff,6661c68c), -S(6b774b76,50623f6d,cedf0498,683c05b9,1de486e0,5f9f64b4,dd13b0ab,eea0c53e,a3dbed6e,ebe68c9a,86468874,ef2ef5ff,3142266c,756b48a,3314698a,c4a20162), -S(e5335352,fca65cbb,8fa6e275,ce8a0432,d7ddbbf6,f8854e4a,371b07c,909c42b2,30fb3def,31c8bf51,8e2542a7,83736e7e,d87f1c97,70465120,47faf3b6,7764d77a), -S(f87c5b0d,a8edd93a,bb33e606,1fc34377,54a236f1,44bc0ba6,1cd26f91,86ac75da,92434741,af204fee,a03027ae,1ee5eb45,82769d1b,c264472c,dfdddcbc,50065424), -S(dd9d3fc2,96eda501,3886376c,88af214c,3a4dfc9f,eed0776b,287cd32a,2fddd2fd,32e630b,2da6114d,f09ff5d2,eec619e4,48f849df,399e5e4a,e802efc1,dcad04a6), -S(10108724,51bbc5d9,b045666f,fc45ccde,c29b3a10,60ba8d76,5fdd1f5c,1dda495e,c86404db,ff9aabf2,599f6c35,e6a8d7f1,2654844d,add8c787,86158faa,b10b5f85), -S(22f7f223,9c8fedfa,cdfe80aa,84477ca0,df289636,2f055eea,3c63bbe5,58443a98,661ed060,8413a4b8,775b9916,14d848d0,269dc75,4d2ff2f1,b4a18fa7,ef0e19f8), -S(9a1ef62a,7567f9d6,9d45edc9,3ecdb7a3,1ee6793d,a2d387a6,304e0185,3416ae70,81f8527b,4c9fafa1,b2fdd185,57998861,4f6ea270,463f8261,814d190c,80f93f4d), -S(b04946f8,8b0c5fc2,13d215aa,53e3d90,df45d13e,bf7b665c,d41ebd3,58cbe5f4,2e92bad0,9b485af3,904446fb,14fe3624,c447e72b,41519297,133933d0,b6191869), -S(aaf764cb,7db7d191,c2dd7061,c213b469,bc270677,7ae0ce31,b0a3f6,7ec26728,4c4f42e,5ffb9d8f,e0625906,b17b7857,8afbd773,834e40bf,c7195f08,19aca859), -S(a236de9c,e071504b,e8108d5d,f5cb7ffa,d4a333e5,1afb1579,2593706e,fa04efc7,773f065a,227634be,3ec7d3b3,4ba462e4,d50f79ee,19541896,948ad725,c26bdc88), -S(3794260f,302e614,aa700f32,e41a0ee,c772d549,58b11533,2b7de77,925d7cac,d1896d9,7b5e2ee6,9ab7e55d,83381ad9,bee1b87d,d3991f53,4bb67237,830e8926), -S(a2436b37,7fa45dec,eda48686,e0705068,ea607b24,58482794,aae3345f,353f6329,e1da48be,8cc2c88,5bae924f,df1a328c,37f96261,3470a841,7784c4f,b965e05d), -S(f9616f77,6a125158,7165411a,582ccc1,2317e260,89412bb7,5c2a63a2,dbea5658,39a790f8,111db9b7,f3b69bf9,9d0982c4,6d97a18b,c937e6f1,3db36ea6,9d7471d1), -S(4a720ef3,9c907f62,720ff0f4,c5d193df,c9bd3613,6f49f72a,69aaee15,b3b7fa42,6ed9eea,cb95af1a,5b91bbe,27ccfa4d,f352a227,67a250a3,179f94e4,bee433f7), -S(dea00421,c07efdd4,24749981,713c1c13,fb23f974,fdb37f45,35314d22,b75cf0b8,2e91b078,2b3dbf41,3de9f98e,e421ef30,bad6cb5a,b57e457b,272f3f46,7709aa32), -S(7e14f09f,f55a0b2a,88518714,68340514,903b2ebd,3525937e,2b0efc79,bb1d7b41,30fa7849,3660b715,514b7fb4,5aa50324,a7958bfe,4db78914,966340ea,c8ea96d9), -S(6536425,5ab57582,feeb109e,7a9657c4,dfd8fbf7,57be61c5,a769ae58,56ae990a,bee94b18,61d474d7,40674349,1b875022,8eedcac8,99835433,529a1621,bffeaab), -S(8448e3ba,f77574f9,2bb731a8,d0d4d3f3,21531c7d,189ba5dc,2edfd54,78ecb11f,425a1eb3,727a5bea,478b82f,d9fb7c9d,b933a7e,8283e897,d1d21ad,2281d39b), -S(d2ec1adc,1d30ab11,b1ba87ed,7765f848,5d097e83,3ffaa26,2eb5aed1,5778ec35,beda7397,61ff8a32,b0965b47,55c186a3,8d24e8cd,5dad81b5,4a106abb,335c3994), -S(3b205375,ae0ddf7,c2dbba5c,9e14b5fd,e8899448,4ea0d82e,a939e1d4,f1d8dfa,bdab6d0a,8d1db118,785bddd6,81c3a402,460137f,f4f1c26a,d940708f,969df70), -S(eef96785,6012f0e2,5934efe7,b9199255,869334c2,59a62384,f2cc4b4d,6f5865f2,1806efdb,ecd0588,17db47ea,10ed1866,6bf0e9c2,7a2bd661,91d92d1f,4ba0a9cb), -S(9271ab48,6a17d2d9,c91ef3f8,73c74d6b,754bdfa7,67172cac,53ea741c,e101abd3,4ba3ed7c,1ea7d0a5,5c4ad38e,cd032e5e,782b69d5,3ade655,a8d8354,422de96b), -S(9bbefe44,70872b67,3ce6afe2,43c32b8,e2409b69,b57f15b8,e1d2b4e,d0e760f6,a1c6f4b7,cab89ff,ea846bf0,20ebfccd,77e7ad4c,68a8095f,c9b56a5b,f57e4dbb), -S(cbdbadd8,5cb42d34,cf249e78,1929bc4a,90977ed3,e6c7fb4,5f0713b7,3e3ba051,1b2a60ba,9f4f727e,c057d149,2ac04e50,42fe053d,89649be9,4fcff26e,8d3ba7cb), -S(414eb1ca,a37e098c,6d4257b3,a9e22047,652e5c0,e4872547,7e97a2d6,b89151f5,27600f8a,b3b66f86,6e6a712,c8d2d557,736b9f2f,3b7be72d,2783a5af,35cdf7cb), -S(be0e548d,4302918,60ac6c47,4593a5f7,169b3eff,c9d18878,6eccd511,e1f195bb,fd26af99,8ab759b,c9a83d54,6296efe,cb0faa62,eec5a7d9,98a0d80,e36a494d), -S(ff38855c,7925713c,80c0600f,7cc3e60d,9aceb7d4,b1199d75,2a83a67b,6b1dec1b,e42b3d08,f12b19ae,600479ca,b593fcad,bf680fb3,da54a1ca,d072d1f4,46bb8989), -S(157631db,883dc9ee,b5b3782b,fba4e430,9426acbe,5ed06fd7,662f06c7,c776e829,cad1de8e,426da993,4a8e573a,5e041952,4b3a01a2,e29049cd,c9439de5,c5cbc4a6), -S(c758ec6f,4a7d15b,efa56470,1f8a2278,ed886788,1aa2a772,c20fbff,ed05885d,e3e80138,4758c6bc,60f10beb,7d75e7c5,d0a541af,38ddde3,b7c5f709,34fe0ddb), -S(e20d3b67,cfb8226b,7b22bdd0,87044f7b,5b29a277,bb5286f,80093eed,69277e67,ce6a8a7d,c1bd236f,961610f0,15a9cda1,9ab85200,abbc6d0b,9a041ee8,9d97c743), -S(b1d70b27,a855ceea,149c0508,2f88d465,6aac5541,aabe223e,4b13028f,10a2aff7,4df082c2,87170b69,88b05b37,1d4b5181,773741cc,70544f4d,7d3742cf,77884caf), -S(f30a09e5,9c163445,5f231a0f,52d9e6b7,8c336b07,5f1ee6a3,bdfd4cc,1bf213fc,acb8bd60,eb919332,a405023f,c799072a,a2838dbc,7ef8d042,7417d61e,41c6b00c), -S(8a615da3,f0f92f20,e8dd5ee6,23178403,ac0287a3,93173dea,1bba53cc,2cd268d8,bd7a5a1f,ac8d4157,6b51f9bf,ebd581b3,ebf470d0,43731e4a,4dd391f9,423d32d9), -S(14d45568,f9b4e6ff,f8062209,7dd34f36,17d3fce3,e5357ead,baeeb480,2a43e7f7,25e65c8d,50296272,718ea121,cd5a1365,d134a134,fca3a5f6,324d7cb3,85f9f163), -S(706f64f2,a7008aa5,d3eabb07,b4a3a3bb,f18eab6b,cf605117,c70cc0a6,280e2084,cce06389,bc03b45c,cb235c88,19639a27,5a78ca00,9e99978,236411bc,687c93c9), -S(db4f0639,fdf573be,8d7d4f84,4d8f781b,51731003,24343be2,6c8805ae,fed3b91,bd1564d8,8abe4aef,dfe581bb,3673f874,38248b1e,7b11e019,6e158bf0,5cfbebcd), -S(43e3c600,4f3cd3e2,aed372d5,60348976,f420d1de,95c70a4c,eadbfc9e,df393d32,bd09845c,429c91af,9e9b3441,321c68c1,888f8c31,15960131,85c90bd8,6b9b30bc), -S(13192002,45d0e72f,e9f289f2,d9be96ac,ac2f1adb,37716658,700aae4c,91267ef6,864b391a,aa20047f,38308f95,e42f4976,494e1a35,100affc7,2d435f85,f936a039), -S(752bff23,288a0554,7f048770,da6abe2,e70431c4,60a71765,40b1c124,89ae7383,aa2af83a,92ab2a29,1c5f89e6,61a18075,d6c3e8cb,ef6fc0ae,c283e77b,56fdcd5e), -S(af0f3d24,25247b8,cbe6e377,ed72afe4,420a886b,aa995671,d638884a,ac238fe2,b7fddd96,86bcbcca,f363b3ba,ad214771,edb9a392,1bbfa25,870dbf52,a42e9622), -S(6be310a6,9ad4a56a,cf79630f,e8767f0b,c986eeef,609eee6a,f1a34657,89c3b93c,2ac934b6,f549d51e,8bc3342c,9fece7c1,c79fc301,bf006cca,20e014f4,b1a9c768), -S(a53b9a96,e9d44aff,ff7f4393,ee691d30,ca4a115f,60267b16,ce11027a,73a7ef1d,d70e70af,5e8dc02f,b3ad170,734e8b13,8567dae0,d73f9754,d6070563,8abfe3f5), -S(e782675a,5a2dc77d,383e8d03,fb2b126e,5abcc07c,391e5597,d127e60d,bd33bb45,8342ae33,fac4979b,fd47d5,b9b40d85,db40f79d,42308ef2,4110b7e7,7dd842d6), -S(eed988ec,3da0c2da,b7235b89,53ce7bb9,7ad8c4b3,7ccafe78,adf5f2d0,911a11e4,b86c5a28,fcabb2fb,4f1c83a2,77174144,b0eb86c5,aec7c52d,59b624aa,38bfff3c), -S(86783a2,5ec820bc,44aa4aff,85212dc2,fb169f73,4b3f359e,844fcf55,abb2a991,6addad83,3d08b1f3,3640ccab,4a68f35e,6ab63752,9f562c11,3ec46833,66e8da1c), -S(3304c750,d62d2678,beeb4c3f,55414ab4,f9507039,55da35a0,193ce243,503b1400,7bca1f1d,87c963b,b2ca8a41,c675b87,205af0ac,ce3d458a,e6ab5f37,fd000694), -S(cd4e3851,b2ad955f,e42e24e7,c071215d,9c4cd24,d456bbb8,452aeef4,4312532d,850be683,bb89207d,62663852,e5b1a38d,d5ec8fcb,c11944a2,adaeec97,17db7bf3), -S(c32114d4,d0c47f05,c31f859a,d26895af,8d46fe98,7565b2cd,ca7363d6,c07cf256,80cd894f,7869eb3c,7df5c5cb,279648e2,adad337,d4f80f5f,501b872,c8b7e9cd), -S(ff6fc809,143454e7,bde3e327,bd7aaeb5,6e7c8c33,93137be5,e63b0ad1,87f3fccc,75aa0f16,ad2cebf3,b8c0be54,aa991dbd,83789abd,214e36e3,3b29f06c,226d0e9), -S(64f9456c,b7b73a61,d9e788d,c31369f7,32d0e34c,5b763e9f,bfaf83a1,4890a8e7,778c77f3,fa3b7edc,afb39532,607bacb9,ed2aedc3,7734b191,ffb5b8ef,867414d5), -S(d9e41a8f,2ffb8bbc,52d10aa1,82d9b0db,f04c0326,8f45d531,500d13c,e25f3d54,728316cb,f2927363,25bb3d18,15fd624b,53e6b442,693a29e0,8d2c98c2,ca524a3), -S(b5a615d5,1241e064,81421f21,45ec55ff,c953769e,74f5c96c,f760d085,2551644e,e2889361,fa674a81,92358a00,61e7b210,c51f88ef,a442b849,d049ce6e,6e9f26eb), -S(5a0c994d,18e62a9a,44358a14,791f4a22,457551ac,5b931fb2,1856928e,a00f15d4,5a706762,8f5ca41f,7df823e1,e27f26a3,de85ad2d,cc2598e5,d8238a0e,587176d), -S(51deb73,6840951a,a0e44ab2,da2a62af,15aacfe,c2740819,9c57959e,10a03fb5,4a0a72ae,f05886b0,6c03b91d,68af04c6,818d5ca3,4e278b6e,d830833d,c15745de), -S(5d967cac,ae97fb90,7f2b8da6,9768a0f,e8a56c52,e79ed9b6,ae4e9a0b,fd92e51e,d840c983,bae8897c,e443d9aa,874bfae1,7475d00,c0728dc7,5090400,47043ef9), -S(2e71c7b8,e187f250,bd500b91,1526f3c9,154457e4,35085672,8d2bc76c,c82b8714,53d13e6d,51840bd5,3e8ddad8,6e6479a8,7b756d57,bf3e9658,c0c0f434,5da398cd), -S(c45ddde5,3660689,113cab5d,f4e218ca,159273e4,db18fb12,d2d80397,1892e9b1,e3bfafe9,fce4db8b,a68a007d,f4c6174,6addc8ce,13b63537,472a2672,48f9203e), -S(4792e0f,2bb7cc27,c44df3d5,b3dfdab7,319ee762,812ff2c6,65da6ea1,2548110d,d3fada96,78c437d8,5d9d9577,3e40ce3a,7cdfa6d1,3e7f4db,17e6502b,b17a71ec), -S(ba662d39,c5c81e15,8ba7427e,8c0633fa,e8e9ef04,7fa408ab,3836a674,328d458f,48ee6efc,f0789fcc,901cd9cf,59fe6d0c,d3212180,20f90f22,682048ce,ca9f1138), -S(be51e863,6aa87c9f,d348a0ad,a7bec639,2ebf2ab3,d4cb68c,680ef1ee,6cf6e806,71ff99cc,7f6cafa5,90bb218a,cdd62880,b19ac007,8f171c81,876370ca,affaa70d), -S(75bac33,bd6578e7,c1afb10e,3521cd97,a51546e4,eed4ad4d,e70d5348,755003a0,5d700b34,fb93c9df,70f0961,bf5902dc,c51c6ed8,163e1fa2,6972e474,9b6da1db), -S(d7647193,14152aa2,98572779,1d1120f3,106a1397,3b964b93,8149694a,fc584bfd,6fa6bb33,a75c0111,cd6f1b89,177b419f,d361676a,93d0f7a4,61c6ce99,e667d6cf), -S(9ac1d334,59882a0e,bce90ae,1a404f61,35e9465f,5be0ebbc,61a479aa,f348800d,b7195d60,a7f4141d,145fd1e0,a5e58305,b1610ec3,4f97b09f,d8a8e57c,3041f05d), -S(bde59b,e8de3bb3,cdc7f5e4,1743a489,eeb99171,a89bcba3,5eae33f8,cfd94d2,208b222a,5831abb,e5f343c6,761343f3,211078d6,ffd59690,9fc976bd,86f6808c), -S(58f7e872,6a34f41f,3720b5df,38a3df88,58d2238d,e60a88da,d4198326,f5e37ea4,13f8cc5c,ea43a637,28c5cb5e,b4fc5381,d5618b4,477758c5,4dbce46d,ad7f433e), -S(fe6d09b1,93d1a7c6,c5d5f6f1,522b63c8,aa257503,9add5cb2,21d5950d,3c4bec93,eb383e15,24f52785,6d8535e3,c6f2f8bb,deb71907,b6151510,a4839b05,7e3e6dc5), -S(8cca7fbd,d0a041b3,e196b08,353c704d,96db3817,29d42f4,513ff5,467ddd0e,23a0dcb7,dd044a24,cd9202c0,4c32cdd1,fd25c979,b0a1aa62,67bc2321,ce7a5f1), -S(a63de000,cd76bc93,7515a124,a334719c,bbd4538e,9d04791b,2b0de33b,bedd2bad,4afe72a1,d26fbe8f,8f3951dc,1dbecff9,c8aaaa9c,bdfa03b8,a6c48cf5,764f65d), -S(5a42a678,c32a688f,e7cc9688,9f93078,8b5f0126,f1eeba7a,c585b1fd,9f97003c,4117bd18,e961dac2,d15be023,6e1254d7,eba89a0,b4ff95b8,82bffc4a,7a375f3e), -S(3c01ac6f,1ba11409,6817408c,5e6191c7,d401f258,f0345c8,6b0c83c6,ead7ce90,f39943df,6465cc6f,792a99c1,b2c97727,421fc8ef,11b2cb9a,cde28709,628efb9f), -S(ae63ac2d,78e0ef81,312fd73f,105d8ecd,8d5777d0,75d06600,da8f5b4e,3e20a8be,50ccbedd,e4d4241b,bd62c0ab,68b2322d,c0e55c28,c8f71ee0,40dbfe6a,d7e33d9f), -S(c793575f,b3ca9516,945bc82b,aec1114c,5d8f8e0d,7cecaac3,31e209f8,22d01044,b2d3a441,ab01f822,366728eb,dc843b7a,82c82175,fd4ff08d,700a2018,48766b1d), -S(e6438209,26baa22c,e33b1588,1b5c0192,b14e72bc,f162f04b,5e6d5941,8053e338,90989550,9fb4a05,741ac6fe,bd4b78d0,15710c50,6c1c3adc,955604a3,1907684d), -S(5d9b21c1,3331d32d,d7827982,6d41a5e6,8ae70be2,b9d5f346,a82b8ec9,aa559323,6e086fdf,95f4a998,66b3f471,f3c722c7,4da8c7c3,1fd65705,68cb434c,1427e5af), -S(81ab7527,8cd4e683,f127e7df,2153fd93,60bd2f07,32a506e8,55f60082,7fabec86,cff8b01d,24be6850,6e068910,55a5125a,ab7a554f,81e5e8c6,78348026,ee7248fd), -S(4684137b,1e19dc84,8a521ed9,e6aa7747,548535e6,6b9fc1b5,a533c580,e7546317,8c2f57ae,7f42873d,5e3ed228,a9276a9,cd684c42,c43113e5,b465cf7d,eef75911), -S(3844877b,e43eb3e,171f614d,7a56aea1,4615ce67,b09bc928,b6a16b48,3c15639c,a2e17211,48d95e9,6690d982,4a7bc84c,c3f0388f,e54e2546,9b58f624,c3761634), -S(d4246638,80a8efb2,99d3d73b,4efd73ed,5bf70111,2b5cde7,631067fe,2b9de212,b98986a0,229fe086,c91b2a3b,4373411f,baa31c98,7f475ffa,1c29ca,93d4b80b), -S(515b8ec9,650c5448,6eab830b,4ee0bd7a,4525c8eb,19520c3c,6e6a214e,a7861c47,a7b12837,51812bf5,c37bc48f,ce08de95,94e4d619,18726c31,57bd660d,80025185), -S(4e499a52,6352b7b0,3d78af31,5597155a,eb4697b8,14ff1d5,93b9b838,6efaaf8c,bd4f5e6b,dbe5a232,c42b0ea4,e55f507f,2ca33587,349b1f0e,56a25820,60ef57d9), -S(2c9a7cf1,553e2593,c455a8af,9b12a0c4,26d579ec,6a097483,a7274edc,98dddb99,99aab288,24298866,f0f42672,395d39e7,338aee86,35c4cef4,ba45f067,83c8c8ba), -S(7d5bdb5c,fdff2871,23a9b78f,3ce189d3,ac50fd6d,fc49bef5,953ad197,8d27b0fa,c76a17fa,97ffc25c,8549d7b8,f01842bf,34afe80a,27be4c4d,fdd68229,2dc83ea3), -S(fb222262,444d6db2,43abdef2,9e0ce41b,818a177,db630c50,9340eef6,24070256,8a42ddcd,a7405cce,9782e8a5,23ab108f,3e5be176,49910b24,c8084253,46b8596), -S(b3212a32,2e415360,62622dfe,43da56df,4beeaee6,b8b5e783,df514a7a,83eed60f,c9396626,6dcc8af7,56efe8ca,e86a7b28,4b2e847a,8e571911,cae76e05,58fe5417), -S(80c90758,1ead4640,94ac1b9,3250b9b4,caebcd74,582bbf20,16f013da,1f4f01cf,d42a5504,c5be0a40,e7bc4242,32a9d703,58370eb5,a54be08c,93f43a22,6e5e6ad5), -S(50d17433,50bcf037,a310a05c,59adbac5,e2fcda09,3aa6ed87,9340efc8,7ce0e228,9e733972,8e88d9cd,8a4e9e7,7dbd7b49,114d5a71,6d91088,df928d60,743bf2ac), -S(c8e7f596,3faec5a3,a32d1ee,65d1596c,a7edc87f,486a13d2,c7ca7b84,3b358cbd,37250705,1891b406,34a9752d,942e6ff5,67fff1e2,d67a88de,ce79ec56,97f5ec38), -S(91f28714,e47e051c,84bb29e2,db84472b,e3b78524,c998a071,731e4f41,9b94d2b6,8ea1eaef,984af3cd,21be9097,99f68033,7c6e3479,643e0c68,b00963bb,d0125f0d), -S(d50a1905,ac4d2195,5c2e6733,5d38a08b,26e29809,674e1b61,8004d18,f823f402,83cdc5b5,33145488,35884fbf,f14b8e5c,35c1ffe9,29fc5222,c7e2a868,d5906827), -S(c45086cb,387b9bc8,a1d7b71,ae74a87b,50ed90e3,a0027766,98f7ad4d,809666b9,1c0abe25,d46ab7cf,dc4a5ba5,e3fcaf27,822b5f0e,1bc08af4,452be7ba,d480e605), -S(b486a681,f9b26f12,c67ba147,7ceb43c0,90539587,72dd1dc,15cf1e74,9fe3856b,f4bd7623,fe97b6e2,6f49e292,899a7f4e,e7925cd5,3fe51cc4,33f77d1b,76291240), -S(c7563596,946f57ae,f91d12a2,4dbd2d0f,726422e2,ff6ea15c,f70c2e7,868e6f8e,566fef1a,aa3316fa,e935adc5,bf1e9682,e3d00e24,2bb57e1c,3009e6b0,df58449), -S(6d0b65ea,265366c1,7740e473,f823ad65,f38081f7,86156199,421a8b46,117b2733,4b724837,8748545,c6d0511,79d22b3c,61932bc3,563eadc9,a8edc5d8,1c170f5f), -S(87973dc9,379225c,50366d92,f0591837,71828fb1,d1d3a65a,20edb955,c2e48414,bb226cc0,67c7fc4d,99791a74,301167e9,62e92498,6ebb0fad,fcdde6ae,8c39223e), -S(72e7347,cf657935,be5939bb,648bf628,6a2e870b,cdae70ed,bd2c499a,be83191d,431e74e6,bccfbf3e,3fdab221,e2274a77,947d9cc3,5bc55c01,afa2d33e,8234cccd)}, -{S(bc4bb9a6,292aa09f,5c66dc9b,667c4642,6b08211f,a9a80f5e,f3f17b,21f275de,5d0e0492,39a862ec,b9649572,6f11bc09,cebd9f29,d9407ab3,1603054d,d9b76b07), -S(59fa87bc,4f47100f,f37135c4,1f5da6e6,28b76376,e0f365d0,eec857b,4b342b19,cbd82bed,1859e567,2e37e18,e977fdc3,6997482,a2db416c,686b3b64,a3c1d66c), -S(3af64d00,ddcaaef8,172aa0d8,adf5ebe7,fea87204,38125e07,eb74a5ef,91c17acd,4d695d52,ab785972,a425f6b8,f9f51e54,7067f9ab,b2af1085,bf22d1b6,7f51202), -S(31f9458f,d3544b7c,cf0a55c0,729ccb70,a57fc498,2078ba85,1fe4bb32,164e9259,31c6bca2,eb57ad06,e74da59,c824c720,17bbabe1,2e71a906,e6ac2e2c,36833b0c), -S(f2bcf05e,bd8ef03f,55d3d5ad,dba85359,3afb6b49,d72b2df5,c8107020,185d8173,a0c011a2,513c227d,22f045d,59d763cb,7c820ab6,e0b35144,66acbf77,8c188b22), -S(9373aead,2e733de2,cd4ddfd9,43675acb,40e2fdd,79c0bf12,45f8cf95,f2ece30b,8f171f4,5c1cf577,7416c873,a87af091,2a2eb20a,82f07c43,1e1f1b00,36c3276f), -S(5d2a3111,6cf78432,c8a3b0c4,a5021720,dbdc5e94,d842779f,6df51fed,5cc1e47,fa5381e6,ecacdb0c,6f326569,771b0f5d,d7e3c3ae,7c64cad5,ec03220a,33a24c91), -S(56549c28,f339c6d5,77efa8b7,3d795f64,580dafb1,f146268a,c7e751e2,fa3f041f,7aae31dc,2b875c94,6c2ce9aa,a6fe33b3,13c3795e,a188f343,89c34a48,bc3093a0), -S(ff4aa1c6,f5120040,5d488787,65f9931f,366fad1f,8a7d9ebc,abba9805,f6684aea,faa72c87,6956050f,663c172c,b3a0a3f,56e7e698,62723659,7a20c0ee,5bec6ccd), -S(65873e26,5ad6233b,41a6d42e,ebf1fcff,e8b1ed8d,97eb9131,1ede963,f8058c6b,80b955a5,d1648b0e,ef8d883c,24c2499a,f0f9350e,d003674a,fec69be3,d9f9d2f0), -S(b3a54b5d,3e19513e,b7be4c78,633a0e77,b4ec4015,d891bb6,35557fba,eee92f4d,1aabd4dd,3a995ac3,8c021f50,f2fcc578,5cdc724b,2b657f2f,9f82e777,fd449eb0), -S(30e69221,e75f5bcd,7b017467,d36abe41,d76b3589,1f82f38a,ff79be7e,fe8a7d44,95d5120b,807d3f47,76b7ef43,3ac7db28,e6b83c07,1e33573d,4a45eb8f,51296c88), -S(3a61f393,d842419f,f9d49dcb,e169bd36,2e28f92f,9d6c197,a441027d,9edc36eb,8cc6782f,898e586,1faa62ee,dc2ceee1,b21ae86,9e40e69e,20872b74,361f6f0f), -S(f46f5bea,e58e4a74,1838e312,57e3b579,5826ad3b,6c0576c1,f8b30874,c3a5779,91e35b62,55148a94,df34dcba,d2aa00f4,95e91eae,4a1c2d97,43a7fed2,d2713854), -S(6db13572,e3b35a2d,fdee5469,52d69463,19b5a95e,9e7ed8be,95cace14,471ee6eb,38c2be05,a1fb0fe1,e9dd09da,2684b4c5,de4e93bf,60fb3816,aa4261e,fdc9d79d), -S(af86cea1,e34c2d74,fef9d3a3,43d66574,2ca64259,f848885d,be0be05b,c8cfa432,8c8a2d2,da789ccd,b7f259c4,124ae844,36890818,5272c381,16bdb76d,f71af157), -S(89e5829b,41074025,cf6929d4,63dac04a,bd3139df,21b589d2,af8a0b7c,1c3c625,f762d80c,99197627,346af77e,f5295bdb,d86b5fa7,94975c6f,881386fc,e2609ddf), -S(2d589866,819b012c,ee8b7f5,63c20617,cf7d3f3d,ad56d4e1,c909c8b4,2071e6c8,cb7b8d2c,ff2bb979,1ff6f9d6,28d6a67a,80d1029e,d8d08573,f5e3b6f8,8dfffb67), -S(93ea11e0,e298b3ac,16ba686c,f5c1b089,55ed8d67,c318dcca,cb320d08,7f33740b,df9fbfeb,fb1547a3,92954300,98dc59b0,8af26c3c,ab7b42f8,5489af52,409a11d7), -S(febd58a2,529be1d3,8176be80,7daab920,32cf355,9ffd7d,154c9962,ea66567e,299967f5,5fbbd509,76271d5c,53975b3d,a4b43d1f,71f12ba,4a618a1b,5c11e484), -S(eb2e3d64,a5eecd,bc65bf45,405c8af1,bf4683bf,465b4a1,f8dc4627,b5b5c81,3c6d2f03,b30b2e49,4d056d55,3d2cd0bf,8c8f41ed,14b260e5,7bab5d0,c77dc06f), -S(9fefc3ea,d2ff9b51,57c669d0,bfea2c9c,7bac751f,9ac83c1a,143d05f,ba408216,10f0b7fb,b685e767,41fc9a7b,6c90191c,6b428e32,d9c3e611,c97aa120,8e361bba), -S(90b9eb4f,68cec46f,b7e426c8,94576858,a49ed785,a1b5be63,9bc68e5,33db8479,9aa3cfd,271602ac,5e9e84ab,343bef4c,9f8797eb,79d247f,7fde53be,11d32335), -S(2b80ca58,85919764,80e54e26,ba726c31,8b491c9e,56ac6d4a,f2163064,c69ce44a,50a00290,17815845,90773443,1c7c82dd,2e071d54,7d4b657b,f9edb939,24cb2a65), -S(df8e261a,55523b2c,933d0d15,c4bf5a0a,a8b2d01a,bfa7e064,d48aefd4,44485775,3d043bf8,7dea2305,274957c4,b8b5b37b,cd477b00,7d86f45d,b36fb42,c53c20a7), -S(7ac6a221,445bb8a7,ddbeee44,3aaa2de9,86ec1fcb,551caac3,84e2d37c,8aa05558,746446bc,64e61523,c52e5a56,b1315151,904a3d75,43191b9c,c32172e5,f08d22af), -S(5c0ace30,4217ff80,bc37f783,aca722c9,5027492c,3335ad3c,aae56270,c58509da,39685f11,9a646344,92a1157f,ca4548aa,ee37d52b,87d0148f,850976b8,4006dc6a), -S(6cd63750,f8318534,74da52b,11b8d66f,2a72c83,582b8c88,31d6be9b,ee5a826,57ca2d88,aa5f6970,54a6cd3c,a568f9a3,cd850d31,3510b1b2,adef4822,a943b3b), -S(9cabb7fa,7d9e6d89,42dad033,a22a1acc,1587e80c,fd7a2c78,fbc9bc11,c2cba6a0,f6bd65e4,1639bfe6,44f1101f,6acf65bc,ae5f56c9,f132b37f,8233f568,a23dd0e7), -S(233059ef,878839ef,60e1756f,771003e8,9af5569a,c5b0b849,fa84184,b9b9964a,654207a9,ff112902,9c9be9e6,d3d24bc8,a61a5c8d,4c25143b,5643e004,4fba7520), -S(7cc5b46c,9944e309,86e22624,99805a7,2b9ed814,954494cd,18c74882,aa3b8f39,c7ebd041,c5877c83,2cf05c42,6569ae0a,c1a37583,ceeeffb8,8cbc7090,ebbd71de), -S(9c55c21a,48c766a9,bc31a0b6,6e65a719,ec4d181,994cb533,3bebe7f,e017faec,4037846e,c6ca685,5764a8a8,230b07b,ccb9b145,b0d4a0bd,8b26020a,2d2c9da), -S(7926a60,bfdfc1c1,4d20082d,37b4a6d9,8e7651a1,4ed2a3ce,547a99cc,feffa208,da120ef3,d60469f5,dafe0776,8717dd2,5f95fc58,87594181,4b54604a,1aff86c), -S(c52dd3ed,e63fc9db,95a88ed3,e62064dd,f7f9112f,c30acc3d,3fc8438b,7d206c14,e65252d,2ecb95f8,a45059f4,68bfccfa,75b3b3ff,2ec9bbf0,46f51b0,416592cd), -S(831432ea,8e1ebdd9,3e254f18,15ad0c16,d637b04,85d43d4a,9eff1221,5835ec2e,af620dcb,328c94fc,b238fba9,3eb0d1eb,6f3f2838,9aedc2ac,26cb4f87,ea9cfb8a), -S(e5b822e9,72a7a2fb,723c135,d6d45602,deed7cff,61124fab,ef5a4fd1,68828773,117f1b94,6f715282,bd5bcef,fc2a340d,de226d52,cf3a9643,bc8c5119,542fc9a4), -S(59b98a72,bb15c51d,15f93497,bdea606f,2505b1fb,f37e42a5,73fefa84,b00deb6c,cb1feaf,bd5325eb,e604aaf0,480cabde,d6a5bfa0,bf9c4bed,674afb3d,65dcc5d4), -S(8847961d,6547b9d2,29f1faf2,ec0aec4b,8579c8c3,b1fe967d,eec280a2,ec45fd92,5280bf82,96b0251d,29ea6573,fccae24c,bdc4af9b,77043461,32103fc0,badcacf6), -S(bddf032b,d6c8709f,4b0f7b0a,cec96259,6db33d02,3d2270c,7824307a,b88bd4f8,b2fbfc91,c7944fac,dc69076d,90a1bc58,4d202119,574f0fe2,223f7821,c8100dd), -S(966bf84d,b5ed857d,cbe278d8,25167aa,eafcd957,597e8c08,241702aa,fe983af9,85e373bb,9788f0f4,2e4d6bf1,52136f90,b0fa7325,d2c791cc,4a7103f3,4ccc0b20), -S(7a16d469,e57ae4ca,46e198b0,4f970300,c2eed190,58d81028,ff2e1283,267099ca,4bfdcb6f,cb3b9c0d,782737fd,505c984,41c82029,db95b83b,c445b581,d1ff39fa), -S(818ebad5,7b04a0c6,f1235c71,634cf8d1,945a369a,8c707856,c58d2316,5bcd13cc,3cb6c26e,a053581e,821fcb36,174e91c5,bdd56144,7e3bce4b,c69f4f28,8968493d), -S(72059db7,2d838163,58b16402,653d875e,da620a67,5628a861,c6162f18,8a2bac61,232ebf0a,d0cb25c1,78626633,d4d61d47,d358bb35,b525e624,c2d6ba41,698f813f), -S(e407793a,b1246e86,aa9f782e,b1a0422c,28846f2e,49fcd886,4348c22e,411259c4,b339b1ab,dab01588,e8abaf1b,39a29055,66c14da3,1feafaaf,ccfb140d,1dc1efb3), -S(50dd489d,851e6b2d,af877b4d,70990326,dd9f9b0e,c22ca933,99dbdee8,ddb7b8f2,a9a28ecc,6d500065,4d3a3747,27be80fa,f41faa1d,6e51406d,13622655,e6cf5ac3), -S(5b592078,d50b3a6f,c94aa2cb,5b1e3a81,74a3d644,2fd12c2b,765678e8,7e00c8a2,8ebd56cd,313938a6,681a5ea4,61409f81,a4af4495,31266c3f,b915822e,845a8d7), -S(f90cbdc0,a228212a,32eee9e9,43e786ad,3a091308,81ad5f04,8a629a7,7035998b,6ae4854f,c789ec49,bbfc5d8e,14cc250a,1b862e51,cb343ccf,a0957b18,b9eb5545), -S(cea133d7,6121db90,c6281060,ead76d4,64b3825b,79363a04,ab0c0bd4,8abd9437,c66be897,96a25bf,867cfea4,f0803e1f,ec3c5a3e,178bbe6d,a972b2e2,e677dc41), -S(a09d9e59,5a4baf0f,b1f479d5,5d3cf051,7b34c007,b41d655f,efe61dc4,4111a4b5,2f21f502,f9752e2f,9848733e,afc40463,8e29d45c,1a294ce7,d09737d8,bc9bd1bf), -S(bebb4360,ec850828,b96a774d,2da91f0f,17c0a288,47796341,d617e1b9,b8728951,ea06e33,55603e97,91871935,f01cb416,bbcd226c,83cad5b7,fbd0eb39,48254a25), -S(d7cf537c,430cb0fd,434e555c,c1303b4,3fb60476,2b7f617f,4c2fdfeb,d5654461,f4ff7415,55841324,3b944ca9,adf91cdb,dbda99c8,90dab0be,8ae2a294,9e61c0ae), -S(1ea3f684,892f93c4,aa9372d,6ba193c4,8e6abb8,868bbd17,d91827b3,54424d5,dd549d14,a684f6fa,b1a401ba,47f42a89,14b0d012,80d24bed,743e3521,16ce17e2), -S(ac0890bf,ad8cab43,fa85b5ef,c10a5c7d,dbaa0237,daf20cc6,efc94c78,d95a86fa,a16a3028,69f2ae14,4566701c,f80add76,48d11ff2,1dd2596b,c30b074f,a5f3159d), -S(6d573525,43fbf521,d49d5b15,36f83a01,748d3470,57254639,4cec6785,860000a0,98b9f97a,9ae8bc6a,7ada1bd1,9a225ffc,8727ed3c,32b169cf,c381a60,3590acdf), -S(7be891a,771227eb,fd583033,e3801618,28cdd0f2,6e72cbd4,d9ffd169,92d7f1f1,be22c30c,3cade74,14bc3a7c,c3b4e5db,7ebb4ca8,b3ef67a0,b89fadf7,7b404fd8), -S(97f0013f,10a9ba96,58a1a5e,bf8f2d6e,4f2c56ff,9acc6221,177d2ce4,fea65efb,bb88987,7b7d1929,4dd4a011,7440707f,916e1b2c,fbf2b0a,5805c5b6,d8e65e3a), -S(77c3d2b0,b7ee36dc,69b75d91,11fdc25f,3996642d,a59b87b5,5f5840ab,cd5cb1b6,769c9cd3,7c4f4059,60129e1a,4bfeff8b,d86a41c8,eaa4e3d6,826a4cf2,5185c5ab), -S(a0a234a8,da6fc04b,2c77c7a7,a3b79f5d,7200df84,76d6737a,e879e4c3,a080fe5c,b9b8a2a3,59af78,9d5f0448,3f77e1a2,923a28f0,9f928067,4bdc1aac,8e8f0bcf), -S(1374c3e7,fbb1611c,8449d724,7ff49167,230b630e,a0c2c0ea,6d438426,9a91fad1,21d482a9,d29778f7,dbc31471,fa120bf5,abfae23b,185dde67,2198c725,47721db6), -S(f6c035f7,270679a5,4cac1f52,449f357b,cc36537e,669f056,3bbe022f,541e5d67,d470bd7d,9459165b,8bd093be,a3f64f8a,fab85bab,25f31046,c3db4167,5e8e7e77), -S(1baff567,622fda3f,7171e2f1,f66498e1,da1a2973,c5ad784a,6fa5af2f,23cfdf69,e1a87fb,1dcf917f,2dd6856a,48de7762,a05e0c12,89233db2,49637e69,15a5aa4a), -S(eabb2399,ebd468e3,84bd7c14,1329f972,96b86a47,53cdefdb,3b539449,d4e04d92,92d94943,ff0dd405,fbf02d21,875b7f13,25eda73,ad65d332,d005870f,951e3db8), -S(9121e2c2,13734da8,23ec445d,cecd6740,e1e5f513,7771ef9c,72589419,25f25ce2,8b1dafb,ebf4ee9a,3c39f51b,dcb560eb,f3e27409,589505d8,a9c18946,847ddd63), -S(51616592,730c7580,c2ba7dce,8f2d7aae,b71c1796,e35223c6,8a6762a8,c0566563,5af04478,c1509a8,905e271a,80c01376,bbcb5161,a78bcef0,1b5116b4,adcf68d8), -S(5489e35a,4800b74,e7d9d8b,99841485,2fd80e19,b290d7d6,22ab9f66,de8dcc11,3ec6df58,ab461f1,9a0879c,149d042e,8e7e5c2c,98dac706,19137120,74a05492), -S(bbd6f40,774d7bb8,e3fd18d2,b7f3c2b4,d1ad882d,73e101ee,3ac247f9,b8720005,17134bcd,6f74cb12,48b10902,b9eda37a,fcf8e5bd,50604a0c,65d08952,460c04ef), -S(1d99eca2,b542ff0f,470e7b46,ffa024d0,ebef5635,c0149593,b4b34f6a,d4531cdc,2e9cc03b,b2e5a461,a3122521,e09cc6c4,63d8e6d7,c4aaffa,c9d036c9,6b74d882), -S(32c2caef,93d345c0,9451725b,84b1260c,a9defe2e,228f985f,f33c3f33,70afa675,6875bdb6,3c8d28df,71317042,d2328d5c,24614210,4d134068,a943489d,e695920c), -S(25107b07,4ac55835,81afb4d2,dbf5e1b8,21c26b56,75efb3,33abaed8,56d0a5f2,626b9614,2d70c2a,5572ff7c,606abe47,cb90f850,2c13d478,3ca4e045,bcc7ba39), -S(d542e001,894cd3e3,97ae2519,f4b69c7,59308117,9ef63ff0,a9d586b,3fb324bc,bdd28dcd,94c208f8,bed304f3,adbffc7f,76cbc70d,333dece8,b2680b6e,19076fa5), -S(c1b950e2,e7cb74e2,a4274cbc,b67772ad,5c32ee22,b18c3d99,e4a92005,3edc000f,e8329595,39709b81,58f892b7,2ac9c0a4,e1e692e4,da526980,2b046759,58f0ffda), -S(8c6c041e,b8b3daca,fe89492e,91829869,2451bc8a,e4dac8ea,8cec1d49,c25778b7,6bb9de3a,55fefdbe,4376c9ec,dea4bc24,ade146b6,c454a441,8c47120f,f1f55d56), -S(4806db6f,bcf9004,e4cc63d5,555ea5a1,cb9107d8,e060e3d8,8fb79fe0,3acf1e46,c0f5f482,288b0036,ca485a74,a6bfc264,88441487,63804ece,e620e47a,16160e95), -S(4b3e050,26545104,176aabd4,40ef4ba6,451bbb0d,5420edb0,4063c22c,2e7d8928,42ebb34d,ec06c95e,11ed8e24,90369796,2d8634f2,2641925f,f765b06d,838b5cc2), -S(be7a60ae,bc21640b,2f027c33,f6ec9422,5e66c16f,1d946ea9,dd881101,5d80a21e,1dd12d43,2b2a2f60,9d434936,ebedc2f0,b9c20747,32275c94,fb7bb15b,bb323bff), -S(550813b9,3c3dc22e,4dd576e5,50042b51,34f1a905,2b28af39,cf87bb89,84cd8211,33cfcf61,91cc032c,dc284de3,7adf0de1,a83e39f5,27273eb7,f361235a,40d6da10), -S(33133c21,98343b11,424655b0,8ed83de4,ab36c87a,1c5316a0,686145f6,62be725,fbf5d264,30a71f5d,bbf33aa,be2ba027,b8abc0cd,37d0130f,a99a6698,75f011b8), -S(dc21892a,8b5e8ad2,2d4fca59,7941bd5a,5099f82f,e47ac4be,7e705a35,9a03eb9c,7d49d315,1d6b6e97,1f8712db,197b3c8f,aa8b79d0,5957379,6b895bbe,581242d1), -S(64e648c6,98b6ee15,c168e71e,dd031c66,27486a0d,8f858342,80d55924,66421465,7244a14,2e7fa0b9,a41195d9,d74655ed,4ac3f1aa,9f055c90,326bd32a,22669878), -S(153e77e6,b1704f24,5ad12253,7f11e9af,e22c2647,67293dbd,fa51e415,950f7b2d,7bcddddc,ba3b79d,7cb6254b,a4b4abf0,a44fdc4a,131eb185,c6a480a7,755cbe6d), -S(24ea7667,d2747412,2adc6c73,4a8babff,df7850c6,a7e60647,e4825f80,9f89147,385b29ce,bad1ef7f,c661e36d,97bb9eec,5d415c7f,613d82b,39f8b131,aca17278), -S(897d6779,70dfc489,800087ee,c67c957a,5299358e,14f63610,c991db4b,530c32cb,42905602,2ecd9bd5,9d8e3d49,9e037e07,4268033c,6ae4c9b8,ea579d96,daca5c6b), -S(beaa3e34,26dbb441,5ce9c604,7db0821f,79af4e5,faafdcd8,8c89f265,77462905,c0fa8760,f9964d11,d2152f01,3590180b,53a67a35,16cf7c3c,403361b8,aab86634), -S(d2c97e5f,85b4025,a66c29bd,23b5d30c,4c8f066e,f68ece5c,df907b2e,558bf547,1e320de1,3347ea0b,13ef7f68,cfc4bbc0,e10bf7af,c031f64e,9a9f2c43,181ddb61), -S(1ec48a1f,169baa2d,ef5bf8e4,e1ec8f51,d91c1667,6906c912,ce084f2a,9aba1d6,498a5d90,6ec47ca9,f6d7c5ee,bd25f83b,a14884b5,a4ad64ef,3fe9ebed,5ef0932c), -S(313ad91d,44f622f7,785b3ca5,6cf9e8dc,389d5aea,b696342f,ce58ecb1,d6e9b45,60f8ac86,3cc5eb77,c8f83c05,81aba889,d48f65ca,b9757076,7d9973de,f4a693df), -S(93f7f233,dee42606,41f8fb3d,d67e6e9b,cb2fdcb0,905e9b0f,92fb2094,701d6ef1,1cda7163,64ce202a,b53e3cfb,b4bbdbf4,1e124e57,85f91d5e,5a5f3205,a4e4ba13), -S(56694a44,a4455ef0,a429a5ef,d11b6440,bfa6e0c1,958b8f2,e3a8d00c,b1f5feed,ae0e21b6,669e1b86,e27df62b,7038de4,fbfd1b10,72da3ebc,82432787,ba5cbaa5), -S(7a6a7dba,80380635,d851f291,d7dbf6db,bce98978,805c738e,8c80c20e,c57e3a0d,673236f9,ea37dff7,c9eeaf34,b63ae652,1b38fc9a,94c111f2,b3e253b,34f05009), -S(d4e820b7,aedaf95b,de86a889,f0adebc6,279e0ce3,b0757972,d574f64a,3fa6a6bd,42762fa9,1b1cb9df,85c55acf,95a421a2,d4da6f01,69474abf,61209ca0,4f062939), -S(62f26014,d06ef2c6,ae6d459,6e45b2e0,d7d28f11,ec84fe61,8baba130,1d483950,d53fbb59,f239a52d,592b6f98,fbe311ee,4c9d4e20,b6d9a8ca,5698503b,eba1eeb1), -S(bc5ac17c,2a9e3731,7dc80bb8,7eccb0cb,ae804158,792b6926,60cf3f53,b2446eb0,e2a67966,a8de04a8,db78b4f1,e37c6885,b99b188e,1d4a1fa3,5e9084a3,96e5d8e1), -S(80743e30,983d175a,ce9ddb09,bb1adfc8,1b059b9d,73c51b42,d29a9f5d,673fa494,eff1e042,89a84d27,2d941b5d,5bbceaff,d3b7069d,9d704317,4b35e2cc,12dad80a), -S(faf014bc,c17df331,1902a50e,fb18469,9f0344ed,b6b057ce,5c922f22,97f5ae5,47301fe0,6fb57e8b,5fd121cc,be2da9fe,e8e918b0,7a9d9228,43e41de,77e2c1f9), -S(9e89950b,e18485a8,14eeccec,4bd484bf,e2c027e9,54cae11a,52bf2a82,43a6faf4,e81f0ee6,c85c5571,f5ae6a03,3ad4791c,68f9189,507e53ab,ee15e035,6372f6e1), -S(496b3eb,ac55b991,fea92454,e844e5a3,fe7595cf,b25fe7bb,c358f0ed,38e9cff4,d13d035d,ae0d457b,540c6b67,4db20893,f75ddf53,5c6c54ff,95e46c76,14a58153), -S(24ed90c2,3547169d,bc55f880,33204740,a2fd2119,63737fd1,debc0578,400c675c,f37940f5,e3e25da7,7ffa143a,865e46fe,a1dd1230,fb42a627,9e791ee7,38b739e5), -S(9cf8971d,43eb50d2,e522fedb,9281026,659612d,2fb2bea9,d7f6a65e,cb2c0703,b0b6a53,103cd33c,6e0c0bd4,5cab3923,29012395,f8e8951a,1fc4c9dd,95cbbdaa), -S(f6c823f2,ce2006a9,6cbf68a8,61f00eaf,4d8524ad,3467f8de,8dc64911,e89b1f7f,6eee9a22,59ad8c81,277d52b2,cb3b5e44,1259fc8c,52868b74,4946b0f5,b8d9abdd), -S(4bfe7,5bafa425,7f1fd25b,12b68afa,abff6771,89f05d07,85e06d82,b6906316,4ee94fd6,a5388fc0,1ab5da36,41b5c562,9f7c966f,64cc387a,9b3336f4,34323adf), -S(d15fa5cf,a481a1b7,8c746f3c,a19e0979,8b7e777c,4841d73b,ec4b63d8,b01c0019,c6fd422,76ae3e1d,b28ce840,29b8079d,7dba4c1d,acaf27d0,d2b29bbf,5ed59f6e), -S(bd17078c,75e7c325,80cf4a88,8d43c5ac,c323d8c8,4e9d5e29,c09c8c77,14ab7397,1094e3a1,21abba10,7da189d9,2f92c5c,f00b373c,89f346eb,351450e9,7377cd4), -S(1acbdb1b,79389dd3,5dfc607e,2aa8134c,fb04a655,c4848cb6,b5b73491,cac2cd87,8d2bcfc8,72da8a7d,1b89863c,ab7610f4,297dff9e,bf9e3f18,8a6bd6e,99421c97), -S(49e5b6f7,243f19b3,c36c5411,a6e34e2a,f61a99b2,38958b93,819ec7e4,6d647af6,9af4507d,850aab9c,9b1eb3be,90c15460,3756e29e,fcba23ce,313a4dd5,290f1385), -S(15bd9023,bad0eec9,fb19a720,e0a7be10,df78b3b0,716978f,5ee37052,b19d1f92,9cbac74e,7adf5e32,8959d826,41fdcaef,1d4eb24b,a5bd24ff,8d2625a,12d0ea80), -S(9d03f121,d28dc96f,ef6eb2a8,d3737033,e9f6703a,1683aeb8,c583b78c,7910eb6,46723472,ae342ff4,fb9fa789,8e063379,3b9b6781,4bdd8f43,840110c7,4e8e03d9), -S(8abe7e21,f025f340,6929eaf8,c818b016,f7423717,c893b6fb,cbea7ec9,7db98a5e,8bde4e6c,c37c681c,4f664731,719ef10e,e0e7f6c,5739cecd,32f6bf87,c1ac6144), -S(66135e6e,e913c965,ecd190c1,9d4bcc5b,e238225f,3755aee0,64852da8,96e848df,c2c5133c,9c033d30,2029ef21,1379858a,ec918357,421b7614,13a4deff,6f855ae6), -S(5dfa7af7,596b611f,24b57d98,59a5cfd9,41ffdfdd,1e80b0a9,994966a0,338d3b27,2780b496,8fa51ba6,b6256d78,aa25249a,982c091d,40cb9336,863ef2a8,9e4caddb), -S(a5a9782f,f7c90216,3a235a3d,9f548af4,a0ccf508,1aebf0c0,f9d4d772,ae3ceac5,144a9e55,f017dcdb,fd093573,c47b9954,20cd8a63,bd7cc456,f301cfa3,b7e7b8ab), -S(fcd5fd1c,44765529,413ef8b2,63d60414,c6b1da8e,3d2e8463,f0d6567c,f9029916,9877c363,d6180a8a,b005d5ee,77eeacdd,ffc237eb,a30da48d,ac582d0a,84e8cb31), -S(95be1f47,e0aea7c,4c0720e3,fd528ece,66627ba9,3f172875,76b1490d,7a8cc395,f68eaaf,9c4986f5,32adc845,31ba80c9,2c817962,1e042503,6e58bc46,f2d18720), -S(bca58c89,dd846a85,6698681d,450afd5e,621c9ecd,3e1cbdc,d8f85582,4a9cb047,8d0160da,d653a54f,323bd258,74360e4f,573d9a18,c3360121,e18f33dc,5be1191d), -S(1508b726,9d97108c,9c4a01c2,59fe7022,dfe63662,c6b695dc,6404a9cc,3a532a8b,e4f1b655,35250561,cf8b38eb,1b43bf23,430fd354,5045c434,dce7d3de,c22528a8), -S(b2b2dff3,fb9b7b21,411195f,c095f2e5,d69dd4de,249aebea,b266f6b0,c45d65e0,f81346f6,2377c415,a05c0a4e,b0b70a3e,95361575,9241cf7a,22918713,199a5cc3), -S(b087aca7,3b1daae8,b5655de2,6ec08874,14e3c2ad,fd3c84fc,4c6ad73,b735664d,402e931a,b04132c0,2efe8d75,6197ee92,90ec0b64,abb12862,728bf679,42244f36), -S(eec45124,dea794fa,c467c17d,5f843902,2f7befc1,f535897b,da946e66,bb22dbd7,18288f3c,6d89b340,d250bbb,afa10261,a30ab71,c47d8f36,a6a29312,e79945b5), -S(9e01ac6f,214ad3e2,252051e7,9802e09f,ff5a1f5b,16fc97a2,f82c5427,515a4fb8,c92a340,a9798e40,b8026d1a,826eb59,e6db59a3,efa12ad3,b891450b,c7ed015f), -S(97c0e53a,f2dcf282,66568795,2fc72a69,33e7161d,7a9312b1,261b0085,8bdd386e,5ca75fc6,b5aeef6d,7655fc27,1fe56c05,8d7a65c7,912a23a5,e4105941,2b20cd5), -S(79f1fdd9,179d870,45f8f8d3,c0f6e14b,2c932673,1cc2e79a,4fefb3f2,9966a21c,38eb64de,e16be6b9,57c5e78a,7a64a55c,90cf0ab3,a99c964f,b0dcbc5a,7f15e40f), -S(53559fe1,d3222709,8e26093a,61770eaf,9bfcb7e3,e5de16eb,df6e8934,a9522921,4278efb3,9cb23458,305c7ce5,bde295ad,856c901c,d4c7faa4,bffd6c9e,52bae725), -S(dc3c9dff,d1ff296b,17667fa,f58231bc,d2c26a9c,8f6485,514270d0,d5d00d37,701693a6,17f6ff10,afd51c26,e760e0d6,8fe749db,aa5b35cb,636643d0,b3755ea9), -S(3b1ee2f2,9ff89f3e,78295dd1,6128690c,557e188b,f76b86c2,2698e0f2,fca33213,69d4fd8,e1886d81,d22461ca,81c20e95,ee813d9b,6bc39af6,38ba71f4,72db25f), -S(8c9b2d19,a576801e,e03f6108,84d1106b,e13481ec,817d892d,4b233aec,3514d12,55e30950,d67bff85,a1fd0efb,210f0180,d349fdd3,20f3470c,3bae1c70,21550dfe), -S(fcd42391,288b05d8,8e23e673,7d612ce2,f45896dc,7953cfa5,fd32fac6,f8ccf8e5,83c5ecd,4148c600,d9416831,68ce71be,dc571321,6ce07f5b,779a1773,412a8e47), -S(92cf957d,a51ce801,64e6ceee,76defb26,f14d1922,9e9e1933,4f13849e,f7922f44,cf066667,272a2d54,acaf3fad,2b9515f5,c8c23828,18a91eb9,d6b03a61,475e2298), -S(646d5ab7,421ef1e1,1f86c4f1,6d308cf4,401ed527,c975643d,e0221f17,6c2441b5,3313b887,226eb9e0,2956f3c4,f764892a,3b99bf6b,8106575e,55c792cf,3645dea1), -S(3a99563d,d92cf9c7,85a0882b,9f51af44,76af2e4b,dd23495f,341a524b,d3643954,8bcc950f,1eabdb50,c1cf6e63,1b491672,9dbc1df7,44769283,e52a5179,303ccae5), -S(e8979b98,5a418b6,13d4d43d,d004de47,f6cb8e38,354fe810,7f47b741,c69a780f,c407e05,a72b449e,43bd8069,9f7b2559,ec26fafc,a016c735,a8fa5142,1beec4b1), -S(5c69255d,207f650c,59fdee77,7d59dcd9,dc75e3b0,8fd7fec3,d6f69929,9dffc8bf,a1ff812a,4690c166,48a7f3c8,cfbb688,fc5450b6,29f8f0d7,41e36883,ba570674), -S(48e3a29,a1be4db1,d1fe34ff,fa352356,a75d97d9,1dd73448,10f9d8ac,ded6ecb9,8bb6341d,d3431054,893dbf21,34e02153,2a1ec461,1f42ea41,d43859a1,4a6fb78d), -S(fc9d5478,5428ea33,8bea7507,488e5505,f82e680a,778fce8c,9f84aed7,ffb235a6,884e8b36,19ec9e19,9650973e,bb160df7,a116f429,aea7b742,b1837e,43dcc4cd), -S(5768babb,8f16cf85,98c268d6,9965f913,1ba2df86,8f96958e,5c926960,9f86810f,a320eb27,3667ef78,4e0a1e0f,a4d452c5,d9eaa349,b44d00da,6373a0b3,377da289), -S(499c15bc,5bea1040,5ef65654,fce454e5,4072450c,4ce5f279,62fc1f69,9bb103f7,3b539537,3e537faa,89adc347,74721df7,ae1554ab,ce2b7ced,38f67b41,9b157e3), -S(e90e567c,20c1b561,be3a3c9d,8a227233,73503e97,a1e88e,d6928465,77188951,26425fb8,49136a00,392a8b01,4248e2f3,10b0321e,d192e9b8,744e7873,5c393396), -S(5555e213,b06a7807,98ebf522,9142f5fd,4867d080,30ff2f63,8b637d74,3ad54e42,1b82a7bc,610284b7,758d1d75,982cb069,dbf77cea,c9deb76e,62eb5324,d726b42e), -S(9b1c140e,38b3899a,c77eeafc,1784805d,1efc1363,d25ed7fa,abf923dc,dc53d9b3,94bb9ad9,9b01e6ed,af7b4807,1ac2f67,ceff22ba,3ed4a26c,7b1b82dc,9c5fb8ea), -S(268533bd,33f9c398,5d8ba9f7,d6d111b5,9ea49cf0,8227894,cd236cb9,4c4d6e45,ad5ce6d4,3f70c08d,2b1aeec7,6e7d421d,41e61276,fd2c5a7f,4d263479,177067e8), -S(9bd29abf,3d69acb,1ca7f6ac,68e47d1b,61f8612b,30c36cf,4ed79939,583590de,530faf27,794dd14b,9fc084a,dd6b3cff,e0343608,501937b1,e7f7fffd,10942e2b), -S(eccd8863,8f3b2819,d828b9c1,2c0a76ee,663f6113,ae8294ab,e7ff5719,c8962cab,18da1af3,db016cb,45d7f9ce,dd4bc478,63aa8092,c674fca5,8f03f703,82ccc799), -S(8968de12,d40a30bb,99b10962,568b1f8c,c37bac76,7fbeac7c,21b80d58,bd64560d,268bf30,ef631569,800f6ee9,548cc7c4,15c1fd7f,b21413d6,3ed5abf4,936e5b36), -S(450789b4,297aebad,346af999,d4ea3e7a,c8867ae6,19a59c13,84b1ff3e,1fd092ef,402789ae,6ace54c0,54a26184,c651e8d3,814c6fec,fdb560a7,51943ca2,24bf25ca), -S(88b90c79,49a79d99,b05a2dd3,cac61e38,783dc306,fccacd97,892a75be,34e67403,3a565d5c,eecfa071,2c9355ea,67009764,7d0e52c2,d6a6a49e,3317014f,56554bb7), -S(e5a45f20,e3f5989a,a9b04119,6f7e1e8b,95f4b397,4e1c18d0,f19bc12b,ceb5464b,d09d73d7,e6dc8239,ef9758b,ae186e54,a5cb4d71,47f6dcdb,ec933237,3b677018), -S(51b99055,b4815a86,d0bcd8b6,8a7b47ce,7e9a93b2,3ec5f6a8,7c185c34,1647cd05,4fa125a1,35f26df4,ad7ffc70,29268830,9f8ad7e5,f3683eb9,b3dcddef,45fcda0d), -S(1dfb4a44,867afdba,892b9f71,1272402b,cd38318,f8f7aea,68c16eb3,2c07d565,4312ffbf,15775c04,e187cb98,166b5bb2,c42582d7,5b8938b5,83613d66,9622253f), -S(f271ed8f,c137af31,dad55775,e38358f6,608afdd5,4cb0d1b6,883ac66b,7b645fdd,1494c658,faf514ab,912887b5,c90e6bd2,a61e9d97,7e1ffe65,a49de27b,4e393bb3), -S(ac2f0db8,43cc7ee6,e268cf62,344fd232,2f0e40db,703a7d33,5437e7ea,de7cbef8,40ddcc5a,53d8a24b,8b5ee481,ef331bca,89e76293,7d1ba22,3471c562,ee7a2dc), -S(1801ee15,c8041c65,b9727159,8194a957,a404d5b2,318308cc,d737d858,4b2015f0,df400a6f,6a50057,1ebdb755,e686b759,d604d434,b9f198e2,21b2b514,30eca9c9), -S(8d304b28,32eabf93,82d71e3d,cbc38a98,437d6a,70c5b084,4486dde2,1104dc80,fffb5a64,3fa633f7,cf36e574,31acdb02,b98cb4b5,9a0076e0,8f5e5061,623b8157), -S(4e8645ef,99a816cd,74a0fc67,48cc116e,a61133ad,8f6bbe55,46ab9aba,adb148ff,594d010d,ff31677e,8c602038,5e071e58,5a72e97e,4d1c2d0,5564c102,56441c4b), -S(b8c26b70,b1367df7,7a14a385,aaec861e,e3cd3945,7282bb2e,935271a9,6c87d589,df51bc84,95a0c2e8,ef469219,f05f054a,5a5f85ec,a20f8acf,6c424ba3,9faff23f), -S(9934e27b,8be7c41,3f5e8ec,f2eba29f,26ed2ff4,fd588918,bda07bd1,5b87f4a1,4488848e,440c0a1c,5d11a3f2,784728d1,34b9a08c,6210494e,c1cf6a0f,71c334ee), -S(56692314,f6a9764,47a1a988,f0a2faf4,e04c61f2,b835f22a,25b57290,b1ee5d14,d8d72ecc,1afc548f,cb1f71e8,144f9f7e,463edd9,5422a607,7b9b307d,15326fff), -S(737a268,a2cd3d43,d6741235,69e2e118,7ae90fc8,669d27ee,504f9e85,5eda3c2f,e3d24166,a5ba6183,730c11bc,8b41845b,3efb7154,6eb1a06f,2e90dcc7,33f68b47), -S(90d40297,4ae9d5c8,f4c59207,e58797d2,8c007a6a,4f6aeae7,9e50bb4e,fc34fa7e,2cbdc969,4e7ee150,b51a7e1f,d81d01eb,71d48027,3f349a39,8773732,4b315cc4), -S(4639872,2ae68fdf,9a98eb24,6a70946f,c9bc927f,37a3db42,f0cda419,7dec8163,6dc0a8b1,81c16b97,da97fdea,ea20bd03,cfec3999,7e192b1b,3e0bfa39,a1727f55), -S(c48cb232,1c02051f,2f1e5aa5,c99f7d00,5bb8af4a,61691f1f,493d834c,549139bb,3eb61f34,a2009094,36aced01,4a11b75f,2d35d6f5,67e5fc5e,2fc7aab4,437a2c5e), -S(eaf967eb,d5f0932e,42a3222d,ac0d874e,af154f8b,47beee08,2ca7196e,efb429f5,870d0edc,43dd51aa,6f518b4,901049e7,865565d9,3e54e475,d587d94d,ce88d994), -S(291f8c36,ae17ff86,d05a5a81,31ae3079,27221af7,7b97d66c,812a954e,ad22d49d,3b515fa0,bfdb0fec,61f838f0,e78bd29c,360b9ef8,c6f599fc,e1c518b2,f343d8c2), -S(d6280bf9,4334749d,49b19e44,b811d99b,2a522e73,dc2afa03,c130a48c,f4ff39e1,5f282a7a,be629408,9672c7cb,c9e46e1,ed2dda5b,653cc490,93f4aecb,637a1024), -S(9f96aaf7,8b26bc25,e321837e,29f3cbed,ba6fe62a,3a66c59b,cb52ae9,daddf9a9,ebbd1df8,a818a28c,e1a61b6f,ed13f139,504d33d0,5e27b5a0,b67c15,b1333394), -S(bbd26954,fbec8b4b,d27f85e,44b1273f,37321a28,fa938eeb,f5e5f50e,fb0e8a40,56a517d4,c54368cc,b40d0653,7db7ec68,79d7d4ea,dcdabc1b,722e1a64,710e9b6e), -S(35597cce,40b326e0,d9044225,82726039,fef5131,9d267240,b2455142,7ff6d7d2,ab1508d2,278b3b0b,fec8bce,4dea9bd9,31859fb0,2f600cc4,b67bf9f7,4f2b20a0), -S(8849429d,39cdb22a,b6d22361,22a59786,2baac8d7,5f858ab0,33c5037b,81eaf963,ec203255,647d27f5,f134b011,cf390703,18006dba,f5ffa74e,593c2711,f765196e), -S(f7519d31,1493f836,ae7c6f8f,e8ee5f11,ea2ddec0,90eae6ad,84c6d0c0,3249130c,de7b22f5,ef095528,5a163142,255b168b,c004ea10,86269d7b,ebf032be,d9a6452c), -S(865cfb50,e57bdc46,166d2b8,17e9b4f9,73db89b5,2fe4ff14,1898bdc,fb4f3a25,36cbfe86,15368e24,b9673fb,f593bfe3,d1a0fe03,54f98c00,bf8e59cb,be930c5d), -S(cf3d6532,8bf2bfc0,8d36a93d,8aa8e8fe,317ed071,3aaec871,48bfb50d,ab1919ee,ad96a551,9cb8691a,e1d535f2,8af23967,704dc578,b7c38cf4,84ddbc90,2c1b26a9), -S(6ede5a39,7aeb2f30,d577c225,29ed1ecf,d28c2041,75e950e,12c98c1d,2ed1c48f,eb102976,b4237833,7761ab15,a8d0c228,a42ff5d3,a1279fab,736e24b4,47ae8e3c), -S(146a2544,cdf67ec3,3bd216b8,51d4127b,bd9dda77,4a78697b,e010e61a,7442a22c,f7cac2,376c246b,ad67a10,ee0fa811,10afccc6,d76a9295,f16d6034,1876814a), -S(bb14a6fd,2129d75f,5aeda8d4,d69cae8f,55b4950,7f709a96,af39bece,8e1449a4,feb4ad7c,1a3a224c,bf4bac58,617117de,811d250,8a948a19,a94b9cd5,8560eb09), -S(69975e93,a634cdfe,2ed014c,33c65a53,b17c6025,ae499a69,599b33ae,bbe52428,e16090c4,2cb1ccd4,7c7a9b91,4fa88027,bbf7155,374fb95a,ff0a06f6,4758e0c9), -S(e281888b,e9ec00f5,71e9d807,35c1c762,4bf8b739,c94f3178,868a7291,9d550848,2066254b,53733824,2a5b697d,a05fdaa,8e2d3b6a,840a7208,6854b55d,af88c3d7), -S(96531c48,abd9bca2,19fe05e,c1ff1ff9,90a526ff,5c7b5775,804c5db1,65b425e6,de07c8f5,32e0eb64,fa76442b,e4269e52,95212bbd,a9cbeff5,40b012df,f0b3ce09), -S(59d3a12c,3b2bf72f,c4ec6d8d,88594e97,89f30670,eae71e7d,2b98e9d7,3d5deb0e,fb338126,9a57fdb5,6cecf38c,ee63631,f520fee,6c3b334a,a47afb7f,7f5150af), -S(1267bcee,c8f3f086,8187271b,3a283241,935f1822,ae5e8e8f,5a4ba753,89869795,5249aa32,41fdc011,606724fb,6085491a,d974d355,9d27f8a5,2e80c376,92b22736), -S(446310fe,7a9d1f2f,632cc948,c86ca652,7358b910,e9532e2,9f394ed0,12c45ec4,f7ff61dd,f72dfb99,bf309210,286005d7,8328137b,6394354e,dd9cdcbb,cff06cf5), -S(7edfb2fd,a3c15d42,b29440dc,b7c7e74,c9530a79,6290cc12,86ecfe49,96583244,c7dc5dcc,6fc1ac75,5eea622f,69799c77,eb5c3883,a628f14,c61f9cf9,2db4e2bf), -S(e34f4c12,896a8400,a79db9e7,a5b0f67,99fde06,5e381181,f79bbb9e,b81d5e8d,e3dd7871,3cc68c48,9a877b32,9e32869a,ca89a69b,2ba6e83c,78af9c60,79f87f7d), -S(f49e78fb,caa129ba,ad6fa192,a26ffb62,d6825cb5,f933c2a1,c8a2c872,c5ff35e9,4e1c9c4,c176653e,6b87bf9b,39c5606d,ace09e3,c3c268c1,a51e52c,c4ebae1e), -S(71d7f117,738286d5,71ce0b08,aaa1b448,fd4a9d22,2e6d4ee1,b8c0d0ea,9275656a,751401a4,2fd576ea,6bbe6e0e,e076ec36,b9db65de,a747b31d,e1a66a02,324e5b30), -S(29f56789,8efe1baf,bbbd435c,7abb043a,284d16a0,598a5a6a,49d5875d,7577dd82,c3a6e7f1,80afe6e7,b761bde1,7893aa7d,2dd34702,6558c1e7,9d4d80fe,108ea6a5), -S(435afc66,f252c63a,fbc56f9c,342aae25,bbddbfa4,9b94a8e3,3d2a68c3,6730e730,d8cbf58e,e7cdff53,e4d52865,c76b9331,7553814e,f9f8c4c4,9c93e49c,7bb98dba), -S(c326c1d1,b2d1ef3e,e4e9367a,48970337,f711bd23,3c619e18,2bc47227,2e53d813,559b707c,4a73a245,c6d57194,9ceee5dc,b5d53645,d576d6d8,309e92d2,4bc959d1), -S(83486a4f,75664f,58db5cec,96af658e,6f669946,5c5b9e71,2e66ce5f,627d6a9f,eb7258a9,30b5e703,39681d8c,452e518d,aabbbe83,1312a65,af2723ab,ab61e04c), -S(85b419ec,e16f8d3f,ef24f1dd,6f8ca2f0,ea7ce0b4,bdd6da80,20eb0f83,7c799bb,37f888ac,3474341b,30a32573,2ee9db8c,4cd9a9cf,64350f64,8845c63e,fffe6343), -S(d6b6f0b9,cfbd4126,2f6506c0,89c1132f,7da49d8e,f9afcff9,ea97a224,35a85015,c5b7229f,dfc148bc,140ab9d4,4895c5b6,db02ae00,62585521,70aed317,c0e39fc6), -S(40f7b48d,1070340d,2382ba1b,794e4069,ac9aeba0,fefa8823,aa9902f6,4386c221,985b387,a3720bcb,a99ee10b,28ad253a,9202eb0b,3167d462,b664d67,f294509d), -S(ad6a6bd0,99789a6,2b3602b2,f75af03c,33379054,cefe6397,a135cf78,a0e13a99,249eaf4f,321d9011,39ce28b,4f09ee1e,4fadc6e6,763cd737,96777f30,aede6256), -S(2e15ccdf,25e72fd3,3007b705,9703b13,5f8a94be,cdc35523,3b349a64,60331e8f,e3ed23bf,5f320a48,e1dcfb9e,38fd2bc4,fbbd5e2a,e16072a9,9f704ae5,2d4c73b3), -S(aa9a2531,8d4796c5,8443eb4d,559dd43c,29efa4f3,c994eef,a1791027,784d4fd0,a32f3a7f,cf3b4494,a4970b8b,d20f4c6e,d82833ab,eadca5b9,4ddbb5a6,e27bb427), -S(f16c0ce8,cc87f208,5f98919a,cb4dff65,b68f88da,6db10674,c4cba867,bb410345,12dd4b03,86509e2d,a79f3895,d1c3cd7c,f5735529,b049204,9b7434fa,64fd382b), -S(f27ae46f,14efa234,e034fe01,f4ed5cf9,251c99a0,fddc9e5b,13ec770,4cbb6bba,4abb2ba9,5877455,ae76d4d2,56216ca1,78b1c12f,3fa9c10e,5df21225,4071c557), -S(a966ac61,ef7d10c1,47ed0ce2,cc383cce,8d83a66b,bd18aed,8261e38e,67983e7b,5d2db9c0,ba8bf67a,d385146e,8ac20c72,9fdbcb0,581cd956,a95ab89e,a927bd2a), -S(ced076ef,4951ee63,ac196d1a,65cab7c5,5654d12e,ae16f4f5,4c2637f5,6b1cbeb8,2b763b9b,bd99ee6b,5b6c934a,ccebdd0b,952cda5,ed266d5a,986be5d4,397d9f7b), -S(9afeb8f7,f445a1ef,c7951fd4,62a0a3d2,500f3527,1f482e01,edc9815c,2deac969,93354851,99ea1fe3,f74a6991,6fa53f47,2d1918d3,c4d0d526,34909810,25830723), -S(61c405c6,93115b8e,325be640,8e30cadd,9e42dd98,8522871d,1612a44b,95c41d92,efd7f73a,f38e21c6,8fa28d86,b3a9b241,27fb686a,75c53c1e,3b693191,d972fcdf), -S(42829070,a896e684,88890114,2763cfe,3376ef87,17aabae2,43981213,9be22ded,d15986a4,412faf10,ccfc34ed,162f21a9,54cc5af4,91ff671,c4634947,9e539da0), -S(d9945ab,e280b7b1,4bf7e65d,ef4cd279,57798612,50a1bb5e,28ba8bec,2b66917e,52902f2b,af8976d2,c77a2026,a8fddd2c,8f2b948c,5086870a,168a1ea5,cf43d134), -S(bd3fb006,3748f21b,cda6236d,a13e129c,905da160,2d8c2867,f39166b9,56a37a12,47654773,9e7ad500,cd0f0853,f17bdecd,ff4eb6a0,1af3822a,1201ed09,a4e52ce1), -S(831294aa,a3fc6d7,e0179ae1,753fb809,1fafa015,9c94c40,a41f4ddc,aa6937c,27509e96,b66459f6,2698d055,7c38634a,543f1eac,ca68f3bd,4d64d3c7,5e5b7e07), -S(c74d8a85,c5d11787,31b8d227,b74cc264,b2ffeee7,ca997e49,d1b0349e,2fc121e,5e5fcdfd,cedc03b8,4555a2de,118e494d,2038a2a1,27913850,e816f707,fb9688aa), -S(1cb36b06,a6aaa255,8126fc5d,b69f172,be012a58,de7d8688,5ac5286c,33e7a20f,a84f5fb3,67c6726a,e8b60e7d,d4302e7,dcd63930,2eb425d1,b89ac986,ee0e6d57), -S(5d69d200,ccad332d,faacf513,433bac35,d78ec863,2928331f,eaab7dda,69a5ce14,4370dcdd,77fc209a,8d558c09,cd6040dd,74ff975,b2b94436,bd2ce044,214926d0), -S(585b2e1c,b53d61de,89fe127e,d20f23ee,26dfc569,67659aa,22a35928,af247514,fa29933a,8ecbd8ef,8a7e94a9,ea267f31,a2deb759,b25c1762,1753bda4,d489c1bf), -S(a222828e,1568c08,3ea870,50f9cc86,17daade7,cc60a72d,a8762f3b,40a107e2,ec282fa1,7a70e5d6,529e5d44,15dbb61e,8e4a553a,11d39f4d,e3183126,73161aa9), -S(b879ab5c,38135c35,a57ebd6f,1ec01a9b,58758942,7cf9dccb,3b6ca8f4,dacf14be,18d8831e,b11a8461,9deae96b,60c656d9,f4ed65d1,71a0f22e,27d6931f,7f34a310), -S(39168674,a5cd3c38,ec3a8293,78a2d108,d44f4fb4,8ed3b09,d491c127,c8f74a0a,e65c3f7,8bd0bea0,e96e728f,d30c8d27,10ff67d0,23dd218e,813b768,b4094faa), -S(1a4db770,85065a91,61573aa4,b96aedc0,5d81647c,fba56946,a5e2ea1,77e7bdfa,78b0b79d,111c0203,ffe518fe,f08d517,78f1a564,d21e2e31,cab63d69,1e0b1290), -S(90b6412a,2626e9ff,1dce75df,c56744d6,f471fa29,d676c0d0,cc8bf515,47b9f0aa,4a7236f5,81fa2637,ae532b97,c89fd6aa,fd2db809,6b8d2b1b,cf6c9ea2,4b3713e2), -S(a25e3d8a,119b1f0,6474144e,81677ba1,811dbfaf,195d460c,1624dee5,39f29dea,cb0591a3,816a7a98,5875ed34,5ecec9c0,cdf02537,db28464c,88022850,2478d032), -S(5dadb41c,b58297b3,e84d87b,275198e8,76c48bb8,aee3041,ed14f7a1,394bfdff,8db26ad5,ae662e79,23ba04a5,87e7b2e8,f64a52be,8a76d4e9,5193e94c,9a80f4cf), -S(29fb35a9,f0e0b7a,d19d8af6,c4dcb5f0,19ac7cbe,b7bfb535,d23de4ea,33df5d00,41ba5e42,64f63b20,eb37839e,44deaae1,47bb9a22,1ef94ab7,737efc3d,ad61693c), -S(7270c153,a2fcacf1,18644892,7795fae1,7fdd4fa0,3e9ac70a,4fd38cc5,c5e3ea33,f6c35e5c,cf398440,a96d4c8a,f981fa04,567851eb,75431a14,83e026,ff6649a1), -S(70efa7f0,33743eb,4f25db9,c43463f9,77a2cba1,ab8e08f8,59fa7780,cf7129e1,f906a344,8cca0734,ed895706,7374c12e,14e6b573,ea4c90a8,b7376eb4,20adf7be), -S(7ccc2d79,f905ef7e,83b888ac,ef445b4f,a7320fa3,79562154,d0482d62,cefffe38,b7453f38,9861e0b3,7596d5ac,e41dce1,bf45374e,845542bf,cfec71ea,76bd4cad), -S(f171415b,58f085bc,cecaa5e9,b9afa67a,a05d9577,a28ac4d8,496fcd12,9b50d0e4,95257e0f,18ed2c0b,aa1202a0,e8f62779,a7add6b4,d601deb3,4944e59e,2e638d56), -S(39baf2a4,d41f3930,33330786,9f181ce9,e15e895f,2f209948,999ba05a,350a08ae,5f4a9728,b84a666c,6a6e8318,9f1e6f91,7c97a419,1d44c8e5,6fd6c358,445be74a), -S(b146000f,16103232,297377b6,f31fc96f,afd90cf7,27f0b056,55e41f27,1830c607,92adbf3,b453cd13,1e8cefd9,1884b3c,b7da48fb,24195581,fe59d23e,9725e0b1), -S(d6127f7e,e94765aa,aa2c463a,dcd518c7,e60ad583,6bd485f4,574e9e09,57ba6556,31d3eea2,a91bdff1,6a420533,2e768ac,2531f0f2,c9d94656,26472c65,4d665745), -S(cd28080,e877f416,d6302aed,aee760fe,a2b0f90b,23549aff,87ef8af4,3841a67,f67c8c08,3d69b201,6f9261f4,81e0bd84,568137a3,777fcf45,e4a4c90d,8338aa19), -S(78d35f78,96872666,aa5f339c,b6c68680,ae42cb38,c75bc287,8e9dedd9,3b0ad38e,7544e0e1,4fa07cb3,9144fb53,7ca57508,58d1380f,cd1909b0,56b722ee,fd55217b), -S(aebbd769,392bf374,2e771e65,761cb834,d8a09f94,400a947d,c6fcf062,3e0fdd6d,15bb21b,35f0abca,5f7755e,79cd222,e58cf089,af78cd0e,8e4a6df4,4576f6d1), -S(cc7bd0af,bd44445e,64a77303,5b66a1ab,e990bc1a,475c0454,2c2e23d5,913c6878,b0bc23aa,53ccb546,51972c58,ceaf865e,1a892ba2,bb7bf626,15793163,14663e29), -S(94b69939,f6ab4f6d,6b5a18e2,4e929afa,c83c0c98,cccfe6d,5b0c1487,c5915805,cf58329b,c8ef2ee3,52ee357d,6ed05bbe,ece97acb,7936bffa,428a6913,1e3e678e), -S(4596a3e,b0156e46,c56b2492,6bf8c419,42588055,96d160c2,fea2cd15,1aa84b61,39740352,fe7ee595,2e114853,d0334099,5e9a97e,f3fb66b4,fc6b1e02,632a39f1), -S(b577c857,297428bd,c331a8e4,e46afc59,f7b2ec2,be244cc9,f52a6d4d,b41025a9,529091ed,1e5525f6,e7746c36,575041ca,89ca74f2,7a7f1378,2a36a8dd,5526abb1), -S(623cf92f,7d87dc8f,74661d3e,411aac0c,a6c9191a,1da93b06,4f756cb0,3b7a80d,6909b404,ccd9e564,b27f82e5,ab6348dc,de6cbabb,c40d964d,daeceeb4,d48d3acc), -S(e9aee76c,9559fc77,5f473da9,faf84e81,3f1d643d,693cac55,3b96e27,1197401a,3893a6a1,10d34bb5,bf007cf,c116b17e,287d3ef5,2451a3a4,e8b251a7,90c5c2b5), -S(2581ff3b,48d9f30a,e533c291,be7078c0,41d75248,fbe46a8,c984e6cc,3880dcb,1e15247e,b97fb35,14da7f82,895fdf41,f84dfcd,9501cec3,c12b1524,be8cd289), -S(72162987,71924cf2,83db564f,c75aa820,4c9d0d9b,6acda46d,7e328c61,a3147823,88da7231,356038fd,c4af67b,3a852a38,e6e12c30,87388b21,c6f357b5,37d25dfa), -S(3a25426a,b615a75e,f8a6d5c5,a5e632a2,6e8e79f4,59eb209,ad7594f1,1669cead,d5316c8a,6f24a055,1d8eb237,91b9aafb,7a00e304,35101080,a543c519,3331063), -S(ab26ff41,8cf02d7,57a0f582,1155f54b,2b5f796,b201ff90,cd78d9fa,76b45ee2,6dc0d3be,9c7e0cf6,60e5441a,7b6fb9dc,fb24211f,cd727441,dcf86644,8e83ebef), -S(9ac8ea3e,fa78c588,69cafe04,23fa3ad3,176b9234,5a3c4cf,8f2bd449,2fa38ded,4d8b4740,b0aa16,ef6a54c1,3591b0dd,58e4faf4,a28aa4c4,b1c730e3,ad66836e), -S(4c1c869d,464634bd,d849b99,a04632af,b8213762,c58d8ae0,858af29f,4a26c0fa,8c557687,bf3dc006,a90f0c3f,6ea33067,ffc34b38,9a75a2ac,3ea843ab,d7af17f2), -S(f73695bc,c6dd5e56,8185b3b8,a99182a9,f04957fd,33cb7013,d887a55f,32eb746,f615ef29,72d2cd2,c4adb932,a201567c,5672d44e,529a1248,3bcf05fe,d6b86fa8), -S(41e8d3da,705535ab,b53ff304,3490e669,4c1f754e,713afbed,34b59a59,c18d3f9b,6dd0728,21533413,b6011200,e4320941,1df89a1f,efdb4c21,8453606c,957cebe6), -S(623f4475,c0691617,1c7cfd60,2684fb11,24f934bf,524559f7,142404ce,d353e0d1,8c94a4b3,bb7de410,fe2e3d1a,c41f2bf3,c01866a1,5e354fea,596bbd4e,e90f08d6), -S(961dcf95,64da916c,9a6ed43a,a8028f8a,8c65a1fd,d561cbf2,a0d80bdf,ef10566f,4d3a2dda,d5d81a8f,9e7940cc,957a4646,c3b7a734,457ed088,998b0c10,1987f16a), -S(5273adab,8a2411b3,6e2566f0,a148d688,4003748c,c3bb79f,6bf48340,75f6ea62,780cb632,30acbef8,bca93510,74a28fb5,51573656,1802992b,52f64319,393cf529), -S(170c2667,d45ccc19,7ac05e5c,2df7a0e3,37ca47e0,68f360bc,ee9c2134,81a0a8e3,6e82b129,6d24dcab,c529e4af,538154ee,319b40df,1cf31f7e,23fee9fb,4bd3a8dc), -S(7a240b1d,5df36af9,b4d1b988,c428d12a,e64cebdf,280da6e8,dfe0d7c0,117f8e2a,d5a877a9,dc46a181,6939b345,6015c592,58591cfc,63ea46a4,d228ba1e,465ae6b4), -S(6a6564a9,abb91408,c90a508b,252b68ea,7b11cb38,aeeb6bac,4eeee422,6058ff9c,2f4c5766,e3dca65b,f991b74e,bb0c64b0,2bd2668a,62e4b97d,8f3b35e1,c3ce614e), -S(87aee56e,bee43b0e,d0fbe101,93218ccc,9d4f8d9f,c51a8780,e0955316,b97c71e5,b2979915,9110931f,d2d9f95e,d6d5217d,6d957a,c2bc6f3b,c23a4555,e19a76ab), -S(193d15e,6ca2fb6d,6ec3b10,945f1174,8476fb29,327e941,ad1f8ccd,d7d41931,fb7cd3c9,2cd51aab,2b78b0a3,b9e5f78e,5846bdd6,822e1525,10d08357,3bbf1ba4), -S(352834b4,5bff7ebf,b0a20cbe,13d51e8a,b4854209,a8c918e7,67f6986,b4c1f0cb,e2676927,9e22fddd,dccf5a71,c4b33ca1,f8e5cf24,43388704,721f3c3c,8669c8c3), -S(843ffda4,5e72ac0d,b27a17e6,65fcb27c,34d325d1,325612ba,6163d5a3,9b16e8ef,e39834d8,c2ebddb4,791a5ba9,a525e210,acef4fe5,9184e737,851785ae,9b228d55), -S(b34d4e5b,5f86717d,2c77708c,a14f42d,4ab21bfb,de36ff49,eca9ffb8,b92192cc,6e782729,bb40e31f,3a0ec687,7a6bd690,6282c723,5691fb73,6baa16bf,ccb70670), -S(98b7f92c,4d4c22c9,2783b2ef,a38b71ba,477f79e7,85d4fb11,acfb2880,709b7172,e30e234e,af0847a6,ee61a5f5,3f0f413b,d68b115,d8a726c0,61032d6,70aadf1f), -S(4e7e4cc7,a37110,6aa13c5a,e47e6962,eb774d7b,5b25d31a,7e6ac83f,ec89402d,b14d199e,9dbf18cc,e03f5cb8,e3e0b555,a6a7cde1,2fc6ba42,52956c43,27f874f7), -S(4db22218,59bcf734,f25d2a16,3af8f5a2,58422913,34bd5e2e,4a322589,d0096a61,b99740ed,41165371,e1ddfe62,4e6f3a02,47ed46cf,4c589067,d12c3a38,b75701e), -S(f1fa9b2a,6983e6d1,b36e4172,20b9fbb3,6ba4383d,cabb2da,845a63ca,8fde624a,539ecb7,cfeaec83,22861a97,4738844,53795076,1657378c,8950a660,251c50e9), -S(eec0d4a1,f551ae4e,f54ba956,e84de711,1fdb93e6,3c7b64e0,bfd4ba42,ff91fa6f,d16347ed,3ea3e986,a1067fc0,a1e443fc,c80c6277,f1018148,744f5faf,65391c35), -S(74be2d2,526daaa3,3ab34527,f26e6979,4d9dc930,7044da0c,babaffa3,be2eb41d,aec5d61e,477d998e,d18ade2a,1eeb48bf,82b34408,e6823fc8,f7b57561,f0c56ea8), -S(6d248800,29578c3,141a243c,324a7e36,c694ff50,1adc4280,31ee3d1e,ca32aad5,58acf9ed,b1b5ddcb,72da7a52,6cf089d6,839b42b7,4fecdfa,b7e6996c,d80c3e96), -S(7525d819,d1dba5b1,1a36a2b5,62a6e65c,3d2d1128,8f1945c6,7daa7149,5894c52f,458998fa,b2444201,b8a57992,50b76be2,f79599b5,fc87f83f,d47eede5,feb5351)}, -{S(c8e595d2,666f4913,1f375b67,81b9113a,d0760e5,9477ca17,8863828b,307488f0,a82cf2a9,d823af13,5c23a04b,bc12dd81,2c352a48,27e19030,8e089d9d,9c316596), -S(54970cd6,a06f81d,3566c34a,ed5eb8bd,aa49c821,41b6518d,88efb994,a67d65a2,cba9701c,b3f620b2,b4756bbe,1d7b39c2,2226b871,19e7525f,ef9f11b5,c2ba0f36), -S(f9b9b054,543a96c4,25baea4b,5b1d7b60,81596be7,7a06f02f,bcc4926e,82d2cc91,1ed468ba,7a674ff7,4e872773,85dd5fb7,fc1f1603,a5a8f249,c808aa14,775d54e1), -S(5d3a25b4,dfe080a8,a13823aa,77847487,2e6ef73b,5fb862c8,5439fe36,cc93bd64,5f49d6f5,507baeb,5e0498cf,83f218d5,743b4d93,82cf0770,a734d6a8,af76c5d1), -S(1c8ed0c3,6b0ce521,89f5ad75,8189df2b,77646a19,8fc3b7a8,9e48f978,5f903409,126ac278,e1194e47,39a5c44a,8b62640f,bec259f2,28f479c0,aa4e5abf,861501d8), -S(c8665b4b,43e23686,e27d34c6,d6739250,4af34435,287e78e3,f9e054f2,33f22168,34161d68,636cc48c,56d9618e,1c92e9e5,83c5fa4,f87c1f8e,126b1ac5,ab79fa7), -S(e7675296,10359a1f,29d2ed5f,4ee7cbbb,a4e9b5a4,5ed6cce,10d36059,6ac24773,25662f83,ea425398,328d3874,a63438ec,3995da3b,a5a731c0,45b8d269,f07a0b0d), -S(875c0b21,43d3a01,b6310ea4,7726f174,e8b9ecb3,34b65ea0,59f877b5,e7455d8c,8712b814,a3ebe72e,df1e3899,bbd34bd8,6d021e7b,a2e9763c,ff526e35,4a4286ea), -S(d4ef4e,78f2d6e9,b0e717f8,21c1a56,3902fe88,c47f208e,facb68ab,5c176f05,2fcbca4e,8338fa10,22b432da,7b40070,90473863,14e28e04,268ade75,57a2d554), -S(31513428,e66de83b,a631a2d8,44e054dd,8ecec644,134c57d2,eae9f6c8,e5bfedf1,316bafd7,aa48ab94,ae682ec2,ee1bc88,f04f2c50,c975b441,f28143b5,5d4bc909), -S(33260c29,cce9b856,dc9a50e6,d41746e5,e73fdded,1fd25d3d,c3659fd6,c2e72575,665cfbbc,9af473b,b647970e,dddc260e,d53af968,79c0cad6,e12bcd3c,392a646f), -S(b49a875c,d46f3ed2,34c3b611,88046b4c,aeffcb5c,1c7b959f,60613357,b6fcc13c,76006cfb,21f12143,6684ecfe,1524011a,a08ddfd4,c26a96b2,f56da73f,ef05fd37), -S(bf528e3e,7a8c7c91,9bc3e4fc,f0cdeb0c,7f8b58d4,4afa7663,e2fd2233,751e615a,c7e0587,674f3012,f05b7d26,f067b45a,8efcff89,bc2f341f,c0f2a829,b2d50b99), -S(b358b816,5db58b6f,64118a5a,53b0f2e3,c319fc59,e4a57657,1fa54214,108d66cf,27cdd287,96758b2f,bff761a4,9daaf43c,8864d04c,dd6bb8d3,669f393a,b74ed23d), -S(c8214724,1e0b2fdc,f054d7b7,75452bb0,98481f33,ef81f4d6,19fc8bad,715cbb76,25808ef,36f52935,700fc3c2,8f02a6a3,37b06ba3,75864817,806e35b7,26a3e9b2), -S(88c95ba8,4f5fea33,e8d848c4,24d4be91,9bcf15dc,988fb9f9,b14648d8,3bda4294,339240d6,a490aa81,e6cd03c8,af69fc90,fb43de16,e456e1e4,40334e8f,216ba662), -S(1222eb56,b6341323,87f28674,2b495da2,ad989e9a,f5dec72f,21022834,190b6a5b,30e95537,c9516bcb,8ba67b77,983f4eba,3a706386,af400253,2f54b15f,9894f072), -S(5adf18d8,e472cda5,d379e5a1,4f66cee5,da7ac014,84b685ac,9234965a,27a0cd69,b36994e8,d17c5c0b,1219db4c,1fbf5746,434c094d,e53e63ff,3d9b4cd7,ba429d1a), -S(bf3bc2,56f019e5,8c0861cc,91a5dfda,bee7f384,70e5462c,5605973a,519c682c,38356061,b7015d4b,e7f43f21,d3b76e9b,bce0c749,c7e0d96,e6bab6b5,8dfbd650), -S(10aa56bd,a7ddf207,c898b73a,22f1e8e1,18fc453b,e1539267,be025cfd,c8194571,be79e52f,59320f5a,65626557,e6218a7d,a4cdde5e,ab00b23,9b411bfd,377767df), -S(2b2c0c46,900e65c,caa1339f,34d1449d,91f937e2,2524df3e,95d9a370,d940f31a,615780b6,6839ae65,87a0bd3e,45d38f8f,d4413e3b,ca1afe68,944e7e77,917d0182), -S(a5f75480,d53b0649,dd72d8eb,a9275117,b84fc3be,288fa3d5,e274a287,27c2e669,a766ce73,12b8df27,aa950f7b,29c767e,fcea1614,de5a6b42,3a57becd,c496d6c1), -S(d886590a,d11c94e1,9aab94bf,9422377b,528c1302,20c86f14,f13ef07c,34a61d2d,2978b774,2968150c,9dd0739f,7b9c4f0f,a5214f02,f828debd,6826d5f9,62cbd01e), -S(63bf32ff,4dda2eee,8aaddd62,8cd75f44,7535c843,19441e07,801f7339,89ce1ad8,6544e852,8ed612f3,d4df9037,4fd22756,3a5d7edf,df910d68,fb4571b0,679f1238), -S(2e42372d,88db8b8a,631c083,ef77015d,c98b13a0,597c6efd,141bac97,ee8dfce1,6454e588,664fe42c,1e9b6646,e82889b7,4497d435,e46c2a77,fb05fd10,c28986f1), -S(4d3b7d17,a4a7d26f,7e79fdb7,477a8f42,e208014d,3f61445b,6c921a3,d5808110,9408735f,f9c384f0,46ff6b78,5ee8914b,a8da4502,6299e09f,9361fae0,25e8a19), -S(c0c2f170,44e952db,3b5e3125,e75c4be0,4b91081f,1858dd2c,ca1d11e3,bfeb42e3,712c1211,f321e4ee,5b014757,87a7c784,fa00d429,fbf1ffa9,a3884a10,ab633dd9), -S(832a63c5,105ae2af,8ae9a062,9f41bc12,d6d9a16,ad764346,fbf45561,fc721e3a,8eb47da6,f5ec89e9,483abe86,d9419561,26d78380,a6818efd,1d6fbd90,9088db06), -S(56db6941,c03ee58d,c4dca632,db498e62,1872a29a,41c42082,79ec7454,bfdaf0ed,c29ca102,5ea7525,68564f1e,d15153ec,aaee2ec,da3ace93,e580c8a4,93e9e4b2), -S(3b46ccef,dc3a713,10e4c8c9,215b3afb,65c354dc,c37700f2,61635e20,209cd7cb,6fd7675f,b779a43a,ec66d9d,66f47d3a,d41c3e69,9db107a,ece85e75,16d924e), -S(ca4d848e,15b27c5b,926cb160,d79ddd80,c618e30,1d0fc2e7,3fcb56af,5ec7ab10,604ec,e307566e,ebaa545a,9a080f51,e2a0b5ba,4a09c8cf,393bc4f8,6f483d27), -S(53f8eb4f,c8858582,e5990bd8,ebb19e30,fd6dc262,ba6102cb,3b71b6c9,e47c764c,30c7dc5d,4fae504b,56a103d,b9318647,c5582e09,e0868bfd,ebf2d7de,e5f6fbdc), -S(4754af73,cf1cbd8d,c231adb2,3cbb589a,705bb81e,b8ad0ab2,3a61ce0f,db6df49c,6784ed08,73ed3a36,14c7b35c,916905d3,dee4ccc3,ab82ed94,1dd4da1c,1d211af6), -S(3c593952,1d1b1fd6,976eec8f,9498235f,4ed5594f,73f0cf2a,14b8a78f,196888b2,4636c4d4,aa2e1f,c78eba99,2dc89151,3c4e380b,24aa1701,8e99785c,2088dd73), -S(a7b104b9,7c1c0fb3,1d30a49f,b2377ebf,df7020c2,d77b0b8e,b47428ea,c60ddaf6,9d7f63be,bdf87d97,d18cdeac,4f97e900,f5579bb6,6b5da626,154b3950,df14261f), -S(234cc1eb,2097b150,a72f1e7e,4c405679,69cba876,f22a9828,4e639e92,2598fc2,677e291,8042accb,e4639988,d49c85e0,3cafe4ee,601eff33,398f02da,9bffce39), -S(b7d66767,4d02da2e,3c1692d5,1dd8d383,b8456c81,c7cad8c8,b2d55204,79c10ca8,da5b5c03,1e4139f5,24920932,74b15eb3,bbd2e5f4,95ce94cb,cc4184f7,f2344d40), -S(c32a186a,6fc91998,8df6cfb7,d2a39e03,9a60f1dd,7852da99,9af32688,200f2a6e,cd027a9,a1c5d0c7,6381638b,21f5bf33,71514b49,9733cd10,fc36e3c3,3e16d262), -S(7d824a92,83976eab,a0f7aaec,4619d13d,abf75df,7062ed63,ab09ad73,7f805f7c,81745e89,a8b8c725,32c81120,c527e5bd,772adbc8,e93c4d03,856596e9,942865e7), -S(ef890d13,a3567150,2f8aec43,59e2e293,8ac0511b,13f99ba3,c1b30a0d,393e0e65,d24a9d5,bab93079,5aafb32a,fb5dd8f5,9589b27c,76a3a5f2,728b5f33,3aaf2e6f), -S(49e7a49f,df1d0355,5a83db30,1ce7de93,84d50894,36e4881,33b31031,4b8ed333,86f8051b,5ddcfd72,3c9b4961,80b5f534,48f9f20a,6560698f,43b5f59d,2205d5a5), -S(87a54ecf,9d6adc7,148da85b,3aacb374,d65eaf67,a978fb07,bbc920c9,f68de37d,7500154a,11651fb7,16bd4b1d,7d74df87,d948ad8a,441cb9b,74523eba,b06a33b0), -S(1c75fbec,2bb178f6,58f8bb0d,58c59d28,37c5bd11,e7c9766b,fc8c71c9,5bcb4fd8,ff17df79,c948583d,ae95c4c0,2be215ca,94189a75,18860da3,55a29332,39c3be51), -S(8b50c207,f02e2d39,dd556a0c,54deb2a3,3a96e8d7,8a1a4d5c,9970986b,46caac7b,9e634e62,448e57d8,8013de8e,6c1dd7fc,39aed80f,5e118cb8,2a659f6c,694874b3), -S(7b4d6114,72e2c781,4cf7a7e1,b2e0587f,f7c758d2,96bde162,7071d9a5,e9ccf458,54092c01,2da6117d,bf24543b,c8143b8f,bb90cfb5,106b3a78,18e9ab6,adb8ee2a), -S(50d14331,162d65b0,6ec4883d,936438c,5cdcc98c,3265b6aa,3e9c898a,3157eddd,2494eb8b,894cde06,5238cfeb,8841d428,e6fc09ea,14f31250,e921f7aa,c5235e7b), -S(c5638477,15e5e0cd,7412657d,63d27e6d,c8126eb0,b353acb,4146e93,d5485293,4567dd06,d6c8ad85,35415a06,eaf9c387,d15ad758,27de781e,f0b2ddd9,fb0af414), -S(cdf1a81d,b618837e,77c4c319,a78ff7c5,8ac2693f,f3ad9d76,f5fe4639,8523d152,3d29f818,1ad01726,f5a57299,e9f8d632,ea50a6f8,f7bfd917,c60cea89,2e026e9), -S(26163253,c6617468,f1b78426,b153aa75,fb2081ae,91f0291d,91785fa2,8eca2271,fe9ec597,5be387cc,600be7ce,28ff3092,fb0cc11e,d235ebb3,bca21d5a,6761f2d2), -S(ffbae863,2dbe89bb,13a44bd4,85685746,160e9cf1,5e02c547,a73b192d,3458b265,c267055f,ade9c7ea,c0ff5356,b3f1062,c764c5f8,b182207f,eec0e345,cab843f0), -S(86e20f88,bd61ef73,2133367e,45235980,b2cf0cb,9801d795,5a3a8faa,53eb6b31,7d7fc09d,a9051669,1772b443,b7204199,51587976,3110865e,96f1e9d8,676ef639), -S(7be39fab,669be73,cea39240,a16922ce,5f1c3bd4,f4036d17,97599c8f,d52bcc73,da152535,716ce5d8,3b223f72,1ead270c,d2f78d83,f1f6b8e,61c6371a,62794829), -S(5dd3e3db,62673c67,112f2457,dc42e903,3b5ea586,676d0411,2c913a03,559c9570,b31c875e,977f1205,3ebccaa7,57e69cb4,d3632130,999b5a5,ef73c4b0,5950cfe4), -S(54692082,90733c07,3032ee6c,208658bd,a87d359a,bf145837,20bdc18e,9c3abf42,a3c73d09,5209d326,8a51d21b,37058b54,93636657,c699b58f,bd209210,f936f72d), -S(d170eb9e,bd80c03,282137c3,a1a36112,e2d965be,a530f5df,fdb34634,32f0e983,82bebf36,6b21bb96,ea0a162b,1a91557,5679c33f,ceb4bce6,2698822,2db01840), -S(2ce91172,e6c42333,67487389,f31600ff,f6f0e5b1,3f7dfef4,5c3119ce,5b5d87ce,3c95d405,30b49147,5cf2e0b,e5e2b0f7,ec84551d,931d09e6,76a1e552,c221199f), -S(b133731d,95483e43,cc4f56e5,127279a8,a0d32cf,26e33971,bcdccf69,e3b04f52,bb69ce36,c7bb5973,794fa89a,d4bdfd69,8bd26211,caca7866,b12b5ffa,fe4c27a1), -S(c9e45724,8dbba2c2,7c9cd09d,de0bc5e4,2bdfe86,2f3a2e1e,12c9126,6861d76a,f36e6024,f5f7c255,e684d368,ed336ee0,668e6bf5,dadd8fb4,6c58b03b,a1417014), -S(99b6d58a,d4524f00,fb7d3c0d,4a521143,fb45283e,2a8f5ba0,e85f1833,5c979828,2acebe0c,9de8dbf3,14b3140a,fcf81a74,b1db3e46,bddd4aed,9014848b,c1598140), -S(2940748f,7feb4edf,c05a0af2,4ada767b,aaac74a5,b1f7d83f,c5590780,640f6d2e,d30e19a7,bb721cf7,f2f47351,a8754476,f97d96dd,39cd6a91,4a97dcea,597e2258), -S(7b53ce3f,456591f4,534d9476,66e01d38,bdb80580,6555d569,72404e0f,5963b5bc,c03dc414,99b7f26c,cd7cab45,c9cce637,30f9b615,19fe4d3a,e9410474,b2f62209), -S(f1e0953f,18f81648,1bc8a21d,34ddb5ae,1fe02974,1dba2322,c5ebf200,31eab9c0,93e9a091,9c6bc9a3,e4a161f8,3f94d274,b1ef4ac6,edb975bf,b62cf92b,97f1baa6), -S(6037926d,772b3333,eb75a6a3,381b3784,ede8cbaa,a4c1aac8,fe09ea20,ff3c6520,45feda12,a4bd9518,96e83b91,bbdd05c3,dee627c8,39c8fbcf,e27a050c,9b082ad6), -S(7f845fa7,49ae8a9f,cb394dba,27e7d86b,e16eb956,b08dadf,a55afca8,5a1c6850,210c0682,9d62dbd3,d1917505,4b428305,78444ed4,ec3ff807,f6593ec2,f39dc1b2), -S(d3780383,8c1390ff,c1b679be,8192b8d8,4369eaa9,5eaacb2d,df7b0d83,4fae6ab,e9d5436e,79c4622f,1ef6a773,af736727,d93f5f09,3d0abd64,acc6f37c,4b7b3975), -S(58fe6127,196f0b87,8acac65c,c0a73b52,7c979d75,ac15ddf9,7858bc4,e4f40400,340365ce,74466016,4887527d,7da89ddd,69ea1bb7,93f886f3,654dbd7d,6b9ea145), -S(798de133,1d82f361,6fe2c597,ce8ef82,9e1419fb,1615b76b,e4e44929,518aeb8a,f8eb34ed,b9275578,74d5abac,2568b1c1,9a751cf7,f2812b64,9b75da50,e0c3d269), -S(ed7c18bf,c58b3202,c97a31e7,4e82aa88,c9d554e0,18afb73e,2b8324fb,bacff740,7337a0d3,f8f42f32,ed0ecb1f,44907dc5,756a877d,d8507b94,442fc5cd,41d5432), -S(41633de2,56410771,aa494b3a,3390898d,e78aeb06,3e8a061e,18c3a2dd,d9a23f5a,ead81878,b28062b3,e421c0e6,c1202092,121fff76,80dbc99e,7af681fe,c700ff15), -S(17392b06,3fcf041b,2cd4672c,780edff2,9e1e17f1,356285b8,e80ba54d,4ca6a67b,af99f6ac,2f9e9178,2af6b677,7163a0e4,b59c4d90,63f8c2c3,9167743d,38231860), -S(c4229eac,5a8333fe,75e90571,5ec787b1,7ac350f3,3ba996d7,8f1c106e,d5f0dc3,9186b6dc,6cc14aee,8833d89b,501e4fd6,ec8158e7,2f96530,4a3a6577,8cef072), -S(a985efae,9458f1f1,8ea8ffa5,84d7dc63,25cf125f,a210886a,e1b1dd23,84c2e786,1ba41023,1036e351,7bf58cab,5870f244,315c79f1,edce488d,35907eb,a5b5e3c0), -S(b5fa6b30,6ba70431,ca33cd5f,82cb1f50,3df04589,c3c66b60,dabe0fe6,e09356a6,c1ff1440,3a4ee6af,940e1af8,f9c2596a,ebcf3691,8f9a77b9,730bf075,42c9fef7), -S(c3ce2028,9e90190c,5ace17b6,7a9a23c3,19161a36,9f33cb91,5cc57416,292d0a8,ebd0b498,59711041,3560bd36,1dffc830,8906263b,a0102ac0,2d871e34,856aa371), -S(ee376a1a,fed708c7,de2bcc3e,54a01427,5e75d8b,a6d8b417,75005eb6,8b29d94c,9c3833b3,1d73f289,cd3064f5,7a1ecdba,48194e3c,66d82f2e,e3086749,62b8aa52), -S(aa25c37,a2e2be4a,7c0c9e4c,e08e20b9,88de0af,880c1a6a,e3117910,9e5b187e,f469297f,1e3010cf,67310d9d,719f7a59,258d2184,1804cf55,66615800,3691a7a6), -S(10ad3adb,7a865784,c2e044ad,19a21199,77cdcf69,3d2d3292,26ac352f,c75d11a9,1e6858b6,1deff39a,1f69708f,56017ee8,a332ab60,a48e2783,e2dbe50,a176f355), -S(5aac0d0b,a2a5c410,39541de6,c53ae936,6fa07ca8,373831a7,fbd87a38,784af72c,4d82d068,9a91355f,6c51df81,78964947,95614a2f,5b5a4d07,20f32e1e,7be78ec2), -S(490efeaf,914e09d7,6bcf2c9e,15553327,d971c363,50fd4134,b9dac978,4a6bea86,bcd02373,44959244,9eec797e,6f50a9a0,5153b3d0,436d5d0,361e7c6e,cf8400df), -S(9c653d81,7a6f45b3,d7e001d1,140fab91,1ee8fa84,1c361ec6,2a62c0d,1f617a19,ccac651a,db81a595,ca2eaa78,f6ddec8,c18fa0e1,7ea19db8,ee4a431b,87ea83db), -S(6e2f2c34,ac914200,759acbba,28e9a2d5,718a682,61d6afff,46171c95,1010c79a,70d43c78,d52dd510,ca0660a5,40ccb0c7,75c446c8,cc5544f6,32da3c20,8fa84e80), -S(b5b1797,730398e5,c056f91c,3c63d762,cbcbf871,9a032ec4,e53a49da,6ac4c7e,db4299a,1e5d8330,abc09c26,191c592f,556236f4,677afacb,b9c08b1f,2e0c6dfe), -S(93beaed5,d689a857,a5c95522,3520b40d,a9616adc,a58e684b,6c47b343,cef0e604,7e04853e,283c490d,a9751ca2,35a3dd37,11597e26,6391bcac,443023dc,e7b58199), -S(d67e7b92,d30dcc65,ab6dcb6,da8daa6f,42aaa41e,980793a6,2cae02ca,14386b45,6903a40d,ada98666,40583bb6,7baf9b3b,4320b11b,ed904987,f11f6ef9,e985763e), -S(31d4214c,d168bba0,cde7dcd7,54415c1e,1313c411,ed3076a1,17e29a84,184ede0d,bc2ec4,65cd6863,5389a499,970ae4d2,953d1b8a,df8a6190,8af2d7bc,48c4254d), -S(4c03265e,9d1b0818,a0249b0f,acaec62d,13525fe3,3a963dfc,7cacf779,a94e42d2,4fc53174,762449a3,a54546ef,1a1a6012,4fd935f7,13fea628,1eb231ba,27efd9c5), -S(9eb8fc83,a180b5d1,d720fd4e,6c873866,1221f706,961b3087,80b226f,7f3bc065,aabb671,9a5ecb53,9266139c,642a24d9,892d3367,146d5718,bf6e2efc,d7db3dcb), -S(7cbaf999,bf2d62dd,cd5d521b,cac74f1f,4e0dbc64,ce42554a,fa140e01,c1ef4a17,a812aaae,59aa8835,7095750d,b0efce6c,411c7d8d,32077185,22470643,9e8b4094), -S(a1cf427d,9a247655,f017e35b,4f5dc500,f91d2936,b54bb1b5,cd928f5a,add7d9d5,92e76ff3,8fc6dd90,67a38f3,c974770e,ff7fb86b,b9c4cf19,724decf7,682ebe14), -S(ea47daa1,d527592d,a1b67019,acf67b5,3729c0e0,44ad194f,4a884df5,b64d1e88,8a8e6e8c,70c33c68,d249c670,3133a665,359af2f6,1b339a26,6c64c227,4091a909), -S(d2bbc061,a7dcee9f,a9d0d95c,5de7c07e,6db3ff3e,1a051042,532c0ce6,be80730,b00cc82e,6a643f46,2a605720,c862164,da039008,34f30f57,77d15564,4a85ba4a), -S(467b855a,410a691e,e4b0a463,4252d6b5,c5c6f075,acd2d942,141c2db1,fd6daeda,6fd32e37,9ff7ac09,7b9e987c,6fe6dcf4,628756a2,48dfc343,9f127a64,50ce339), -S(841cf771,c0ffcc5c,4a5d30ed,2ff39fb3,c7e3d76f,b9ade58b,2c9c3f91,30589bf7,f4bff35d,98ff8629,a9b48cc2,fad49d8a,88ae7957,33e573a,82649d75,cbbc4c32), -S(5d9f954c,d2972a26,7110d9f7,dbd34b85,ad9ad480,769b7d17,bed01d45,d523c583,ce860464,688413e6,ba64468f,6fde939b,1f9e3d95,b7955a50,6e92e235,c1f85b87), -S(1dcfbd70,cac8cb18,31531b3c,256ae415,eb846804,663fa826,7b1edf87,11d076eb,9579cfae,31cb98cb,62e54b86,cf90abeb,4b537093,898b732,98263988,b870288d), -S(6fb4b3f,2ee3128f,14d810ea,a989d5b3,5feccc55,8d44e3c1,694e5dbe,14d98cd3,f67c8f00,9205f82f,cd2d801c,6a19e35a,61ba0cba,fbbd15f5,c7259a23,14505719), -S(e17d12cf,d261f5ea,db611d02,8f3720f,e4d00e61,5383389f,48c59c0,791263a7,b8bbf87f,4aeda898,1c3c2ad1,f474a7fb,69f45180,57a8011d,7456b688,3839bf4f), -S(3fd5048a,4e2ab188,6f0b1cb8,cdd59182,3e94d853,b9640a33,cb3f5718,ac30f3eb,14d769af,5dfb719e,b4a154a1,f93e10b5,c1d23993,36e1597,2fbe4c76,9c088441), -S(36941001,5302571e,d7c4cb7c,3d479f55,e89193f7,5b52bc7d,d65ca207,41d14b2a,c747a1d8,af196bed,df1c5321,d58a0a19,171ebf1b,1a855b9a,3f90f16e,c333393f), -S(42b5541d,e161fd92,f2b92c12,826fda42,49f05c1d,2f79d951,1ee4fae5,3269e1f9,d6cf742f,11daf585,bc7b4be1,784d55de,2ba3b918,4df6d81f,723eb593,2862dc5e), -S(dcfe0685,c9452c9a,be819a8a,574bc35,760263a5,edc0e018,4093cf0c,b4406acc,fb84c487,873ee72b,49dd61e7,46a8cc1b,8485c4e8,fb5f9725,a17d98d6,62aa9d58), -S(cc5e07b4,c76bd9cf,c9b040bc,c3d0805e,487eafb4,430f2265,adabe2e,7bcd5874,6668bcb2,7a297c14,d4a046aa,59028e39,be049894,764193b7,9dc1658b,bbdc3d25), -S(74cef0b6,e59cdf5d,47244fed,491b6c0e,76d9b185,1a3f084f,9f783a67,d5f4c70b,3560eae,9a4c4b65,3831bd98,d97c5213,25b07f32,d40b215f,a93f2332,b6a8209a), -S(dd1b1359,4ee43b44,1f54a620,6e6295c9,80bc664e,3b5c19f4,273e878d,3340b605,4db95cc0,f8e2020b,c0f0eba9,d21cf630,e6c5ff77,dff8bb2a,8b496dd4,22cf6a0b), -S(f42815b4,76b4407,9ec05cfe,aba6f179,b72dea78,767fedda,3464e9c3,53b3ccb0,89004efd,2cb91fab,7c8908fd,b454672,4ad8d851,55473b21,e8e3d984,6d913098), -S(f20d41d8,c096d2eb,d480f9da,5df1bff9,570dd299,16f87ca2,19ed3fd2,d6c072e7,3eab3c48,be7e6d6c,bd1eed0b,33c54d49,72d96f86,67bd857a,8fb3190f,92b22a9d), -S(d84b9d43,20d76cb6,13df70b3,d0dbe935,852fd9b2,86978807,b6288a3d,27828a28,73c0bf55,de9ae18c,a56b98ae,3bc86a48,15d1265f,62d5856,f0f2b182,b4596941), -S(ba0ed2aa,3944454c,7581223f,d1dd113,9d340ee1,11d08d7,98f278ea,7160ca10,766d5ec,49b48092,c007fa69,a06b22ff,e02cbc30,6cbc75ca,1a5f0058,73c44299), -S(b5393ee3,7a8170c5,bbbf70,fec33e90,71e52f4c,47e21d79,e9f7413,d68050c,7eb93838,f871d769,733ff7e7,d21e3848,8632b7e1,6483202d,50a2fab7,1fd7180c), -S(820d66e8,41b5de10,e28c147,d43a0116,6cbe764d,c8ea6a42,e7743732,45b84190,cf3a65e8,80727c33,3e693586,78033805,6482b2e,53889a0,bbf834eb,c94ebbf3), -S(247cc086,26f54562,8d48634d,4bf7348d,cf60e598,5570527c,c20ce901,ef4172b5,acc2fc2a,9c939cec,a51312c,d56734f2,87d906fc,c4d42f17,82606c37,b0584dfc), -S(81c41e2e,752e0d9d,c66cc618,5aafe042,8733913f,5b597ad5,66706d72,da80dd05,8ed860ff,846ddc23,e466619e,480d944b,f171707e,721110bd,119a128c,e8a623ef), -S(24a22359,7bca9222,dc0c82f4,b7ed4ced,f5f41ddf,73e5c8a5,88bee89b,3b21fecd,7555cd9c,da2e75c6,d8c5fea1,50e3feea,b3ea1573,d7c163f5,e43b3d2f,31b0f5e6), -S(db074838,ae29a327,b85361fc,c9ad2bba,38917d58,c17ec58,9c22d6a2,f9839185,a1f7280e,35bc6b7a,b05c1704,abb46a90,43b3f7d5,30434450,f94ea1ff,f787412f), -S(6adb02c8,fe669d1a,8c7fc3e0,60eee0f0,73409111,c6013619,770d0ccb,bd8b950f,3fc12c9e,b1d19234,737a4e64,9aa06032,35d4538a,ecc6cb9f,dd1f7777,46edaf5f), -S(e06dd5c2,1d109fb6,3e5429ce,11fd5a40,5118a84f,863095c7,dbfc2374,6ce1429c,961b9d5b,c5b82b23,c8e69b15,15e28700,13094f48,c8ef49d9,37e1b440,c306eec0), -S(1b599e47,ef4e5369,bba2a71a,98cb03b3,f5d9d30a,a5e309d0,cf7e2d19,27f95c18,5a40c3b0,b949efeb,ebbd0ee7,1a81c9f3,d6fc20f6,c9effd98,f0492ef,82710072), -S(92da076a,ca5c2267,67abef5c,d06a830a,a6cd1d3a,2224a845,184b2e7a,275eebd0,db28e087,d7e29f20,d78dfa27,bccb47dc,f2a3a9ee,db0db1f2,63dad719,4ce9e997), -S(afb97660,7b94dc70,a87a2be6,53ac2f3c,9a2a474d,ef065f77,b06fd417,44b13992,68d14dd8,e3caf1c7,e39ad23c,f8e83577,d047530f,2c7d5b35,c509a3e0,51eb52ae), -S(bf4f278b,e99d1297,742600d5,d7ce7791,970de902,aad9920f,a8083a3a,a50229c,b4ed5f80,f3995be4,22fa8237,d77b1424,1fa974b1,9b725016,c20e555e,f0ea2bed), -S(c059a980,f1a7c648,95a1acd0,f9d2cd8,9dc02acf,c372740b,86fd64f7,426ff54f,dbc12822,e8155685,170456c8,4d548f39,afba1676,15655d7c,7b8c31ca,499902b8), -S(2f4d9b08,282d9adc,2d80bc6e,b4c1e2e0,553971e1,f42fb8ee,be615d47,61c023a8,fdb056fe,3604068e,2f5e5223,d3076d67,41e939fa,f2e7d0b1,76d3ec89,868cbc06), -S(a7425d49,934b13ec,85aa5c30,d628b94,f0054374,19c5a0c5,6e126a7b,261c005f,f475be59,d5dd5a7a,42d15531,df24fbd0,12d84fd8,e89ca95b,23bdd70f,10b0326e), -S(dd3d3a96,cd232751,5820439d,6455bb3a,d749947c,884a2e90,5791253b,aad726bb,9afe6071,4de46f80,d22b7ac9,a555a7f0,6e830819,437e9f98,b944d8c1,d4722027), -S(7c427ec,eed88d6,a48f7204,e43ce8b7,a4c5b6fb,ffca57b9,bd128903,c3c7fc46,495bdff1,9b1711e,918448e9,a46416de,e2d51771,43007e1d,c1a64b4b,8d1a815e), -S(bf610437,6539cc63,4a1f3e2c,4fc3f762,69752d64,2756bbfe,83bdc404,f7be496d,5bea9e3a,33d7318e,9c03baf5,3e5a0232,440ae61f,25407ab4,23514eda,1a69513a), -S(f2dad2fd,178ac78a,168981db,14c4fb0a,f7e69dbb,453f0d53,456470f0,a22cc730,e571813b,2a091f17,23c21818,789e78a0,e23e74bc,b4d037ed,f8f49fef,9623f42f), -S(51243664,8693af91,8c79fa28,d7c12b37,db24f719,bc0dd0e0,28c6c1ea,19aa42e3,fa116d7d,7ebcbfdb,8ce76cbb,e6203cea,25b65559,becd1ca4,65f7dee2,6e49746d), -S(75f316f0,c9706cda,9cbf6c8f,31266c75,5183ee71,a098359a,ef06fc3d,ad645fb8,518d90ea,af8ffe9c,44cc122d,7659d292,8a979e6f,de2654e2,e3554b71,b9e7b820), -S(565d92c9,93f08563,f65eb65e,6ae4edaf,ee409d1,e00a4e74,5d439d84,a431a5bf,b8cc1eb0,1a532023,ea17bb56,f9345420,a40b0a7a,d247ac43,4ac9347a,51bd0f31), -S(64b17b4d,a0341dac,bbda0a6a,e386e2a,64d0e517,2a4b904c,b26e45c4,497554e5,4028951b,3f17ae55,d114d6f5,ae793460,91d8d00c,c1b2aca4,f0d5b51c,3f8a7492), -S(70ba7f8e,65669610,5496614,c6c1ddef,b8c23f0c,847d8be8,37b4699d,511e3ce1,cfb1028a,2ddb2865,633f358b,e6439ba9,9fa8b1bb,eed6d988,e8652661,9bfcf28c), -S(84c79c6b,23bffd84,4cdc85f7,3180f451,3e6cc4fe,adb7056f,7de267a4,75605d68,beb80b8c,3b2ddf4c,2269431b,bde9aeb3,55e97faa,385c8776,4bd15fd8,344e8ac0), -S(c6f4eb7,106cfe74,82cdfeeb,af421137,f8665713,10616b0,b2b5ce07,8f5ff9bf,72ccb3ee,52b77765,e931298c,204e7b07,57c3845d,5abe7ebe,37db5aa0,203fc81a), -S(c58b8483,6b41a2c6,f56abcb,61cb493c,a314063d,9091ce1d,9b13cdb3,fad79f90,a1e846d6,5fce2f4f,37e210f8,cd7591d3,fe1f6c93,7fa4ac4,ec295078,7cfe84d6), -S(96e430c8,2a74ed53,7f5a181e,20faea66,ee77588d,66eeaaf7,50dd5b7b,e42ad21b,5aa2ee54,96d711c6,e8b95609,ab383b4e,993f928e,d76843d4,52a5a1fb,3e137368), -S(53868e1f,bd086477,60aae23a,3f2763f9,cf6eed71,19ce1c17,b226b48,fa85b8cb,b94b6a7d,4c86d90d,98c8d359,45949b0e,9c958ea7,651c901,90e5988d,e142493e), -S(d6bbe341,8a6bce46,2f091e5b,161dfb15,8c454eda,add230bb,254a5989,df9ef899,f1690322,6db63393,c01fb1ba,3bd83bcd,dc95741e,8ffad9e,56efdb08,837340ac), -S(a496bcf,4317fb5,c87a41f2,58e716b,98f5305c,fc957c83,c2c40397,49de94d5,2479a3ed,e3fc60f5,ea880b29,353663ba,6d9da119,52468686,bbc2d0f4,fd8dbe21), -S(5bfbaf07,3c1cb96c,45bd1191,bacd3bab,8c33ef0e,e9708164,98240b52,3f943be5,96009bac,6fee957b,2e26f717,ddf40b4a,69cdbd5a,946e70f8,b70587c3,b7fded2e), -S(955fa716,f7f0eca8,325ead5d,dac3fed,bc477c22,3c0fd563,2e37ca69,ec79f61a,418c98ff,23d7de2b,2460806a,75fc0328,5ffe9660,b7447a36,c088883d,623476ad), -S(99d3b933,e7d8c8,e1480e6b,756732a6,445036e,9b964a32,53f3cc09,f3d9211,97e70dfb,faae8f58,5a7b5da6,b0c775f4,9c095d13,5526b521,d57c29b9,b2892dae), -S(a01775d0,5b9d2fb1,277f4c3b,6edc8f7,c342c3ca,e9244fee,57cc2d9d,d5b096de,376293db,5c929468,236828a6,1e291811,316ca7fd,90efda51,2bd750f8,62ebabd8), -S(697cb417,bea89412,91ec8ed6,f62f1914,96a22208,905dec11,463014bc,2e9a04eb,d5049ba,aa04b285,f3085c24,e54ca476,cb266f3e,15699d12,fd250e39,ec4285c9), -S(b23ad54b,f9504c8a,c0bec876,71d2d41d,ee04bbcd,c5ba224f,85e3d4b6,84d8889a,8f0b0da9,db0467aa,5b21addc,d3951b72,8d23099c,47bf7767,24e1eb23,ab32e7fc), -S(c8af03ff,197dd38,cdc294d0,28c0c418,2d517dd7,54669894,812d870e,65160c40,d4537dc1,e594be6e,cf2e3ab8,6f42cc3f,a70015a9,ed8e2850,4fb6f9bc,676be0cf), -S(7ea5647a,f0f8da46,6e6b0615,28d0f472,79ae2a2f,5eaf0dc0,64ccf902,e060cf1a,bc5a47f0,d95e37c2,ad9c5fc8,48eed4f3,c62c974c,9b96b250,ec076851,12a88ed3), -S(78cb2c40,71bc6abb,cbafee4e,cd413181,cb1b5483,ea1db7e0,f902f31b,346f7ac3,86f334e5,5560d9bc,60d8463b,269c2626,45eb9964,970dea35,eacd9236,3a36d198), -S(f968919a,7d90997d,5863c9e4,e214cb37,51dfa039,75d876b2,3f1376b4,ab79cdd7,ae3950e,56e4c856,ee56e236,bd581033,6991f8a0,e9212c8d,9e9079f3,9edc2038), -S(d7c2fe4,6d1ec3b2,3dcf9992,357bffd2,aea9bfea,da187cdd,6bbaeb2,51ebf663,ec953c2c,5fb70a14,b21791a5,979a182e,c3facd73,a59d0f50,c3231485,f376039c), -S(63aa7712,4dfa263b,fc8c7b,85dda505,14d694b4,5ac9f06e,1482105d,ac04af87,d368c24c,18de3ed8,43f521d9,3633e9c1,53627e54,bdc10eef,15491802,41dbd9e5), -S(47fff446,884d94f7,a1b2253d,2f2cb718,70a6a42e,36f63feb,65fd7e98,213117d4,ac52a32f,55dfecd6,68b61733,3fb4b7c6,fbefece2,d2cd43f5,667bc42a,f17d02ef), -S(b3d96bde,5770d471,1a91b0df,17c785c,ff7f51cf,c4d46c27,7dffe07e,6c5d1173,78e408bf,6d204097,40a1145,becb61a9,c78120c9,957c6457,12254e2e,f5a1d77e), -S(f17f1d4d,7df494d4,70321d27,420deb68,22be3877,78df53b2,37876928,d6b2168a,4398f0ef,7cbf1188,dbced020,7b2aadce,440b1df1,7db6870a,a05c6d56,4038306d), -S(10833a6,6f75d109,e5251b43,f05d9069,2bc216a7,bb06032f,c2d142f3,cb1eb1fd,f77ce6f4,73e861ef,23f67a77,a5052dc3,4b617279,1e69a688,308439e8,7d91bfb4), -S(301bd783,a82ad1d0,daea7641,6575db5a,1763481b,3c2f94a4,788f7a54,6f9af647,66ee6029,13b6bf11,e8e19392,633fb8b9,e2a3dc51,bd891ad7,3fb80d31,854333be), -S(98fb5877,816a2c9d,df0192e7,beef06ba,c19b3760,b82d8e08,1f6b2431,dcc20d6f,de59596b,914b994d,83a68c1f,eacbfb8a,17b9c54,9561fd48,4f7f2f80,bcbc24cc), -S(5247f727,1de92a64,dd35147c,879ad2bf,4cdce035,2c077e0a,19164052,e19e2d68,75cae57d,3e54bac5,dd41655c,f62f6ec6,7e84255c,bc0bd176,aa505569,675ad042), -S(51d7bfa1,5829219f,6af5d2a7,1ff220e7,9de62e7c,a3909d4a,37c918e0,6b60504d,9d1a5e54,77025129,1d42c64f,14d27eb2,cadc09c7,bf3899b1,b85119b2,a5326f4b), -S(533fa077,4c05ba3f,b32ac60d,13fcc4b2,a20ccf97,bacf2abb,d2d9b6c7,54678437,a41595f7,3d604126,7b82b50c,22d39ca7,7454bde8,97dff46f,3c57f7d8,ec73e818), -S(a549dd6f,2c8f422b,dbe464c,48f61d13,b3537a7a,2fc5a8c0,91d7d33d,221ff3c5,ad126f86,b69a56d1,2ae18f0f,253a1989,ce80a74f,114e3813,2199d1ac,be03efa), -S(7b9161bd,b4d5e56a,c9df5417,fd84aa54,798b9328,46218731,ea289cb2,76a612c3,72e268d1,53fc13cd,743debad,16c98af3,4756244a,65b7f7b,33794aa3,1aaf497c), -S(21557200,4f644ced,9c2aebb1,43beca5e,d54bf17,d2cb1ea6,492f19a9,25a5be52,19dff558,9c87a8bc,d02af10c,4b32aa25,c80b2542,62ecc0cf,bf4439c5,c2184cc5), -S(93d2caf3,c1a0a83e,ecd9adb9,abefd119,1000e482,2670e678,8859fffa,a2784cd6,f443827d,c5437809,e5cd0eff,b48d7b7f,ed4b3ad1,a724cb7e,35aea03e,655895a9), -S(388a2c3,f621470d,eab3d1d8,765d6af5,629b1cd9,10ad662c,43abab6a,9cee5283,653f3611,7e335b31,48df68b5,a8cf6fbe,134cdf35,f659f14b,9036b933,654df3e8), -S(9d9c6f6d,7032898b,77dc7738,426723ec,dad11684,bde6e061,63ed6802,69aebec0,f20282b4,96183c42,8275eaf5,95834713,338112dd,9f2b0924,8445d56c,15a31276), -S(6e1d3bf3,98cfb2f9,67464d53,755f56d3,bd4de638,4425975,d96df00b,b500e825,6f8afe06,eaa52db7,291b41c5,959aecab,e7111b74,fb260d40,68f2a8d3,895012be), -S(dad8454c,5c6fc1e6,35c4ded8,1f2e3870,a5f24fea,be8b6d7b,a2adef19,32bbfb53,7c6aa3e7,615cb467,42b42973,64222157,de26f811,b4046d4e,591f9824,4fddec5e), -S(5ade9345,11ffa26b,a147ee6,fab27693,9828a8ee,7cbf5e3e,e9052b,a01e0893,ed84e129,7d98895c,b7ceed84,52db80ca,3f44d127,d484364b,652b96bd,82f8ae16), -S(d6e9e33,6a39b415,e5909463,9d621291,9c81a084,dace8a97,a0372042,14cbe366,4f274e3a,1ed0ecee,c7d1d4bb,28712e03,7632b43,e1f8b75,a9100b4a,f74e90e9), -S(a913a4b0,a990ae15,60caa68f,e45bf7b1,af500129,a7bc652c,b47e80d3,34bfedfd,1bea9464,6a332e2b,8d94dc5a,32ce31e3,1aef6c83,ea7a261,99da6cf5,7892f63c), -S(7380fa59,b95fbfe1,8e1c3809,36d10b23,27fcf8f9,21aed806,1c602498,c2c6ca5f,fa24454d,bc8cb2b8,9462febc,2e74fd72,8d300617,a601ff12,a599d2ad,bac2fb7f), -S(9614b47,50073368,4d26bd95,5b9f4df3,8dc11bfe,4ac65d17,6149e1f0,89f3a69f,12a2b07a,49812efe,1d3559f1,e282f268,813e5572,8c959a9a,129ba886,9f06a66b), -S(5f2956dc,436e7a52,176d2709,362e511c,cbda57db,ca347ec,63b63147,33f14d5a,f7b399d7,7b3e1d75,b5578e3f,f324ae9a,76c243f0,8dec8cb4,9bf7a78c,120ede0e), -S(22d7dae2,38885aaa,fd51858,f4bc1042,5d57599,2fcb4eea,eaf6c222,c0ae9e7c,6f3e789c,24247afa,9ae0adf,18bdc160,b1d6d956,7ee8fefb,e9db9ae,f0734909), -S(9e5660c9,a5f53e77,59586df,b2b56dcb,8f1af69a,aabcd59a,73573711,3fbd4dd,2868aeb0,5efe76a6,8037ca6f,d97c2769,edafed65,3f38555e,15ff41f7,fd1fb8c1), -S(7abf134a,123ee2a5,eb4bc1fe,6d06f5ad,655991c3,dfa91ebf,ae46ba80,899adf3d,c96dd41a,238cde21,3f628bba,a2488458,c0e35896,f32cf7a0,45b252ff,ab696522), -S(95da0b80,e45e13cf,f5f4f4a7,5265a310,8424fa09,f07f2c07,efb7a018,b5edc82f,ab645319,b3645cee,d1e4823f,838435e2,79f4f41a,af258432,b210a73e,569bb4e6), -S(8a095bad,b000f2e3,26b0c8a6,f1363fb3,4e2f59cd,978d736d,d05614ce,dc849fc4,4e367851,5c42cfe4,6bd3b6b1,6a09bd66,59626f10,a0087591,6b7d178f,14eae676), -S(de5f5b91,eb34ad1a,9d3c60ed,29c683b2,59f4c7ad,819bdaa5,f751c1b4,7ba28567,cb9d478c,58a02246,44f59a4a,cf2fe992,15f541f5,febe0ebe,439a1b8f,baeaba58), -S(94acffd1,b87c644d,b359cc14,c1d996eb,a1d7e773,d902dd5f,7086502,bef6180c,8e58ff91,ae72b071,abb09a19,4afadb4,b3a54c3f,91857b3b,bad991bf,a605cd78), -S(fb75db19,87635a41,e325f08e,3203e0bd,e7ecf969,e46244a3,5d63dc5b,a64a3336,14d19c5c,220b044a,72b58666,9c74ee94,2df157ae,67524f01,9707806e,1bf73c59), -S(9808674,a196cb3,eb0b2558,2a9bac0c,659741ee,ce6b1c49,678e318b,f6456081,f5532b86,3408f545,aa218a22,405b0839,9e59fdcb,e2c54230,9955aade,3660aebe), -S(f2b603e,d1d8506c,b1280f50,f3487f1e,71d797f0,f8c8a1b0,fd153683,18d843ca,1d6f91df,d7bbe002,ec34bd9e,9b843620,ff43a756,88dc1398,e23b73a4,9d3e53ea), -S(b9327718,4586a524,389f7e49,adac31f7,45ae323c,d3ccb1d6,a2abc65e,863e684f,b28c0f77,b47bdf1f,390eb8db,b94c606a,84084e09,1202dd3d,654abc10,3589b6a0), -S(c16eaf54,572c1a6e,142b6617,b38992a7,9cbbb577,348b8768,56ccf471,e21b7b63,bb9e7a6d,6d8ed16d,4f8f5009,76edb112,4d5c7ede,cb2b8abb,73de287b,5099035c), -S(97c03ecc,6a87d198,13d68f64,a3cd91bc,ddf45350,383b90be,c5565c48,531999e9,f5cf3c4d,71be1dcd,60b39aef,f1cb8ffa,62d3e07f,33d4ea1e,adaa0569,3c239ce8), -S(6a224e6a,85d31717,10013b13,14ed6c31,adfd153,df8bb9c6,47428e85,12c1786c,690a057e,ef9e425b,651f55ca,8c72169c,bf337e7f,cb779ce7,81e1ca9,5feac5a), -S(1e89ac78,be4513d9,38e58385,7256eead,54afceda,32edfe63,c70b0f75,83eb9ce6,bbc32d24,d58f47ff,2686d804,4e62e575,a1f1e805,75587b90,1a362461,93f9aea8), -S(40df4fcb,8648bed0,44050957,8ce57046,bb8daebe,5a7ee63a,e69decdf,a5de87b2,154c0c93,8f5dbeb1,80939a49,aa15239,e3308e56,ae8ac16,3be19bd9,33fd07f7), -S(a03f1ac5,a3738a09,d4888626,72f00159,59c280fb,274e9974,7447dd30,260bbf8c,9d28b67c,3455e338,1d1f84c8,d60e4fed,c39b5d05,8d17829f,ccba683d,cd65f093), -S(c7d9dc5,d2712b0f,3da6b4bf,1b6d74ba,de6f9586,a794a1e8,4918ddc,d115d1b0,b1727ad7,6666c0ea,5abfd80a,6aff8e66,b8b63c27,6a8ff457,573d8336,fe65dc0e), -S(3c1f81b0,2e8794ae,135db6d8,ea6e1cf2,adcfd535,634ddfa3,773555a0,e0efd26a,e21915fb,abd19ab1,a4cf84a2,a5275a50,24d0fb7d,c841fa43,284be38b,788d9390), -S(69503972,3c4d14a8,1cefd3c9,ad7c4a1b,d5b01ec8,530ade4f,fa7aca65,28ca332e,20bee7c6,5d499abd,f9c9fa2a,585e3f73,cc52141,f4276cfa,aa856c84,6114c1a4), -S(da655560,50683d9,5f81b2c6,e504128d,5f58fa43,4cfdee92,c0324b84,77c3ed70,297e7d88,2009d30f,bf0b5aac,1c7572c0,78192a1c,475fad61,64b25ea7,871017ba), -S(f1ec70eb,ce501e37,f79406ca,f120046e,6b064b80,b8db9d22,d41f9b8,a229cee6,8688ba6a,ff61aa53,4dd93b02,e3eed5f9,f1622d2e,6fd3a3fb,594b9bc8,5beb55bb), -S(fd0c93c5,c2334d97,1e1eafa5,6b62d377,d1104ae9,1c10e707,a404674b,796c51cf,e2529070,a0ac26ae,bfa954ad,801d0e2b,cecd4102,77a7cedf,5a707dbf,6c8ef5f1), -S(514a3ce4,b9f518c0,ebf15b1d,56687638,7eab4df0,85f93f0c,53831536,ee75c78f,8b998180,c9e78405,cf9cbf2f,7495455,6d5dd04b,bafb010b,db7a4cb3,6bd6cd30), -S(6d0e5be5,f5bcf0d2,37726045,727ce85f,336bc6c5,743c0254,9dfed03f,234fe265,df071d23,bf3e151,5995d25a,f7c8cb48,d81ec018,af8513a8,e842e3d1,484f99f2), -S(d37f48de,9143228e,d5d02ba7,f5d97b07,922e75b8,54eeb91e,86643a6f,cfd8416,f7d6e782,af5c8c0d,f9d2c80a,e582b88f,bf9b0824,6e749d0c,9ac72afe,847842c0), -S(d44815f7,46405f75,f03f4749,b5696cb7,54fe1633,7c721602,cfecd1ad,fdbaa875,a6b75d70,4d5c965b,43284bc4,d4db5d1c,980d4bba,e8f8157d,c1cc322d,44fce058), -S(6ee0ca27,441c80d,83b710d7,a6e4f5d1,a497287,a16e3f67,7ad24df4,4db8a287,60d12357,350a737b,74f857e2,ad3865c3,5dd54e00,e70d1aea,cd77c12,fedd02ba), -S(86edff95,6ae4aec4,7a8b4927,4170faab,dc19828,c14f3de2,84362bf4,5bf49d6d,c9f571d8,1fd0b910,7043a52f,79fde3fe,339b17f,ac0e6461,8c601c17,375955b9), -S(c8ea3038,f056e115,aede11d4,ce113663,da276b83,12510e72,1cd8600c,a4a573ba,a662f00d,952d21ae,e26f97b1,6b32dfa,c0b58c06,6cffcd79,3755cb3a,85fbf3e), -S(541b43c0,16ce2179,9c7db4f0,e06b6c7b,bf006f1e,2adedc1,e8f4e8e3,1572b199,27742f79,a0986843,1560799,c11e0f43,be6e8631,7abf4d25,36e09e25,38b90ade), -S(1630dee,a2d1311a,a7c0cfaa,2693595d,48c274bd,d24cbc7e,4c15e458,f7547d40,f1a92fde,a7d828e7,bf7b1c8f,512a21b9,7227eef2,daae040,f8cdfab1,a728f20b), -S(126f6117,456d919c,49325ee4,1cb1ace2,fdd5bde,31208bfb,58b5fc1,62ec799,4c23a017,73d47eaa,579e5cb5,14bb8584,7955f03d,d097d527,ff366b81,1e6abc81), -S(b6210ef7,1bd1957e,51805a9e,70c6663c,6d8aa371,e1012a46,8261653d,a3470c98,c491d5,e98bff1c,7ce97493,612dd726,bdf69d7c,a4524721,79ec57f0,fd123b87), -S(34291314,3842cc68,b0184bb7,13f7c6ae,aba928d1,5df911c3,3bddc99f,ec8a5786,4b63c3c0,ab6efb2e,bc343cdd,dd43d553,582a53a9,3c3663bd,138eb1ef,d2a245cf), -S(5aa2e234,938e26fc,12589307,afe2d797,bad41d73,3eb6dc66,da9a56cf,d4b6c4d4,db91df9f,1856f8a7,83696842,1887235,5111b973,10fb5975,154cdfb4,2f2f2e64), -S(8c50cd04,5904ac5,d9c6d555,e7bf188d,d2318edf,cd90ab90,722d8552,edbebb92,f60add37,b3578fe,f798d8a3,99834ef9,16e9ca8e,2ca8b9e0,1537e7dc,533154e6), -S(591e3233,9e5ad324,be635ef3,50884aa0,bf3efa8f,7ee012d7,8476ca35,ef586ee6,6e219d2,ff115d36,b3688e09,b4788bd,19b5e471,6f09eb41,cb598ad1,b60c069b), -S(7d4464b7,587b74e8,82c85444,4d7637b7,9b6c586e,b4a032a2,6e07b60c,470d82f8,3f1f3d44,6ada0a0c,4e082bf2,c31ac7a9,d2deee7c,4d9492ac,81d47a3,db7794f5), -S(92e55e29,e333f65d,1fe8845d,42d585cb,55db9cf3,223dc567,29906df5,bdc93387,5ff7c2aa,25b670bf,5ab2b57f,831c3e6d,b9801ba2,10aa76a1,2eaa45e8,29a64454), -S(a0fbf93c,c47198c,9492defe,fedb5ff9,dcf178ef,70a0f416,5128d18e,49083c28,dac0dc87,4bf9f134,fcae7932,46a6306b,5c876455,fb493b04,9a74f94c,82cf0a56), -S(5484f0ed,aabe9633,f0384de8,5f86e77d,8153acba,b8922863,6fabe9de,3dd12fef,180e070e,a3712386,cc4ca4de,f54c0399,fbb017cd,3ac0704e,52d60f50,8c0f2c2e), -S(f2452493,34b7983f,afe9d99c,55023ae8,c8591405,4cfc930b,3c76bda5,6c106445,6e800534,948b6349,f85c5164,ef5bd33f,f8d209eb,fc25944c,110f04bf,fa47c604), -S(d15f5c6e,20f96f4e,d1aaa912,b47198a4,fdcb1101,c258cdd3,52cf0246,2679f845,7751370,ef04b59b,bd74d4e6,286d690e,9158f004,826b2dd9,37070544,b06df5e0), -S(75ba968,f35dbf2a,bd92c08a,24930949,7a50bf27,efc51572,232e152a,a5988818,64be1522,78e3c24a,890c584e,8f2561c7,62985b74,e803d124,11910af2,487f9491), -S(c7742126,88b392df,ccb6721a,dee4f49e,ab1fa24d,84695994,f7d0a7a3,3cd52f21,e603fb71,9464ca60,a8ff9047,6093b2ff,e9091815,58ab8d7e,aaa7bf14,396610c6), -S(d15a536f,661f00d6,ce0892c5,6f7ec1ad,614becd5,9b5d3019,a24923ad,7bc828cc,b2d1c3d5,a9a84da5,cdd277b0,512835f,48b546cc,3fd36b16,f83b8cab,caad96ea), -S(64a9f14e,bbb02687,cf9ceed5,636cc349,a8e55cca,4913a221,641a0916,6afcb872,76b2ccb8,2dcb7837,97d31ddd,bbf9abfb,5173b495,6a6abd10,f9a583fb,981bafe1), -S(9eb0c54a,9490fc39,75170e03,1d3be45d,1eb54587,41db3f40,19e83ac6,be7915e9,fd570313,71616577,36c736c3,b282b0c3,f1f9146f,1aa9f,8fa1b34b,f10e87b), -S(141e12c,501af124,a22cf65d,b3996c76,44bfccdc,2920342a,4f3becfe,d279005b,1b6e9acc,c61ad52f,d8f00405,f2191432,b379492d,838865cc,58eb4bd2,c1f1735b), -S(63f9a52e,aebc297b,5665752,9cd93a78,a0ff93e1,f94629c4,bb9b19ec,68ee1895,8e403a45,497dd525,b2924861,978da88f,4823236b,338ace3e,76330b21,a9ad14c4), -S(af31b58c,47a9c9e7,3bbb583b,2178deb5,bd430031,9ddec2fa,5e66eee1,f0ed8b1e,d1fbdf75,8ac15977,cb8c9e1d,7863c465,cc4dd8e3,e299f116,74b0035d,291e1472), -S(985570e3,85b4ce30,847c2a7a,cf5a3c80,ddacb47d,dc1ce66a,d001cd13,36293ff3,5b13a12,75c5b519,10398a58,f42158c6,1c064600,809d7a8d,b31e14c0,84578854), -S(37ac2f59,ef79be35,41e46114,c4f9ad15,e6c8122,db85b62,59604adc,c8cd303b,434d325d,e4ba5b11,7b876da7,8c387d13,3d0fba87,d784cfc2,1ef689e0,4c1d52da), -S(2b002a0c,280419dd,7911a522,28ea70a9,7ec2f9b6,db5316b6,7581a6b9,7354ba70,dade84b,34a23024,785c211b,73b006d,7ad1e3f9,e344c783,89d83eca,332e4734), -S(65c4d14d,f9a0853b,61429a40,50d2aa66,19f63bc7,12517118,784c0100,9d7ee08d,4cc1bc89,aac9c9b,931e9546,cac82cd9,6051b17c,991cbafa,efd52f44,e514241d), -S(df27b45e,7a49695c,8c38d85e,5eb7e9d2,8cbffd71,8520f681,1144087e,8a372c32,cd3d4c1,5ab586fa,ba4af68d,9bf04e13,31f7e5a3,95d14c67,e4ce598a,4077fc6), -S(268c1fc,eeb3d3dc,55daac92,23b9f511,418917b0,3d8a8210,8096ac34,35a820d4,d623750,3c42a02c,5a386e1a,f39694e9,844272b1,766ee986,6d4b67f1,81086fd1), -S(cbf09fd,f85c8ff9,3b1e800d,8e5901c,35728aaf,3d2824a2,bd09e1ae,c76fe1ba,3876982e,cacf4bc0,aa53fc48,6a98cc01,8ad33f67,e4ab0abf,dc8677cb,e9619556), -S(4126180c,88d7066c,8f7877c6,5e41b4e,c15f94da,e68d57ea,a2131b1b,6b9bd2bc,1bfa8de1,71947fed,a0c8ce3a,2cec0e5e,e307f7e1,dd3b7ca7,4f0e0682,c1c3d087), -S(bea8d718,159940f,dbcbe23a,5911dda3,c75b7931,cede87a1,5cb39de3,3f35c022,e723c23e,6bce4f27,fbc219d5,7d7ea196,e3ce1273,58e7eace,9d6b686f,efc35509), -S(2275f050,a18ed0b7,af54c69a,aabdc987,9eb9dd35,7211a964,23ad6e86,48624e3a,3c025a31,1a0ad11d,c9d930d0,7bd101fa,189415f7,c705abeb,bc585948,14f4d88a), -S(1925ef48,16c17466,f7e16c4a,7c6352cd,a12a2a15,9880a482,a06f8911,21b32fe5,30f83429,fb20aa48,ca4470bd,f90f9d6f,1660e583,5868e67,94ec16ff,e06fb81e), -S(18720528,a0612661,3ea23c29,356c4a2e,db74229a,79f008a3,1d6e1357,f873cbe2,ec54426d,a41525fd,d74e018d,dca72be9,e7a28000,2abe1a12,4a73ed4,21893106), -S(b8a6972f,c526acb3,4136cbb2,4850ad15,cd70a4d0,ed66a9c,8605b257,885c9d8f,e043953a,698e3225,a35271ad,2a173fdd,a1d37ef8,98c630,d02b80a0,cd729fd), -S(3839720f,b5c7c3d6,3a0ccf99,c0f951ee,b257d818,b3ef1e52,b530aa23,8ab06887,9d58a455,9e5268e,48292e9c,c6d78275,c733c2b5,b31326bc,4a0546d9,7d950529), -S(c204f868,e6632183,88024c76,4ef92286,68ba2867,bd301c88,1bf8e7b3,e6677e0a,490e59a9,4dd95482,8b386c0e,d6778f93,5a692d4c,74f6ed47,61aeb26c,4b1eb048), -S(dab95115,4aa1451e,95cc374d,6a6d6801,9778f54,9672c4ac,f9d16b39,ac2464ef,e32e5c8d,453be5b0,8c5ca506,b7875565,7f269a75,daa83a4e,f11e1266,f442d85), -S(ff283b71,7118eaba,52225bc0,ec0328c9,72e5c13,3ffab3b,801dded4,cae7e596,36d8b7e3,4dd684d7,e9b0bdf0,3d60304d,7d990a85,a955cf3,db681d03,b0af5d43), -S(30eb08e9,6f4de692,d2eddb8e,aac47b48,1f3406e2,235560e5,b23d0b9,f2ec4597,cf05cf0,26ed3094,37aed28c,2dbb6f9e,94f83333,15f00832,1286dead,1c931be4), -S(9a51edbb,e9146fca,d3c9580e,9ee34252,6b2d59b,c0531051,76bf3ec0,b86dae9a,94d549c6,2cc12e09,63c844cc,5dce24db,834fdc93,4c8b06e9,afc10f34,f08705c8), -S(ac1836ac,2f0d0158,650238f0,7b2ed1b,111bc56b,b176558f,7e018111,ee520c09,562e108a,a842608d,7c86eeca,f6f2ebd4,ad4d14cd,48c3d068,eb658c28,ee1aca36), -S(5c33360a,1bc8e85c,b0f78d66,8f6ba33e,4537e0f9,88525a1c,b186fdf,7ec65596,8f86a399,ba2038a,9faa311c,f2646ad,66de6c86,c3280d93,71d1bdd7,d9df698b), -S(40798759,c22a7b60,464fecd7,d506bec3,3614c895,c6d60d14,d1ef646b,38559793,506dcebb,aaa057a,433b0eb8,96d35070,a871e11d,216d6a42,19689167,b8588b9e), -S(36466772,ddf9865a,c6940a62,abbbeb24,3092f44c,58e3c052,9cc0d3ac,738d99cf,60ad37de,b41ee4dd,8cfc755d,e309157e,608b0a5b,ef385836,8c7c7dd1,cbed7075), -S(e6169ba7,ccc02fd,cfe63742,910a5e9d,3a3e1661,d8da60d8,32b86e9d,487108de,f29ff08b,afa4568a,4ba97709,477b086f,31685c1b,a6de5c1d,eba8269b,32c2cf41), -S(3bd8fc06,2fe50198,b77aeb1d,d42b9536,7fc172a4,f2528ffd,597799a6,4c0661b,c73a3d92,bf87cceb,f0020063,115aaaed,ecf414eb,f03179c1,86ef37bf,b452795a), -S(aac77264,829bfc44,6c2427ee,8b732a82,3480f11c,32cfce72,35b0b5b4,6749260f,c788928d,b75ea7ba,e216d8ae,91559d05,8597b9e6,3bc2fa6d,276c29f,50bcbe7a), -S(1dc5e0f4,ed05486,c883b07e,e78f1b96,49858bcb,6dd396fd,17a19dc9,a788a1c,ee4fc404,d662abb8,bf7122b6,c3a226fa,ef491513,49231623,a9d1a796,cc6233ff), -S(82a1f055,d885501f,114fc40b,123fbfd9,f45499fc,fb8720a3,c730fe75,ef1a8601,39fdb201,d30ae709,486fbc27,1603bb93,826ca4c1,395bd9a,112ea4e6,476ec20), -S(f8721b28,ea842788,863a1ff0,339ee75,7c508ec9,49e4f4f2,71d2a460,f0c14ed7,761ba386,5850303c,4449a3a3,44ebc7ec,bbf365a9,4688f254,558289fa,5b0715c), -S(9a8d123c,71377193,79d44740,af95d63f,ee954c28,55eb7aff,56707a1b,f0ac683c,3479784a,e683a3dc,c1238f37,5b6ef82a,487f6e5f,df487ba0,10477e45,49652d9b)}, -{S(49e7429b,e0d97bf9,3f17e9a8,53fedb6a,a9bc6edd,8e85f44b,9d2f1469,b2d3b178,ff9e5dfc,2746679e,9826039d,578bac31,c08fbaac,a075214c,73c50f,74568fff), -S(e872efd9,8147527d,7cf1ee62,e4980ce8,f1a7f561,a34ab662,1d503a7a,e98c6433,c8c62103,fe01e381,2553e68,5e7d221a,974cd4e9,f3247078,de37f5b0,1b9ccde6), -S(617f6235,8bb46c55,7608c7e9,ee198fcc,77b61c64,5e953cb7,419375ce,1e06fb58,fcd7edad,db70f22c,364cca9,9a792f53,c71474a8,707e2cbd,551d2626,6b373158), -S(86810c6f,f27fc69c,31d69ee8,4b616345,fc1526d7,9dde9dd3,5e1fe6af,d8fa0f55,718e736f,6c57643c,a8c0aeb8,b8bc6466,108e0149,db197a44,14f067a6,10ca5f84), -S(89aa4974,44ded8e2,4553001f,4a6247e8,bade925c,a35fda1f,38a86f84,b5b6c581,dba8df4b,9c9f02fe,e5a996fd,f77c870d,4e447410,de27d7fd,942e554d,fb1edecb), -S(9d89ff53,d85f9e10,6c78c86e,b114c12f,6852a457,d91aa28a,75f2afbb,e9191fde,7b1b4d70,5beb53a6,84a6f596,e6b22751,28b49be5,2ad37ca5,bed6a952,68880ce6), -S(b21de2d5,767f595e,5b873e39,9c02beda,571cf7ea,48236aba,fdd69729,14e4eb86,1cafd24b,2414958,9812ceb5,1d02d5a7,14f35c04,8a333f21,922e6baf,52942c7f), -S(d64c65fb,627b3d76,135ca1c3,ac8794e7,a62609b4,a71609ad,73972df6,4f75ca5a,6301fdba,278e846d,246e4a54,10108682,7e815fad,d30a58a1,3247779e,a397bbdf), -S(85248d03,5f4598a8,618eed84,92ef45ce,29ce24f7,4476cb9f,95168197,6fdf83fc,ddde2121,e31b1986,6ccf28cb,b1f01925,7ba53c8e,88eb3f3b,a8faef83,274de6f), -S(2ccb22df,abaaa33b,6da3d166,b2f85408,231edf40,fc9f7f89,24256378,7f10984f,35fd70be,fe7d802f,c65e02de,e5aa7ac3,67ca0b20,a5e3404d,a5e59eec,8c9cef5a), -S(3f5c061,fdd98ecf,ac9fdae0,3b527223,319a871c,c385a134,d1b7e35c,9bf5d42c,a1ddd10d,1789d24b,9fb96387,8789a472,96c757ca,99233b97,899bcfe8,e7760cca), -S(2e1525d,f6ae8b7a,84932980,1d4fa138,5fc07382,1a197e00,f9a8c235,68a75647,af7a996d,71ece94d,4384bcd8,60e947a1,cde4ac6f,408c31f8,cd67f0f4,a0807f6b), -S(247becc0,556b2585,9e426838,bd34dc9c,e194ac7f,b4ace971,9ae317a6,d87f5316,bc63b0b2,8051432b,4a6917b1,7afd8b46,d8fe2599,99c8f254,1e5ec22f,cadc8c9e), -S(3b39557b,8f9bdf90,76acd422,c46d1681,f7b3d29a,40108214,2035e3a2,8c204aa7,773f2a70,7e6288a7,9c3efb89,19eb100a,772fa946,c59f0bf8,6796b76c,1d7194c6), -S(d1bb4751,49254987,5e4bba5e,a0d2cfeb,703e149c,5ef6ef14,3f4df5d8,93199e7b,75d04702,60bbb309,73bcda42,808c4cf8,1f33dd89,e5412e7a,bbc6e722,7f0e4acb), -S(2324c1d6,96933334,b3023542,c506687d,8e7b6854,cf0b1ca4,902c8874,39a3a4ab,269c5c10,3731f1c2,419a5b53,566cfee5,a878c33b,c2aec368,b1b60a3c,bfce7776), -S(5896a34b,37869f15,7d19b9e0,cfc927b,7fe0ff91,a173f480,b371d18a,1d72c0ca,ea9331b9,b281b800,38edea52,1ff8a3e7,ab0b7e2,e431e9e,51cff269,cdab8c52), -S(2553f696,b32af6e2,1cc2089a,63439911,4d7b9d96,a883651a,c66f1d8d,1b74dccc,44c3915a,6212f827,3f02a0c2,b2de1e74,295b31ec,d2457da8,faddf543,c9244ffc), -S(131b4dac,25fea2f,715da576,3c175d97,657bfd68,21224136,5da967e9,c91b8ccf,30b40489,73a61cc1,91ec22fe,3429589f,13aad7cb,cbd533b7,2e692f75,f728b668), -S(59d0164f,e8150846,874f1658,3af49019,e300a2c,4807d18a,389f9b12,60585910,eb91680,a580a52,510ae709,1702abd5,6264181e,477c99de,6cfac0e,5533ea88), -S(691e86be,3a30e851,4286fa5,517d1fbf,c9a969ae,d7837e4d,78f6ca3c,e088f2f6,b8108fd7,e5bdaa7b,9d34f1ec,b5251705,76ef53bc,243b864,d20261a2,b9a6ff5f), -S(c68d096c,23f562a2,2ce91404,6b82a43b,22b1e7b2,63e58107,96128ab,a680ca71,c5eae54f,b59583be,509466d8,95ad482e,ef73b8da,808be571,d79402aa,26723774), -S(eeaacf5b,e4ec2817,1acdec98,7b5cb678,91666932,42b4c546,8debe163,430c20da,13e8c773,d867856b,af5b27bb,ad7adf86,a3e4826e,12fb2b9d,504e63c2,2b2460c8), -S(5e3d98ad,35e8c90f,131ea3af,2c99c45e,7ebe6eca,38d02120,c0876a8a,b4b8dbe8,a019fd63,9bb8f5dc,b4776131,398be36c,b3419a3b,27596462,1ecaad5,8a3ccac7), -S(1a43b7db,a042bd97,ea23ebfc,1384587f,4f66587b,1fb0f3d7,c32af9db,449ded4a,89667998,5946f126,34f00e5b,b7f0402d,ccbc8ced,a8389e83,872ad821,3bdc2f32), -S(2222292a,ed3f69bf,1ed2cd12,3272a7b2,b57b2b29,c9f756f6,9fdcabf1,1b67dd57,6f6671e7,d22b9cd5,d70a6490,46101054,f48a39a4,797964d,c4c2df99,a982b3a7), -S(5d5bc560,8ce7cb81,ed23304e,fce25034,8dfd497f,80dd3d9e,193641ef,9358a16a,b63c4202,be581677,ec334ddf,5855e39f,9f8f9544,f9f1171a,7823f0ce,61e2051c), -S(1a669fa7,2d96cf78,886bd7d1,36e7dfb9,8311b4f6,9067f47d,12830ecb,612ab969,e45ba9ee,f80c5a3b,179726e3,4b770860,552b0a6d,6ce02e70,529bb5d8,b2eafd9e), -S(acf341a7,add1eb1f,b5dffb5f,cafad928,b40ff6a1,fc0bdc67,9380690a,7daaafa6,69a7231e,ad015747,60b6fb6c,4a7eee54,ba348bb0,1d201d86,614b9397,89c00cdf), -S(f4238dfd,447cb48b,fb9f6678,11168126,446caf0f,3345ed,a31ba759,3115318e,5cfb371f,296c3a50,6d8569f3,60902baa,35e710d3,619c14f2,3564f6bf,99bf7149), -S(cc328f03,fc2b3590,3b8cdd05,514dc673,1446fd17,3349f0d7,a7a99da3,d2271847,883c8b2a,dca40796,68b0e472,c37ac41a,c91dc5b3,1aa84cd7,7f319828,3b72e2b1), -S(8e9bba4e,5fc87283,fb3a1b71,3b493127,e0c3e5e9,e3f2da4c,51ea3d98,5f3bd579,325df34f,dd64edd4,880a8ca4,5bde671b,af67a76e,f1a5a27b,abfb42e,c2b7d29a), -S(790ccd03,fad172c5,10af246a,a6e4a87c,56db01a4,55b4bf11,8670e5f6,54b0f816,de872f4,63083283,536d6943,ce8c67b6,6476cd8b,ce802fa5,e0817c5f,7ab684ff), -S(feca35f3,f030cc1,e0cf0a86,3a11d035,95b2ccf,7569dede,1393cdaa,a972d1dc,3fa066d0,565406d4,52aefc9d,ed45133b,48933d79,e0a25533,e9a24d98,f608818e), -S(c6b38388,cb66141d,777b3d50,c5224c63,94e587b7,9b62fee1,6fa12c9f,d7771d66,3b9647e9,2ab35770,e0116e36,27a31526,ae48a595,5d46b7e9,b27e5747,c066fd80), -S(db412fb6,3f925c6b,62ed566a,de8b4768,f3c0be38,dcd165eb,eac7a081,fdcc43d7,fc305dce,74f64672,2eb963b,792f312,4b5da5c0,ec8c47fc,254648e9,e562d2c9), -S(777f3e29,83e8511d,90ec346b,1cf6ecef,4539889a,c124da88,337dfc6e,222eb810,e0abd8b1,fb97b582,27beb723,3308a89a,9dd5cfa7,303d06e9,2c2fd427,ecf3741a), -S(a8391b7a,3c3e788e,724e373d,821074ea,b1768e16,f3cf7b63,80a0f9b1,7a1b8fde,f9feb354,ca45cf5,fa10eeea,1b4f4936,2e4ab403,622cb470,26f529c4,69f61d59), -S(1b86c4d4,40532e3,968ddcd6,2012e455,34ba0045,82409c74,add1797a,fca29640,2217842d,fcf1d171,b18a57c7,1ed6d329,4491a422,45e93958,570fbf81,9e6bcb41), -S(65e2a22b,779056bb,6f7ee1cc,efd63066,e5cb594,a9496d6a,772c4e18,f2cc7d48,8adb10e4,e984b024,b420ae65,d2dbc7db,2c12b4b5,65b7b81a,434d16cf,52926238), -S(c5090c8e,ee079598,57b8bd0c,fae29cdc,e00fef57,49204908,cee6a5ab,1d4fd970,fd7d0324,fe41fd86,3b103e61,a391ee36,167af582,e07c2cd4,649d31b,86e6c976), -S(be9e98cc,c6a230a,3e63ae7b,f619d6e6,b27253a3,5f26648c,8c3f68b4,e193b24c,d32895af,d8886f1b,9aabedc6,9a79fb9d,ca71471a,97728ca,1a55e701,e7d5bcd9), -S(2ff0dd75,8de2de40,1ba00665,c251f6f9,e342265c,4a400684,ceef256e,7d6305a0,adb558ad,61769a42,3dfb2d3c,c44da3d0,15a2aba9,ebb4e29e,70fa7ae,6307f4d8), -S(5dd98c43,caea001f,75846c88,1a39fc77,cdae9882,62cac6db,f6160aba,f00c8d51,2cd50bad,48c1a136,9a37762f,e56fec65,8a8a3e36,90813d50,6dd94fb7,de90858b), -S(18280710,c4d14765,b473cbf1,567dbee7,d53a127e,2aee22d3,198dc5de,43c3745f,1c8e417d,83b0540f,fe800ec7,1937f855,a1066dd8,4f7f6a06,9722ef2,e2ab4bbc), -S(7f3fc319,62da2c5f,9e90a8f,308f69b8,d17497ef,7216a5c7,228ce9a4,1b35bbae,ff754dc7,ca0d3148,96b18f27,c516fbb9,d4d21cf8,48a61f0e,4bf3cd60,f3b1e7d), -S(96809ebf,3d08f713,87271a1,762c9d9c,17355ce1,be770361,e69506ff,f9bcc41d,412737a9,3b3d1835,cb487c78,909ccc46,624f8335,46eb168e,bd8c4408,44bdb4ab), -S(9308499,72dcf389,d1200b32,6a60b0be,72609de2,2a66989d,17c97f3c,e61f2769,fd307c40,3c29d78,14f7627,b7575ae6,40bb77f4,89272d91,4111e1a,2c81abc1), -S(a66a4d1d,1e2bf54d,b359db03,a339c40,4e0cf102,88dfa02c,da95c158,74057754,16d1cf4e,79d00675,cf6dea6,7d8b6c2e,baf59eac,cba2bfb8,e30ac368,ef875d5c), -S(4571f513,f3b73e0f,a7ca0801,30d6fc0d,ae8fe66a,3caee9ca,807177e4,40256f28,8849186b,79fa99cf,49674ed9,9010bcda,7e2458bd,bf259bf0,30a3b655,61b88842), -S(28609798,fa0a5b48,f19bc873,aa62da70,85c8b9c,271b348f,ada1ac16,a0013bcf,9716c9a,493d484d,f6c588c1,aca279be,327e59f5,92a04f5a,840bb7aa,34b407d9), -S(77b7e18,e37c4a78,721b28f5,1e6cab87,9c4149d2,92fe9675,fcc22df4,8dfd6465,179a09b5,2733b042,f702d649,4b2742a7,ef82d050,efe0992,4584d6e5,328b14cd), -S(3c25bbdd,cfa0ab2c,cce10476,79adcd9d,bb63595e,8a7bb841,cea608b6,82c71f5c,7a01946c,b0e650e4,53dce44b,eba509cb,fdafb57e,f130e4d3,facf9ebd,6d7886e), -S(c22b973b,99f9b4bc,90fc9e0d,b2d73c7a,7f1051a8,d19c474a,3bf9aa43,3b0fe52f,e0253dde,dea6cd0,1507b251,176562cb,7f73c22b,b7d10015,61fbd723,4d5eac80), -S(18c7f4a8,3f7dec0a,76dae14,3a49ecc2,4d5fd4e6,5880ac51,627c86aa,60a8ce71,978901f2,3d35e23c,36dd34d9,cae08290,641163a2,c55c3028,11fc4120,4a35653d), -S(61147763,8a8c8924,2fc31730,2e0b1475,514025f8,dff26b1a,eb4b7f28,51cfa5c,23152003,f2d12370,84ba60fc,bd653aba,37c6b20c,18c85c62,b6ee196e,2c684d5), -S(1f025444,17e67747,ab9f81b8,7a960663,ef3effb0,259d1795,f25c0a4,96847292,8d7ed884,5cd4cb73,27d31f87,ed6f881,a0de6f51,768a5ddc,b404139e,d064fb4a), -S(90493828,a1633ce5,8f962a78,2256d6e2,949f39da,9a865dca,d84b3e46,408d7b3,4c6bd158,92330e5d,1d97cf27,fc8e8fdd,99f39bbd,7ede306b,336530fb,2d46e51), -S(ce69b160,287b6724,8a11db83,418a302a,daab31a3,9c45b5a4,a02643fa,21918461,617286d3,c223891d,c86a2bc9,5727aee7,3016650d,cacd6692,c4e24a7,69b86701), -S(f20ad3bb,1b962fac,3d9b2c08,df726791,706b3006,60f894ae,379a6c02,77e3e8c5,fc83a778,44e35741,81dbaf95,de91240e,879ccd42,5c28a389,a01943d6,a954a5fe), -S(fb535599,ca57b6b3,94205071,f1c07afb,ace578b2,5d571bc3,1f669a8c,2345d7fd,b25fea48,f9f36d15,feb50f75,2bfa03a7,bfbbbd7a,8de04ba9,eb58d6f9,e4a77c1a), -S(c3793655,c789792d,e43a07f9,61d774d0,34253bdb,31c3428a,8e941731,6cfe5565,748af2bc,9459b7a9,cefee955,81d3716f,2c08d5ef,f988ef1e,85a14290,3fdd72dc), -S(34304c83,9c33334d,216d1b4c,4808d14a,f5952d45,9b8cc1dd,5e64c6d3,30807110,82a01c14,95639827,8c9a0189,5b0d1e62,572b1ce3,565ea53e,9afa8d27,36b17c75), -S(8100ba8d,43d8cf1a,53f973fc,544804c4,4c2e96b5,9a877496,7a7c4f57,862a0fd7,675c2c52,5de39794,2c42babe,8a3b8e65,1c1aba24,f2da644e,a359a0a0,892e983f), -S(b3f979e4,487081d1,44161dbe,37ef2da4,de16b9d2,aee1ca13,9f018e36,d4ee64c9,bcdfdbb3,e6cec91f,3dd41871,9fae4213,be273923,a8daf8bf,919c0145,11a93969), -S(df0ddb93,e54b94e9,cc7460ee,f14f3512,86bc8f0d,7b928a6,294f8ba4,2577910c,b640541e,b5958814,e348d634,faf04a02,3a38235b,2250eefe,3145bb40,64abecb6), -S(54a2cfcc,eefbd58d,3924f305,2bfdcce7,508e7d82,e82cf354,9a4f0141,52cb717b,17d80293,d00c0d82,47013168,24e6138d,1cc77672,7a05ddcb,909642b4,afb88578), -S(fd384aff,fa1398bc,1881dfa0,d8b72dfc,3f6a4429,52d301d1,53d8bf3,705b828b,78dcfb76,f958da03,dfd7f6be,21f36e7c,59c7effd,c4e9a305,b934e9da,2b30f684), -S(bc7325b3,181554db,1e19f120,b6bfbe0c,8e4c003a,461ac2b0,83269e23,12d3395c,c101647c,9e2ccdc7,7ad89913,699b3b42,5850e30d,e52995ba,7985f73b,db6700eb), -S(e9ed80e3,9ed744b2,1a9aaaca,1ef4959f,64ab312c,d7cce151,cc6e383e,dad0185,ab101dc0,af3ef33f,9f0d6bd7,4ab4e938,25e999e3,4730a9ea,4ee67b2f,4f0cc790), -S(8f63fb71,67716f8a,749439f8,25f2ef87,3c4e3d09,6bbe06ae,2aa8bee3,faad24ce,76d6652e,b0845f33,42b48ac0,8b2d70a3,9c601e79,fad31dd5,6701d729,1331a5ae), -S(8ed0dda7,5d3a1e9c,8a497ccc,aa3579fd,ca5f8628,239a01ab,30abebad,fc6b3476,6f4a70a4,54d8c0f1,4bad62b5,b9aca8ab,846c4bea,565870cd,28f2437f,907269c2), -S(7c2d0104,3735fa17,5deac20a,5997c20f,748baa84,75f7492e,d4889de1,f6666f2,236d1659,54504475,7677240,efee6bbc,559b64b5,96358ea7,5dd1598,f3e7fa6d), -S(d37272e9,a4bc1bac,edfb2131,2f66fa5e,dafc83fc,39ce55b5,66d7b395,9aa937da,111fb684,50913dee,2c6a1a0a,7d7092ae,8db98713,90a87a41,4ea52793,839d7492), -S(db8375b3,c8c574ca,a8d66487,13467abd,793f75ab,47daf5d8,67f9018f,901684f7,7b23db42,56ae1546,31e11cb1,37c091d2,3ea5ead4,32f2038b,27e46571,75526e3c), -S(d077223f,149956aa,1dfea1f,35f1b237,f59809a,8bb0e78a,f9bd9520,34867886,71fce205,bd0b6728,766da89b,55168777,b2dbd672,ed8b391e,97e74d25,2ad028a4), -S(1deed30f,7b7c1a02,eba5d86e,eb1e055,9c776d85,e264e842,8489264e,4f68c907,a2050287,d41e8218,9044b3b1,bd1e4c6c,3baabd0d,370d6f2a,d39676a3,ef4c672a), -S(ab0be6cf,57a6da4b,f6ba7963,aeabd62,d2aebba9,acbfffd7,a18e2579,c137752f,7d6c1113,7535c914,dc58a5bf,a53a82ee,8493ac83,cb1839fb,badc6fd0,4575b70d), -S(3c72f165,69ef77ef,a32347fd,d14e7ee4,82206c3,1fd9bb9f,367fb84b,9abb5d06,3f45f3b5,d08ab10e,1785f62b,20f2efcf,2a6b104b,cea583de,89c791c8,e2f732cd), -S(b0697da5,6030bd3a,ec311758,fbc0f56d,90544123,261eb75c,644b37c3,2f888601,50652a49,a3b7a325,67211693,197f136b,f38102a6,954dc6e3,c8325303,2378d6be), -S(906ec5ce,4273798a,9350a79e,8d64970b,3209033f,9f7c56bc,75e2b3b6,6003d338,a9a0a4cd,7c512984,ee4d1da0,13476077,80c664c9,8e0a416d,856dc7de,5923c702), -S(64b6c18b,d207619b,35f76f3c,f36b14,7f3dd79f,c0147536,25d7566a,c0350a7f,4226dcfe,f3af6ef3,40b883c,7d4bd1cc,f9ead936,d1d42a1f,59e9754c,23ce3b92), -S(b1d0d916,e6908910,1e5262e9,9ab94a46,e0a1db5,45b9c572,3dd79212,4afb34fe,be9d6c09,3c1adafb,5e8cfc25,5328a31,aa7daf65,74afd3c3,f5256ae5,33f67570), -S(55fa9d6a,d8005a2c,8889df76,6b3bacc4,dee487ca,e65a036a,9b1839b8,2a0c3c3,cfb17a06,2a9edcc7,88f5ddd8,a0f12211,c21877d,80c9f30d,cde71a8,af3c10c1), -S(c231d95b,6144337e,b25cb40c,65d6601,cb4426d4,b6d7c6f9,9bfaad11,611a1854,b0b1b6e2,4bc88bb7,a277a3f3,bfa74b9,9b1eb5fa,a16f4a7,e40f9ae7,629ebb65), -S(b6053327,960dbcdf,f13842eb,c50cf09b,d60cb656,3e1553a1,7f7985ef,7486afd5,7f195737,9ed11b9d,7ea08068,c6dbf3b4,36eac86d,2efb81b2,99f89854,65766266), -S(8ea8e96f,619bac9,c6805dd6,e8115858,50b80cf,1cd7fb59,e9090316,c9190de3,92a305a6,8a1300fb,64eff4c9,fa781270,2a85a71e,bbbc7910,a90eeb87,8b50036c), -S(cd8fe341,ce670725,22bb9043,f3e31f31,3bab3052,d1316da9,7e96bebe,710bdd8f,3a3e6072,295bebd1,7da2462c,8ad8cb3a,2c170c35,9d2b96ed,d805f0c7,fcbb4ae4), -S(3fae13ae,cc9b0b32,37d94c65,f769c57a,6265f37c,7057295c,dfbf9086,b27cb599,5baae4b3,eea7ac21,4372748f,d8b6b9f6,24755dcd,b92cb3aa,63a5ba6,16b88a97), -S(7b9399a9,49077156,b32b9cbb,7bfd9416,c6468838,c87971a0,d9e221ca,c8e4cb25,504b1b97,c7f32154,f2e5664b,8c180f96,a51783e,c041fd2d,1e8fe493,26ccadbd), -S(8ab4d5e7,e112d259,30e2b4e,7ff4cf77,b2957e10,fa9fae5e,a2f80940,8200e511,6d0328a8,69bb9ac0,71b6a4d2,939fd4ad,34066606,1c3ffeba,1500f831,8aceda6d), -S(87acd768,24a369d1,210fc798,69368ad7,fb01dafd,f5ead811,f5d03169,ba270d4d,8b9b706f,15ebb721,9654eb04,f846d1f4,49a6979d,53dd03a8,214fc285,c86baaff), -S(f8179003,b5a2ba0c,ae5e7c33,90f99da8,a1ee813c,c5ca0d10,c8b849c1,42ed6ca8,20710e6c,7ff5e563,36855a43,a372fd00,e7bc7f97,d7d0ecd0,f7a63641,a96b2c8d), -S(2a2b3fe7,d2c78d9c,3d62a9b9,202ea02d,e422f14,23e300fc,70cd66e5,ddf9e69e,ed122cc4,96eb517b,fcc5b393,8fc97001,194c3c92,f612d062,95ac6f5a,7d69ca3e), -S(aa80d414,e1f91e31,73483761,a8c34490,202ef4af,4b39e6c8,8726fc29,d6f99a39,7632d7d1,e312af35,7ad03c90,a5ef9476,cdd8541a,ec03a0a1,b02d8ef2,fa380245), -S(2e6f7aa9,193b67e8,c00703bf,d7ddea0c,199c857d,90d03571,2b41ab0,6b074d98,ee2dd743,952c47ea,e03653a9,22bc1965,6783beb1,76afef17,36bbe2b4,3af27827), -S(d3ec2365,4346428f,d38153d5,eb6f82b3,409baee4,4bdc1c6c,27b198d9,b9403d23,da15f943,6b0ec0cd,c4769650,8da28a12,32409c80,4484b395,40ca3beb,437104ea), -S(54500eb9,33d4fbc8,d8f96e3e,dbc93e47,a91b799b,510fe73,61a507f,95973a65,277be627,356c7342,56b97d1a,87f733e2,10531732,6eff535f,6ffecf48,ce635e9b), -S(b3543a2f,b3898a9f,64eb2863,7bb3a33a,82631cd8,d1e41b22,7ffb268a,d6710bb9,383187d1,bf8afbb5,dba13d77,25327d40,5c363bf3,f8e4a13c,1e259b16,c7dd8e3e), -S(7614313a,176d1ddc,c28147e8,39d54d78,5a3f42e0,5d7d436a,3be2c1f6,b7ff3606,d540b46c,d87f555d,fa8dc374,8f1c997b,5d4c1c52,1675bb7c,4e3a2d15,8c1e70e5), -S(de1c503,447eae30,e3fb1ea,bcfd108a,cbfab506,d52bc997,b1c124f5,b610af17,3b7d0b8d,e4e1de4d,c17c00e,ac0727bf,f41b0730,2080ea3c,9c18bf85,9608423a), -S(47f2fee0,8bffc7fe,5e7fb417,70ea71c6,9a30308b,cea4ebc,6b2861bb,8aa94a41,31659afe,6a09292,da939f3a,fc89e4fb,3fd2f288,7b6efd49,ef1df90c,a48d6e3a), -S(824c2c6a,f7b9f3ff,a1dcb278,ae2bb3d4,d7112ae1,cb66d524,85c49cce,35382572,dd548e84,3ac82ee5,9004320a,db9f728b,dfa0bfa8,5544e55a,fe8518f4,a9350006), -S(af4482f1,1157be70,14eb09fc,80bc1857,43ee62bd,376f7df9,f7507df2,34f6881,ed2202dc,182c188,3dd864ee,77b51deb,f8d048d5,79993a77,3fec978b,c880fe6a), -S(386c5a63,2e56795,54c53c2f,824bdd3a,c8c22364,612efef5,13942da3,cb8cfef5,dfbc9df9,f1666b9c,54f02eef,d482e71e,c33aff7,3d8c1025,7ab17b19,57489127), -S(5cacf202,1b442903,333796b7,d9d1a8c0,a8a26b00,2ab5cb3a,b6c7a5cb,87ea778e,e522602e,41b4b90a,cd6c121,4959990a,d77f3f9b,87862949,2c4119b8,54e31cae), -S(3a783ed,2357399e,8cd3c67a,a2e1f321,9900f6af,368080a6,7f18f6fb,c5442e65,d23403f1,474ec6ac,5071d084,2a05a58f,826e4418,c19451b2,b60ba182,777290c2), -S(fb6d745f,a0bbb00e,f92026a9,f216d470,9090649d,5e761f37,6e4dd81e,51c84954,39cb6685,c0001c34,1d1d5523,55bfbf94,5a97446c,593e0518,baf039c2,368be918), -S(12d8154c,ed08bba9,d6be85ad,42305603,74c82c2d,bc06d80a,2199d3ca,e113eb96,90cb6ad,3b62fcdf,d0d2f3ee,9e89f7d8,cc314d6a,bb22025a,876f4001,21a3b4a5), -S(313583fd,66ee564,f546350f,22ab1324,fbba2319,ef69cc81,6c4e9e0,26b3367,dcda990f,b4f2de57,72d6fa51,36da8215,f66d189e,dc91a46d,d50ee2c2,3398d21b), -S(d27b50d5,30a6a777,3e81ea25,77682a21,a6055afc,4bf05d1e,f0c1e5ed,a432b6da,f2a125b1,abfbd478,74b1b1f9,5d03ac5f,24610d34,d8b2ca9b,90b30c63,33dc9214), -S(d78933bb,d228b9ba,9332a511,a6d4741e,a42ca4fb,2b79b6e7,1d4f34ed,66a57e5a,61520901,c37fe630,35a0a80f,86e63939,133ec632,41f3daed,e30af5ac,2f470778), -S(a737c959,b9f386eb,e227f5aa,6cd83868,7a911290,e8ecb6e8,d24a3f18,a1171965,6648f272,322bc673,f8d4b877,aedf25b7,dbd2bcf6,bcbf3fac,ebdcf2c9,a531b149), -S(9c2033cb,d00de2ca,f6a6280a,fbb615ca,f0513816,aa12d994,e0ec0c01,37b5025f,1efcb986,dd4d223a,1fc4a7be,58bc6f3a,76b02646,c23a0c7,7f174a06,c75928d7), -S(75b51376,1d2555ab,87027458,d6302f77,26434e84,ff7bb7f2,43b5a6a,7afde413,de0d1bfe,37af2be3,302fa887,ea87a678,264534e9,c065df8,b1f3e326,a47fcf4a), -S(79fc6858,8d117c83,8a8b8134,c8071d33,2245e6b3,6107e1d6,503c3436,cb00dc8d,78d45ba9,69490bc8,7ff05b6f,2e6f8be2,8700216b,db76b74f,dbf4577b,f6169914), -S(de006398,1d8914c5,8702699e,40486195,a6647110,2b6576b0,6879b41a,207b6bee,22ac0aef,4a565e1,f159f6cd,5e04c68a,22e80d1f,f946aea4,f5127fd5,8707dc78), -S(db714e6b,52d32de8,43cd649c,a39307e6,540c048b,e0542b19,cefad32c,a9b435ef,d1ea87b3,ab9acebf,3573625d,b2f58a73,fb3864ac,369ca451,49a42262,b1915101), -S(25fa0fb5,af46c0bc,75b4fe67,fdd53d51,2303219b,38448403,186c23d9,7f7b6242,45985834,a9766f8d,9ea9dc82,3e6d55c0,75393446,f38e3e39,9b2b7b9,d6b34f6f), -S(acaac641,852406f7,69e19429,b1820703,fcedb664,407a5cce,8d96c779,c1e51edc,1bcbb918,88be19aa,4f02c320,4f18effa,cfc9c376,ac3dde0f,a529123,7f715cb4), -S(3674eede,62af1a60,77df180e,260a2d02,db43b440,b1e7ac3c,4ff368d9,8c3d8ed2,d0a393d4,7f953a8,fad2e045,91c62914,14b7ef2,694cebee,6a1c84c1,b8e19888), -S(f630a661,e54045aa,54a86a9,386e0466,a7428967,43d483ee,72a87d5e,34b255d,4ae7305a,be851491,83b7dd6b,f9faa5a3,8c2812dc,96475a3,87906759,85feefa2), -S(6b191486,9e262afc,51a94712,72b4765,78337a00,3556aa96,52acb8dd,36f1b3d0,853d994f,f728cf33,85990b39,d8736d28,faa0e8b8,c8b7c5f1,693363fb,6c842ebd), -S(c9fdccb5,be931d35,5e3e4baa,816d6cfa,7af441f,2d6b653f,d0fc90bd,c7afc681,d2d0190e,c3360886,b2b3d3b0,d8e05211,84c8fa05,b912a105,374325d3,75548908), -S(5e16743,c976a908,fdf3bd1d,46735de9,f3446673,4af3bd3e,fc6382f0,d834b500,3a8b87d8,28d99eeb,351186aa,23b76376,682ab598,165d7f4a,1c40d8ec,62840a3c), -S(67858166,15c4c7d2,f1f2da88,1aec2147,d51ae770,ff2c7afe,e007e4ce,a4faf4b7,74404a26,5f0d41e4,6e1f3bdd,929f26c1,f80b229a,18d0d3d1,68e936ac,e3447266), -S(add083aa,fb71a217,6ef2b08e,8bd713da,27c5cef8,958f47e6,f90dfb6d,1c1bf122,b835f39f,27e27cf,28f45ceb,7c26cd60,691a89f8,650dff32,44374957,c412accc), -S(5b0c33c3,b669dafd,74c876f1,72357a12,8117c8b6,59dae930,fe2310f4,f96a5d2b,6aa36784,3a973f6b,6a03faa4,b1226950,f348b6fe,e19f1c48,f4dbcb6c,3a141618), -S(5ad43f2,62f9125b,55a419bf,e6ff2a04,4b09460f,fe6f1a26,d8ab6127,33d50301,701ee81,dfea7250,fab2f190,63df6120,ce47500c,debf7371,49772e84,cc53d54a), -S(8b78adfa,af8d7d08,d1c24e36,1623da1c,659dcf91,dc51922,2e689267,7277c05d,3a0cfce1,3c25700a,9b255606,f8123a00,ffbdc3f6,8eb3fa88,cfd3b478,e4ed0fc2), -S(679bd899,2dff3884,dc680a96,134290e9,3c66029b,922706e,54f3827a,383a9e17,2a70a1b1,948a3c01,f5b9e98d,54069cf9,b5a7dfe0,d7ce12cb,731b1fa,83a8d54a), -S(6b82fe,fee6d419,b66b29e1,88954e32,6c426a92,bb539779,1bf562f2,e06fa73f,918f66f0,10980d3e,b3d62bca,d37074aa,766bd449,cb07ac04,5ec1aa25,36b258bc), -S(a2174424,8125296,680f8187,493e18cf,41501fea,2d4de1c8,25b048c1,5ef63cde,2cc8623a,42f2c485,7832e98f,a0830c33,7b873166,7ec7d7d1,f560a0d,f2f35b36), -S(e5c0134b,90cf3791,28515ea7,4a1a8be1,1f35c98a,74322879,e6144f0c,7c74ca2d,2e6b7b85,ce459368,cb2e0cb3,a3291d2d,8f1fc947,2df3111,87ee6832,3477d908), -S(d44c099f,3388ffa5,6dbd0761,814cc46e,c0f0950a,869a4fcb,af3c0022,f3bf3618,a93be4ea,b5e7b6e1,b3085f3,85e348c6,aaefff99,2c6385d3,c6b941a5,306f3940), -S(85c3c19a,33794fae,f400eaba,ddb4f122,64888604,ad1096e3,8864a304,e2c07ec2,9100190,4f8c0961,50d300e7,897caf49,c3869abd,ca59c78b,504a78b,cc313d46), -S(8398d41a,77875b8d,ed646346,c5d24772,d1b13891,98c1a196,c6247c87,c7d7b8b7,4fdba1b5,9a2455e7,5fd6a3ef,83def66e,74361e5a,7a4e5143,7e4b198f,329db7aa), -S(eaa31564,d148b856,be888987,4f4b7442,38fb849d,988bfcc2,acee61a6,adedb93b,408065a,a219f9ff,395bf932,9b172642,181495f8,43900489,9423ebad,3dfd0382), -S(d2c6b904,a0ab1acc,a12e5e1,3e794364,cc7d3c25,b53b7bde,812fe296,6fb23626,85a2ee1,df9d42cc,f44e327d,62369563,74fe8e73,c32ba9bd,153d833d,6af8cff7), -S(f00854d7,742141b8,34d0c2fc,76b73993,a9f92f1f,256b1865,e9863989,cc5bab82,3346d28,63813a88,f874c5af,eabb768f,a5621abf,c57a9002,965a597e,1f7632bd), -S(207635fc,7364852d,15a13254,9f21196,262a1535,bf6782dc,3ff2dab3,e429f9b6,ffbab84f,ec05fc12,63c6083c,7192f825,987b6f4f,a1a9ec5b,e01e1374,652700c4), -S(3cb8abfd,a8a5556,15252acb,c538f91,a8dd2523,a3ef5805,23367641,904b0fd3,9715d371,20f86a86,b98980bf,4c9fbed0,cfdc2e8c,fa86d60e,9d35222d,dbbee8e8), -S(8dccc315,1f8cba9e,384cd23c,c941a3ba,5a11be94,3af2000b,18127932,9f276291,6de7b0a9,49487cb8,6adad7e9,bfb0df97,30f460e8,ad19dccb,7b7e9a79,57fc48b4), -S(4f0780b5,137b113b,b843e566,9bf5dc39,cfe82b2,d6f61d4a,76555b56,9c93cb6,14de9aa8,8e7d9cd7,61f7d08f,41c4c92,f57f6a7,266e878c,cf407bea,11b9719f), -S(d2005b24,71e3e622,1ca597ff,9b0a59b,7eeb558f,5103a39f,630f7a45,85500810,1bf3440a,477786ec,27dad5b4,5d219403,9cefd000,802d0419,df34eb32,cdda121d), -S(4b4d17f5,c1f6b85b,60a1e1e1,a9d1ebbc,dcdeb1a6,3d076dff,541950bc,23c347d1,f8ffeeec,e591cb04,21f97aa4,f016b59d,610fda19,34470b9c,67248011,8f07332c), -S(a4d4b2c,5cc168b0,a24f2b25,4710ebf0,d5f70a4d,569a966a,cb8e1f5,2c2b7beb,f2307744,f8634646,19723122,71c7275e,2a2ffa6a,3a227294,122c8786,b6941609), -S(2fd89831,52c10fd,faaab8e5,dfdcd737,b13a394f,4c924adb,b8aee90f,2bf5d1a1,89f91750,69d4f115,d3e3cb99,4f1c298b,9de9f312,74d18976,65238a84,dd5f92b1), -S(2b66ac34,a669780c,d779423c,17e7a26f,f19cef5c,49919fc3,76255ddb,62c5e2ca,13b2ef7e,c4fb5fc,93fa016f,381dea3b,cbaa9c90,193b3c96,c1a3d86f,e2bef8c9), -S(1a1dbca8,b710565b,152f3886,e4793f37,36095569,2e782f1d,3ea662bf,87305c27,5af8c42f,99d74980,baae2dac,a58c2d05,718a0abc,ce40ab54,565e7452,69d7f0dd), -S(5c85b30c,d201e36b,c6c9d70e,da01a999,3a4f24c8,ea0e03f8,226eae2c,877538df,15ed51d7,85ebe78a,bd000285,b64685e7,98bfa397,40ae17b7,f1ddba98,a90ed521), -S(dc5a2996,fcbf99df,257b14f0,658725ec,184f3411,9271fe9b,9da19708,6aa487de,45ca8e07,e82cd9de,8dbbe106,1ade8c62,846cdbcf,85ed5b13,e51d1680,4b1e3a0), -S(ebcb525c,747d5ed8,d877f3e0,a632fd7b,88f7f894,84e16ddf,6cd8ef6b,f5925dcb,64a4b31f,50fb389f,cc92640d,c7aabfa4,189e46dd,15e7308c,8d7c551f,789aa33d), -S(a63c01fd,826ef945,43243395,2344af73,9bc5ea53,3b5e2e6c,2fe64b76,58f89238,867fcca3,7e861b09,4ef2f151,75ac0101,36cead9f,67b00d09,a50a94ad,453a1d69), -S(fbf5906e,e1e05f1b,850cfa93,34b3b230,391fcf13,94791696,fc63d6b0,71c29c58,61290a35,410dbe52,f64b4b4f,a5dba1a3,23c98bdd,f6dd7957,383bf40e,ece088ac), -S(b9d3198d,ed13334e,1d43b7a,e909713d,af368d88,a62db5b4,1552ad31,7325e249,4ce0e6b,72358d03,4375c5d4,633ee51c,ff9e453a,4ad7e88,9dde7d51,83adfee1), -S(b928d409,365d80a8,e7b3e61b,1cc2976d,c1db6158,a31be035,d1e9a8a8,66e976fc,ba4ef615,81b4f698,f653dddf,5956fd95,f6a55cc2,618c0d39,c3c789f4,61be8e7c), -S(1b4fcf81,5be7ac87,60582a9b,39b62317,4c72e043,48dc6f17,caa6fb5c,9dd46d1e,c845031a,df207d9e,3e006d11,880f5c82,50d225ca,8dd4d3c7,ed0ab170,5bea9b4e), -S(7f33cba5,c5391f36,b5d1f186,50220df5,cb79ee4e,cd1ef5b8,2b2d8280,394b7d68,91025af3,68487978,1d88dd42,f4746c5f,7cda4733,141c003f,ee4fb1fd,8523141b), -S(986de6,fbcab206,264c34ad,c38a397a,384bc794,b03e57c4,e3f0d253,fc94c3a0,b148492,16a7623d,d23d76f3,9cd22603,a88f81f0,a2351dbe,b825d1c1,6d46ad81), -S(f9d3cb99,a0ace3dd,65eb373d,24b3c05e,eb995a5b,65891ef1,3dcac23c,4784f224,3f94c6cc,95fd7fe,63c97138,90c031dc,c9361fc0,6ec5caf8,2e392c1d,b6fa6058), -S(44b5b53c,9da33493,bf040994,d195f45d,c9be8284,4d12315,4b782a98,b45383fd,7dc44fd,ff6acc88,9536ff19,4d28d892,d1e1fe0d,5d59860e,b58e6283,88a0fe8), -S(90db2c94,39ec0476,576de7fc,e6efd4d9,4cdc5052,56cf030d,ccba218a,3b3037fc,3f243dd4,4b9e8733,1548c213,9728de99,b520d31c,876dcc8d,ddb218e0,835e7f8a), -S(2369f76c,240f538e,ea7fe150,3c753bd,b41f031,5f703d3f,236745b7,ffa1f7ce,df31a9d0,dbda6762,ba904f41,3f46ce84,419a6734,56c6013b,939050b6,5d4bd15d), -S(67ded26c,dd7da1e6,d8373706,7adffda3,3d9fea3,8a7bfb87,5ba7d6f5,96ba65e5,73c5c136,d53162fe,35e5a3de,4190a79e,cc181f23,b5367ba,7d237903,890f540c), -S(3bebf79c,fa918ec9,2fda707f,800af057,13fe0ec3,efc1edbf,b9fd5917,1bee00e9,39783b0,bcae56a0,33e73001,e1fb24c8,c708c74a,fcb42664,53962973,d361f8b), -S(31cf34dd,edfeb1d9,674a2de5,11d7177f,e054181,34da2b0e,dd955c52,67eb605,659dd41,89c1c195,6dd21c44,bb37c910,df2ee864,aa5a2a61,a08a9349,34ccf9b0), -S(86439b3c,3d830a79,1f5cdde0,35821955,2eb0772,f5323278,b8baea2d,5afdec0e,8e5b5552,e244a208,6d5fc389,4965e367,77395e4c,d88b0c6c,ed513dbb,58836e0d), -S(a7041438,d237f957,cd3423d4,70bf34fc,152d1823,c389e5d1,d700a5b6,34101b4,aef966f8,c9acd2f1,625bfd1a,712d135d,c8e0f270,3fde3ee0,3c6d274b,101c26c9), -S(8c29a32b,b154eebb,a17eea82,9605b681,4f728f1e,7be0053f,139f6599,d2a6b023,a9813842,6c2ad3fc,e157de97,69caf8cb,f2db0618,b5f307c,200414c8,2fb4608c), -S(ede37b46,82448954,d786bbb4,874a61d8,dfd38de4,a7968876,c0585cfd,95ee04ce,3b9bb92f,a8e8b6ed,b30cd1cc,5225a80a,53fe738c,cbf6c2fb,4afdd6ac,7a10cf53), -S(e5cb4478,e91d2fd6,26950da6,53445dcb,5d591ea7,5915e637,3d82f963,f3ea6a2e,dda0bf97,cba5a77a,3051a09c,7d29f91a,3b8b1b3,c1649ef5,23c692ba,18cc8906), -S(e85f3a7e,cfbefff0,f3ad866b,3838208b,81d8c4e1,dd2fc809,8149f56d,e4c90aec,732a7905,ff3ffe33,d05738b6,1e6c0f57,4c1eccf8,e883a75c,76e50079,b00a9799), -S(79029c02,c2b0322f,2bf76cac,4b5f8356,4ea652c9,3ffeac8f,7f7882b,e772cb80,3e630bc3,cbf85752,f90b6312,4b9bebfa,612337d5,efc8a0a3,157dc666,27020f62), -S(9b827836,a74cdfe2,3dd8adba,542e13a5,c8e413a,cbe32695,b77fb140,8ce640b3,66e4c425,7d99f9cf,d9d6a18c,fd40e7c3,9fd37363,b0228206,f3ecb699,d6b2f2be), -S(bba7b2b7,facbfe34,b945ac0b,9d609b0f,3f0adbc3,eecf16ca,ac54484,dd564c6a,3619817a,1304fe3c,48272292,5d911d7c,ca33980a,33ddf647,19eb63e4,b7a1e6ce), -S(579c9681,cc98eda3,684b5d4,7f1ee3c4,5f8e7ace,c620509b,56f9e116,4bc905a8,48bc6bf5,90bc2d33,937df32e,a082102a,2f19a6cf,6ebf0985,6acc53cd,b2933d37), -S(23b30759,4b171e8f,ff9de455,f5eea514,e4c49e82,6ce3bbf7,6d3e750d,94c4fb8a,df57c655,45cac843,6db4dfba,abfac03e,a0489ead,6fe4dcbd,d12c2d2,21d8df8b), -S(8b4de9d4,f5c53178,aef16a7d,73429825,9e87e3e2,7a803197,98793d23,4c4c29da,a66d90c4,9d441721,3a399ac8,2c84baf2,67569201,3782a5ff,b2cf55a5,7deba029), -S(396fe929,2dbf359,ad3dfdb9,58e7337b,fe8791c4,d2ab6dbc,35d8c436,c30eea03,69fbad37,4fa06b57,9f67d8fb,48a6f09,99b77ba8,5fa7b6eb,96ce1028,44fc5371), -S(56acaed9,34f376d2,d036b7b4,7749829b,f7d32a78,bc6b419a,c25b33f6,808d94de,aae2c24d,8569060a,4398c5a5,a6173cd0,dcfa15e4,49642720,32785ff9,f0a7c164), -S(18ccd734,cfdeac35,1dbc13d7,2cd095a0,49a7c6c,e3fd781c,ed552e71,5ce14b0c,79cbb2d0,82272c7b,9af52227,4354c2fd,80a4c2df,5b434bc8,4c1e99c,f45a1e61), -S(73f91ae9,f75ee99a,227785e6,7ee3e1f0,384fc259,6a95d8e3,2436ffed,17f81c6d,f410e115,f57f618f,225caab8,388c97c6,46a37aeb,f184bf2e,408bae0d,ab2d475f), -S(f0216cb6,e9868a3a,cc859cd2,fee969f,b35fccdb,1754ea51,52995dc2,1d9b318a,e3a9a102,719d8398,610498ef,b5dcbb0,27fb3509,af587b9c,2ab5b5f6,35e2ef1d), -S(8c92a0ec,935d03d7,5395de25,3c2c9e15,7026a8d0,ae59a2b1,16d175d7,f70a8b46,8a9b5351,f7a8a20a,e159fa6f,afd58419,bd0e9dc0,def54f15,aa12abfa,65eb73c5), -S(be3bdb59,6c9ec252,5d7c23bc,788ea0d2,7f4c51b0,69182cfe,c095a13a,20b650ed,932c016a,7f006ec8,b73a6d7c,1ad1f2b,ce72706e,bd7e8713,e8a8d093,3586c9bc), -S(24fe525b,362650cd,ed8dee61,7ab4fa69,b06ecac3,fbe31947,4dbd982c,52ad2260,d9c484a8,e7aa329d,136dcd4b,612e0768,3796dfc2,a544a237,73548b9,be96d555), -S(f3a2b68a,8d16b9b1,20067bc0,6ee2f0eb,bab70ac,d6abe6b5,b12ce933,edfb2ff,a3abec92,539974c2,c2217584,2b9ec9a,3bfd4b3a,21c64a6e,ac3f608f,6bfb45aa), -S(fc9a67fe,9cb9622e,a9f20b68,3b19f623,5e12ed25,4a1371b8,196e0629,e43eaaa2,8e3329ac,2191732a,45afe600,43c6c5fb,ce9283fe,695d4f3c,9035ea60,2ceab399), -S(c539c35c,9bf0bd06,af690154,88e4eebd,bb766ef4,737c176b,3bd412d0,f933554,caeddecf,f0fd023a,dfc17791,95f18c1e,bea4bc70,b98eb85,405d5739,d5871906), -S(15871ace,89c88dc9,1d1bf56a,eb4fba,8f0fdb6f,df107705,65ef33d6,345c8ce4,70577775,4dcb9ec3,4765ad82,2070a26c,53c5fc5b,d3a6d8c5,1fe9eb83,635bb9fc), -S(1087625f,6eeca00a,fb9f7bf5,f4b94515,2316693a,ec8fff6f,57217e6,38804398,24b6cd00,e9ad027b,386afca3,44bf48a4,ad587342,2d3d24a0,5eb17150,bdc1a929), -S(98d7bcbe,6aaf808e,3909c417,66e54495,236e1724,6372f821,ea07fd82,686c0d07,b911aaec,47b9e901,4c990d08,e094d124,d8fcff77,f594244c,899a736b,e0661d89), -S(865989f9,35c9b044,7ed36d43,90ee5bb8,6403ef0e,67c3fb9c,eca1f2a2,f7e170c0,533cc475,ed1df473,30a032f,1db8ea42,d6b0fcff,f53007fb,cd41cda5,cf06cc1e), -S(b67f49bd,f912c892,9b26c35f,bfe2535c,830e8e4d,6c62930a,aa8527c6,1ef9cf14,151ef7a9,c08909a7,5daa0d85,e593c7a9,501e492,dbc41800,bf03fcf3,5c12c427), -S(b1ed1735,9a5f07a2,568d9740,3bb402ed,b313bbec,7d037bb0,cbaa2ed3,eacbd50c,5635c19c,1932696d,577a7bbd,411cff9,81bb057e,10436fc,91000bed,b638afa1), -S(6d268375,ec82b57e,7f8499fc,bda8f952,ff6cb4ee,a0f7785b,a8ff6610,84963c71,6b019ac4,d809bf4,1ebd90f5,4d8de537,6171702d,da3e4e21,b2301014,87379b95), -S(8a17346a,c18e4d6e,677db3fe,5df942cc,ddc66882,e39002dc,5815ea02,1ca5c332,c457ecbb,add867b8,70b28f7e,b27bd804,812c362d,1e94d89d,741abe02,59990928), -S(4dbaef58,9616daa4,4a8f892a,e48ac0e5,135b7385,25178135,a233af40,fbe506,90df93c3,9badbe3b,6eb28cd0,8120df1a,442429ca,d8d80108,af4bbf19,2d37b9cb), -S(cb18b241,a5d1bd30,361bf7c2,beb4a14d,3909be2d,dc7c62,d44e35c2,298b5a96,3c0a09a5,d96cd4b2,a1d15a13,341d455f,c04e3008,87c4ea96,d8f71c7f,ed84cacd), -S(cc463ae6,a1114d8c,107f543a,ef50bb07,cfcb222a,de5920ca,58ccaa19,750eb90d,31b54fa1,d115415a,b7931343,a8143a7c,cf2877d3,3d3d1f44,464163b5,c61c77c5), -S(8a0c1391,777b772a,c90d4d50,6f0a398a,45b2fc65,331a67c9,dc39aecd,835bcee5,b8d2bc1b,21248b66,2acd6e9e,1ae802f5,34558837,7da057f7,ad732684,79e4720e), -S(6fc3ccb3,acdff113,69caa83f,e304303,4a9dd77d,fcfa6c25,876cd2cf,75a5d7fc,5d0d64fd,d8f23aa3,5a7b9601,fa6d6deb,bdba27c7,2f227cd6,c4d3889e,49b15379), -S(3b10fd6a,125c3a47,2315bdc5,9686cd80,5b221012,65726bb0,64c974e,e74b778f,20bf9e4,521abdaa,347fb4a,a98a70f,303842d8,4f3e04c6,92d798ee,be97313f), -S(cd78581,a4707b5b,710bb827,b3d9c1d1,ee4a595d,29f90d50,607e3970,620ef0c2,26f5320f,2b512c50,e773a94f,3efba18a,cf343c5d,553f9ffe,67b39cbb,7f0b8831), -S(9bfce83d,b9e2cc9,969d17aa,eba0e037,22cfdaa2,a4175180,ed8d8ce3,7a7deb5d,2d2cbbf3,fc83d702,2d39191f,42eb42a8,555c3884,21add05a,18bb4376,4652477), -S(124e59c,53bf8d0b,a4189a1c,5de61726,3f6739dd,323ba104,892b505e,d8248d31,92d050a6,3e83521c,4b08061d,aa635990,46d52c4e,67c014c,5e33d7d,a6e01942), -S(20948e19,7a26173a,44011c9e,41676cd,661acb99,45a9e4ca,c0dd42c4,6fea02e1,8138a593,be21c5c2,472a37f0,5f2e9151,31bf249e,c6128dff,d218307e,4b661d48), -S(50726fe5,fad5628b,441bbed8,5347af3e,506cc7d3,43d7f0cb,213d63a,aa54365c,47b065b3,280c1f8f,585e05c,dc9f8b28,73f79479,b95a1bd4,c0a80469,eba92c48), -S(fad9bfdf,550fc926,da189531,91111112,a4120e56,db459577,aeea7e13,c2073f2e,a87e89e3,8d49513b,23aec5cc,a251098e,c6216ae8,96257461,2a7b4e08,470d680c), -S(66fe56d1,7395a7b3,b016c8b0,e5cdafef,d9e652cb,526374e,1f7000ea,b956f33c,ccabda97,a6b6b288,54efefa1,ff17f621,88b7cbc7,c3d363b3,25c31235,ecd26292), -S(8273997,5b5cbb89,e4246a1d,6428bdfd,14cf068a,6394a31c,a5cad01e,de3f6da,54d7090a,afe68aee,95a2f829,9d324bcd,9a1c4e16,17370b1f,5b940cbe,845a5013), -S(dc038ef1,5db1cab5,25660c8c,11afd35f,9423d230,2bf5b002,5df30400,a84907b9,cff2179a,904e5f81,e996700d,e64a548f,6ebd7b06,bc12a6cd,2ed74af8,9cabad6e), -S(fd501f6d,fa76dfc5,8da70f14,32eb1053,a5f82fc2,70ed661b,fea83798,acf02483,c04b3038,c2f4916b,178cd919,e953853,77d7555a,a7e3695b,1cc8fe89,d5d001b5), -S(c33af33b,fd47af39,ff687775,aa5e6ead,430821bb,695ba499,e4433a2a,d6190ed4,18555539,664c445b,6d317892,1af772d,7ae10c15,62d1ddde,91f47b5e,a1d4898b), -S(3e1835b6,34c53347,5fd5b032,334dc281,97068930,fb7bdedb,f8988b64,acddd3dd,2fcb5d65,940e235b,f8e1de7b,6aedd7d0,d2061181,dfbcd049,85df1505,a8c61db2), -S(c3b0ff1c,6a0ea466,357ebb78,f9ad0335,2b964b19,8e30e1c7,5b37bfc9,87e0061c,3ddd3d1e,7d97ee9e,748637ea,d8ec4987,d06b1f11,cf9ee9bf,12e85965,8574a95c), -S(1b690634,fa027e38,cabd8f87,3733476e,4f8e4bb0,543c5f6b,88575103,b51f29b9,3fede999,23be0482,caeb15c6,c7f2a00b,92b92a97,e66f2db,2c5d76d9,aa58210c), -S(4f661a50,fed5fbb4,ef8a1888,f1fbd3a8,b35b38fa,91d8601,80a3a70f,17f4fa8e,80e5e5c,7d41736d,29f94284,ddf06611,2cbbd024,60723497,9540c1aa,26232e59), -S(4a251861,333df3be,7b5852a0,f8eed900,dc58d2a7,3cb6d2d7,d45ac506,55126096,7b0734e,be6edf25,b9b4845d,8a93b0be,4f9958e1,2be61a3d,1513dd71,1004361c), -S(ff1c9a62,10360484,6bf46453,246be39d,7f595da8,dc17c86f,8c441b28,64b99d6a,7f01a489,404fa78c,aca02b7,f12a654,5692c8f4,fb787e4c,6e18a9e5,8e1be696), -S(4df0bff,651a53e9,30f631a0,3b6c170,ecce67a3,f92ed930,79e92099,46994deb,c79c834,33a1e795,f4334535,67e122de,bc81c4d,ab48a11e,a64af4de,4c6ebcd4), -S(2dfcd43c,a0000881,15845e7c,966004ea,bd4c909d,fb725642,18bf28d2,d66610b0,6ea9912b,e3232c75,c25b8272,820db699,bad9c292,8d2fa03b,c37dadb5,75a78b1e), -S(2cc759bf,7caff909,4abb456f,f8cb214d,f9353f97,e4f802f0,879b7ded,69eab4db,76ef9968,553c505e,697e5981,1f85a6bb,4d41418c,4b3b5dda,a024d69e,3a2a66e5), -S(a72077e5,8d73d653,66cd0f70,fe79c8ed,e9ef34a1,3e03fa67,70ae3f99,3210403b,8638634,217b7929,f8bcdfe6,4a64c053,5cd1640b,cadd7a2c,e6c5b880,90de01a8), -S(9c598d95,41c3ef74,73c94eab,20021f56,11ce40a2,34936d66,3130f788,14136c47,49702707,51df2f9b,d41b1ccb,1ca90f65,1ee65f69,75262725,b6962c56,dcdf2c4d), -S(5704f6d6,463ed861,cb25dde,343beb26,6557e3d0,7ef35c9e,cc435efd,f880622b,6d605d31,402c9bd0,9360f2d1,1a4f7a36,ddb8ee7d,543932c3,d546162c,cb0e4660), -S(d47b07dd,58962226,fdd1ec80,4a484496,ae3dba3e,41e18f9b,8e48ff60,4b00d727,26e1094b,c62614ba,1aa4df72,f3486975,6b8eafc7,b04a3770,22865b3c,a52028c1), -S(3971f023,44b7b268,754180f4,fa30d0ed,6596d59c,eb806e0f,9186c9b5,54e62b09,1895d58a,c951971,39d03562,6676fdf,cc53dfc0,317d976e,b0afb990,cc1b91f), -S(4b2be90c,e3e3a804,c469fd40,57bcfff6,6e9a220e,713455f2,ce4ee3d3,3cfa73c0,c0e2b79a,cf348a04,6f301f71,bba98de3,b9d1d8d7,ee16937d,e11e49e3,67c3cfd2), -S(2138e37a,29bbb1ba,2f051d4c,984d36a0,7531aeef,63fea098,417db4bc,241a180f,2e243bd0,69c0f7e7,f7319bfd,bbac12de,e03cf686,c97eefa6,dd58f17,c747bab2), -S(bf7bdaf,15838ccb,21a9ac7,3fd8d2c6,2013a163,85b583c,4c458db7,f8ba787a,8481d283,c1c4bac9,87ddd181,b12a2e79,a60e51a,2323c981,efc7cf51,a1768168), -S(e000b589,51237195,b81ea4ec,a4cdcb3f,b509eb80,4322ac0b,69feda94,e78fdb1a,cb527a4a,39a9c03,3dc01d1,d4221deb,b89b1126,8594dc82,fa5faf80,e538783b), -S(dbb2947c,2602e2ad,19ae7079,b6b9fbdc,59bac7dd,1e865f8f,3c802ec9,ed951414,9f646e9a,9f069a54,c1f3e88d,e8fef48d,9c6860a1,afec56be,46ac8943,d83e3cbf), -S(40bab32e,d118cc1a,bda71e7c,828d1ca7,aac8087,b720766c,409f4d78,e711dda9,ea7cd00e,c553e8c,56c9f992,b16a9830,a4ac30e5,cdae357b,148bb413,9e2b1d3e), -S(b2860f17,55e3341,eb6bbf11,a043b6bc,bf70472f,26b2d276,e9c30516,9c478b9a,bf7cc672,94909583,ac6147f6,2c9a3a64,8249513a,9f5c42eb,d0701bba,24b9b1d3), -S(d6e4a042,7f254b5,f2449539,9d6c0ed3,a741022f,f7fcf819,8a7ac04a,3e0183d6,ab1127d5,17900200,4cce6a56,7dc4b9a9,c88518c6,a8e03d4e,daabad76,f86c7be0), -S(57c70171,aaae00e5,e98dee16,e0d74df,82b05fda,8a01db96,67ce4d8c,ddfa9aa9,f4306dc3,1b82356d,8875244d,a713b6da,9fcc95cd,6c861ac1,1df62e6f,c6469e32), -S(e95ec894,230825f3,83442633,8cfef200,69ecfeb1,41c4bfc6,d0d6f2dd,216f36ad,e1f9012d,ec6f62bf,a1b5df85,c4ce2572,bd5ffb4,b8bd28d8,bf982833,e2d50eb3), -S(99d32dde,ddeec538,c8189f02,40bb4d44,cfbee72f,b3d42f9d,319dd7b6,97481451,75d2e691,ca7706e2,9d8c3686,d3fb1ca1,5a505a11,7662a2ed,347fc0a1,8531ab77), -S(be2418b9,b2c44233,b4d97d43,87085579,9219604b,f1a689fa,54523d2a,85677b93,69046a2b,8c329e27,cbbf7b9,d31f2009,9f5aa01,fd0b3905,988f2299,1d73fe99), -S(a88ef29a,67ddd120,c5d43d52,9d270c64,16750835,84a5dcc7,2f05be84,7c3b9b3e,902b663,4466410e,fd0d2251,ae10edfe,72a85d32,6d6a638c,122d7160,49c6881b), -S(95ea7c70,c4d0afc7,b31826e,c6dda0e1,491181ae,8970cf24,b99a8f41,bd428b3e,6bbd0bdf,d884903c,63a2a1c,df73f6e0,6ed335ae,53c64cc5,fc775666,6d8a15ad), -S(3341585e,671b8891,2d0b2944,334649af,a0bdebce,cd445e40,6e416ffe,f2cdc88f,bb17510c,f427e741,5b36269f,c702fbc7,42e36c20,95b69fce,bd31b7ba,fec345d4), -S(34e362c3,7c2c7b59,c972eb54,ab315cd3,da472933,34a305c7,d35c754c,3a440045,5e5d2940,3119cbd0,685f1cb0,b1e446a8,ba9ad625,8234ea7c,8652f971,c53d1b44), -S(f8c6c1c6,16b8bb82,c8d77244,86e10cfa,105e9a01,675da3c9,8e3936ee,ee01cc69,dbbe7cff,73929f21,4bf4fbd8,aba3f18e,461c4855,a204a7f6,319ffcf4,2437fbc5), -S(f4f98cf5,2be30eae,fd2ab1a6,dbfdba9f,8676cc6c,8b32a6c8,a53b10ef,dddc3051,77fed97,782ade72,bd5e41e8,c4b376f6,fde76267,b0a0cc45,a56e3f0f,ce6b2f03), -S(8b642ee4,8487a3fd,2d983039,48cd523,6456f3c5,f9d8f4e6,4f0af631,96b47d8d,22ecdb21,2e8ac0db,bf74c4b3,685339d7,e417686e,1c5337e4,872db54e,aed524c4), -S(5f6923ee,efc718e3,25d22dc,445e04ad,dc460268,58349b42,528c0078,f2a725fb,4ead0dc7,e697cc39,35d46533,73a21016,1a00ed11,273c3ba6,9c5f45a1,a4f38198), -S(1da37bdc,abdce508,9dc3aa72,2c93fb5f,64dcaec7,759064f7,82926829,b91ee1fd,1ecbb28e,f4f4b980,d92db2d3,c78919c9,e762dd5a,ae449d58,7105d84e,41f686dd), -S(ff3be7a2,cb1cf4e9,7b276ef0,235a7eec,addee879,78147bea,120e8ae1,bf888cfe,10a7bae3,da012eea,89b0cea,8deb02ba,1515ec2b,e0b83d05,a4fc152a,8b6e8371), -S(1658579f,72067096,947817e8,e9c22574,8495eb1b,75bb3729,88d45b93,d90531fc,d4538ab,19420b47,3ee869c1,cd1fecbe,f1a8ce73,871a7195,2319bad6,2ae450c), -S(96edfb55,bdc70246,21e1b92c,d2e85b07,b0ba9244,adcb5dae,f82f7afa,a97956c2,3666a36,1c8d1b06,e053ba0c,4a76dc88,2e3fe10c,e741defd,48ebee6d,4877cbbb), -S(4b4d282e,853b581e,55ec4271,e78c2cb9,ebf1cab1,8c15bdc2,2cdb05f1,7f8e44ad,2be45bac,a3257d2d,ab1a5e66,216f421a,2339eea6,89123e15,2bf7b010,e349ee2c), -S(fa12b099,eef9acd5,4c1c6224,117bfb60,12d5a208,553ca232,e030056d,1a141e17,40ed149e,d62259f5,fc98142b,9753503,ab7e9736,5238d4ea,c80b6859,52bba875), -S(c6243386,53084c9d,7bbf3b74,39f0b21a,ad2e5233,17259d9d,af2de00,1d4605ad,3b5376e7,1f08cd2d,3d319056,94608618,960e73fc,d27625a4,92613667,caacf3a)}, -{S(9a1db7bf,53241ed1,df8d3ea0,f70c0b26,76b43ebc,bcb4622a,9704b0a,3067400a,e3638ad2,95740505,455b2e1e,d495c57a,54ed8e8f,c647a6b9,c69b7dd0,715cef52), -S(90bfdcaa,eda30aca,f86d6eab,82407089,3746efbd,62f4a400,86e0589a,f3ea5cc3,9400154,63e05bef,5a4e2c2b,8681a1aa,95042864,447c7bcc,5ba2576a,eae911b7), -S(4666582a,2265fc0,643b1f3e,d003ab1a,d4567a1c,239e82d7,15a8f6c8,23616100,d7efadc1,2e71ed16,cebcd191,f34a70cf,eee6a7b0,dfa87724,dea4e464,ce50c9bc), -S(a5338432,7502bcf1,4bb11dc0,33e544bb,7aec0e46,f40145c4,db65cc46,203d969e,b228140a,7f3fcf9d,fe400a28,90200ef2,6e5f3c78,989406cc,b9fd31e2,e9d54049), -S(d6da1a9c,c1d81eb,9dc9a048,9acb4b74,d119dd52,684f12d4,3fa6a74b,7130c43,6ca8ebef,39c08b97,761cdb6,dafd2143,55715bfe,e8ab8e12,e51bf1ed,6eeed696), -S(27249c84,e21154bd,90034fe0,c5c5c510,c6b90e32,1ba4aa98,ca34be19,c918fb5,60327ac,f3fd64d1,ab14fab6,afe20b42,cd493af7,1d3fd0a8,ec2d064a,ecefed86), -S(cf6fe5b8,cc605dce,97c1b586,e3eb5945,38c02888,43bbeada,65a6b2c1,c2d66d66,21f3d35d,69afd6fb,704d1f0e,1cc2f720,2852892b,afd431f5,8fe3c1,3df78c1f), -S(cb10e984,f228da46,2063ce84,3503b423,20898a8b,98795846,8438d88d,4f0344eb,5bcab6c0,5de27bec,714ec992,dcb2875,d53f3f6d,a5ad247c,c81e8093,504504e2), -S(58c2a274,ce1e7d49,5a1d7fb9,7ff21f88,9e6e5230,5453eade,4ffad95,36037bb9,82e4a06c,5f7a5dbc,5e30b43,dac01491,addaa6e5,8b1a33b2,c082b4b8,fb50072), -S(d59e4e8,47e98edb,a494a195,25d1ffa8,63b2c22d,2476b2d1,2d704c0a,b30a56a2,bc2296d9,53902891,4278647,fc755979,c8d5cb3,502ffedc,8f412cef,51245085), -S(bd7feae1,1c4f02e4,9b1b3697,9370f319,88227ebd,9f4a6711,62e70744,6e452cb1,84cb5bd,1ad0381a,c9eaca88,b50e27da,efffe65b,f16f6bde,50bdbfee,69d22e72), -S(4757cc99,f4010ebd,d2e8c24b,ce7e86ba,febc4175,3f1f3ea9,f7afe8b1,3b0e7070,4b5cb36,55e3f5b6,bce14af,62ca1ad4,97480431,3deca874,dd2f8580,730ab36d), -S(e673b505,1e2f3e1a,f28284e9,b32d0c9d,16e7918a,1b8a13b1,602444b8,875d3d4b,f17f068,d02dc75f,dea5ebff,549a2f86,f9598c93,4db7050,915dc965,830bcc1c), -S(63d23920,6855af5c,c8c7f9d5,4986513b,455ca801,e172937e,a93a98df,78f36679,f95c588a,ba4d4bfd,fdac3c8d,f8a7d14d,7800212b,504e3deb,9220bacd,69e12f2e), -S(e74fb7b5,202d5a24,37a982f3,5018450d,ffe2e238,cd4fe3c0,60ce38d,18fa18b6,4715c0a9,f58d9421,6c3535fe,d6140395,e302e18e,2df0a870,52cd05ac,db917ae2), -S(1929be94,197feeb5,ac631038,f07c7db8,ff2226d6,c1763d47,a45c9e5e,7719c60f,c7816c80,8fe129ef,9a5bb8c6,674495f9,3f1e711,133e3cb6,19dacef3,815826e1), -S(76a43955,8d625d34,8c5cb3a6,e2274b60,8c93f08,6a0a7aea,be1858e8,7c1c359c,9752d697,a67a1743,9b5c4359,76658df4,be1452ee,1d4e0645,597f59a1,c60b3618), -S(4a3c36c,6418b8ac,920004a,4f47bfa1,1807619b,9fa39030,95f1b0a5,d91f46c1,95668552,e63f7fea,cd2b09d4,9c49e2a3,2f2fb824,11c5b819,c0efd09b,d64f6b8d), -S(9c5a32f0,d1a0f2db,253d47d5,e7c44967,26bcc7d3,b61e3731,3bbe5fad,ccbf4625,232fee50,bfd72474,af4bb5f6,afff7eb7,17efef90,7579d0b7,38542e56,67e05de8), -S(672eadd1,652ec6b6,a0c37e3e,7c8f0d5,a51d6f40,fe7bb66d,b4fed735,2e066063,ee5ba376,b53e9238,efb76b38,2424c8ce,d3b0f91c,99da4a5,7c98b7eb,48e5b891), -S(f78a9f6b,77af560d,c42d7061,831270df,21a73ecd,a7bc19e5,bff6649c,414b45ca,9f9897db,a7ef70cb,f4ceb71c,2572c3c2,b89c9c0f,a18ebdad,fc413d34,5289776), -S(2fdc690b,b0fa8c76,416b7ab0,ed6fd336,af4eb887,f13d5b1c,f7aab941,a7f63690,ab602a5b,f8ae3e5d,9aeaade1,1d126154,2f38a881,d577daa8,fe89bb22,6352c6a9), -S(3e6d45fc,5d8a498,b31d95ea,acb33144,ebb45ddf,ca3fd8f8,b5b22f4c,9d57cb6,f7e817dc,b718028f,3b18691d,8b9a25e2,884954df,59141cc7,ed939e0b,94cdb2d3), -S(6bfab01c,caec1bc7,1c38fa8c,b62ae3fe,9a24ee90,f6af6206,3b12d9dd,e83db7f4,5fa5e4e4,9d5f9641,559636fc,35b60199,68097451,10bfda67,a27de3c4,6792eddd), -S(d0e37c85,88d9a4f6,f135156a,25a15af7,2835de73,53f7b4af,336df017,d69a7fc4,8b9d798d,3cb04f70,41ac72f1,38462cbd,533324e0,871230ed,c3a06ef0,f524e20), -S(3f2a406d,eef9506c,2432dbe4,cb2d0a6c,a794356b,7953abb0,1ea486a4,e5db86da,ba0e92ef,aa00c78e,6f854963,7d8cdb5c,30869636,2cd71113,a3cea5d,9b492210), -S(d8b41f1c,2d2eef01,2b994dc7,21ca505e,818ac75f,4a396750,3fa3fdb0,2cf56fce,293fa011,7d231d10,30daa322,94d74507,3f9cb4bd,297a2f81,c812735e,33dc13eb), -S(64a07ffa,80f69a36,19f29cda,d1dc1b41,d7d58d6a,83470353,1f8aeb3b,eae51d91,b9b83f0f,43349999,d8efd66b,695bffbb,f67d3817,808149da,23978cb9,b43ef652), -S(348c104a,9bede4ae,3fff9b86,15eaafe,440a1cc2,1ff484bd,b442ad84,86dca015,41820b57,f62d6668,ce7fb53,2f3d3a94,4ac47c22,ec302d69,f98f355d,ad9e79af), -S(29fa80b3,e0a7a062,678c4612,41fefd8e,95f8e02,14795ae0,2afe449,1cf58041,6e3ae72e,ed0db6ed,1398068e,79cbed22,791076f7,515d5383,8581957,a73761d1), -S(6ecd85c0,afd6c385,15d8ca8c,30d618f1,8963b70b,fe73531a,11444a85,35c4ef29,c3e0cf48,4522b927,c1615ac7,9943e94e,aacd0849,12cd7221,308aa14d,95f05021), -S(7602cb28,f9703b3d,e0bbdf84,5e4f9326,712582b5,1a0cd719,a6674343,af2d089f,5b026bc3,bae6db2a,86f6f970,1682d8f9,82363e02,4bb703a3,945d7e19,d0b9efd), -S(a59436c1,389b4c00,5e4534a0,c7ce00b0,56f72ddb,a2b920e8,896d3bdd,74b29723,36c401e5,df5f695b,959c0474,28c9366a,774f744c,a60dba69,4fa55d25,2a5afd9c), -S(55377738,4bd49ab8,21e96778,17e0e95e,b6b08aa2,92a5ed47,9eeeb607,a0f4e176,61257b61,744f2c95,2d80a9df,29e47bb9,ad933877,eea75922,a31acb83,ce7c478e), -S(ac7ac723,2ac8d976,8e34fe45,18f5fcb5,518ea1f3,37d5bd53,5d5df329,d20a5f4e,e2317908,50bc5a02,f14ffc6d,c3785319,c30e93a3,29304698,a136d6ab,957ed52f), -S(9e49dd3d,aa78f89,af09eb7a,a87cb01e,6b55245f,dbe5b5d8,4c43db0e,1b5d26a8,e0ea375c,dc5eab64,54d16b5c,ec1435d2,14b54dc0,51806c9b,e232c64b,9843812f), -S(3537f749,4c903cc5,f5842fdd,c28aa98b,973dcbf3,20e2da65,127e4b22,4c747f59,f9cfbc26,5666e24e,1a9996fc,389ee639,ca350fa1,7a2191bb,13a2de15,63ff24a4), -S(d7ff3397,7aae895c,48e262c,1c93a0fd,2ea94961,bf19f720,77978415,e0f8591,2d3f2397,1cffe0f1,74a3ab24,614f54bf,85f4c513,21cba826,de24b150,cf77abb8), -S(76336d96,8a54c4f0,365712d5,a34c60dd,ed6de6a9,f4883994,f4ce2331,126078ec,ce745d4,62ebd771,359309e4,ee03b19f,83db6e4d,5ce7fee4,f5e3033c,9bae1c7), -S(63b503a1,615b32ee,520657d5,d2354c66,6b7ba964,a5efad65,d5957c99,65bb6991,af4ed8fb,bbe3a6ff,ee38c670,688351e1,d4a4a45c,7d5b9d5a,ebbce84,9a4ee02e), -S(a562ffee,3f8e26b7,1b3bee24,2fe06199,a198f76b,8b98a8d1,d67e176,1dc070c0,ffbc04e2,c268c14a,1a0fef4,bfa32008,f38a21f,891df618,72fedd7b,5f2cc270), -S(5be4337,20a7b123,1a171a80,fb72b580,a7045724,20d10b9c,786cb0e6,2882044b,c592daff,38d12615,b6af0225,7f39cc28,1447e965,9daaf5d6,c45bd486,f140efa6), -S(86f7afa1,e672e5e0,f33b0346,fa6e3b0b,1087f85,1526271,2ec07e9,82b80843,e7425903,c36d44df,fcbd0d4c,1a272123,18463d3b,12aaf1d4,9174c4e,3777d32c), -S(74751604,d00ecf1c,a56ca92e,9ef64457,fc2f6abf,d067cc8e,b761e120,c0019c53,94fc0537,6f69a1be,f8cfe400,31078265,39d625d6,8ca5df8e,2829469e,d3729995), -S(8b6a6378,49ca68f9,27f0b6c1,e934892d,f100384c,5d902c12,feb4956b,44016e72,862e9458,3835340a,f7c4cb5f,9ce0c566,c1a42452,c4420be3,2ed88324,3f6d7cf6), -S(9812ea51,ff0268b2,f94063d6,ec285595,ee8351d6,b95bb35a,d6577ff4,79d9d18d,c4ab286b,2e9d9545,d1ea9b8d,6ca577f0,ec7479ae,97ffbfb3,27bd9084,8f3ebe9b), -S(4bc3c5b6,3e1a82bf,3ce44d48,25c82c65,8d5d69a8,a1e5b4a9,358ed443,f89cc7eb,4eb838e1,2eed6fb2,81d9de11,cfb5dad0,b08ae9be,f7c82d80,5f3c7a19,3d46b1b6), -S(e269b40d,e9dd3fa1,b5edbad5,83a90477,2421326d,61611b51,bfca9231,4afb2c3e,76633ec,7793b5e3,7b1c3bd7,981496a0,1b9cae51,2ce5d589,2b69c1f,a437931a), -S(7abe755d,9bdc8c37,e99d6917,e5d0dfb7,7e90102d,7c278af,e10c6f6d,74880322,fad617e,3612687e,d31b7597,2bc98e83,c7af5e9d,f4a6e12b,ca812f70,1c5a7a97), -S(8eb690bf,8c75a72f,e635bc55,ad05856c,9083a672,3577d776,2743b1d4,df0d88c2,7737abfa,76ea68e3,1482d3d6,95f1a7a8,ae4249ae,37c68c95,ae605814,6a288958), -S(d0413b90,c3426609,6ea9401c,8e41f0d8,37847c1a,47a47b3b,fd6ffe82,58d3b38d,38c1b369,1865a029,af58a847,4278fd49,9ea44686,7a8b4ef8,63b6dc96,c66e1a38), -S(1bf1b231,9468cab3,2011fffc,96f296bb,8bb64c69,47b590dd,d9d8edc8,ded3668d,1a87ff27,bbf79298,807dee37,bd488762,3a9b5c7f,c5d61e4f,d4de16c3,e7988c1e), -S(bfbadb48,ae5a2997,c368e44b,beffea6,b1682b01,f492c9c2,6bca3fcf,1a0e01f6,7fe11de5,4037bcf4,3418d062,d0bf0bd8,a7399f29,e65f5ecd,9f9e2693,dca6acbe), -S(c2d48434,f2fa7dff,d206ec93,5def03b6,ef2401df,c8c3a126,10f77d49,c14f239d,68e9c025,7483ec64,fe6ec6fe,1159d5c6,400c9d0a,397f0e08,9e92430b,51883316), -S(4af55e6e,f210442b,95a50aeb,51e87ee1,b2546337,664d3a33,9c12a655,2e3ac08e,4f81a92d,fc5c3e62,da712c72,cbccee05,da2e4cd5,6f901bed,a96f9b5c,5c5f9d48), -S(d89bf279,472e7b5e,6f41f460,3d348143,d15b1dd4,7bcef4c9,1274f9fe,9f868ced,cdd02079,9e9d91c3,8fef3631,12a3edc0,962bc718,b7f467b6,45f743e7,db1d66ea), -S(c7cd49a7,27c9e003,dea93f26,fb888cb3,770f5637,58d4f40d,ccb4e0df,d2d1ba1,85bc461b,7e583884,2d4e643d,91ad3179,30d9949b,b29fd94e,4090e6b3,3cf2772a), -S(e1cf9c4f,e0b525a1,290d8ec5,1a3cfb9f,6a78d2c,e817ec9a,a39a538,4f9619af,b6aa8225,d0ebf9c3,4aa0392,a81df722,c8d29cc1,f03abff2,cb7392ba,ac78f5bf), -S(4f628bae,d84bbf1d,fd568c23,10aa10e3,a098131d,65484a80,653b4eb4,ae59b970,e86292bd,cab0f1a,63ada7af,e350fee4,2dcbc618,6838123b,186974b4,16ff2a5a), -S(90b17b58,9674a91d,7c2c9443,61cf8adf,b47e733a,bc775b57,4838fd2,d40eeaad,72c69fe2,ba39f165,5ca31f41,7ccd004c,1eca2392,2973e47e,ffb423c3,5c9f54c), -S(1e13fed8,6aed242d,c543d2b6,9d3ffa88,c87731fc,c4f6ea48,fbdccace,b60ab263,9c1a66d4,47de8c53,2f740f38,af9a52c8,160890d9,5b573c09,9981297f,df8995b4), -S(fe036a4f,713794cf,c0cd3b66,b1a124d4,c6a5374f,810d11c1,30c16fe9,1d8e81aa,f7ff5760,544b9e87,489e3c76,addbca52,308b9155,a7848716,1dd8c1d3,f3c81816), -S(2f9a25b7,73b6cb87,56d1f4ed,691a4fb3,be7ea324,bede8c0a,b9446103,dbb96323,df92e84c,7b76c4b1,f55e77ec,d541ce34,963e9f5a,f4d68fcd,1685d060,c99dda22), -S(ff65bc77,a459bd32,21742391,6e2f9438,b6a38b71,c8c06d24,84cbcdac,ac0522d8,efbb8c9b,8ac9200d,71d4a944,4dc9050c,4661ff4e,fb0c953a,c1c1dcc6,2e44071a), -S(d0e325cf,775d47a0,532b46f8,4ec41698,82aba5fe,83c572a1,1bb18b9c,84edac13,2ceef205,c424441a,fee6879a,a577e1ea,423514ff,d95bc282,6e27b5dc,72f6ddc6), -S(27700ed2,bcdf8ba3,f5ee842,945d9473,9ead9ca3,7741f31,1fad3503,e052b8ba,69c780cb,d6f2c1f2,5104dc40,cdf07ec4,ee76478e,98732995,ca85b5d8,f070c8df), -S(205bfccd,37349c79,5077f5b1,16e63990,8703cb74,f2835302,44bbdcfc,fac24a98,edf25093,8cd87a81,b6f3da85,9129b399,a1971850,86bd63a9,1c370165,a22642a5), -S(a5f79343,8b402d23,6e9bc997,cd08557c,7f83a343,32528a19,c506e5ea,8045bded,9679de58,13c2c74,cd82315b,23b6819f,4981c6ef,f1a2ee00,af5efa4f,807f2b3b), -S(aa7da8ed,a97ac1e4,d2b2abe4,c8f727a2,5643c5ba,414ecf72,70a7bd65,612b1a53,83736a4,de5bae56,8d55de7d,6e2d4d6,eb5d9965,f08e08d6,dd6419e2,dc8d4057), -S(ee53a4e,1eefa289,af562927,9d58f02d,529663d0,8a290297,d7ea92c3,64f5d41c,aa0fbd01,727c227e,662fa63d,3d6a834,476e00e5,a96cdc97,d78c21f0,f3b2a83d), -S(8fc52dea,bd8b3e4c,fc6a2490,176b74f3,cfc55118,2d5134f7,1364a8c7,b083fdc4,1a8b2a23,d9119901,7e1de607,6ace873f,32bbb342,e93a9f82,ab1c3a29,18d603f5), -S(e0f5e5ca,6395d3d2,390eca9b,4bf50320,4c1062c6,82214c36,b1b0587c,cc0912c3,4eb1d022,b4971d9b,74244e8a,5565e021,b933b2f7,e8ea60d,fc259511,a7ee436f), -S(fd31a893,17476bc5,e278bac3,99eaaf6,1716586a,38410172,48170f7e,4d7821fe,190815b5,a2affc9b,1cb91237,783959ac,2058e75f,16cc2e7c,a825ab2f,8af9ba01), -S(1533bab4,eace4f70,74067a55,593498e5,59fa78ba,b74131bb,a2a97412,4e855be7,a04ff3b9,c6209ba3,69b19863,5cf8b4da,9b6a5a04,f90e29ec,9061a32d,f3ce6361), -S(8d549288,93390895,f1310e4d,a8b8ffd0,d9f8226a,b414180b,bb280370,93aa90df,fdafa930,f892b478,c7e6cbae,3f943615,ff08c2e5,64ff61c8,dcf19ddd,5c458081), -S(1b17a4c1,736fc761,f3091367,9ff22ae6,2ce76a6d,716e9b1b,c6cf28c7,cca59a03,9435ebc9,edb1a948,bc3493e3,e7434b81,cb671439,365843d8,819b4eb,786a191f), -S(3500c8cb,e37f659e,48e3b619,7007f250,9d964708,14c06977,a9861a89,eec11b52,8d5de084,b45912af,3ab8a8b1,47304a2c,45b839a6,41713563,f11dae45,2e5ed94e), -S(42def4ea,50df55dc,cdba6c04,ac2855d0,d706ef40,6ad56ded,50d49aac,3b41c049,9e354094,29b46cec,329d906c,9f9ae965,ac3adfac,251370f5,60b91550,4a7e114c), -S(b83c1c07,2087e92,11fc3302,fafb5be7,8fd4853f,9f8aecb9,5af83278,d488600,e51c2222,910c6d19,3baa56a3,63e330c6,390dcee2,c33ad00d,771fde6d,3bcdf973), -S(beb27e28,c59f5b87,d19b0274,51a51e58,f0d10402,e7343efc,d302437f,f9ea2004,ac188f43,c0d6b91,4525f6b3,5897d7e1,7a0543c2,3ccd8001,509f50d8,a95768de), -S(9408e5fc,877c5635,5a3339bd,3b9f7a8e,22a361b9,ee5e2f1a,a2b47eb4,cd665328,c51663b2,f9ad7dd9,6b120c25,2eb8493d,d68be9f4,ed4b688c,f5d2bde3,618658a2), -S(a4d0c5e2,9cf83c46,5a567288,e6c0573d,c7766450,d88ced27,cb036db,47ecc96f,ad00c513,63a3d265,1318ed9e,352be903,30febde9,7827d8ff,1b5b5bd3,281c0c38), -S(d38d0ec0,4d3819c9,665b42f6,24089402,e923a8f5,6e7567aa,bc12e5fe,c248722f,17e171c,5c6bbc7d,dd7caddb,652dfee8,720c319f,dad6b117,56596bd8,b554397a), -S(4fa66f5a,7c294bc2,a0fb7951,7e6310f3,217c2cc9,c712f6ad,c5042610,c29b7a26,8b79a582,b3d9acb5,5653642e,8b8c6f18,f17e0541,179c4d62,8a2976aa,3c760d1), -S(ec9def33,2bcc66f0,db0e6b3f,684fddc3,ff1a7ace,80c2adc8,82e4e5df,5ce77861,9ae3da13,563aface,d4988a5a,5b3a95b0,4b72be95,dd8ec898,f46fcb29,f43cae94), -S(90422949,23fc0bb2,3263ca1d,768919a9,846e8eed,4b595e56,2d5103b9,5a479795,7d8a7b46,e557e1c2,c621d49f,b8f382c3,1feccfbf,5cb8c755,1f02309e,bc5881d4), -S(9c926be9,68275386,95549bf,2cae2278,56410e3d,1e481cad,995c687b,e44bd1b1,56208afb,875c94cc,bcbb068f,f8ef6fe6,9615f1db,21c2b43b,59c8e80f,db5670e9), -S(8d7f3cd7,2a6912ed,f0fe9343,211cb3d4,20229f19,3e956ed6,9c4a45bf,c7cb84a7,a45a7fb5,d4e9c531,4defec11,ce95e054,1ef0575f,b6b7f299,72bbb008,c9c3c3c0), -S(a95eb316,bc91485d,9a220af0,a201378a,d0319bb3,473a0db6,e919b3b8,ff181952,41664555,3aea43ef,d7819025,acad34ec,6692f9b8,bf6a86a9,7de32f18,46de13cc), -S(8ffa8414,1e806ac3,df613a68,a8395111,93569368,6e2b11ef,a1d53493,34e8da55,5dc00c59,12cedd0d,4457e779,e82ba2ee,669f7fa5,75c42e1b,abc1aa7c,7cb1bb1d), -S(2f1645b9,7b58e33e,3dbaca4e,b4ee6fde,2245c,2c9bf124,46e262b3,434641fa,d3d0a603,6ded3010,319324f,34ae1e58,a6ac0b6b,9ea15b7c,3052b574,f0b2823d), -S(95232f86,d2d1482f,a6656256,3751c2a5,16e1a8a1,66988471,f6e0aa69,f1ecea2f,7f54837c,4633f938,c0ff4fba,e59b6e4d,1a7b336,83a1ec1e,fe1ece3b,a131662e), -S(676d2a29,50e66454,97e678da,68a5bb2b,126a8eeb,874fa8aa,ee3738a,cb7b3cc9,23fb14fb,674ca1bd,8ccb8248,48334f6d,4ba47d56,c7969cf1,fa3ab1d,78a22a2f), -S(91df7ef4,3ba5bf7a,11d8418,e553c5b6,d2031b89,c644d08d,88f1cec5,9d4007e8,e7b19092,f45b6d,7742d4e9,37d80d32,63ba2945,1fee1259,a13b5b1e,42072f7b), -S(1b64a5c3,e14d8fed,ac3c5eba,e6848e10,6c9db663,b18d48f2,b948be47,e8dc3b4f,55caac6b,18f294a5,f3dc9f44,ebb276f2,fbbb506c,1a28b0de,a55ad2d3,ac5eb8c7), -S(122f6415,3a73b8c1,f1c935a8,e99590ed,16ed9660,66816cb3,57049803,c7d7420b,f5bbe828,9693d573,7016fd9e,59cabef7,5eb7fae6,ec9614c5,3c47736a,f3276855), -S(745ed438,63d669e4,397bf391,14af880,f87334cd,62897aea,634b5c7e,cc6a074a,c5cb92e5,61812f7b,65930310,88b45373,b864b51c,18326532,b2eca5ac,8608f155), -S(4724facb,e60d62dc,da536967,a4650a19,1e582045,ea209834,f1989d0c,db8baad5,ad70a8b,ec1372b7,5e3aba6f,8c031d5b,ba540395,b610fbbd,7d5b6ad7,4e32a3b7), -S(a31bdf87,40d7a1c4,88f23ae5,9b54c976,56887201,6c307531,51ed5062,dd7613a8,e77b2633,af3e9b42,a2a05b45,a0f5c9ec,28f72387,2cb5bacb,ee5a8360,2aa282a5), -S(990e8453,81efaed1,8c3fda39,7d4ba832,d509851b,8503891c,c0ea0ae3,4f5f1f7a,339aef51,e4d4ff8e,49955166,4408c312,b943df2f,fa62becf,51cac7b7,eda7d8a4), -S(bfcc3e62,cfc9808f,bdceaa55,f75331b6,c9b1528d,455c33fc,9690d84a,d89f68f1,7b07149b,cf648a16,b3be662a,d203837d,fe5a2357,1154e65a,78841ae7,a906a7c1), -S(284b543b,5ad3aa4e,5a4ab274,9acf59d0,4045bbdc,1ad204af,3a7e841b,330c7ac8,43d50b60,d23281ff,1ce15241,80c05e53,e5fb5bc4,a4e0ead9,19a2add5,f55b10d2), -S(e4c147cf,beae087f,5c9aa83b,31514ffc,5734feba,cc743203,7a7a9931,4101bc7c,72ba3a91,3a2fa186,484bf856,ea93a725,5f6e3b1f,d5bb86e2,58e45e43,52073787), -S(54cbe831,a201fa88,a3e7ca1,aa409449,509269a9,1b229892,9e9f9dba,a7e8a8c7,60705c7d,ff74d8eb,1f85b9d1,d9efcc58,fe463e04,b19f56dc,a724dfbb,630661c8), -S(c8dc9e83,d4e4f250,5e8c16f0,a5e8de3d,1ea3711b,8a927a63,baa9bb33,6ff302c0,62211dac,15b97856,2dd71543,b63edca2,4868ef5c,6bc7e547,9fe81da2,261f6150), -S(4bdbd22d,5cb98e31,ddcd1e76,fb69ae02,1915be35,5fa326e8,506c38d7,3c93dd8b,9401c173,3bdd7728,fae5ddce,d708119f,b0cfdd41,2b3fe599,e75b5a8b,b84fbc55), -S(ce988332,84a3fbb4,31b716cb,3b6530ba,bb41785b,c7f0564a,8691289d,9d35e689,2d6d9b1a,7711c5a3,2ded418f,9b52c134,e822589a,789c2b33,648324be,508f4f14), -S(2815b2a6,ab505e2d,ad759c85,6aebc3e6,133826c6,d3939a6e,8795308,5adb6bcf,2e6764f1,f90c7ce,a03c5d8,a1465d26,fb2cd430,edf9f4ec,13ea71e0,51558b7d), -S(65380aca,14b90a7f,e6c6452c,c3d811ee,88128fcf,fa009d7c,1afb3195,8c3bd1cc,a73d691b,cde27cfb,dfe4180,e6a8d2d8,62615b1d,59ad3487,dc914045,39549ee6), -S(7bf3a1ed,4e7e876a,1404493b,7ba01911,b5707f09,f18694f0,fdc35e9c,27f1b89f,b6dfdc2e,e827967d,1d1218d8,975cea61,9a740521,a0e0b702,7df1ffff,dfe45572), -S(5f635ad5,952b3f2b,e341479d,239f4ed8,8c33ed63,87f62c4,40a02665,4e469aa1,a49b5262,32361560,c2105db9,3b500fa5,bfe3ef99,7efb826d,90781ad0,143fc0c1), -S(4a212245,8bc099fa,7792d0bc,a3d1d163,58fc391a,82dc7f47,2a457268,1be9ff8b,fbeb9575,6649a3af,923b28d6,788c8662,9b488166,23349b93,755d04ff,bdbccd97), -S(1b56d138,e71aa703,e2566a6a,6f0a29fc,e7a7b999,2c454248,5ab29c6c,eafc86d8,db7b41e9,217fd201,4f4e6ad7,818dfcce,31823069,d1e87ab,85bb5ccc,c870d476), -S(cf9dee0,3d9c1724,24ebc37a,1da32a19,bec78003,29def8e1,b7c44b5b,59e880b,20ce898c,1b9dbef4,f47c5b6f,be39a8cb,91bd244,b0df0bcf,94c01616,24ae24c3), -S(89458ec9,1bcac5d6,ba51b7dd,d32119c,eee5f535,5e368e22,3a35b9ed,b8bce2fc,33ebef56,190a0820,9e508e1f,6dd57a37,141cc7b7,ae8a3583,41da1ae7,24b40f0e), -S(bc1637f8,39b45eb7,66e7ede4,af989ce2,20ec795e,d8454ead,6053a392,18c6cf13,e64e7128,240d9c9b,4018c56a,bd71e9ef,30d7cd1,8a036ff6,13e4dc52,13e88b71), -S(212c6c8c,3e2d406d,4fab7bf1,4f7dee3b,a7820821,ecee711c,f63fa0cd,49341157,2c2caa21,7ae6176f,242ac6a,c951b628,5daa7dc8,ef35e996,12b7df6a,b7966006), -S(8ec5f69a,a77e4faa,a70d129b,685f996e,36d4591a,9f03a047,d853f81c,483a371a,69eb18df,9bc54f0,804f937e,4c88eeb3,a1e089fc,6fde0ddf,e37e2de7,892b8b1c), -S(d77dfe3e,6370e677,bc0442c4,4d71e7fb,fcf1b7a0,5a39831f,6c02daea,70eef37c,e5582098,dcc957cb,6308e51a,817c2764,1c34a3ae,4a1e931c,9e741c29,241df4a3), -S(95a98fb8,178ab7b0,45931f72,f9d3411c,3d6c9bfc,47b9db77,11dba796,6600d1f4,789034c9,fa371e65,e47e936d,d5be1c62,d660c12f,d7a0164d,1507b4b1,4d5a5d58), -S(dfb9170,5c2eda68,ebfe7b2a,f2c76eb0,c65fe431,d3a893d2,b202b004,bf532063,2842d35d,73985521,4dbf015a,a64fc5d4,5c763a0c,81be6302,ab16eb45,64e1c020), -S(ae011375,773a319c,12a49e8a,24f4a84a,70817591,d739c604,e76314ee,2466136a,fba7f0ee,758357ed,f296ec2b,b4d0f9e,6c38e29e,95daa163,f75c82ac,48988ba1), -S(e906d6fc,6930a06d,846d4804,f2affda5,955c0718,e920aa47,724a4903,d644d4d,abcddd9,fa93df1a,6c4aff95,a7ff30e0,8768bc94,5baff83f,1278dcc6,fb797ac), -S(39d6a839,e4ec9f30,7a4b150c,9c20f918,5626c93a,1a077cf1,b4259d9b,cac3eb5,2b0173df,699d9213,989b16bf,a17b0996,18eac71,b6f21611,e20cad8c,f9609c2a), -S(11541976,d8c7da9d,b9864344,a2a3ecea,499f538b,224e74c1,546dbb82,a343c308,692038e0,d63da9a8,c4c7b9b1,fc3384d7,d03e2dd9,156f90d7,68d31f64,eb46231b), -S(b8edf6b7,8b0ec547,9ee981dd,e7d8052f,7d613d32,a9677bf4,623c6695,515af54e,4e391006,443f4578,7951cf57,d47100de,7982d0df,cedf7c3,36193ed7,a7f986b), -S(dd4f1c04,c7f106f6,2d8f49b3,f96b919e,774cec1d,e470e670,1f72bbd3,2236d3f0,bb46966b,fa105ade,17aba7ee,a2c11e02,ace8524,1e3da1c2,4d30ad99,dc695175), -S(794d4cc7,aee8f9da,ac4ddc7a,bb4278ea,d8de11cc,c4dad583,45c3edb5,b9c7b2b4,d0024919,35a5f7ac,6ec9a6f6,85aa16e7,61329642,c002bb59,a9a9e135,63ef3688), -S(90dec6c9,97e0906a,fe63cf90,2b6a5a6b,ead0653a,6c9a8337,154eca0a,7e1fda8,3511f4a,49540228,3956e249,e9caa7c6,222c79cf,d91fcad5,c35b3737,931308bf), -S(dbe539ca,27d132f2,e602df51,6582c3a,9bda3a82,ce3b52d6,10f4bc45,17b52119,9f52a5dc,417ffa9d,2ccdf666,63ff60,8412460b,15adde93,a11ceb9d,4f859f37), -S(a3fb9a06,7f8a9364,87bd6b2f,eea9e072,6902c046,5bd3a9fb,5afb9cf2,8af34028,b3de3a34,76028531,192d614f,c720e0ee,e7765fa0,14dfe4a0,ce0ffb9,b32f123b), -S(47c00044,c66a8c7f,f6242613,17cc9950,438544f7,31398212,bfdbbfae,d2e34ed4,215f4709,e2bfec21,6990ddd4,d37a0c46,b2cb44f9,26d3523c,ea0a8b2d,7f949015), -S(b59b3f1c,cbb0cbdc,4e430788,f934f090,aa0e1047,24d8d1e8,b7329e4e,c1d6092a,f96cdb74,a7ece8e3,a9f631cf,7a740a2e,fc9c9020,8ee0a91f,42168990,d9a3cee0), -S(c4efffa5,92a27b03,a05686e5,8ce4cbe,d4768e15,64d30450,655b6d0f,5dc5911f,7f095e1a,9108c3fa,a1b1043a,ce870f98,264916b6,f8643370,4d36da78,deb9d826), -S(df9f6d4f,e169d748,5c09f5ad,a2eb46b,be5bb378,919291d9,e3f60ac3,2644b6cc,7566af91,e7c37fdd,72b68418,e6ed1929,c17517bb,bc8666f0,d5e28eff,4d50ba54), -S(bf3d3814,11130a19,23ae0b6d,f333c61,8ea598b4,1277a568,85582688,6bf8deb9,861edd8d,276fe3c4,cb7496d2,9d313697,77df75a,d8c40a85,19ea1415,9ebf533d), -S(8b822d8f,640dbd04,d2a35aad,e4309992,3133fb0,c97073d3,b23f767d,f3468247,71db728e,40b1eb39,7cb69211,1ad24e63,79727a77,bb028db0,51ef9b67,f31d036f), -S(4a0e24e8,6d588f32,7d41addd,c4659b36,d6406a28,91ace143,d24d98cc,cfea28b6,3c79f61e,71c3c9db,11c97734,da9d9d29,7b141060,589c029f,6eb888cf,7cb6f04), -S(3df98e9e,c1bfd244,86c6e95d,8ab19c93,c89751d7,d408ae98,44c90c2f,8bee9685,fb6bd949,afc7c8d0,a16e2c45,4869cc4e,899e6b6d,701eee28,7434439,fc61074e), -S(1196aba0,2bed29e5,2ab28d7b,74301095,ca68fd6b,1e2d0893,1e3145fd,3dd1047b,d8dfd4a4,781ef486,8513bfae,d0b0ce98,5d80f6a4,556da69c,aea24c1c,7e85b27f), -S(5746e37f,709a62f,af3a720f,2c7d5ca6,5ec8a3fd,3e223b67,b839dea,60cc1505,eec14b2e,76e888a7,538f0fe1,32268576,4f91d70a,19d9e885,168af68d,5b9678b2), -S(3c807748,606480e0,9266fd22,69b9c7aa,9a2f87e9,58d3264e,77cf2140,e0f2dcef,48b70aa7,6f86e7a5,c02c1997,fa029d78,94398324,82d3396d,2283dac7,dbe23c00), -S(52885fb1,f40dad6b,7c0f7f0e,3e9e230f,b45688f1,a9f3adbe,710bbff6,d56885b0,372ba4ff,192bc456,56240432,db828847,98cc846,e810c99a,8e33476e,1a674663), -S(60fe0096,4fb56044,c506b551,3504a800,7c2534ff,52f53f54,31a479fb,166616da,75ae6371,b05b93a2,499563d9,887f69ee,f9532a1c,6695e6de,966f0b73,90100ee8), -S(55439653,f8f659fa,9f2ad854,2b1beee6,6cdf34e,d3e464e8,45ca34ac,70d88434,c7883ce8,984db19f,a1866e82,f7cb0623,e6de0446,a8ad5fa5,3dcc775e,d2a9f871), -S(18ea4c5d,24fd7a5e,9463b109,20760dc7,fb4ae56f,db00f0d1,805a9e19,c02f8687,3e19b983,93a440ee,99fb1a25,d7283f10,cdcf3b7b,8b063ee,5eb05c56,2edc9251), -S(8bfd7102,9c7a5747,8eaaa0de,1417ebcd,16731b31,935b7190,d536089d,56dece82,b8fdf97b,1a4d9d35,f32504a7,2a03be23,e71fa005,48cbe33b,8a85060a,21daaf5f), -S(e4fcbc12,22987f5a,f97c0ae9,be88dcf0,23ee2366,4a2f3b98,d19f3687,b82d89a0,7539ffb,33cfabf8,582ec993,8c034688,f8aea8c,7fb6f73,ae09ce9a,e63b9da6), -S(bb20ed68,c9a83a86,99a42cf3,9a51af62,534da50,36bd8cf2,5ef7f7ff,1f08ef85,48d64269,af2c39dd,d6c2d703,fd7832d7,c409d76f,8a8ac99b,d977e7ba,760e7428), -S(2d852cde,fe404dd0,835c781a,11a23db,bce9b015,637c4a82,e0ae009b,aa2ee8a4,d69c9056,66184051,f433e99,ce03c3fb,97107229,d509cb69,59675300,8951f4f5), -S(37f5037,beda50f6,c485b78c,ae4843d2,cbbc50bd,c3588c34,54a09dd4,4b5504d2,d2ec7671,9eb38781,d2954fab,34f475c2,2c297238,70bf7ae1,1124231,2315d8d8), -S(7a5fc0f1,5747caef,61882134,40cafb3e,e8cd6c25,9cdefac3,60c4a9d3,6c96397f,bdba60e9,bb96fbfc,e1fdc22f,d4282913,7c717a1d,f907d441,94fbe55c,bdcc7d73), -S(d50843a7,4602c5ee,298e9ea1,6ecc75de,c0bc2b0d,150546e1,4605ef8e,c0d33eb6,f95baa7,aca33535,b559aad8,ebb18df4,eec43134,6ccbdc72,a3551b53,9797b570), -S(e5141e1b,a2a9e653,5baa4cc3,71f143e4,c4e3be94,4b81ad88,4a1cbd15,1052ae67,afd5328a,75f3361d,ce8b7e84,1e091835,2ef1f4b1,986dcafd,40ac6aa1,12a65838), -S(892a2bfa,f1869c35,34b50649,f4e3bca4,2fb6845b,f831471b,4b6c80c4,650ab82c,ef6c3f52,6deeba94,563afd1,5b9246c9,b397ac2d,1ac38a79,c7f24dc,1706a402), -S(7a8b233b,94e81662,1ff28218,c60e56b8,15e7f48,9bf401c0,182f05cd,57e1aca1,de6fd62d,713590b,f0e81723,a25540ee,3a98b68,68d4bfa3,d0b64b60,1bd02202), -S(66c7766,ec95259b,ca729173,a721d3c5,a1fef897,6ea25f9e,4c5ef3bf,93a659f1,23d66628,1cdd28e1,18cea2bd,bb8bd13e,af6fe7eb,d282e5b6,858656b2,31a8463f), -S(14c8b905,9c41ba45,7c8ef52,c78bbc43,6a9dbe69,4e8ca807,1b538e0c,eff68d64,e4c77c72,5c9c5cb8,2cb26618,7fd77fcc,cff42520,5428c0b,b7a5145c,fef3ea12), -S(ef36e454,185b6147,9e0c57e5,92ac7b06,d59a4d21,6d0f4794,15fa728a,181e4024,a2b298d0,abdf1d93,7e6a15c9,4a77a72d,4cbab1b7,5b27ff46,c217d1de,b47bb006), -S(6848b754,920b0919,b96c7c54,5329951,ac7f71,7cdfcd13,9923d4e9,d4fc3ab9,a9e4722a,59c84597,a6f9eb15,50230182,af76f6e,eb8f9b80,c4b14d7,2f07623), -S(a8f4f96f,c417bf04,15116fc3,d223494e,4988e32,855e7cb3,c52f3c77,382227ef,3f5ce509,f0aa36ea,c23603e9,b08e08db,4a9df67a,bd1735ea,1f3cad02,8f63bb8b), -S(372bce7,9b26b7d6,6026375a,1d8f7858,4770d17f,e23a53f4,3d84b577,4e1d540f,ea6ea296,59226bfe,cca23e38,f341dab4,a3750d10,c9e9d662,bdf90b95,c68ff345), -S(ede230c,fa48b0b8,affa246c,af849946,3c89b87b,148259a6,bb319895,c5d1decb,76eee3c6,85fbb3c0,ed86e7ec,9bea6189,56ae98e4,d1c7a17,e9f7d796,eb8b1540), -S(1fe48c38,964fbf0,438f3b,95d15871,d8037e8,a80bcef8,9cf19a54,370457cb,33c60da0,ffed0f,392758f3,76720d71,42a66034,ecfb83ce,ecb05bc3,44fa9fcf), -S(3ef6a0ce,d6b74a75,7da5e17e,cc0b215d,9cacd353,44c90c07,cb7b86e5,2066d500,a361d55e,82a75506,ddea417e,5f3ac744,9642305b,92a9bd18,b8fd2fc9,b3e0bf77), -S(165c9a99,4f26f8ac,528caadf,57d77d82,b74d3f79,1d2f18a4,e5947aba,7e25ff56,3016f139,a0e0c5f5,abdc57c0,86489330,f3b83dea,46396fb9,d1052753,785da130), -S(e07ff9ac,650d90bf,745bb6e0,13ae6587,e96feb6c,e1c003b,c0c44a6,6ec415e0,8bccd0e8,77dec06,e4aee5d1,76313cfe,de90e6a2,8e98e618,70e31b8d,8da3540b), -S(d1133e3,62cb9ea8,4d4da51e,763d1b23,ee018984,cbb2302f,c5789278,e60cd0fb,b66e8a8c,3f41461b,8d1358c2,5761456c,b5c086eb,b67a0ba2,b02166ac,9b0b2d65), -S(fe40c8f0,41c5f50f,789b4c2,275892a4,547da456,ed1a7558,8529ecee,6810fba6,a27031bd,d4290077,ad0e50c7,787a222c,3c89b27b,13159117,eea61c29,f126831d), -S(83b7184c,2b76a015,b80c1269,a78272d4,374a00d,340500ea,ea5df081,18ab986b,41ca7c04,774653c3,87782499,ae88e219,a16e53f8,1a87b1f8,768933ca,8315df89), -S(7c230724,b72fe375,bac73f94,5df4e542,c6789c1d,ebaec636,730f07a3,6c3a0648,a173576e,8c3f56ba,543fdbbd,c650d004,3fcda4b4,4684a6cf,666b7423,9cee0152), -S(652207a8,aeb1c301,932db5d3,854efde6,da5c9912,ca6833a9,79499ba,8549dc7d,14ff67f7,d0d82988,b0b947a9,b8ff8914,8bd0727b,f72e9ba6,18028c42,792aa3c9), -S(13422e69,12a1b8d6,db99e17b,7606f3e3,b6d5cd11,5f47d50d,587e131d,477f983a,f72d5395,a5b1badd,88074638,a079797c,134d7415,a7d4be7f,23b12b43,f1f2b1b2), -S(3605aa35,29438d1,90c78de1,7223c468,ef36b28f,bf7fa6a9,d809b113,7e251481,9de174d6,43288a16,3dbaa04d,f4cd8214,f3e68c8b,13b71ff3,215447f5,2522b8ed), -S(fabe9cb9,d1e80ace,f13e49c0,d9cf2e95,12091e07,a9b0ee68,144d92aa,8a3f5f7b,7c05d1d2,7144b868,33c1dddc,8374d4e4,16df20d9,e7111415,8203ffe3,8f662823), -S(df84793b,e4c7a574,9c5cdb3,10ed4e96,c05298e3,d7c7187d,93018dce,ac6d75e2,62d04b5c,1cb578c3,8784db96,8fb8786d,59c92183,c226df41,d164fffa,c076fe2d), -S(90585ca3,730b76,78a731ad,ac186574,911212ab,58d826d9,95499433,5cffbdac,85bcac15,d41303c7,bb2b2f87,eb3d5101,eb35818,815711f4,fe72d243,50f5f6e6), -S(89e17bb8,56178598,74821db2,28956cd3,8e8cc6ef,568ff68,5d5c2e22,5cadd959,e759f802,faf4feb7,4ddc888f,38b8faa,2661c56a,367da1c0,781ceeb1,7b30e37e), -S(1d43bd3,df9f1f25,c061538b,6d4fa0f,dc6b3be1,c7443616,51420d09,7aa81e9,ddc8f865,d85daeee,6faedd8c,172568fd,d290dc12,fd41925f,868fa03,ae8176c1), -S(6899bf86,10d6f8f4,f2b50e47,1eb5bf9,77924580,3b3a8636,b161879d,35061e5,c4c472ec,37bf52b0,3de23bcf,188dafa1,5aec0c9b,4f023e9,b54a8d9b,2940a66f), -S(b42ff8f6,6ea45365,485cf5af,ad243cf2,f6d63e0e,d4a0386e,475dfc99,70b9ab65,46d2ea18,495a980e,db65262f,efec578c,ed829315,15ac74bc,83d8d385,d739b2ae), -S(cc1d2622,9e9cacc7,f84bb974,e06e9dd6,62fa261a,a90e271c,332c289,1511dbd9,206e7e03,b8c33605,ed870f52,2e31aeb8,1b9f8a70,86732a49,6761f00a,bf0396b8), -S(21f031ea,16cd5c2,3c5a809,3a93656e,950feed9,64c8e2,debc0a98,64c3b30a,2d038c76,f07d43e7,f70d289a,32115679,232bb02d,7f237f20,82f085a4,2031f61d), -S(8bd83272,4e955741,3a6f5fe2,b5d0cd06,ca80a3f6,eb8f6449,516274f8,f98c689,71559502,b2442397,62319105,3b440a7f,fcff2a76,bb4e9552,37dacf33,b26d19e), -S(74c61963,edd7e01a,5ecbc8a9,76a1f24a,fad2b1db,1e632edd,6ebbe3c5,49d2af07,9247fefa,fd6ae328,f3cb918f,3b6ec823,4c0320c,5a317a54,19fa17d1,bcaf9f99), -S(1d7e54a8,597a36fa,4a32a46f,b40fbafa,dfa50c42,c4dc2228,b30c53a4,17b38f24,cce12594,2f1fea05,1cee6589,c26ef75d,f88d7242,bf3460cb,7bac2566,498e8ce5), -S(c788085a,893e3e58,bdad60f5,a177601d,5af89805,47bb9e1,2bdd2294,a850bdc4,44292afc,2ffbfcb0,5ac838b1,224bfa98,fa09f219,b81611d2,d83c9239,4165b415), -S(d87e2357,7984ef30,a3243b79,f0a53f84,93b38e4d,6b182c47,d1e6f48e,3d38db8b,b42950a9,16c616aa,1fbecbdb,70868cf,28106872,33b3b549,388c2255,a157a50f), -S(5d3ead44,592168fe,d898a5e0,bc7c0aa,ef926d4c,6f06698a,e5274aa9,90307ef0,ccc1e0ba,51eded41,714e8039,4a626a20,1ad5b751,5e6d8ad6,25895be5,8289f1f9), -S(ac063972,75d60207,fdb67802,5d86424d,d47b7fb4,8d20402f,bc683c2,b7e9e63a,b02c5027,e2488ee2,4c53365c,d9101fb9,5bcd0c45,85e25738,36156286,fcff1c89), -S(815a5ad4,fd1e59c0,56bfeeeb,b50e5728,18a6412a,2eef8d42,7e27c871,e41fcca5,4f358e87,5c7b6e0f,ffaa3026,205c07b,4a438394,276ae929,e24ff4f0,307e956f), -S(10902a4c,a24b6807,ba67d735,3fc9582b,ebfbe13f,fadf8146,e40016b1,40956db0,bbfdd872,793fa436,5263d277,f2ae1512,b5f349c7,270561b5,4c151824,6b430743), -S(858aa1f0,dbae0cde,a7640775,44f99261,af16469c,602f31da,3345671b,93758d48,ff63509d,d56ff954,3cb112d,941fe16b,b5fef4bf,96b8923a,c0e3d3ce,6f0e4cad), -S(1be90c71,7032671e,3cffce34,1a6c507,e5564576,ebdfae2f,bb28a20d,ccbbd6de,69edc8d2,20bec442,2cc47888,22eea780,3d4a01d6,1f8da9cd,4f8533f4,146c16cd), -S(6149cd0c,162f1ae9,163751a6,e967422b,8a80816d,deaab38,e73237c0,cca923f0,9dce938f,fd20eaf,b518752a,9cafb862,8416e3e3,8ba723fa,12442844,1bc7a477), -S(20696c11,f43db49b,d891505d,cffd36a8,a0fd20ff,1c56896c,51591ff1,421680bd,397ba456,6566244b,a186055,bbbabac1,620d1b9f,9d2d06c4,44069ba2,22041d79), -S(caefe4b7,91049900,5f6247dc,f1e49aed,22493a96,933ec702,c93f83b3,455fd6c8,6191fd17,4ff0887e,886086f8,c8f9cf8,5d3d3e03,30f436c5,50ca153f,cc1af003), -S(849d894b,2720850b,bcc0bd08,678205e7,1ce2b041,40fd138f,e16709dd,f3c9981e,8909d10f,494af391,a3ae9000,7af2a292,8f066ff3,22199e64,e3416799,a25c43f3), -S(d27b2fb6,e38544f9,eff19084,cc901d70,3356937e,292c1989,856bdce1,f6a22364,8c296bb4,a89bf08e,2ecd87b5,b49db335,b6e2faf1,b1b57146,3264993,77e56175), -S(37e04b68,f476235a,728bbc12,e3572929,97243538,e37bc2a6,bdf6b7,e8ab4d63,ce346516,383c0573,9de7a2cd,c4b0c0ec,9c3f7bd5,c3e8c27,271cb9e6,7ebdba4d), -S(b3c6c10c,5eefc0c8,832d9c99,183417fa,9351868e,42952b96,2d623305,9a1a3eea,d7ad6ba,968091d,fa8c68fc,49aff425,44f35d39,a75824dd,a79c5b1b,602ed3ca), -S(5bf180e6,763045ba,1453a353,49711a67,9175a21f,f2b7b381,8c8e5d8d,4927f107,72ed6000,6cbe16df,48d037cf,237cdbb7,93705ff7,2bf38c73,e6a87f1c,46ed40e9), -S(82e13ea2,3cbf23,ed3e2f47,922b08f5,9be10fe1,48de26e1,168b0784,45705ec4,288ae681,decf904c,d490b6a4,d5a3e5a,75bee593,ddfcce76,693ca57b,f39c1805), -S(4ac56d72,b9a5587b,dbea0ca2,674d343b,15adada6,f30d7a3b,fa481f7f,69af9467,5db2d7a3,3d42f04f,c75ee27d,7a7fe9d6,3eadc5fc,ce770e3,78d09ff2,eb62d78e), -S(bcddc00a,4fc9976b,6795da19,44f181cf,6bbfc775,cf4c0212,eb419580,82eb0e4c,30eed6ad,bbd149b7,49053931,65941084,470f0338,396a6c57,9fda211d,358a48b2), -S(9331e909,bf2663b3,8ef46e21,2293e63e,c7c1559b,853c3095,cd749971,79f116db,8ccef168,4504893d,30418aa,343b3f9,3fb0db2d,895359ef,f1b78d6c,1f074fe4), -S(12df2aa,c307209a,23b543e0,7e220557,3bbd8cb9,e341fdd4,6326ecae,916c329c,48d2da1b,dc2a251f,a861339c,7b92bea5,cfaaf0b2,3f4bf625,7493df8b,228fc8c4), -S(987e316f,f09ad376,eddad996,98228fab,90573f6d,60f13772,e55429bc,e77a91c2,82484e05,45aa13ae,23007c0b,7d6e0d0a,7b8ee542,bc50ed28,55ffc819,aac4cccf), -S(7be67dd0,e377aaa8,f13899d9,3ee2e9f1,623d5efa,ece91690,82c9dde9,ac7905a3,ba82932,93f21a43,23ff368a,86c8acb9,63328f81,5f003f5b,604082b2,4d4dc3e9), -S(133110e3,5e53940e,928883e5,fe5150ab,303af955,7450d37f,20dff5db,c8e2030b,54ea08ae,730c8117,ff1abf61,e89fa960,2e434dc6,c43c6a35,3a45d535,69f7bf96), -S(a000b820,53c27e06,3b6ac0d6,2cc0bf94,449ac467,800ebf8d,5e6bfe91,bab6cb36,af600aea,4261cc05,48e7e30d,f9ba50e3,e4ca8708,aa276bf2,ea7e384c,f3e3880c), -S(df50b710,59dd653a,f1f2b8d8,f39e12fa,134f1020,4e794ba7,9a734a39,eceb2217,17b8416c,51c8d01e,7739645f,eb5344c6,2c5b05b8,d27aa83b,d02def84,c128c04d), -S(b3b6ea83,cc9ee99,d7518cf7,94fcf12e,5f2d9845,b165330a,1e55c4a9,4a601b45,7e9aaee5,3dba428c,b042c0b8,87701d57,bec9635b,f54bfb64,13742d7f,3a7576fe), -S(7c81a6e7,36ff8ba1,82e516eb,b47be4fc,98e926f,bde294de,e371f068,687953c0,9d8d9b8f,a5b608eb,46bb5fa9,e162ff4f,47e2a8f1,86f41847,1c2433b2,462aec03), -S(e370435a,c9b0d2f,175786d8,6e2bfef4,ef7bdbab,3048fdc6,abab0fa6,ceee0cfa,586bc07b,a05088bc,ceafe00a,dcceb00a,4c1a3704,2f43f011,218ea8ca,7df4f04c), -S(999bc950,1d0b31e8,5175b27,17055c41,e5711b91,fad9af7f,82018e4a,a8f092d5,592cb475,2cd85ed,23d10139,55118027,7f6b5065,9b374ec5,55cf8f08,bed57ccd), -S(2241da6d,60fa77b2,f844f4e0,6972c230,1305d1d5,5d1a1453,16436693,232a622d,1b3ca0b0,8ddfe046,b916c1c3,7e7a29ad,9d235e6f,4f9aa72a,9676d62,e3770035), -S(d4e6cce1,884a77e2,dcfb08ff,6e4717ff,ec85343b,fa2b3415,1e290c2b,e9560171,3064c1dc,9eb6fbff,baac5bcb,ba14ed43,523db1ef,8fbbeb38,3e57dc9d,945e539d), -S(d2baeaff,eb5a040b,a7627374,ebf692ee,65316c6f,b30c03a7,7a6c7882,f98d0ef2,7f5b6e13,d91cd74e,6841c97e,32ad8e4a,3d8c572,1a206b30,e89c6f19,43313f2d), -S(150db822,7f60d338,73602400,27e859b8,7e4cc5b7,749d8d16,6ec3ac03,cba95331,12938598,70c09913,a855559b,2544d3b3,3de7a12e,da4aeedb,72b44568,7f6ab9e9), -S(bd607750,1e8d489c,aa24a424,8baa60,e0a86ef8,f9f6ed17,4537d826,c3e90fbe,9617baa4,c6ee1d2a,6231b3aa,5d145b30,6e0052ea,d1a0cbf5,1f74ce5d,7461b54), -S(ba04c85e,7755ff09,97b5c7a6,552e79e7,455b85ce,3498236b,6452958a,d01e04b8,e82629e6,1513be7,719c2e52,ddb4e8e4,3530240f,d4e3f199,b1738596,9498321c), -S(be1c6207,4ee93f45,6dd94b72,afdd295b,f751df9d,a77ebbe4,8e5de0a6,a6f9ba8a,3a1fdd34,72474e68,83130c08,b1e99e51,5c3ad11b,7c321b52,fce159a7,127599d9), -S(21c4ee54,bf48268c,44996b18,aa38a92c,7553eac1,2f4bff57,e89fd389,c9ebb1d4,7a0cf9a6,c45cd57,d0a1aee,3010ed52,220194cb,ea43715e,a4252272,71064b6b), -S(2ff1ff0a,14c965f4,9ee43f0d,64ecb94a,344d36d3,d90616d3,2b208024,4729d291,47d74f0e,8c9c7dd7,580ae2eb,3bf07a4f,320c80a1,13a5eb73,cfaaf7ca,e38e9803), -S(6d5ba86e,be2f0de2,eee9d917,aa69bf71,9ee9e93c,1ce7cf74,a993435e,480b5b39,9c19c406,1d3fb92a,4dc26c8c,26bbbab8,5b4e9acd,950a7ec6,824aa915,c1f9cd66), -S(49316bcf,122ac309,2ece7f07,c1449a7e,db2bab4c,29c7243c,41dff1d0,feea6aae,3fe2db4c,26ebc1df,66a03c16,deeb4f5b,4a3a32fb,2c2db184,7dd93738,a43e68b5), -S(329b8fda,fed0ee52,b86a0963,54c2141f,c22734d9,fa8e25c1,4376d539,72f123f6,35365b1b,8ca97c37,1f3c0d34,599d114f,ee3b67c0,fa4973ca,b0aee621,5f07de1a), -S(c74140b4,8c998c17,e7895174,b461c733,e687f71a,861d5687,9535f11e,31ecf62a,4a648bd1,5ce47fd7,b9a8382,7842281f,59a6e0ac,6dd049d5,c05748cb,ec607556), -S(92f5177e,cddc78ba,37a947bf,c72d4bb4,531ea7fb,1e7c103,d312fc2f,a8e4cbc3,2d348b69,cdf37794,383739d,3af49d0f,7fd9b0b8,1b5b918,9d3cb49c,ecd25d0), -S(31ca4598,daec4eef,975b3a18,b14420fa,48634ed9,ceb31b64,faea0fb5,32673490,574e1a82,b029e852,6e12a242,a21179e3,d7835a62,384da226,c7b9c879,43ef506b), -S(f7a66fa1,103f1fde,1392d998,fd5d8c2d,9d4804c2,999df8a0,c3d6780,ea915b36,94b115b6,897e00bb,166d01e6,e0b0e3dd,7399e7a1,98985a00,f06312bf,e31ce81d), -S(39cbdcb5,8ea994fe,f678e688,c01fc74,a643b907,b7d00c59,98d609c2,898274d2,5c256316,3717961f,3dcf176,73183034,9d881d7f,11544246,1a42a9b2,8b524e8f), -S(56fe8710,6d493892,4750fedf,8cfd9597,766699b3,ef9efaf1,26fb0441,d01becff,6b16649,80e3bec2,9ec107a3,f02a0831,5ff24460,b0b0e29f,208610c4,a3ba722), -S(e9ed0bf2,81770721,b3132049,e48ec3c8,9b33e62d,6eb3f1cc,b50ce7c1,6cce6741,ed06f8a7,d93913d0,fbdbd2f3,ff5448c8,f004f690,340b84bf,ded66508,19c356ea), -S(a3e250a,e5f568f1,fdb0d60a,8856aabc,a3d35a9c,4f23c07f,587646cb,41b9d29,3d2c6652,31f48e61,a6c4b571,6ba8a07e,5c8374d9,2d0ca6f4,970aef59,3f2a78f6), -S(bc08e135,216208eb,8bed1164,3deefd2b,a89959e1,20d3aefb,4f02976c,ebea4fd1,bd59151a,ecf185d,a0da79e3,817c9b67,605b46e6,41b733eb,a70180e0,47bbc4ae), -S(1008a624,ad6badc,60b3457e,702ab324,6ccd3f90,aa64d741,69539116,64ce56f1,de2d4c03,69f0faa3,5e039afc,1a650137,cb299fdf,8840bdc5,219bc9f7,b94c7219), -S(a298705b,a7c0a8a4,7b68b674,c63d9d7a,fac19b56,eba7f866,59cace5d,fdbb4b05,7b20b074,33988789,da3b41d9,5a9f0c71,f2965ff0,16714652,926f9e32,287f703e), -S(325e58ea,980fea75,a79f4254,60afb0cb,8f68bed0,71857e89,e4e7a88e,34b5cfcd,7034e0d4,ca1844fc,47d4c813,736bcfbd,7cf0c693,cbdc1ba7,b0d29019,44212c16), -S(22d51a7e,22bc439f,9179932a,254bcdb8,eb5bd7b1,515645e0,2340cb6e,8b94cffe,1da471e6,1c8ef75b,10525d6,132a14af,9096a429,e277022a,d667e204,91a786ff), -S(490cd510,a010e368,b3e4f0e4,266bd0c9,c04e3434,6d039f0,764f5108,aa31d6f2,2ee7815f,9ec437f9,3dc69f84,b0c91231,326c0159,4cc492f0,1f9b8d88,7fc022bf), -S(f8896cfb,f2d14e5d,ab1f3c2c,1e669cae,433a8a9e,42c7e68b,206a0d88,b4aee3ec,a84aa805,677a7c6,12e7930f,b91293ec,afee667d,2b033019,ffae8d8c,bb7281da), -S(9be847b8,3ff9d27,e74db522,cbad0ceb,3feffe52,1dd8e7f,999e515e,253ab848,c2646e15,b0865eab,c459a0c0,233bb52b,e202b681,c060f06b,ebb3a39b,69cc19bf), -S(1c6e7cc3,f35b404d,61d0454f,1a9b5c58,40b96207,95b613f0,a896d781,9e29271f,352cb00b,5d556077,c9fc75eb,aa1c28db,dad01cdf,dd5e75fe,ddd43ffa,8042385c), -S(56c10f,e369938f,13863e7b,5135ffc2,6da9eebc,5cfd6eb0,7f7d1f67,fa94132,8bdc142a,f7ae1906,c63e3de9,5bbb63cd,650ed4ac,b9a2c321,e525b512,397c5e99), -S(70897a5c,2d8d2e10,d24a0c43,a689c11b,be2b9f2d,2934ae6f,b3dd130,34046227,3f9d0207,3e083e16,f64ac869,5c1616e9,8f87e8b2,c9c95ed3,3bbd85b2,dfbee7c3), -S(e2fcd5fa,5c6af2d5,1297f97c,d2f0918d,320c785c,ba3802c4,48fab36,2147f39e,5308f1c9,b9a24e1b,855b038a,41004b2d,492fe91d,8ecb076e,9aea21ce,ecaf59fe), -S(463d53de,9f07ac1c,6eb5f7ef,2bc70046,261d6a64,6fa516c8,f7677ec9,b2153acc,ca198775,f0f19d71,48c138a8,4f5472f2,f8e5cecd,e2b7df53,61261cce,f322b762), -S(663438d1,82758d86,f292f12e,cd173445,2b554cac,1561f0c5,8f5fae70,9b165c21,23eb676,75e8f8c3,e78fa6c9,99d6e185,e0f789fc,80576620,5c50518,39e15515), -S(9a8317b0,65ed508e,4c9239b7,af39f42a,1d43bd98,8fc101c1,d45987cb,ca58f7a6,ce0db1d5,4df13594,57d9df20,6a487348,97102335,dd24b2b3,6e10bac,4d9b5808), -S(da6f2ca8,915e313b,8c4b221e,b81aadd1,e7468004,8030b8f1,48d1b733,caa33be0,bb59cc06,d267cb7d,c954338,9010d49d,466e4c3c,91335f62,1c4fe7de,d17cabbb), -S(7a18820c,1774251f,c299eca7,871bb526,b01081b6,c5321056,872da42b,9198954d,3d216aa6,1702fee0,9cd2a72f,e53d6092,2b07b51f,506f7a44,ae490af8,c9da7598), -S(1240d207,3d234306,70d9f2d0,17bf81dd,728e728e,5098238d,b0d79397,2628f5ad,612c97d,13c5a948,88ea389f,e809b656,77fccfff,d5db913b,771647a6,680fc074), -S(3862d4e5,c973e75d,ac6e6ad3,1e3e24c6,e9b8f5e8,6641b20d,f0bdb04b,ca98ecbb,524c8d0c,7f485be2,decedee,8320ec4c,79b1c25b,414e129a,2f848de6,ce3997b3), -S(afe8a621,bbdb4908,5726bbdd,b0d31469,33c75a94,bde06805,179729bb,1518467d,19b94d68,8a7346b2,e80ccec5,a393b7cf,afc4954e,5793cbfa,e02d7f70,7610fc85)}, -{S(50cd2e16,997d7d45,98bb2d9b,61aceaff,5ad5f38c,8286a0e1,d08055ad,726c7800,dd19c3b,c08b8d97,88f9de1,5941f5fa,6402bbbb,5fdc708b,cfc08844,eb23733b), -S(428114c3,8fc9e242,451a001e,34df1509,1f5c14a7,870f110a,fbcb0895,4c4b2496,4c41e9fa,ef00faed,fd12d4b4,9f5322a1,47ac4a7b,f8c7fc84,3a6250fc,efefb84a), -S(c0b87aac,8a4ee530,8476632d,ca83b163,3616bda9,5609ce58,8c09a48d,f544051e,a054562d,4bbfcd57,dc7ecaba,f110a6c5,e75e2d15,226bfb27,b8f88172,2a2bcdad), -S(e7abdaf2,2ddccdcb,736bf2e6,fdd79362,b02453b6,5619ada8,c018fc62,9fe2a74d,8e8362ef,abe83261,ab1843bd,2a477a6f,4a6a4aed,462e266e,e76f5913,1277c153), -S(ab7c1829,d773868,7faf5581,150db894,4d0a4815,c31e768f,ad3b313b,b159f72c,c687f86e,7e7bf0fe,a625143c,d6d7d130,13986eb1,5b2184a1,9f42a799,fb6eb703), -S(5f041f43,9394e0e9,23c951e,1fbfb8c3,8e1e3ab,58640799,b4ecf906,a6b2f4a,9f30e2ea,d04ebee1,f5e93cbd,2ed2682c,f2c22a0f,623f981d,f59d414,8c4d2d68), -S(b1347d84,86341ce4,84433a1,d00e9dca,63b94338,3818ccf6,59b80582,a027d202,2d30882c,d961fdfd,bb6c38a5,a11b6e89,25cc7e03,fe48abf3,3bbd86a1,6a65887f), -S(6e862ad8,859cd489,16a865db,cda120c9,2a5d8862,460a823e,9c47aad3,88a1c580,8854b584,e25c1b29,1c17fa6,bafcd67b,11c9ffa6,480679c6,8e253175,3faa4ad6), -S(a1b78338,c54bec48,aedcd65f,c60b25f5,eda31e34,d6badb32,75c128b,e3b8e752,86f46d95,157e23f5,6ab1f851,93e623e7,f693d74b,a08b47e,f776eeb3,cfe2ceab), -S(5fecd94d,128ae25b,b29daffe,c0d0131c,74df3dc8,9c4d573,e59bf41b,3f83a628,4f2ee3b2,3e5a008a,4c26b525,a5dfcd69,93215d8a,8547f13c,1c871f1e,fb082c94), -S(bca9377f,c179a785,f7b470da,51bec3cc,d6306938,f21cd224,7bc69651,bec76b36,cd1b6406,a55dceb2,c34e5c70,ee7fed4a,9ea3b1c9,92425ea6,72aeaf04,e5a464f9), -S(95d910c1,684c2963,6f90ac23,32461ef8,6d87ce1c,7dbe889f,405abb1f,cd0f57e4,1f095ce2,45a207a6,3c8b0602,4b4f25f,30e541d3,c325ff2d,c2c6a9a0,2db14235), -S(77cb5deb,ce99ddaf,4aa546db,274be540,a29b5664,5fdf411b,879e726e,61bebebd,df4b42c,63787720,42a10781,fafa09d8,e0329d72,1bc2189d,5dc0b56e,4700910c), -S(152ef349,2f9a22c1,87b70012,5b08a6da,68b50df9,1e671571,5ae11edf,6a35a3e8,d22a3f0c,654d88a2,bccfa6c8,704b99d6,7f5cf72d,ec1213b,f2c682a5,1bb91c81), -S(aa9492f9,6a2f4ad9,6f9d3b57,312edb60,1ab404e2,52ebbd4e,f86d5378,aa7282a8,bad928db,b54e8af4,2931d08,612ee412,c504c28c,31274bc9,d63366c1,c7f072e7), -S(a89ab05,ccb1edbf,1d95f7e5,5b2c1aea,e1c45b03,e352b2b5,b0e6a731,898a3453,72b9172d,548e4899,d24d5feb,87df8432,e1a6dc84,8dd28233,58a48c59,578cccb3), -S(e96d95b5,93801cdc,1b2b21f8,81f4154b,3967e7f2,84fc5a25,99c4fe5c,cf0ce66e,1a43ceb6,afcb7bc1,f285aaa,57dbb2d3,10d09cc0,1942aa72,daaf550,4c3c6bfc), -S(21de9188,2c8ca8a3,847b65dd,c667c64c,8378a756,cda3b9c1,bd6e438b,8b619cfc,d1d64895,a03b455c,1f52a019,6fa3191f,7dc57f9f,419d159a,d0faa03e,ea1f09e2), -S(9df78d29,3fd3a96c,f3d73bf6,7cec9246,edc8f68e,7b10e7bc,8a14e8c1,980eeb4b,d14369c7,993e8ccd,b89ed1ec,18a3fb7d,2659f70e,384a9f3a,55761eab,5925bcb6), -S(81a04986,e34ce13c,b01e334f,78bf2a3e,941e3e4d,243418d4,46fc0cd7,86f5dfff,3b6093dc,864ad994,f1c3b88e,81a46f1f,a916b51c,2d45eb06,46793fc2,e070abc6), -S(2f725b7b,8ba1d7c9,1c7b2d0b,65fd4328,f468b516,5cca7699,3430669c,d5643b95,dfc13e39,8ee1099e,4ecbd8ec,8847caed,e9872ab6,c9b0533d,b6191ed9,fa9b0e0f), -S(794a6094,8ad0dea0,907a4010,222754ef,c6e67a7b,d6c5957c,5eb004a9,a5518693,59897754,d7799fda,fbb2cb22,57687440,4c4c1318,b73745e2,e37b7f9a,51eee929), -S(7110e58a,64e526f9,a9caf9f1,e0ded62e,53450a64,3a6cd150,76983083,1d113dee,4629d7b5,e44421d4,4631658f,23ea59ab,1f15f446,790a600,483c1539,9c597aca), -S(1d550551,fc307b9c,b16f034,b79e7937,79127f55,8258461b,a786726b,d4c4aa65,51c47d4d,70f9090a,a7f8a183,75f74d4f,ac9c98ad,5c3bb916,bd87a9,aebc3de1), -S(4973c3e,97daec54,e5b9e9a3,6343e7d8,9c57380f,803f597a,25a386a,a652da69,cf403eca,b165571f,6b509b04,284c6e36,2f082b5d,5e7bc302,3ec0e55a,e73bc4f0), -S(61f7b3ec,444021b,ee3fd421,18e7b7d,fd795b36,d0145b08,ae09e1f,c0e3b07e,7df1f20c,79e3a7db,72cc08fb,98fed87c,ea923a91,815a187c,55e4430e,cea5e963), -S(42426dcd,302f698d,9376959e,50e6f471,5b1e2371,fdb03861,6ace0e2d,e27fa90,4c054664,1c4a0ea7,8280c526,70455e3f,51bee24f,acdd46d2,e9f82afa,db42d1fd), -S(80939488,3eaccc24,b1639e9e,656e7b76,2a310c4a,778b390f,d7a708d7,69c63fc8,b83fb593,a2e198f2,5fcc7add,310c8285,c19d314c,7614371f,9db28e28,8c2d47b1), -S(3f52b480,40e1ba54,67cd752e,a0265f50,c3bd1964,8f54dc8c,8dfaaf16,d9b3cdff,207a0014,1ee322cf,24d81b6d,2a7ccd87,be4d0b94,a7df9234,c0093bca,3a36d60), -S(c09cf34,bf1b1f94,15b63dc9,8baf66f7,68b073c,6b88fe53,7a9c047c,30703ec,757fd4b7,4f0fda31,99928ba8,39999cee,f2adbef1,8cf2aee3,4ce3708e,2897f95b), -S(8c1d9d66,b10dcb56,1fc72060,db7780eb,187b38ef,b18d6222,64188a60,da748871,b413ca7b,61ffe6c,16d493d1,1f955cd6,c7d7bb53,1ec4191d,85cf2f74,4506d8e8), -S(e31c4039,f33a6a5d,8682c906,612aa37a,3f522069,3948bfa0,dab4ccda,4f08900e,17d345b3,e92d1174,73330b73,cea9b1f5,f1d95ddf,40bd027a,b9b9a0d8,f84d5e26), -S(c4d82663,9c182e6a,b12ca500,3d5eca75,ee2944de,b9222c4b,6f73c58d,62d24bf1,cf4a0f43,e81dc58,c975d59d,73811d14,b01587c3,1ace50c0,b0b41f26,1f010e8c), -S(7c2514e2,fb6bb04e,829d82a8,ed9160ef,c9db98a,f898644f,bf2d01bc,97192be0,72114f16,4ec6ba1f,c41d6b0d,6746da06,4b46a506,171707ed,36cc6051,85f57ca6), -S(fd74379a,f6a18e2a,cd330fc2,49e346b6,89f7a73a,5f4d8862,4997a3f5,826a244e,dfe69f23,b9b2e402,f612abbb,4a4fb044,6a040706,19d6596d,b9953e6d,7179a9de), -S(a1c639bc,b913e3db,5702956e,9806430c,6572e908,a129bbb7,7c8ba5c5,50edb48c,7db1fa15,4c5841fa,c2127793,e9bef5c0,f749c99,66ff8d92,5a8ffb54,e701579b), -S(922dddff,7449c027,daa267b6,83112b45,a864a11a,1bd1cb61,ca76fe3a,77a6dd09,2beb84bf,87b85974,316789f5,148e4f18,386e20f7,41ec5066,2066c454,44c840dd), -S(ea7714b1,fcdceb95,407433c3,4c43a50c,767b3db7,fc7f6e6,81e79f46,44f044c7,6936f1f3,585c04ac,a1a2a562,424e084f,44e0b404,f97f1db1,37b3f00,b02ee04e), -S(cb4c8e7a,f5aca51d,448f3463,9c631821,9dcf6377,9383ba05,5e44966f,47fd36ca,8b0ff5bd,e8285a2a,1f4a223d,f6d496c5,15825ba6,d835370d,b2313418,b947b4b2), -S(921d8dd7,ba630901,3f365eec,ba09d017,2d579b8c,9550f6f6,a6d098c0,bbd08b3a,dad72fa4,9b0f415e,d9f96bc4,78a93e71,98d9456b,6ae10f3f,a1c744c6,e494e5fb), -S(7c9467d2,2cf5a364,191bf731,1ada75a4,3d081226,ff2e359a,47868572,3af15f29,50b15ecd,73341559,32ce1c54,e9a25b96,15dda8a0,6f4bc132,cafceb57,2fb48581), -S(48d10472,c10f4c90,713f899d,65f6edd0,af1724ae,117174f,55d4667a,b440e13f,baedab21,45103f2,aa668f05,2413b8d5,61ce5957,bebcbd8b,c49fb824,1af21303), -S(880d76e4,b95a3a8d,7ab6f9d6,f2069668,80069c0c,c447dcb8,f6063d9,271b570d,150d6984,2f638d03,881480f1,bd2a1958,9728ad72,f97d909b,17f79cdf,78416360), -S(286eebb7,f9215e09,969d8300,72b15a32,fc7733a0,455d2db7,71e527ba,e81caca,8584803f,db64bd55,317dcb87,a8c316c2,f48b3417,d0087527,338635c1,f78decf9), -S(b3e39ada,c92e1922,de3922c8,2c7e19d7,b5d10f4d,5e2cd771,492ba2db,444ede5c,bf9c1afa,d2cec5c0,66cc9e9d,61cce716,f58164db,e31f389c,2b596c38,e4c0ec9), -S(749ba52b,b88bc33b,b31f7aa0,fb95a62,932e447a,9a7a2926,56d16676,d66435f9,7075f278,6b7df61b,70065a46,7591fbde,ec40001f,242775a8,67fabdc7,45221691), -S(5ddb1306,a33c61c3,f0386141,7fd924ba,3118fa2a,53943221,b24cb748,841e4aa9,9602608f,4fd2f4a,511d012,320d05ed,bf1b5ba7,4da5f6aa,2dccbf0,83a18551), -S(6ec58a5c,d0ade361,93c644cb,e96e64e1,f2b519d3,80f7162a,b962337e,5b5c8918,85bc58f4,49b7fc44,1e95721c,b9fd8cd,63e8a250,83d9ffc7,fbfff18e,a2ef7453), -S(9b2f11b2,f66f7b29,e8421aa3,549c7565,87cdb7af,24354a3d,5e397515,f53f8700,3faff052,d2557793,b14a0574,942fb52f,1a53f6ba,e7f4c6c0,a2491194,2d9ca567), -S(d260f1e7,57c31844,9e12f1c3,15d28bf9,fce06b1,f7ce5db6,3210ab74,fa45cde3,54952184,1936423f,2314754a,5b419041,7510f396,90996d90,47ff1225,46672ce4), -S(c6b77e18,b935c842,52aba9bc,2a5f9a6b,86b207ef,5487e89a,7c754a7a,bd03b3df,1ae09c2f,61732aa2,9267ba72,8e22241d,efd6762,16b3173e,239cea45,60ad3978), -S(ea2c66da,fe996ba0,ecde644c,28fef595,490710fb,1052b81,57b63260,e53e5a83,ee91b4e3,cb71b268,dbc394db,7744ef3b,ed0362af,592bf252,71b8ff62,b821b8bd), -S(d6f6061c,904d3a40,75b2c0db,7620a6a3,9a7c21aa,9ea5ed11,c661132a,8cda9031,48fd7dd2,50bf50ca,91d362d0,f646dd6b,7e0f240,4ffc2973,4f131e9c,dfaca469), -S(30538847,93e3b958,a808eeed,546484d1,10cbb833,29a2b2f7,6f61bef3,b47eb9c3,ba914a53,87705dcf,349f5257,6bce5ff,d711fff,6fc8f6d4,3fd61b1e,2b47a577), -S(38558d28,18358d69,ac6b59fd,22660f25,58d6a000,35469f41,6f0970ed,1eeb8a59,8922887b,e256a2c3,3a3ea6,e745222c,9f07e9b3,f94ab1fa,2926e04a,ccd0c609), -S(fbc47f3f,534e67ca,d6f6de48,b88a0846,ceda2d84,afbb601,db71a61a,fd2e11b9,dfbfb0a0,652fdf29,5709b06f,2e61a703,d287b2f8,cee4ca,6a9f2627,2c30fd9b), -S(614d35c7,23a14b11,f3ea097b,6aedcf2e,536e077f,85cab312,74b7c9ff,a6b3112f,5b91b524,5a85c3a9,1194e8bf,be940984,c5866702,b51417ce,7a436642,d87edadd), -S(8304c266,a9876255,70768130,ad244f73,668a6bf7,ac611ff4,e782a6b3,761e5284,e47adf0f,66d4cad7,5834e7b4,f1a26b82,d5f9285e,a567fbfc,5f7fffdc,3df10311), -S(b1d777bb,76529faf,3ee711d8,58ba2509,c378c99,4dbf27bb,deac9d98,cd0202f,11f7598a,55c079f6,7bd036e4,e3a3bffe,159477ae,45c33ac8,8321fafe,3141bdcb), -S(7b91aed5,408649e5,41ea21b8,326f9549,6228e3ac,4e460b34,d77a526a,7972e4f7,12dff7db,c620f9fc,4ba287bd,2744e1b,4294e723,cf475d58,22f718e,c2dc326a), -S(56e7d74c,a4e530aa,7ae803e8,734280de,d87092d8,78ce187f,4a13ee50,c3d58f0a,d69161fa,901bc6ea,fbe62498,4ecc70f0,24755a0c,100ace31,7e677911,5a4c038e), -S(c83cdd85,43dcd105,efe4312c,f8f5e73e,1849364,668f0e50,dc40b13c,1c44fda,bad22032,de13c4d7,f2a61ec,947f266d,812e8b3e,d7fed352,93d161a5,844c96a4), -S(fe6f32d2,68be724d,28d1344d,8406c60a,70a2a009,db4c8e42,f434534c,4df9c3f,339bc5c6,2692a66b,853a323f,d09526f,3b336c73,bb4cc097,7b78fd67,96506d6b), -S(c3f6f279,fc937a66,a494b2d5,3bc6c2ef,13088c8f,842e1d61,3c5a35b9,ef2fcb5b,41cde800,63e8bbea,b2246885,59817f05,417d5311,e9fc8b7f,6c247488,10b30d64), -S(3dc7d5c8,abb4be85,9f6ba28,67dad2a4,7ba7970b,ffd77ca8,54107333,dcea1dd5,851d695d,54d5d7d0,b7aeac6b,97a27a9f,2100fcc6,facdf142,c82cdf9f,79c5cf7e), -S(2e28aa72,54ca6c6e,5891ccdb,1a1d2a85,53008b29,77a04ea4,d5deb497,bbcb95d7,361191d5,945c523,8908e0d2,6c08ba77,aa7db32a,5f19e348,a0037255,4105f55e), -S(84796cd9,233a7af4,7518bf99,778abd4f,a0238434,b5239f49,fba6b27,90f67bae,deb650d6,be46f3df,cd80fcef,20317c93,618156bf,343e9b2f,bb158871,5ce40c2f), -S(dbbbbe08,e4c768c0,531a3158,9b8abc28,f747bf69,228d16d0,8b0091bc,b292531a,576081af,a5aef1be,9916bc4a,2abe3970,12e371b,4c05e5c6,c97879ae,9e73c8a2), -S(25f6b015,45a8e870,592d532b,de9e2e8c,feece584,1667235d,a1bac7c9,58350591,5faff24f,2fc43cca,285366d2,578814c0,879cabbe,cde4b557,e7dc6fe7,43462ba3), -S(1cdd628a,a5ae5c80,85e83c74,986dda47,1d12fd07,158b20d0,d2d58599,f4648fe3,57ed9696,31e1134a,dad47894,f40c3e56,852d1ae8,5fba733b,d46951ef,7b33e5fa), -S(255c35a5,ce78bb41,ce85bef1,9804a70e,86aee3a4,24dcffcb,47180671,475080de,783f23,71984093,7db83676,7c3e20b8,f216bb68,bfa8b90b,7d9d95f1,1bf2db1a), -S(517283fc,d1cf1144,4f7375cb,77af87b2,3a11ce7,a954feba,378fc420,a05a8c9d,612cae52,640568af,607af275,4f6060a7,40b89f00,5dc02274,f2c6b8cf,e81c2e15), -S(39ff6f76,c8e4b6d8,4e742b0a,67725f83,51b782b6,638a032c,f9690635,fed32d55,c3d54b29,bc4ab777,c027f5a7,3ee75b4,a82dfb8d,5a5aa403,9f0a8787,dc054b58), -S(bf620a81,d6ad1d03,a66ca76f,c3b20e84,2fc75ea7,ca7e1f64,9818b27c,902e1ca4,4894f0fe,c2aef2fe,67c8aeae,5a9f0424,1ef68975,955eeb0f,66f63753,5d559351), -S(4c34e4e9,7584b95c,9bc6608f,7dba493c,97022eb6,14efc494,fb721fc8,3388a06f,b94f610d,b8bc4bfa,cffbd677,264ec28c,be18cdc8,db64154d,b62c4316,e9bb59e0), -S(76bbfe7,d39d6e03,9be09174,52fb322a,dd3ea192,6b546918,41b97913,acf75247,7bed078,7752a432,f0275ba2,a97749f8,754dee1,a5cadab9,5482d27,3c99b1b1), -S(deef7e31,9decf761,18e42c7f,27f427e3,4cae0d54,d7a045f2,dbe68349,c5b011dd,d3e73e4e,8f89b39c,83c7855f,8b5e352c,64f7b8d9,7a00c5a2,4b1b7997,c1db907f), -S(23f66927,d6a94731,2b43d845,fd0ee2f5,8cc329df,8ec37f11,75392bcd,c8d48857,747d60ce,bdc9858f,cfb28fec,5841d362,5750dd35,d08d0f27,4f173fa3,2fa0c4c7), -S(e885b643,c668ee81,4b94240a,4a68126c,625eaf2e,6f9dea6b,230a0bed,dfe06d9b,b575dd15,7436244d,191e3b13,d1bc8682,76940436,16b52aeb,7c731b5f,120d4bd8), -S(4ae81c35,d39ea1cb,7e5787a9,6a7738ad,89a0aeff,c556ba4a,d4dd1c5e,bf5a4044,76a3e3f3,96b88cce,2c978354,16cb13c0,f74bf815,ea9c9397,86da049,64f06d61), -S(490cc37b,6efe437d,35043f53,682dcc1,2b2a4704,c8102413,62fe38da,44717b5f,fb5c012,b205a188,6f1d639f,228f6388,2c598299,d2d6ee45,be44d994,bb6b6328), -S(c408d649,f8524311,14582433,d4abe603,5e66413,e65dddf5,f2ce6854,95be8d4b,bc9a1d0e,18504133,4e4b43a1,9d34b07a,1b3f7cc7,290328a0,71437e12,ed80126e), -S(af445e25,7fcd5ac8,54992782,30280aa3,354d296,6d494f6b,90c883a4,829ee71e,f839efee,87643874,2440e65b,870b0e37,3fdbca41,e57f3765,2cf479c5,cb7f6882), -S(f2c1adea,d2f8e95f,ad6a475b,199cc75d,a8471b82,1da81d5f,6d8b2baf,a1ea01bc,8e3543b5,36247e35,c2117eab,9d3e6783,f48bc2b8,b20993fc,1a0ff28d,1aad1666), -S(17b3dfcc,fdd57cdc,8a617eb1,5ec80659,fc695bcc,afd3a787,fd91d8d5,69abb5b3,75f1aea4,70f52f18,d2eefeec,7fff7f48,6718f784,a47cb32f,4f2c8574,591c122c), -S(f4d6bacd,1c8ac10e,7e97a6da,8a7d1af9,1c96a67f,fe76982f,a0ac95a5,f9f5a9e1,ea6179a8,1ccba22f,4dd93b19,5e151d38,cbede6c8,70a4a383,edc7898d,1f8f19be), -S(8011232d,32d4bdef,1fb56ae7,3e231a01,b877be6,72567310,2c30478f,50652092,49b91451,23311b4e,6c038801,f84561b2,8db03ccf,3df20b68,b35714e9,56b4f67f), -S(e23dd461,b79f6b64,5da455ca,90711ab4,cc117d66,ea8c9835,67f70207,ac5e1f31,8e84c4d1,ea634402,375c4d4d,6e8c8427,fa2479fb,3461bb5e,5fbf1f06,d34c866), -S(a2f6486a,97afc8d5,8367a949,278dca64,ed265743,16827b7e,7f3710da,9d7dfbc9,a723d6fe,419317d,623f8e24,75b365d8,cee8cb15,d1c8df2e,218f1b42,a72e7170), -S(f789b715,a7d5ba20,c1f8cb05,86cfe13c,59d27b83,ad1ffca7,75b2cb7d,9af88999,149bda63,63072ad5,279885b2,be81923f,ac9c4d07,2ee57602,5d99e727,150a26eb), -S(24078518,7abb2bbc,721e59e7,923f9832,77b13422,912c983e,d8670e96,c698c1e0,7e2f792,7976ba59,20748e26,ce48b29f,6ca37a67,6c8b4094,e661d5a9,be39588f), -S(8703f78b,17ff31d6,89833226,8fa9db6c,759e6066,ef8cf8cb,719f49a0,d7af6264,3b9c4023,d92827a6,53a7798b,fb21fe94,cfeb592d,a55e21a6,8c6615ec,2bda7ada), -S(52f6da10,3d75bdfa,4e0e7637,229f0c31,a6f5aaa3,2504daff,e1ef639e,2daa16e9,5d71c088,e8480d6c,e51062f0,241d0b15,9bd143ea,451193da,e13466c2,bcbdd037), -S(c68fa920,9f3a997b,2cc91748,3570ce74,1a0dcd63,1d7b483a,6f73a3cf,17b53eba,1f26839b,86154284,28858ba3,a3084947,883053d6,3bf039ca,89753199,21e505ef), -S(ed2deef0,9f558dad,84202b6a,e2456f38,39755fe5,6afb5aa1,147adbb3,915023ec,40be5a33,a71290af,e5080e32,dd9fa12,4273f550,9e78cda2,395235fe,c78e3274), -S(3538ad8a,98625432,2e7a9655,4e12d822,812b87fd,778e4482,b255b6f5,5c301442,5a6960b5,d21b0a7d,4afd9c62,7caec1ea,e8fa82be,e2ef80f6,50c56101,ba3a76f7), -S(a9580d1a,2b6544ad,65e45228,8e0dbdae,ec6de5e2,e9efc056,ff048883,b9f435d0,1a70df90,3d932f52,a9b3123a,1384cd6a,cb5b811f,bb267179,e1e4407d,9269af21), -S(efcdd63b,3c964ee4,f04a6618,ae526958,db1ac41f,bc53978,84529401,c0c53a26,913bc698,4d51d792,919b389a,dbb2acb7,7b3df92f,138355c8,7cb3caef,8cc50c7a), -S(c518437f,7344d6e5,8cb5ae74,acefba6c,a2ad92f,57f407e7,29f39221,885a8e17,efab7c2,145a8abe,50b46c51,9a679ec0,1fa017df,7c82d27f,cd2f93fa,affb5ac0), -S(a25e878b,9cf81fca,dc06a526,a9162260,d42273c0,49e7038d,ba66a450,25fc75c6,b08a8220,ff708833,56702dd2,b4971eee,956b2711,2767448c,7f2e553b,965f7bb2), -S(ce0ed297,f5961a82,327a1d8b,2c20f8c1,b996815f,c951f8d3,3bd0c16a,3ec45c3b,c4d21e67,8456fc84,955240e6,984b0a0c,8a10eeee,f40c6a4b,76aab8d9,5e887e7f), -S(b33ac12,369bf1d6,22c2c557,7fda98e8,f6bb4389,fad53459,e824bfd,e4409229,52925428,66a98f73,aaadfca6,940490c4,91e4ca9a,da343f8c,76b7f6cf,588802d4), -S(958d34e3,58ba9546,ab139250,d47f6bba,59f13203,e07432b4,f37da854,696e134b,e0c35ab7,45e91cb1,53ee07b4,f04f1258,9eeecb89,c30d10f5,d0322a72,7285ef19), -S(cc633cb8,b2465aba,a9a4428a,5a36c8b7,cb2fca1c,9702aef,8d54d249,338dac27,b6933908,62597527,8299b8e1,5fce0cb2,1ed84a9d,2533250b,6e417d2,fc19b06b), -S(61b81bf1,3ae0ba48,eb630593,512be80d,c4960d2a,9f0a6589,65ae04d7,36b4836b,43589e39,7f4d8df6,562fd8b6,8d4ee7ba,9faf441e,b1b09b8e,22f81925,9f0a9269), -S(2ce3ee71,b411ca31,74f0c249,7feb6bc,331a492b,85480be,32193c25,6321f853,32669ee6,8062bf36,b8c8853a,eacf0826,dabc81a0,48ef504e,e2ddf10c,8d6cb4c9), -S(6ecfd338,ab60c9a2,a50cfd16,498dcb45,8e6ac09,d5517fbe,f95f54f8,1b5a7551,b73277ba,4b7486a2,594f6571,a86251cf,54a1a5b0,9aa3017a,b4c0212f,cc94ae22), -S(a4cde541,dd4897a7,95f90ed8,75907a6b,8406a888,dc807d5c,6317c7ea,7f226d0b,5cd7591e,a305d546,14ff4233,600c813b,414fad07,8c1016ea,b021cd69,1d25d879), -S(4961a20d,ae4956c6,dfd04d1a,a261bce1,ff27a2ab,e0c3cfa5,6cfe51e,24c20fe8,9bf8d311,61ebbf5f,94c71ff0,7a9a04b1,92bc6cd3,e50baefa,71de2af4,f38a8660), -S(4b099713,d4622a37,d013359f,67983269,3274d1ed,4345cdb9,96ef3550,a57064a8,dfdb479,e07a1fb,ae741a92,2a468c61,7ee4cd46,25b1041d,f554e0cf,7fc5a776), -S(b5ae6420,8130d080,6c568d95,8222a1e2,3e649a67,8af5f0f5,89acdf17,8f79e9e8,2d883796,a8f45bb9,7d30e88b,99f6b01,dd46d91e,60d20d1c,430c36b1,b8b8ca45), -S(f7f1820,23de8475,7591f366,116bd60,5312706c,2d380d7b,16f50bea,71abbb64,5e3844ae,1db871e0,c12a7205,baf101e3,77af946e,aaea64f,c9aaf9da,e1ebbc12), -S(6d2620eb,ee6ec651,792adf63,9afb0fce,ee933e69,337ab7cf,2ec85ff,917ef538,e159145f,6aeff15,2e0403eb,f3082906,f98313f0,77028f74,bbe562b8,f335b6e6), -S(a98cec29,2cad6781,d4339548,10609d7e,77f7489c,2253c04,3ec1eb03,a69eda44,c5eb7257,c5b965ec,1ee643fc,7f48ca4a,b612f616,6a3ecd7,4c8da3c5,3c4efcfd), -S(6a88d0c4,4055a898,28a7003a,1fdd9941,4c1adb0e,90ed8d9,acecadaf,6a73920e,6fe7abcf,25385db8,be815eeb,14302bb0,5a630f92,2aae66cc,b0d42ac4,92224c97), -S(8a101a08,52559761,e2c6522a,6bf8909c,2547ef9b,550ee027,45e23592,89c34afd,64248f75,469015df,d9045beb,2de9573,c1f2e2c0,9f7a4cb5,cc85511a,f7182fac), -S(ea84bd08,37bb25e8,27ca0241,2cb8bd7d,ae47661b,f2460598,7ac20c80,753249da,15be2ad9,d4a8d7b1,964db56e,8415c890,93214016,e694f258,96574d48,45c8a1dc), -S(be2f219d,60dbe256,57bd9b46,18f62e2d,7501e302,885731c5,34b1187d,2c750f31,f521ca05,48ffffa3,dd70e0bc,79602b6b,617b9ead,b64e7af7,3d9ebcc8,bbd220df), -S(418d2b33,ce151147,83a75265,a876a709,ce7f452b,de9933cf,6e7ab1e7,7412437b,52693c44,5e1ff5a1,89b856d3,9d413514,aee35974,fc4678d8,86d5f998,a18047c6), -S(3e4685e9,3c65f31d,c58656e9,a8913d19,469f5e,2d49322e,6a99af10,c1142f16,1ed3edbb,6186e995,8241f3b6,ff7659b1,bbb007f7,f9b5f91e,92d5a8b2,c780d914), -S(35e15d66,d952ab13,de14a71e,20b1ed8e,f4b3f183,db75c62f,9af7ab3f,945b2d29,813f47b2,3fe523ec,12557edb,9e1b465,4582de57,5ca3752f,2e60be32,eb4333c6), -S(f025b371,b5c98b91,6157e1b1,53aac27e,ed42d435,53ca159b,48940bdf,b0f8d262,70fd31b7,a5470435,7936f98c,cb4c27eb,115be6ea,b4de7a88,1151e5a0,4364f12b), -S(31b36d5,b52ea8cd,c0298c03,8fa4f99b,19b3ae06,65d667d3,639ea3e5,c73875c4,924ccbf2,d1890df4,783760c,e6e2f50a,8dd8838a,bc87ac29,bbf89eb7,f0b46eb2), -S(1d57ff02,22db5c5c,f6f1558b,f71f0498,b706c7a1,84dc463b,77b4e21b,9d5c1699,b6238d2e,1bf715fd,d5cc0843,dad6fdc9,e1e6d485,c3584dda,3d06a1a0,414a3b31), -S(b5b7da02,4a6626dd,f67917e0,63a3a64c,f389e8e2,a631853a,c8e5f45a,4395cf24,151c4b35,22b4f1ee,2105b3e1,4ea193b2,ba6bf1d0,feb4511a,d72444b2,66fa7f0a), -S(2a58e24d,7f43233a,55a399d3,7cc0fd91,9b451985,13bd725,e24edc1,75ff6163,4f451eb2,c7374944,7296e447,406d5025,b5da17ab,8567cf01,ccab260b,da6834f4), -S(d8e2416,99d7e8ff,15853778,bb52a218,a2ed0c45,c7ebbdc4,a7357acf,86e7cd52,e849021b,83d33fc6,826c0a35,3f4188d4,37273a7a,7adeafed,6514bba1,a4fcbca4), -S(27f9e422,dd1b9a6f,64092125,71543d87,7d8ed097,52b2e6a0,cecd81e4,659e1f41,27563650,6d56cc26,cd289851,2274314c,bef8da2f,a4b1ba19,740d8ab5,4d4c3e60), -S(2071b53,72a746ec,a0795422,ea0dc0e1,b105e1aa,fe2fdd64,b08ff2c,47f4067c,1c95ae4f,986047f3,d969e8af,99775aaf,59a94c56,a47691db,fa0175ff,17641b0c), -S(b8decd7e,15355cfb,dcdb3ab8,48b2d717,3d61113f,58d21580,9292d4ba,379a839e,2ce7737f,7dd82aa7,76560921,21cf93a,a5e3c6d9,952c3adb,b6fb1f04,4274ad71), -S(23c7a3a2,70f20e77,d62f3d77,a67535ab,5554c821,71c77bee,1b05d2e,5ea67557,b8657a68,e2ded30f,19365bcf,916037e4,a1d87db4,632c90cd,ca782e40,b27bfda4), -S(b9af932d,753ba63,f7ecf070,d20d4355,42de9c72,a93f44e5,7b978e5b,7428432f,c2b21fb9,64593524,104c980b,a53de2c1,6e7408b7,33e2ffaf,17ed540a,6253847e), -S(e461cc8f,ad51c58c,fea92090,c2d3dc1c,41971918,687368c8,4c84a04d,d094704b,c1b114e,2cccc522,6fa3f753,5b6f356d,fddcad24,86197d90,4ab00cd2,f3d0103), -S(817e0633,4b8e706b,b7282b40,a4e243c1,87b24bba,6bfb69b0,d5a366da,c383e3a1,77593627,482c198a,f29a892d,5fb50a43,d10b4fec,5937d696,ee8fc6a2,20deabd4), -S(30bc10bb,d203182a,f7dbcf39,f0ee3013,7f26980e,e5f934d4,f151f080,b1341e5a,40fb3e2c,45dd0832,cb50d0f,4f45025e,3285bb6e,adefa1fe,4192e4b2,8a77197c), -S(143f113,8c45ea5e,a6bd339b,8d1aa91a,9db0dfba,90600868,309c0b5c,1a97648,e45fd7b6,8d025855,1c35285a,87fd77c5,1403c836,e0697b9d,4dcca76a,1422a6c2), -S(f3d30c38,4926b19f,5bafd37f,ea9b7c93,d4776564,5b8b4a89,199ed005,883e8c69,2f6179e,26dcba73,81ec7e57,1eb427f3,455808c2,21926af9,79efdcf,c7ff364f), -S(54fbfba7,13facf23,1013a1b6,ed7514a,4fe11323,3c363ca5,118a7d9f,63b4c116,dbfbec7d,152e7c9,2bb98067,37e926ba,66ed85fc,2339ad8d,410ed762,4407061b), -S(81d00298,aec59abd,c3ed4b5e,11d4589c,9c7a7ad6,54add200,ea6ab124,3b0c484b,226d41fb,a46202b7,ecf1ef9c,11acb33a,cdc15547,7bbab0c,1f56f385,6401984a), -S(2c088e50,50061a7a,47d84141,a858df75,f51c5c17,717b35f1,cce982e1,209712a7,44700a1e,99cd0f9e,8d05c8a6,18a75edb,d9d7f67e,45f5f40e,4c00eda8,290212e3), -S(2c903ebd,68f2053e,7a769b86,bb017939,556b532e,1b84cd7a,2397b1f7,f108a145,2915c5b3,f16b1eb4,8ed436d7,4a79c50,72a2eb02,b989da66,b164d475,941a8b14), -S(ffac0b8c,76c6b7d9,24ed25e,3f43ffa0,b261141e,715c07c6,c327a719,6b11fd43,9c25ada3,fe7d1661,1ba95eb2,231f00ef,cd250e16,68dd85d3,96025f65,4fe7da52), -S(d81236c3,7d7dda31,849e20b3,c7aebb2,b782a1e6,17b9d6f4,f56da4bc,d860c573,ac6628ac,98c0896e,ff1802ce,a43ae085,66e902aa,abd2cefe,b910465a,9f0fcf30), -S(19d94647,ccf05308,32903c94,7f149f0a,f1f7503f,92300232,a6f33e15,7874e321,3402ad42,87ad0814,4addcf3,2f7c60a6,6f65255d,ab4bbe,b10826f0,f5a07f39), -S(2248a7b4,37bb8bf5,df85b382,224a3d68,45965330,24f8c872,f81e2c33,610ac810,c3942980,b054122c,e806a67e,7f004b18,5288ff5f,d7e17ebb,97e68e64,1c416bd1), -S(d8a71ff4,a9de84f4,f28e78e9,4815ba2f,dfe48256,7128d149,e44d5419,da84531b,d3258392,34c87aed,8534e6f8,f03802b2,e76a5f20,552873c3,991c8d31,346f67d1), -S(322a4b9c,32ffd7e0,2548cbe5,9f50c2b2,e2a8c70c,dec7e39d,61505a2d,4d780ea8,809f262f,d258b1e5,b140822b,caf74d15,9fb764d8,53b653f9,7358adc,5891b0c0), -S(4b7a2f4c,e7cdc092,9bdf7d1b,bc91a60a,2e16bd9c,ad9f1cce,38ed644c,3a790fd4,5adcd298,78333b26,20d43235,8178c2b6,a4e697bb,81c3abd1,b850a334,933573e8), -S(2d7d8029,8da39ad7,ae7ee3a8,583768ff,fee73a78,728ffdda,b3921988,2ba3d8b,6f9e5aee,bd08f707,a49f120f,26869ec1,cfe9d9f2,a6e0f0ce,b6ce545d,43951358), -S(256b5db3,24dccb17,3b525434,ca36d6fe,37d469b0,4484dec1,cd44d392,b0f7aecc,c35db3a4,61f0f477,1a5d0131,12be5a90,64bcd516,2566a373,daa82b09,415c84e8), -S(9b641c2b,b2e3ee32,cf592c06,532dcd71,af0a1196,3a82c3a7,c0e809d5,8cc9b65e,e5925900,9d981017,bc12b524,b00ba98d,393be520,651a7b0,ea8f9ca9,75142814), -S(69700df9,b800a1a0,afa144c6,3a637027,ae53a786,e9938345,e147509e,ab6d44b7,227f91a5,b0492dfd,1e9b5d,bcd02bfd,4678bf86,8e69b7ea,e97e8b17,1aa1babc), -S(5ab9358b,a7008f2e,75392981,d93d062b,849cf9f2,216c48d7,4887d50a,3d8ae5d9,7b8e1ab1,9c6e9f7b,89a524f9,e39d5a40,90179745,1ed87e58,23f23625,115043b1), -S(46fa087,213b7db1,32997f64,cf9adee0,149adaae,e4d7c9af,61aa3193,606f12e9,2c428c7e,1c80e6e8,92f89777,d8afcb8b,8c0dbf3d,f8958f83,6ff1504c,e0517443), -S(c08b8c75,cede8e1d,c3ec26f6,ba7ae08,ec22f798,aa89e258,a0291e30,ee0c06cc,8454d21,18f72ff1,17866e63,5f65c349,2baea002,97b16e47,ef8876f,d8b7f5b), -S(f50450ff,aa054493,b0660d35,521d1ce0,156443b6,f5327e68,31385219,8e39ece9,aff228cc,970fca4d,9b583c23,b8e6eda4,feb549a8,2d767b4c,e535f6ac,d68d8287), -S(e80034ad,d9f421dd,de74ef1d,7a7e6e4b,fbe2dc0e,5f50b05,f7e8560,3c52ff0f,ef285764,dc9bb2fb,e6751352,a1926075,331c4abf,51e36cb4,36c9ee36,fea34e10), -S(cdbd6ea4,b3580bd7,29032b34,7e18c839,4832d8ee,11fd7a4f,c9c63986,54790037,80f51eb3,63d9f7a1,1e4508d0,643dcaa,7fd1570a,8d3e5f71,8371e118,d29f340b), -S(7eba7974,42a779a2,5d3ece2,a022719a,94a14eb8,e6f821b2,136c0d1f,f5637f70,5cd4f314,75808559,77def43a,9c974f4d,ed3772dc,b9091e7b,28745827,477a8611), -S(b44980a8,5e5fc57d,83d9791f,54418ad,5337eb5a,61746d6,71fb200,b5971f82,ff6cc373,5122c494,fed9063b,c8ad9e04,9842c639,db750623,997570e8,76324da3), -S(71057596,36c41dfa,b4bcd0e2,5c5d1d47,e60b283c,4a9762ec,10b15464,4cb07802,3a06998d,23644db2,b9cd18ac,1a077549,57e1cb99,d75ab6dc,c81db6e8,dcd947b6), -S(c134fd2f,c63a27a8,17e8f797,a120ed41,707067,c09931de,73e71fc1,84b1015c,5cd78606,9cc187f4,a3d2acc5,7b41d22d,cff9aa26,235ec094,c892a111,8488fa75), -S(8942fdcf,4cb81983,5e03559b,c81f4da4,bdba287f,b84c0ff1,2b023658,e389e146,e50d5d33,b47da2df,3130c838,5667c158,f5034d02,bbdf0be0,5760863d,a6cf2120), -S(3aed32a6,5d3188f2,ade2e91b,552d4c56,5d75c72d,dd51efa7,ff2e2e4d,49d71c0a,9f980569,e231ae71,3f524c7b,a616c342,340a1cc7,2a0a78fa,461c732d,8b3571d0), -S(5b824633,8060ac28,f228eee5,405b10b2,8b33ddb9,9d09aab5,c8f32ca4,b3aa59e0,ee4e5740,206040cd,91c46d93,24a94b6b,6439e517,cbbd0619,80b5e4ad,91938e4c), -S(4eac5700,26a7997d,b5864e0d,1e7fff74,61cccb83,aab89c90,bed839e1,a6392220,9506b28d,aacec4f1,9843944c,690adbc1,ca8cb6c4,305510f1,31521569,fbe3281e), -S(c205259a,feb286d9,bae84b81,debad402,c60a59e5,68a0f4d0,204e909a,41119044,16dad4ed,eb541c30,38af010,5ed75ebb,e281de77,c3e61e70,344ad85e,2ca34662), -S(dd215ac7,a8023c12,a7752db5,89b72cdf,90333791,996f7f01,67162221,db0b131f,8436a84c,4d7af578,2c377394,26012793,b99f5c4b,f6c37a4d,a2ff2847,c4222a6a), -S(2d71215,5647ace7,88354c3,522da12f,fc44920a,9fe67b1f,e05f9eaf,19997db7,23cb203c,4c904541,2e942d3,da6cbf37,3f40a1f9,b6d896ab,b797955f,3666b0b1), -S(59643435,43bd6f7b,658055b,2f9e5966,303c276b,b79438bc,10014301,7b6b04ec,6bf6b2cd,7c88a172,25a68dad,e029bb0b,26137995,cbcd9d5d,8f93c6e8,fadb52d9), -S(1fc70dfa,bfb7cf69,21f682ae,ebdc182f,f0ba39ee,8c28b779,325f9e7c,152a00cc,f79507e5,51c7b44c,c9525d97,5110a19c,3d51593c,4aab618e,641d6de9,466d8df8), -S(d1dbe6bc,1821a383,d10318ca,c23cd56d,17106937,42609427,edebb18d,9ff8592a,b45168f0,d49ba0f2,6a8729e4,c860ff1d,e1dcfb0b,7c1ff20,48b2cd15,be043205), -S(4d15bd89,53a4b5cd,5d11a16f,728397a,744db565,cf744494,b67b1b4a,ff07f375,9cfbab6b,e9cdb650,fe7ef824,c3118722,e68fc601,1b8e84e3,e7028e69,d3235565), -S(dec346f8,34a5575c,d58f3bc,86ca0d8c,9ef3f556,5b091917,c80f467e,fad12a98,20741ea4,793def6c,3b46e8d5,baaa6e4a,1f529cb2,880b4142,ef0a3ed5,6d445efe), -S(ccc91a35,3532454d,9fb0d811,941eeafb,890dc07d,ab4c117c,f9547c7c,6b45645d,9e25533f,2f6bd1cc,2fd8624b,a64d42db,fd8ac325,37f09c7f,1d74fe46,40aaad82), -S(feb81407,df6f1137,e257c20c,f58a77b5,83ec8f2a,b5acd9e7,12ebe6c1,2aef1d60,b7279d4d,470318b7,86ea0630,3e78981b,ea2aba8,162adfdb,5a8949b6,1c1e3e73), -S(ffe40f24,eef97a34,e57728e7,7c445209,29058d51,1bbe823f,b354f853,63009c7a,c71020d3,2946f80c,700ca0e6,a6dd43cd,a9461db8,a25b67fa,92008da7,a96e680e), -S(a36b2254,2f8d9055,41369ca7,793eb500,2f6d8a69,410086d1,ded6bdca,692d1b6c,b9b73b65,e69950ad,f25787d3,897738b7,5306afa6,8156419,892799cb,20a9556a), -S(92a24def,2b893f11,b0056962,b41273f7,76fa4a0b,4d525f3a,14236756,3d5b240a,9e9ad443,5fda1d46,a77ab3fe,62971060,8105f5b,a6d9fa83,47508d6d,7bd8d288), -S(8fd20215,ba152223,ecc28d20,749ccbdb,9d536b64,77474808,9d2cbac3,e0a11f77,434b10d3,33418084,ad2c42a,651b52c7,bff040b9,333fae3b,26935997,7f6be47), -S(b4e6caec,c78da734,80884183,d0aefa0e,82001bc8,2c376981,f40b5c13,4c8a034d,95f192ca,cb5059f4,3c6323a2,a0e09204,4f39ecfa,92c22dfd,e0bd5365,5b500c3d), -S(9536a1c3,ee4b8aa2,8edf3a0a,e2981657,df90bd4c,c62be8dd,8aad1a85,8c4d84c5,fcf54bd4,665ebaa2,9ea4d2ed,40bc8a42,34e6e061,e325abe8,2a123b06,36d99d4b), -S(3e15d13c,75ff91bc,5e928cd,ec8e303d,286deea7,d7a4d88f,6613dfcc,a0c27c59,f98fdca2,1e3dc253,44ffab,2865181d,b830c74d,2891c80a,b71a8,904cf13a), -S(8215dd74,1eb7a889,7895feae,170dc452,f8fc451a,2037af7a,fbc02813,827ed4a5,bad149be,dec24412,4f65003d,d44656bc,5e61e332,aed71f73,b58492ba,ede0040c), -S(7b3755a6,3913920c,83a2ab1d,6a738122,bf7a67af,ddba85a1,6b9d7de9,ad6cf0ef,25752fef,1ce6ae9d,4f2ce922,fc610ea4,d4351718,f8e97bc8,bd4396c7,11697dc0), -S(cdb499d,f67a81dd,db28cfbe,bccdf877,4f8b76f,6464ff8c,221a95d8,3e3ffe6f,4b08bf10,15fe6b37,98fa8da1,7438fb88,eb96720d,495d22c6,336e0225,454268eb), -S(ac0a10fb,b902bcf8,205b2529,7724073b,55fa2837,dd99edae,e256f7d8,7c19aac,7ed1aecd,d088097f,4ec8b005,892fd069,ddfc319e,f5bb3b25,2ab7c597,d775e615), -S(1e9e3fa9,fa96a4e9,4f19c5e1,105ffc9d,fd7add4b,63c85ac0,5098c839,c0e851fa,69bffc28,5927b917,dc4dc5c1,3ceef964,27dbac93,a778a01e,227906d,6abf9df8), -S(14359ebe,e923252d,f17e2320,d97a991,c16d7819,d9791f86,65142b93,4c2bc20d,3248f24b,d31f47ef,dd34853e,dc84f8f8,17403b4c,eb737d8e,c144daa5,2e5b65da), -S(13363dd8,56df936f,35f1bb71,eb2fc4b,df232e76,1fd9ad9f,db3a6d6b,ae78e837,8160695a,7428e400,9fc88172,faa6784,b3a2d03b,71f89a5,89dd85e2,f5565436), -S(6b71ab46,20938910,bf2e16ca,6e40a653,2c6c1b58,b258ad04,b1d51656,3a5520c7,2e72f5ef,4ab06562,52e224fe,1c670b2d,39630f97,f78ee55e,d1e01f5,c967d988), -S(98f0a6aa,7590ffae,731263a5,b940dd85,6d0306c5,ae98bfc9,9d164263,ec14c21a,284bef1f,a5a54c96,f5aa7c41,ac50c5c,fa88c352,52b923bb,92da72c3,d3d7d8c9), -S(78d11179,5965328f,cda22443,91871ee2,574c0886,f82e942,12e261bc,f5c3b9eb,83802a00,84e8b578,4450a423,1bc1a99e,6b9b545c,e32881c8,8487bc45,59604f84), -S(f0856a2a,2b8b110a,dae99427,9af3da1a,a74e1b77,46d4ece1,f054bc55,905aa49c,1a80e529,2b4dd9ca,4785abff,edbbc11f,7111663c,3fdf55f6,ec3031aa,3c5f0890), -S(2c5fc446,44d1e735,3e2b3374,89eb432b,f4dfaba3,39051221,4d279de9,87d6df7f,76c8ddf9,d2339112,c10ac9d0,5a473d28,cd066ff1,acd63e5f,b49bfb8,bb34d3cd), -S(3cdff15f,9953cb19,62cf5024,4b8db26e,8180090c,d6baf7f1,f60e6184,73a9336,275922c7,6d4841c8,324d1ea7,9948765c,ea399a78,51939f80,15b0b7dc,9f22d37), -S(d36724d3,91d3fc20,d1273367,97f8d961,18543b2b,dd40a77e,88813634,1c5f5d21,bc81050a,e6cac0f,ba1bf5e7,f1232d5a,a90d3b29,a0fce8e6,4dccb5f9,3e6a4d14), -S(f91cc30f,acc100f9,ee054e7b,5aac0294,e50035b2,2e7f35ee,306a30a5,1d5d6a00,328094f4,26ac3ce,71d53f82,c3deb250,be6a44b,6704886e,424e524b,c50f3e65), -S(48c715e0,da1ce36a,13cf4b8b,d5294baf,84a3fb08,b353e43e,e9f37481,ca2beeed,9d7e13c,f09c64c5,fa4a852e,206cacc3,8d398693,31368cda,1b06d242,2f8e26dd), -S(74ca89db,72b0796,af9b6d5a,57296952,1edae51c,5a3e8a76,b1746b87,4ce9de25,c770dc38,db1a585,43367fb7,979d7016,15a0a112,61064596,ebb40e63,e41ec50f), -S(36e77506,6284060f,8f8e709b,88b90125,f3c696d5,64bc048c,8dab4b93,40fe170e,b760473,d66e32f0,a716c1f5,ae462b0a,b5e77e6e,2e30fc58,e5ac1099,eb7105db), -S(a0899b68,99176eb,77c78eb6,d4a7786c,8afe1898,d34d3cfc,5f286528,409da4c5,f57441f8,734c16af,7ca6c64a,6fbe557e,11463e6,6482f7ff,d46f1b91,eb2a3cb8), -S(3503ac4d,9c9fffeb,d188d81c,9a92e506,a91fd15f,6bc67dc5,502b3ae4,d39d8e5f,dd66ff4e,40a5da17,3d3b143b,60534b70,33a5444d,98ed15ee,a6644e10,766b7918), -S(7765e5d3,2ceb50d0,b9bf9a80,48179d59,9fbfa214,4f183c63,9de26485,a87590ea,2052dbf2,718975cf,3c225235,d2504b4a,6b9026ca,731939dd,6af8ca08,9bc7dc26), -S(eeaf76ae,d4e737b9,900d4ce3,f39a880c,e060eeb5,208bf4ee,81b173a,dfd193e9,5490a02a,4ad8595a,6afd6612,48a80146,14366bc3,4c9167a,f290e164,f32eb9d), -S(f64a505a,4116a861,12914f01,6ae52fc7,5499efe2,32178ce3,d653b030,5b0cd0b9,4a8bc675,8353b7ec,e89096ab,aaa42a2a,e8af1a51,2e6f9323,1ec71644,1a09ef3a), -S(e73f95b7,b13f0907,53ba9ad0,c8b7f2ce,83ebea09,cffdf313,868a6ade,ac9c9efe,17986166,e766d323,cad73824,8eecb239,255d37ac,af72a56c,69594ffd,78281818), -S(7d2f8553,a46fd9dc,6fbd149,abd07161,1f279250,d508b9c8,b22eb2c4,99145d36,b88723c7,462f5f81,f69c92c4,b204f499,b3b826d2,1c05ceb6,a30bb285,c4bc4fd0), -S(32dd097d,96318d8f,69cea5f,f5db9476,33aace77,9059fb08,4177b8cb,36cb334,b078ae96,3cdc78cf,bd0e5bde,532a1269,a752c8ca,c8dfaa81,6ccbf4b1,2c3057aa), -S(7caeabfb,be7e30e0,345161bf,8380e160,2415178d,314caa33,b3c99d55,1c99f506,9a449ab,6cc98b09,6487475d,cae39e13,7df05d2a,f7863080,393ac16a,802547e4), -S(e5783a81,16e1e396,4c693fa5,919aff98,bbb954a1,e8503974,a27af353,3247dc86,d9d2c1b,633e2217,b66cadd9,dcff6880,be272900,e1c966d3,3726ae66,21860fc0), -S(9c7f5cd9,c274177,1f00e117,a62bb197,d0a8a18f,2ad23261,eb04c91,47561c9a,6652063a,9b2a5abe,38ab7b50,5768a5d7,e098ac86,bf127b48,2c56a417,175cb5d5), -S(fda48685,28c4f2be,58cd9b00,6fbe1121,ef009361,f0198b2,f5c56b44,1d28e9dd,3055bc29,fe08760c,ab624154,ee98a506,9de9dee8,c1db40ff,b972db60,30af98ea), -S(ecf9f4b2,2feb14a4,14628d74,8f7e55b5,886f7d18,d107e4b4,f985df5,163c3eb1,cbbafcf,84606b89,63e4013d,3c730edc,da808338,3f681153,307929cb,905beb69), -S(ee0ca18,25428e9b,a4c0be5a,8c9da473,f73c43d1,54a6fc52,176ffa4e,c05af36f,c8b960ec,91139b08,25face64,fdfa01fc,7390804,3c4f691,bf684dec,bb10cbb9), -S(744d4c0,fb5536e4,99b0397c,8cb127f3,68865b79,fbcbdb37,ff9f9c8f,59372ebb,b9ae4d36,489ca0ec,c318098d,663fe8fb,aebf149,fb28abe2,15ef6f43,8e414a4d), -S(910d358a,710c8e22,314b9eb8,394a7770,4549fcce,c98046f9,9c0a3e04,90510c49,5ba779b8,530e57a4,fec63e86,188d269b,6081fff9,d3f49bee,b0b62e29,540ae214), -S(2434ca82,89853823,57d1f537,ef02fc12,89300332,6acc9c67,ca2f3b96,691e94c4,e4608778,311bb1fb,f88a771,f6281a0b,7f850767,af4b9699,77b1fd6e,8df34d7c), -S(cdcebffe,d7c410c4,18cac7bc,cba49a59,b3ad5ffb,4c0577ba,19e25dca,c16fbcce,9745ea09,ddeb473a,a0b861f3,7d16d83,a8a73289,d278ae12,1168a6a8,d6bf5595), -S(826f49bb,90a6b195,b7de613e,ccbd1230,930c0303,d88ee0b7,a7c40b66,cf576a56,230ee0c1,c1f86c3f,a79e98f7,e63a7a77,2ad22724,ff6ae39,ea17cf43,e2e44c8), -S(d8bb1cea,9976a5a,ef1a5e6,57b70b09,e59cdf59,c67b4de8,9694701b,fc73c7c0,e76bb7a3,60759c9,441424cf,46aaabce,331e749c,80d588da,e3039162,e1a95d35), -S(6f475ce4,d1c3ee7d,130d101f,fde3f250,d1a0d884,2239ef78,83d67254,80b750ed,13c5fe82,7c76f2c6,4739839c,4d8ab9fa,3271dc83,b949d123,532cd0eb,71809e0), -S(d8d129e7,72635a5e,bff00c26,8ea30c0a,bbe3c635,d49818c,a3251082,fda4363f,4c4f8a79,d88bdf32,9b7a7121,7572da21,f89cfbbf,22547269,1362d5ed,c50b471), -S(19aa085c,e17cd19e,c610d3af,91d9a263,3d706773,1d5f6891,e31de7bb,39d306c2,aea04c67,efe26,c46dd958,e8fb2d4b,726e003,2d33355f,e7d256a3,842f75b9), -S(3712aa15,914e6f15,50ec12b0,f7dd6b2d,854d9f95,e86e7d2f,103b9925,dea23828,f5435b64,af251cc8,72c9123f,964c1c75,47457e1e,8c8942e7,852f4fe9,a9240c84), -S(f5b9a5e4,db49b7fd,b00912a7,821b8c37,a89ce6e0,12286f40,852746f0,1d4ab4b1,7ea00e84,d03d8654,ea03759a,69a3b055,60af6f38,55dd2ccf,a2e4da9,f8820114), -S(4ffbb51b,563605a5,eb7e784b,93eb7ed5,83c65968,1446a776,443cd436,e86d9f13,ff8e7729,e235ae1c,9d0ff576,5dc8763c,7bafc9d4,f3eae4b3,b7a58871,add58688), -S(9b3fe406,55f0a924,ddb0cb1,48dbf03d,5da4f1e4,e8b7307c,6b261915,2fd5c3e8,46dd956f,583120c6,91961916,1a46023d,da55bc27,b0717029,748673ef,b6aa318c), -S(86d8917,9410b427,b8008d10,3e481c35,2f089dc3,5c263804,ca86e08d,9da279ef,9aba2027,c3e47bda,aea2eb58,617ae633,83379235,7c233d30,e070115,d46ec081), -S(414b3ae5,23a76abe,6ba71141,8ac0a61e,4915076f,a0c2528d,e20a0b5c,368d2245,bccb169e,3091f7af,bfb8a251,958ffcd4,6f0c8c5a,f1662640,6c7c9993,3fb8fdd8), -S(7aacfb93,8644090,57ef8ab1,63bffd25,d8d43166,e8f31304,57779b20,b5da5998,257b5c42,2cc77f41,a6234a9c,1ae8d2f6,e91fad8a,78c39a6b,1d380a4d,7c9684be), -S(2e51b2e3,72a64010,92ace7d7,b263f897,ed629521,d45d962f,2876c266,3e42d7f3,fbd258ad,28324ce7,6bdd4b38,44517a40,e5cbd237,3bdcdfb0,862e768f,8e6dc5eb), -S(7721f122,e26e0fba,f6a33521,841be750,5a47dbcd,941191c9,432bc25f,56aa6e55,65e23e03,f03785c7,c81695cd,b49dee81,b9f678fd,55325ce9,dcefea04,f11a79b8), -S(aa7443f8,435fd4d1,e2f1dcc9,bed52a07,66f3c62,543a0f3c,5ed7f593,e7933f9e,858be190,a656bcd3,5b377138,2c3176a,45e0a53c,8a346743,e1c595eb,f992c70b), -S(23a3de7f,147a4ca1,bcd19afa,a8e71a58,27c7e7aa,c7db0c3,40d37b4c,e97a76dd,5361192f,76a37f5,d02e697f,288daf6f,34313d58,4e33344b,32cf1c0b,2c711217), -S(ab65c884,73b68402,5929fefb,322667f1,bf02efdc,d33552ec,4d743222,2b2d7352,c2949d4a,af2c3ed0,f9284466,a572b1e0,34e56e23,4c928646,5427d60a,2f092d63), -S(5d82cbf8,71aa4029,b16d09b6,ed1a22c2,6a94bc73,c1bc11c3,ae27042e,92fabe78,2610095f,c1dd2eed,adf1ecd6,a5b15b0e,5c714fce,87f424f1,5c198588,8b2ae3b2), -S(e5338bf1,79e3b22a,306e3f36,5121f94d,cb5a072d,6acbedf3,87263387,7ee23090,a8ce14f9,36d0b486,3db6f79d,d10922f4,395804b2,37035103,b59768da,c1f8600f), -S(e936f432,e5cefe07,e4e290ad,823d90a5,c2701eea,57bebac4,81b97400,b8964544,ebb65cc,15843766,77e34e80,b665567,19189319,2a298033,a4786974,5152b5ef), -S(a8f4c429,d93c81c5,7284f59a,a3a941ae,536f7c2c,e3707973,ac3eb5b4,a0ba1ad1,4e39b9ef,5e1b885d,b3a8e72a,8c069800,fa539e6f,7f6ffb0a,4b22ac8a,66c8a83b), -S(76ffc741,af278fae,39081989,d884b195,9cb7f240,d80c35f8,989310e8,64034e40,3df6c05f,12b2ddd6,262e3837,5c2876bb,e0f7b769,7d4cca13,be11c55d,cfaf6618), -S(eed12546,217f1270,505f9235,b875f6ef,1ea38bfa,6e790cce,97d491a7,30683809,6edd20bc,75c215a2,9a162bb,f19b757b,ae5d22d0,1c7a68b9,e2e0b01c,21e4d193), -S(8a975564,196e1add,526576ee,dd330a0b,bb1dd32b,85ae095f,79666907,15637aaf,5ba79be4,6db3fc66,c2f9666e,86162767,4c408e7,241ca378,47b8b3f7,ad5c3c48), -S(87728750,a68695b5,a23a86a0,50e5a015,e721ee92,da191a77,a8945c92,e356f3bf,44746e19,eeef603a,9115bdcc,b8d4146d,a928e723,e1736c9e,a352e8b8,8bb5c6e4), -S(83e9abe0,c65a51ff,c9e70748,35d1263a,5c31db10,6647e6fe,1ff9613d,6ddc6479,2b956ce9,1dc3fc78,b5d2c0e5,abe82eb5,d1fdd4c4,f2fcfed2,acbac011,4950e7f9), -S(89f0cbc1,5c7c60e1,6503fcf8,8c70dc2f,b3f18eda,3041ab27,e917b93c,a837b60c,9b25624d,1e3d2dc7,7c4a1b6f,4daa6020,2246386,b2007dd1,efb0043a,300975b2), -S(b64246c,e22786aa,8f269907,bb819041,dc564b0d,c6e14987,c5ac8fcd,a7f5a98a,68d776ac,5200e1d9,68088a72,af4458d7,85dd81f8,37f877f2,f4884b4a,3fb4d5d7), -S(babdf57f,ca92a314,6884f3c6,509a27aa,c8793214,49f55c78,7eac3531,74074127,380fff63,5aebe191,3c6e690f,76045577,21f65949,6a1df010,32726fbe,ceba0038), -S(92eade4,5d8ebce6,3685ed69,56caa62f,2f9eccd4,55f57bc6,4a75010d,20ac2df6,3b5babc7,16be9c71,e87bb0df,54aba5c4,3bd1f820,40d98f83,f2911eab,deb32573), -S(ac69071b,c1bf2a3,b01f633b,fff39f4e,3c5376e4,620278c4,ed9d98d9,5ef7025f,252a56cf,7d6d2835,6defd43e,70e6bddd,6462bee,d37b5227,d7d9fd5e,3b95fc6c), -S(f05e2926,848849b2,a7d9b980,c5e18d11,73db7422,4a3c476b,f2c44b,4d81b49d,59aea3ba,83cbdad6,4aba7857,1228acd5,eb574350,a9d1940b,68a4e495,2ded3c0a), -S(468ccfbd,aaae8f16,b91f4,cf41ec7b,f65f5832,8a3543e7,106dedb9,be4896fa,bfa82375,5e234421,19a18f8e,d182c52,1caceef2,3811a874,8d30b143,5676a186), -S(92452b56,58086172,625ae89c,48491669,e5c38d6,6280163c,397169,79578e09,6cc0e425,1da8e662,fdd858ca,e213cfb5,ae819d79,23372d39,d5a9722d,66543782), -S(3e201b8f,ce5bc832,c336c15e,2daa7770,1835c00e,3852cb19,7a9d4a2c,a902e287,5096a11b,18ce12bb,27f935b1,3e664d26,2cfe6be7,33c8b5e3,45cafe32,9f0804f0), -S(68ef4ac,e421f24f,dd628a01,56caf9d1,24bfbfb1,d6651f35,10ca5e48,5bfff389,8ebf4cfa,190aadca,b04c256e,ff0fbb04,bce8b360,3e308fca,fd8dddc8,dda15ce), -S(d2e44a05,64718ff2,85c56932,8d8fa7c5,530977d0,56fd8090,972599a8,461b5d39,a16bc6e7,3d514070,702db8bb,34f3cfa4,12099e19,da5eac7a,f87076f2,88b88bb6)}, -{S(4bd266bd,4a730879,cb06d8dc,bd8e5854,c50b6221,d83e0a10,3afcb2a9,a64cca67,a4654a1d,835a51f0,5a877200,1768c549,909212e5,78e3b1d1,df935959,93650863), -S(c275fe8c,b742a78e,7d78945d,34d988e1,202e1807,905ee89,d348957,f44c319a,88aecab2,7d47654d,df33617a,5fae27a2,8968ebd,284f5970,e0c39a2d,1e8039bd), -S(9dbe3dc5,ca9889c5,af21701e,11c60d,2eb901f,d0981d51,faa8c79,8b766a99,26878a40,fb4f091a,7c82cbea,db50bd98,8ee84e91,f58cfdf2,647a9de0,39f614d5), -S(4471b988,ed964b29,87a79324,a251f228,321523d8,1a7039cf,43af4c90,f63c3ebb,8196836,d28e4dee,9022c609,4f078448,72e70cf,c0b8640f,a28bece3,76c5aeec), -S(a7f5ebb1,7f00f9c3,d51ee4dc,ed4d713b,916b8049,17604d2c,1c6ede6f,4a9308fd,954f55c5,83d49978,cbe0bd27,7b2eaace,92e43012,bc31d63d,6f8d117f,e1e80223), -S(f80df047,a066a8b8,e1c6c6d1,12af4a5a,92894eca,d7946929,264b81bf,b060db7b,b3295268,6d708b49,73f0861a,3ba7256c,709fc322,9983c28c,6a76aecb,48032947), -S(72a6521d,60423431,a29ef70,73467d31,f654034e,3618c2b5,b9ae057e,b6c85b2f,f2cd61c0,58988546,7197e84b,6ee01d64,d200a135,542d5a0a,fb3ad4de,507dc900), -S(e1bc0481,d40b97ad,c4eaccb9,377674d9,ff106f94,9b3ac081,965b5332,5c981be3,a717e82a,d9ee2fd8,c07e3c96,a224c449,bc16032,3d0f0f1c,5e5b0f88,47f3a7d1), -S(e44aef3c,f9651799,f07b2ed8,b9e86780,fcaf26e1,2fe122e1,edeee3bb,a45cd461,c2a599d9,cb14b881,53a18c84,3831c475,4245b403,840e8cfb,6442446,d412785a), -S(3db8c67d,1964077c,bff351e9,ff770afb,5a7836ba,8e8916ae,2246c183,86e17177,1c02f899,1cc2b1ab,94affdf4,a302042b,db88b31c,5a516b4a,6d63a667,10e7ac32), -S(107e06bc,96acffed,cafb1205,26c61c9c,7a67618c,d1d4a1f9,24f7ff89,febb8316,aaba34b8,7ea1b235,720b79c2,b84ad3db,af6da2ae,3447df19,77e0a08c,366b3cc1), -S(b8f30382,716e92d9,7607837d,b162b56a,8b50dfe4,76f5f700,832dd55a,1e686a73,90a4b3a3,d11e9bcb,55d76467,a194f32c,e2fef47,1fb2408f,b71b9326,3c722688), -S(a3d1dd0d,8a5181a,b06639ea,f4f3111d,3de0ebd0,5567b9ad,56df821a,59191b04,65b8e7a4,fbb854f4,3699e509,4a9da6eb,f277a0f7,a38dce11,8dc924f1,ba916726), -S(44f3f1a6,8fd1c5fa,9de45857,7f320273,69cfc6ee,5e30822e,cec0605a,dbde28e0,400f764,2566009f,a7482bf2,7ca5b0be,1621b94b,ef42f693,417412cd,835c922), -S(d2eafded,346b24ef,633e925f,74178ac3,5e6f4d32,173797f,1f51e12,2ca65f7,6d30ca48,b1f675ae,1e1978ca,6c05f542,2e2864cd,a58480cf,517960e4,f373d79a), -S(d07404c0,67917364,7b2e946a,87c5cece,20be2c5b,2ba551e7,864b2b30,8a7695de,d685ad61,efc4fae3,fe60574a,8a20a6f1,9243100a,4bf945d3,de002f81,3b91c185), -S(38936927,ecac3831,2417ee88,59318fb,724e758e,a175bd3d,e2247b2d,1a037a5d,da223eb8,71b3f213,ffe0abbd,8bf8152b,afccf3da,4bad091f,38ed1c5a,b90bbb9e), -S(2e0b714e,f9bf7154,cc41d846,9fb99eb0,7bed9ad,3ad4a60f,b3e88fab,974ff918,8680512b,4a6dfc2e,9bece0db,435d4420,c745b611,8feb15e0,7f1ce001,6a65fdfb), -S(fb42c1da,8d1b62dd,7949a6ee,1e8605a7,fc774863,eb4c7e70,8826aa80,c5b22aa6,272c0d71,127c514c,8b2905d3,d962080d,b5644bf0,25ae95ab,5d88b15d,596c7eee), -S(5dd9e606,61ab076d,d7ccb699,caec20ea,49b5645e,96662119,15f679d8,1dc88e70,e17753cf,6bef65ff,b2739967,e64f7402,54562b4d,9e44c297,3d1e841e,ba2ca74f), -S(5c8ac07f,466b9f4f,3d6f463d,54f16e0b,3661ff55,8a1ad864,bc86ec2c,29bd8356,f849f526,77b36737,586b8782,27a927b6,300ecb2b,cf25c53d,1cc18c02,366a9156), -S(ba773918,50f9faa4,715a8b00,bbb3abf7,c78f17e7,917172b7,958e0439,7b974887,3e38618e,743539d3,469820d8,c1e127a3,cb2cc6bc,a386087c,ea7296f5,46ef4418), -S(eaf36e71,7c23e7f8,8f1af63b,fc7e56bd,fab55922,122e868e,5456d556,eb3051cf,843239de,1e94148a,54a00e92,a649ac07,e8fb0883,7de8a3c7,405bcc0,26bec993), -S(fd76140a,9e0504c,5df9aaf7,ce77174d,d64a8131,2cdcdd5b,8b82985d,db980f2d,7da81b12,d2836ce4,ee81c288,9db2408e,38f7888a,29282a3f,22a32cb1,5630c5f4), -S(7db855ee,a3c28e7e,45f51166,f32a3af9,3fcdc75d,acab827d,3844cd0,b4e88251,8cf4f691,9dd33bd4,d95aa1ac,c9ecf926,4be5b588,7453e77e,9f69241f,9498d929), -S(dafcba5a,e148fdc,aa431fb5,db8f4edc,f43168ed,5e381fa3,e5789c89,82f2a90d,a6c718a2,92c522a7,8dd15fec,e3ddcf50,10327f8a,1f601544,dcfe0e66,41404275), -S(d7de414e,7ccdc7d1,e934b10,17980cda,fed701e,5b3c4a53,d8ec0021,bb6b7015,47ca5491,2d5fd9a2,37daa64a,6434d6eb,5a8e27bc,665d3cda,d3164fab,f185125f), -S(7391420d,d4585846,cdfbacd5,63c47521,cd3640b7,4ba43c86,3c5c09db,d389133f,243bf979,ceb34758,84130208,b3a8eca7,bf695c38,5c60685,6785fd65,b1114e79), -S(a387b4b7,6c49ea0f,9b5e20ac,79053b7,a7391c3c,984c7e0d,72116ea9,85a11f0,fe7097d3,ab64e202,e61cf2ac,27e506f1,78bb534b,1bfbc8a1,9c435da6,b13776bc), -S(49df7215,bd8ab08e,21c56507,b6e57425,bc4c443e,ff0a49e,ec4ce0ac,4caf132f,9f6eed66,1066c373,275d82a0,4908193b,5477690b,5796be1f,533f67f,b9fa18c2), -S(ebeb0f66,1a66ae8a,fd0b3442,45f78f6a,cd414431,13bf03ac,3c6f5641,b5a62dd8,fca3f129,76d11af9,81f6c175,5b9015d1,91dc21e1,a91098,3528516a,a8a22a09), -S(367a8c75,e4fac5f5,55f2f48c,23d3c344,ca4bce60,b188be03,5461d077,af8a5e9a,8064dcb0,e3c46a0c,3cbfeba5,20b18f1a,4b7171f5,7db2dd3c,829d9168,f9275792), -S(d3e2eab8,ff9af1c6,5a881738,d52ee173,7baff4c9,31937318,287cdadd,46ff98b3,f7c729cc,808f4760,5757fe5d,c150ffb,ea4bd6d2,78e3860e,56b45add,bf54875d), -S(86c329eb,3adca5dd,7e840133,9025cd69,461367b,781acf0b,fb2f760b,6b56df9,6db54fd0,401af8d6,bf94cb4d,c8230161,ddfeab22,2c6802ef,1640334c,bbafe470), -S(ac9cf2bb,fbbb0be7,8fe03b3d,5b0aedf1,3d36ec3e,d8748a68,ba873bf7,3eba049,cafebc22,ede77a8e,fd3926ab,dd69342,b3226271,9a7719e0,540afa3c,c23d60c0), -S(54f1d996,ca39664,f03ede34,3dc394c3,aae4b65a,e75aed69,1427e2fa,85995d22,971bf54,8445fe60,714cf038,6c801979,e6eaa1c4,d51aba97,24b3491f,5b490fc0), -S(a01cf61d,b77a9519,6b8d0f1b,10f087cc,3689ef3e,56e66f4b,918baece,8480e8d0,d6da0432,2822dded,838373e,70550728,1a1ddb83,375944e5,4559e360,165d6b81), -S(9c971dbd,7bd6933,d4d4c918,ee7c7236,45fab1e6,1f50f54a,5474c711,8334e8e,767e56a8,e6aabede,53566eaf,daf22c38,b2f949b6,4dcf006e,b24469e,c2ab6e82), -S(db08258e,4dfa75a8,940c111c,1691e148,42a106ae,11e6f266,8a6bd70f,fef3624,9bd0de5a,f568b6e,1d05bc6f,e6999245,3a223e91,61311b7,7e06cd6c,faa956f4), -S(1f546fc9,2f784ca,638a1c8b,74664baa,d2da0745,199aebbe,9fd1d65b,48bcaf91,5470251a,9b9d5a79,be198076,541ba922,d7692ebb,f65871d6,e9daf078,52428dd1), -S(a318a92a,e36427c7,6c8387ba,d4420b29,a8b0f583,76d6e049,e70b9a3c,55b5d799,b38888d9,574e6cf4,991d6608,ed6918a9,92ef5a1e,90d405e4,da8280d6,74f93b2b), -S(84c29d90,417579d6,6124a754,aa77b711,4758f383,20a395b3,44b0e547,d8779b2d,2957cecd,8766c432,49ccc288,c6f6b005,b2726bcf,9bff51e6,d676ddeb,ebd340dc), -S(4109a1b3,c740a287,5b06f841,def2cc2e,47d82029,bdbdedb7,7a225298,e3f010a6,334cbba3,6526b308,ca45e487,d10cf54a,fe229d66,e3538833,754c7058,5f9f368), -S(99cb215e,9ddcfba6,bc703e59,c3d3abc3,9b0824b,ca0a5cb2,35cd2a89,3fb2be6c,6e1494f4,2df30735,45ac89ea,ca3834ad,553bbfd8,ee0231e5,c803661b,82a16cef), -S(2bf5a599,18959366,e7740ef9,8e2159c9,28cdcda7,f38753f3,9e83923a,5121b490,7a70ee9f,387e09de,6a8608bf,527e9d0d,75903644,c4efdcdb,916f7cf0,bf35bdf8), -S(234f1de2,aca81510,1a9e8659,41851280,8d8801df,2d63ed83,e7c9899f,6881ccc5,d43dada1,7029e6ba,56fd9c99,29810f3e,c8bd27a3,5671781a,283abb97,12014be5), -S(7a691d3,2b6d605b,c04723ca,a6d7219e,39d73fcc,e3b4e4ce,ddde027,eb31b918,9e869d3f,d4802e57,34969854,12a84c77,42dbfb65,f70d2d4d,a7ddb858,f68c88f2), -S(963764d1,75a0cad7,8e87e2fb,d3f32dd3,e45e57f9,ccad6560,dc58e548,8bbed05e,d5faa558,ac6a9a20,74c5166c,72c15cfe,b509828c,24a1d967,8aeb6dff,5eca8a7e), -S(9d250071,90c38bd0,64f0cf4a,dd0809fc,95c02956,9d199840,e6d947fb,271573d0,5eedad5f,5930c244,b3fbec61,425da0cf,6d0eef25,87e84f42,35f08429,9e38d8a4), -S(83b30514,e1691531,5eb6b9e4,eb1affa6,533be8cc,c8af829f,5829321d,cd3aeacd,7eb7fc6a,e43b73e3,1ff48193,947eb01d,3029fab,e51e4344,a278f142,9ddc9752), -S(4365f9cb,8ea699f5,284e21bf,fd4184a9,685c6b9a,c07b555b,eae2b2f1,838d9cd8,4b0c0ca,4fbe4088,e1c55eab,f80858c9,6c5d3766,7af397ee,ffac81cb,3e2d2394), -S(7bf3588a,9d51278d,539b7e72,19e32b94,336441aa,3c56db9b,d70d1d13,4425ad3e,442a5e17,27706843,fe43b75c,ec629876,2b8a81ac,26f71371,ac78110d,67d9f54c), -S(bcd1ea95,621c195f,b37f0ea,aa7c1688,35e3ba46,e1fcdf8b,c6d4ba36,9dbd46cd,799a70c0,422c82ba,e3790abd,22346df0,8d1e80ad,9194f70,f94f9d09,50b8719a), -S(9eff139a,7e728eae,57480c55,b5a5752d,83c4b92a,96b72c98,ea7fddd9,9cfaa8fc,656a5a97,1de87e12,afcba7da,f6ee5020,7257f604,5a909707,b55a83ae,ebae5f62), -S(16edb231,17a09c6f,bc1b0142,c06d9f8a,ce125101,a48229b0,a7605a87,f3fa59db,1f41d18d,29b720e8,54cc7876,d682efda,97d27e31,3f66eb89,7e23d85b,e160c9b2), -S(890e1604,5f35d432,fb62b4b1,aa8e8aca,b08a5aa6,edced104,841ee569,f8b0dd86,7970b632,a25643ad,df338a59,4f974cd,701da359,8b845ab,bcae75b7,f2168e19), -S(630d23c6,f5586b45,59d68f49,6531cb74,e2075ae5,3ecee2d,3c1c8ac2,b01362f7,5a9c6335,dbc506fc,d8abf476,ee5f5437,290cdeb8,9c3ace9d,184658b4,67478c74), -S(9348ad11,53e90953,65a13cf5,6cf05d66,a69e509d,ccb1be8a,5a985472,f5ec3909,3632b1da,48e2ce33,97d25cd,6fa6d55a,9fed786,9a7b9bf,d2765af5,81af7206), -S(e507b132,8614fd05,e9d8fd9b,5742cebb,6e7301dc,defeedb1,5f79022e,79acbbc3,e09d5d09,2eabf8d2,d0186df3,5007570,e9e85f22,269e0342,183bd375,a5e326db), -S(81727248,d85e0f46,a8e4b09c,ee17658f,557e1dee,a7c9c12,49012f6d,76f5432,f1654495,339b6da1,981e8e87,eb95d1dd,5b62ba06,67ce8a2f,889081bf,2aadf), -S(54f7d9a1,806fc37b,668a97ed,286ab04f,a2a96f90,aaa92118,4bc0034d,431c5d18,26f8efb0,5bdb0263,2e7561f3,9f56c5c3,2f41c8b3,7771ecd,897204f,33c1da14), -S(75b272c5,88900750,4b139b59,f3188477,56aa22fb,b1981bcf,74491b05,881a4be6,1b7ef1cd,70dd43b2,851220bf,b3989bf4,66e76fc3,e9262d89,de46327c,30a73c31), -S(9880a12a,10a9692f,b542943a,ce6513e1,bc95fb8c,618331d1,413657b7,13b2a811,38e33a55,ef745420,98d92ffd,17a7882f,b2e9dd69,40deadd5,8dde4a,8c31dec8), -S(232f85b6,f3fb87cc,fac4c06d,bf585c3f,c5ff3d67,114f1187,17d68ab2,af6e24ce,44981280,9c5b77b3,ea4d6b1b,e1872fe9,c295596,839a135c,443a37c8,d0a1f405), -S(e7e0e5ce,292f1386,3f186534,200727a3,46e60312,76ec0831,3fff6810,6d378912,404fd06c,68a99234,9d86e1cf,c2aec52f,bb101169,6940c961,1c052d86,ce87cb6d), -S(7ceb4d25,1844992,86b50e20,efc3bab3,a98cf466,e22c4018,eb22a97f,51a2182f,4cd70a08,609fa1b0,d55bf37f,2be739ff,8af001a3,190b7b4c,9687a3a2,949e99f9), -S(bb22eb38,cb29566,57a046f5,2f97d3a3,83bde5ca,e0e64fc3,6c5d28b1,be701695,574027e6,92a28c07,9fa92945,cfd36c73,8ae59c35,c869d17,d460f9d3,d12f7ba3), -S(e9803291,3c7e0c3f,4e0213e6,a6488dc3,f5c0dc6c,9246b655,5dc0adee,978ec5f8,b3bd6f23,bf63d3f6,ef4b4e45,6ea7d58f,47136aad,da5b1de7,765dae5d,b4b6986c), -S(e18f27f7,f8a95e81,fe58a13,329d12f1,4118d924,2bfbbfc0,f64eb2ce,b233c15,66b93d85,a1c7dc3d,cdfc3970,ff0f61de,b6b0adb3,ad8b0db2,fe766606,3c4630c8), -S(e6243ac1,f0b1d402,363b4b37,8ca320a6,68595325,a1d0572d,38a54476,a107a2d6,5286e1b3,54a3e264,4d9c91ff,cbd141ce,58c8a6be,5b609924,5821dc49,d1e92df1), -S(a77f0928,c24f4ee9,14a84684,568ca975,322ca71f,dc78f389,9aaede60,9a3df1a8,1cc82bd5,7d6eaa18,a05e8096,441676d8,d66c1584,af2cae0,ec118bdf,bc32272f), -S(e79c0aa,51e9fa1a,c6e330aa,b9877118,ff672fd4,46f49920,fcf14f26,d74bf10c,6d952340,708203ff,109a0d,7dbedf52,866d204d,8f5c9cae,bed7c724,4d726ac7), -S(6f5ba3c7,202c796,c27d342b,9e5f62e7,b3962a71,7fda573c,87d30071,796e592f,174aa4c,789ff3a4,1c5a42ad,a3bfb2de,ad3a5351,cd9bce90,f983a9d4,e897f053), -S(701c7dc0,9edccc89,530845ee,6d76dfd0,ec06a842,49ffa8bb,1f5eccee,c8aea899,1f3a2d11,a53081ce,6c326977,911ed535,2de2df6d,e3ea92fa,7946efe1,a2afc215), -S(3c82e97d,f06da304,13439ede,3a56a48f,c4fa7c6c,9ef2a74a,cd80e58,3e3e4104,1ec4e9c9,14dfe93a,13a91edd,5f7f63d5,fe60ff4b,bb271624,d5ea48bc,7833dfd9), -S(88d3451f,3998286,2cc3b867,afd91cab,6ccc737c,4cf1f41f,1c0d702f,a2af97c3,2e3d51f9,141c94a0,1c1907e1,c5328653,a67e80a2,80883f2,2caeab79,70203d05), -S(dea9dbff,93f8f6f1,714a49a2,e9154fa,766b9627,e64049d7,4363a542,f30b0647,deb01f8d,91c3f7f0,ccfe5fba,a5525b4d,b10561c3,aefb11eb,6e540844,2813b714), -S(7e715f8b,68718d16,ec601550,f80a7f91,d1f1f3a5,ec972755,66ad93d6,af205104,9c79a5cc,3226c625,d734b73a,f34bc14d,a5d5007d,ecb402af,b815bf4f,18df8260), -S(6bfed43d,a9196990,c03f788a,9b27d023,12394f38,78bc6d64,8923ec4e,3db64d98,672d59b8,c2c40ba6,4c88e516,d5602983,7a9b328c,6c28701c,80d47927,9590a913), -S(177bd160,1c53637,28e341de,4e7f8a22,9a561665,c1548ace,7e6376eb,dc790009,17585c2c,9a90c5f1,3a97fd24,b7cd0358,762f1217,e4ce2bf,832c008d,d004186e), -S(f1b16245,4181187c,f5251139,8382026b,ac7c4355,ec7cd347,9f83a66c,db63db19,5d261ed7,3c9611ab,d983d74a,9ce05bbe,cb32b858,32d00e87,fa794482,41fa70dc), -S(aadc4097,ce6fb92a,6b77b5c1,abfdc345,85982877,5c37a522,39518559,363d2fec,825fecfc,6f11154d,89559a63,56308d34,5dfe2e8,a439ed20,eef0edaa,3d506a62), -S(ba354351,d81b0113,a215ed8a,3a900fe9,3484f35e,36988664,8c830d79,699932b5,c18c12fe,9b2fa86c,982ad09e,5d29475d,7a0b7f93,865e8300,f215affa,48bcfb66), -S(ee1f269,ab870c07,1ad7d7d5,a84b5c64,140a3bdb,68f0a5de,c4a80c52,9bc7f6a2,67f62848,f082c3da,69056b00,91ddcc2f,7687f630,7f4044c8,8196a368,d441a44f), -S(9880ef57,5b111cc2,c51b9b19,d3c154fd,30d8b967,312e30f9,2f210a9c,13b8531e,af790a63,c44bf477,8884f95f,91652c14,f1ee73ba,7c1facc3,8ccac2e9,8382b83b), -S(996a6793,873cf119,f77cb23,1c8771bd,6226d90b,d319c2d7,d9793a30,4a7686e4,983c75e2,f0ef1d60,dd60ac8c,d3df6e09,ae1a8da9,17b1c63f,f59e17c2,c19a7d38), -S(35faa9e8,7fefcabf,3aee306b,a88cb110,1514db47,9e559e6d,f8b995d3,1616395d,bb7560b9,fcdb7e2e,7522e5cd,7bc42236,79d1e546,a7f7c0c9,44186043,7dfde05a), -S(70d1471a,52f0fb45,50d2c644,b7925895,5e27917,13ac9a68,2b5351d5,333b3fcf,a84cec71,622fddae,72f4f995,2585ea84,c15968eb,666573bf,254d2144,e0a523e1), -S(ac990fcb,477409e4,442a7635,64ceb28c,26adc45a,b5b99441,e9d7219d,593ab4c,3f3ba91d,c08bf75d,5e764b72,d048fff7,fd6ee3a3,758bf5be,d9a7da1c,6446e15c), -S(f8f64b95,69be42f6,1567f537,d9e60f6b,f0608f5c,d8ad8567,ccbfa02f,34b26208,d818300c,ee7da0af,1542dcfb,9a62ebd6,86c1bcf,d9e5f41f,31f79892,fbaeaba8), -S(c24cb8c0,eb923c9b,d12db26b,9473982a,73099bc8,1f0ce101,49d153df,e77bd5f6,7f47cd6c,123cdb2f,f9772b09,9f44cd9f,643929d,bf0132c1,4f9df2ff,cf4ac056), -S(5281bd2e,f6089825,91e8310d,4d626c4,4e68ef80,b9e6abdd,6a0af7b3,4b957f1d,eb9a808d,97ae906,b029a24f,b600712e,3cbd406e,27380c8e,bcf3287f,fe1e2cdc), -S(d525c063,fbbc8ba4,dfed492e,cd056ce4,fa60b04c,25c850b0,70052ec2,6f592be4,8e5b03a,9268a809,a86f3842,10a4dfb8,1a5d4659,c2695723,db7982b8,698cb778), -S(b0a5dcc1,3b377072,9ef8ba6e,b0550b3c,968b4f1e,2a2ffe0,54a89eec,ed3adbb2,49865cce,282b337e,14ab3f17,4a07979d,38649ee1,951f8aea,8a6ba657,8bcd4356), -S(ef3b5acd,4bf27694,cd96f70,7708eb1b,26f517b0,37d44194,ef3aad38,98d53812,db292747,53593713,1c0a9be8,5b020ad,34f2040b,3b60bf65,638f4561,709889e1), -S(dca55235,2326841c,625226a2,6844d317,adbb5cdd,a08f8931,68920aff,82d300be,f48441b8,a104131b,bc1a2487,eb3760d1,8b60c53e,70b693d5,b5db49f,485ee525), -S(53a47db,565ec4e7,255ad4f7,7fa28644,2ecfd91,32a0e8ec,6e4f119c,2d090044,1ee6a228,b1615640,83a62c49,f3f92c9c,9d6d46d4,6c7a277b,7ef7705c,4a20a6b1), -S(8187e675,78d1c19f,c1624a5a,386fb1a4,2ce7df06,8487baa,f20b0975,6a40ce91,241bde96,53091ddd,49423bef,e6a1ca6b,b75e312c,46ff803b,bb709a4e,25a691f), -S(3ebd8f13,d92881af,1a43223,335c7eb0,7958b7b4,e5af5cfd,f320228,64eb7937,72b3ee1c,bf91271c,84603d64,a8feba9d,bcbe4626,57c4d084,d2d3c8af,e7489c58), -S(90de5cd1,b27da158,a73ed3c1,f23f9390,9e281c65,6d50f8d1,b70294a4,9f4bb4ee,1619b365,238cc8c,be2b62db,ddc24381,4ecf4095,8617ecfe,6315f8b7,a1d73b3c), -S(e44c5ccd,d2723f6e,c44ba386,3337d911,15a73547,c2dc77bd,bfaa6e1d,b4ba3d62,f150acd1,65fc084d,b8b442e8,8a6fd033,5a8383df,9b2639b0,3248a1b,72828129), -S(62eb6bb8,67fdb48b,f474318,99536489,437a7086,8f27287d,6ad56996,31d6c845,1014f43c,517b3a80,d2cd9e4a,7d76693f,61afef58,4ee80ff9,8d20bcc7,c077f7ad), -S(a44ce0ca,a242039e,3defa271,59976e2d,4bc9f1b,10e07b83,4aafee6a,7ae93066,511dd603,d264403f,19da6380,dd470cd3,2fcf656,2cf00b3a,d6a209b8,b244b070), -S(1f1be63b,414713ea,7060e264,ca58dee1,76677033,66002c72,fb8beb2a,a661539c,ecdfdf49,a771409b,2cc03f7c,8640cb98,49c00a82,1d40d1f9,586763bc,35815ab7), -S(30a76480,5c483013,7bbce984,10a2c250,4dc2250d,ed82f853,7caf58a5,b52bd8b5,2edb011b,ae585fce,da2e20dc,3d840c5d,704b8ee5,8578c573,d3363a0d,83168c7), -S(3d6072f5,dede706f,593d93e7,73e3555,c7ab31f5,60a83985,a575294d,1c73d135,d8348521,802df34e,ffc3956,498b0f25,91ef05cd,b71da7,20ce9b3e,b9de6db6), -S(12e42941,44a1bb18,e7944b3d,846429b0,cb9010f4,b42a31b7,e7642b73,520d2ec0,bd7a8a89,f5e1d98d,adf3dd7b,9c8b2bda,5e49f178,cf51796,9bb99903,43901cd8), -S(93b9a4b8,bf35a92c,1f008623,ef3c864b,79de76f8,5d52c4a8,67d24e5c,970d3776,10d1fa77,43bb9211,76801b67,5ed9d304,8fb25b31,65a0f544,52709615,965a7b0), -S(29cae9f5,688107b0,d7cd3686,d30c0dd2,1f65bfae,11172330,7d21b8cf,9d95a49c,dc8ba474,da42ca9e,2325123e,1dbf93fb,c25469a3,381b6833,437034e9,2b6a20be), -S(d1ecd9ae,8af12732,f9423f23,f261caa0,c75a7e,58e0ab83,7fd47568,d3da43aa,c24712cc,49a9a669,e0e46068,60a8c0d1,969aaa66,a436f3b9,1c530e3c,6c0a71e8), -S(fd43cd42,67c4d07a,d70df093,863feb4c,5f82f94d,c81c504e,f95dfce4,4092104b,d68e7968,e003ab0c,ab98beb,796dea02,e854ce39,ecd79ed6,53e001cc,3be14c78), -S(d758723b,587c3af3,52fd7d50,9ef63ac9,efd9235e,a8c8d8d2,41de2898,73d5fe94,43094c5f,1c773577,29b9638b,d180a70,b3c9ac41,8e078dd4,99f5d2b9,1f02edd7), -S(e8fbc8d6,51f9828a,2ec3ccb4,9b7fe22e,18604125,7c975ce,3c01b362,d2897e36,1c306170,f2e1fc7b,ce0d9ed9,fdfa39a4,99d6cd36,bb04716e,e1ac003a,d7573242), -S(bd8878bb,f050eb0c,bc7775ee,a3e991b9,5e72330b,fcba7b3f,cb7dcea5,f1464f2b,c3bbec0d,e87c5a17,5370e6f2,f98b7adc,3538a452,e04ba2db,3e193ba2,d9d1ba5f), -S(e47e80c0,bfd82bf4,8aed911f,236a7d96,4f370d11,c5c10912,3828e3dc,e87e0b3,1856149b,230697d0,1fa39446,9434270f,d0932196,aa7e4551,faad127,b0d22d60), -S(224963b8,57e650e1,58be4862,bb70d566,c2fbc28f,c6892eb7,6f04135b,7a91761c,28e62c6e,887010e9,7eaecc0f,b67e5630,eb2ccdb2,f95d0be8,51c43db1,54ca6e61), -S(b500417f,b75ea406,cbbd77d6,48ac1e45,70703605,8990b340,85856564,a64af549,daad3ad1,9579c990,a7e061fa,f98fbd12,5678de87,ca16c708,7130dc85,abcf1bee), -S(a06e6152,bf4d9aef,d18fc0e3,6e0eed5a,a35b316f,7db75007,ca5a175f,3a80cdb3,6faa9900,6bd783ed,d8c207d5,95843ea0,2819b277,7db69ae6,908d7ef4,4e04e781), -S(179f9602,2ccb2620,3e94101,c9bc95de,5eb6d3dd,8a04f18f,17f2ddf5,1b0df5d4,dccee7d9,30f31ea6,3903f801,d4712ae,ad5459a5,b0ff2987,b3b1f454,650180a), -S(40312ffd,1e4508a9,854c3f94,ffb878fd,a5912ba6,5ea241dc,ea82cc66,e586de28,e111c511,5399357a,eed01d11,18ec409b,febc525e,53cee921,d1dd0455,d01854d0), -S(a29e24d4,c72bd5ea,98630030,a31150b6,5a1c9676,d661ba8b,19d95d5b,ccd7bf31,a906225a,120eb05c,3885e734,75765949,a4da7e4e,a6aaeebf,2f23a011,7aa8df9b), -S(e2e4adce,eb40ffbf,f2a31a97,a34e5f4b,9dcaf149,76747838,3fc0bcb0,43139bb8,94ef60ec,26dfc1d7,dacdd451,2f8c0a0b,ccba1b04,7ae3c197,46f3c234,54a007c4), -S(2a11ab6f,7188858b,e0c8c08f,22b4bd83,3c864a74,4c43428e,2c467d4f,a71118bf,27f83304,ae9e599b,2a212050,c8c363aa,34ae58b8,13912bcc,f6df669,f01a690f), -S(23cfaf4d,57e0e9ec,a8d180d4,568016b9,4f896063,c6fb4e2d,7cf909b9,6ae048cd,62b11d6c,2c3f30e7,655d2c86,8c7fea1c,391d2982,5fdc92fa,f2ef3e5f,f2d65587), -S(cc112ba4,a6b684c0,6f95458b,18f1d41,d0c90022,1fb6af39,203efe1f,f32a07ea,7919e449,eb1720a,49f66e8f,fb3bbe76,4a5e23f7,798f47ab,281d7cb8,9409465d), -S(4d9ad572,bd2829b8,ab98f048,88ec4369,b577846c,59e70414,7128c4ae,17159456,4570249,6405ee85,4bcf1201,9b56cef0,136a4cff,cf90ce00,52711348,a459e1e5), -S(dd32548e,826e2aa9,faca198e,f911d0d,7ec33ac3,41f625c6,34c59c0,ff3e3bb9,5526048c,fcb29f30,ac84ac24,5230b0ca,a0e68e88,ad6c3c75,544bb137,4b1fb47c), -S(c4ca7cdb,93519cc1,7762ce27,249e21a,e2bc5dfb,727a4e23,a38f2938,e41e57f,8233f977,3aeb917b,c65dc1d5,a539f62f,c8403779,f1edc4b5,781e92d8,fc8bc802), -S(a1e1f0d6,2a0d616c,ece08d20,fd529521,c5872f8c,8cda2bf1,a679af71,71bc46ef,68a2a818,4340b803,c7641034,fd609333,180501a,612d3b6,c66754c8,16e5368b), -S(d099aeb2,a5fae253,6a953441,7439e745,35fa8236,96731b6,cd327332,8771bb26,c526ff8d,f32deaf,b7080667,c9d74257,f294355d,4cd10414,e8e38fb2,b3722eea), -S(87fbfc7c,ef2301a3,b50c3bdf,993c52a,b2c32ba2,893b8d60,19f224aa,9554900e,aaaa988e,cf77f228,ee4f42ba,a7ef4a64,ab475e3,3d708ee8,e2826fbb,cc3b92b8), -S(4b440dc0,d6673ff7,cae6cb6c,5ad6d54d,fac23da8,f8e1a570,82fff0b3,eb165493,35841c69,5eecaa5,1499676d,a97c197e,b60fa733,281823a4,2e0bbd8c,ce44b2b2), -S(3ccc6802,cc5fd5fb,82bcc9d1,4e2a2765,f68da87d,7fab7e0,d1c05c68,515fdb2a,3be7e4dc,fb8c734c,d9f0254d,afde26fa,1772f094,43420bc0,aab9e29a,83de67cc), -S(e98bc0f2,d6f9e71f,deb01296,d12a7a0d,b617e5cf,fe2bbc9b,ab166eba,e1a59b85,2fb5ee36,2c01c58f,9a113e18,e03a9e49,5853f5fa,a11053b1,73ebe019,58710ade), -S(5c0bb588,69cb2007,86f2d549,f4fb4146,5656739f,15c8ff95,afd057f9,5db895d2,2c69dc05,b3b5edf,a4d8c3f2,41afe00b,b67a29da,4f1a1301,83c80876,21ecb08b), -S(9c8ef657,972b5330,caa9b64f,7d7c817b,7c0b1047,ae2984f4,3d4f4085,3cd01267,98a3630e,ea6b3bda,c9e9df0a,807eabf5,baa9b920,524a7aaf,2e1e9f8d,8173917b), -S(43b18341,11a7d2c1,d5341b95,4972d28e,e734cbbb,e352460b,75fff2e4,a9921035,3d32e375,40e33c0a,5d4eab42,6849230,22a7c560,3d47e789,30022b40,8fc99f96), -S(89d86eab,b52a84cf,9e53d7b5,270cf9d8,198f032a,e43a286,e18fbfbf,3d0e59ee,bb7b7247,bfb01ad5,fe143967,e5cfa75c,d00a54d1,83322fdc,63a7e29b,5d7f47db), -S(567061ea,2b03428e,d8430f6c,5f03b469,cbb265c,ceb9d999,30509d62,25805515,ab9917,15fcc760,c9aae0c6,5862333b,b886ff7b,b423f80a,92ff44e7,f55f0259), -S(50e830fb,6efa74c4,5460d96d,bb9acb33,df2a3ad2,83602ddf,214d66d7,967bb35e,b5914d4e,24073b29,31937f67,58d69c46,917a70a8,213617fc,4f669622,401b17f9), -S(2bee6cda,ed042f5d,c28bd7b2,a9266c1a,eb502ded,379d4eae,21c8810f,7f8dfead,6bc759a,a1a950,e506c504,86392bf1,4c1d9e8d,c212192e,6f99d274,c1b82754), -S(c4482ac4,508bfd79,b4b6592e,d72b5a6b,f58f1e08,76194a5f,9829cc18,a7959fc6,e99ac34a,91d46cff,e9ab0b74,883fcd24,cc93eab,abfd4873,14920417,1bcb7b54), -S(55bb94a8,70858f43,2753df21,592479cc,32cd6533,f5c7cc6b,73517cda,1814a57,93bdc1b9,8b64d43f,6fdfce00,b8ff652b,ffdc2c75,afc4c95c,ed7644d2,86dd4224), -S(2e17cf48,bbc6b561,3fb740f4,52e2f03f,64a01a9b,bc770df2,b0a4d8a9,71e93fc5,efa5836e,183e1d1,b8e02309,5526ab9d,fb1fc046,92e1ebc,56a6e3b4,4f425c4d), -S(86fa5013,f9928726,79276993,ce380d50,ac17d961,24b48c6,b68f6565,6e39a418,d66a981f,95bf103d,3ee373b9,af27ccde,8fa454b2,1277360b,995a02b9,b7e43b24), -S(6990a5e7,d3d4da2,48f4b621,4d8d3d04,78b9bb36,6647a0d5,3cb66412,120bee3b,5a75c630,d1551aa4,ce9a8020,4ca405d6,dad9291a,e28d0fa5,e14e8df1,1ff79727), -S(1a901e6d,2bf440fc,97075337,b6188f4d,51aba0c1,4207ff29,83ac6eca,9312ab50,6a40d2c3,c497f8da,cbf7b079,7cfa1eb3,80fe0d6c,f3b74a88,7ef912dd,3d8c38f1), -S(37d9f2ff,3f14bd91,3871eda1,c5719b8c,c6e92717,dc97b308,5b0b6890,eab8284,84b05081,cd3c21e3,b36d1766,f133284d,d4abd71f,dbc94baf,33d297f3,a8a238d2), -S(8a430121,8acbc3a8,44436a0f,c476ed74,3548a445,8deeee56,55717e7a,1117166,accdb0c4,aaed4b97,658b77b8,af83248c,85456cef,ad368565,4f73b013,3a258e25), -S(452e5c3d,9c95fa1e,f5b9b508,8a2bd2d9,ad1b6871,5b07d4,d096e99d,22c7fa25,ba4d9d3d,49092858,c6a2b44a,56586ab6,8cf1d7e8,f92a4d35,7b1b91ba,509066bb), -S(dc5d9da1,efd435cc,70c5ab24,994b0fae,75e9a628,a71d1794,ea620d18,83facee,e16e5e82,91f44b12,e6512645,d9ef73b1,4ce928ac,3b4fa30f,bb2e958d,28f1263a), -S(ea6aca7f,b52088bd,7094764b,bcc2c0b6,9ffd5859,e1fba329,4212b0ed,7fda33db,d81cf674,4ffaab0c,71e43cfb,3c1b7ff1,480024bd,1691eaaf,cb5b8174,af824cfb), -S(2bc369d0,ae283c1f,ca38ee72,8a154d9e,62935f97,45f3f043,51800368,651ecca9,b469499,33f679f9,5d75cfd7,94dad8fd,b06d91ad,8c019dda,a819261f,1492eafc), -S(c4c52452,80983e50,4a599a12,782f006c,c7a5fab,5b782d18,b68a7143,ef1a382,a23e7df3,e1443d5,72278fbb,5ce63ff8,b7ac020,1544f21,3c9fc2c6,6c7a7b69), -S(42e4ce90,1240f01e,82f0f4b4,6ce1a1ab,9b26d339,b7a4e128,886031e2,6e6d08cf,61ce91e3,b05dd18f,6089cc3b,9fab7541,d23725b0,49bd16c8,9e468bfc,5af82be5), -S(288a0ac9,72a2333f,f29dcd93,faba3852,c749763f,4fe88a79,601ad6fa,7440836d,fd15dbb5,26ccdaea,7a02807f,f1edd91c,28409802,8f84eb5b,18cbd5bb,1bcc5daf), -S(1f9655aa,5434b9b6,e4b76058,6557e2c6,77df18b6,1a732003,c9cfc21c,97db70d7,98366446,9229d5b1,67bb328f,205260d5,96930a73,8f562c73,707900b1,52b15632), -S(a509bb96,95d4ec8d,93fbdbd2,7280b68,597cce37,a0d71fe7,bc0eb915,41ef6e8a,b28d1ac4,7f548df2,4de2ab4c,271a69da,4b0ae5b1,a4a8c8c6,1ffbdb21,74863e1b), -S(10a2d8da,bc8ca5dd,88b84e39,7a4a3119,61c3470c,9924491d,bf206432,a95d7d79,aed65260,d2eda695,d67a1abb,97d24e96,83ce4a38,46c46d19,6ebf3e1f,5ceec78a), -S(222588c5,3ef96af3,af198f26,34180c2f,13941afa,cf3ffa45,29bfbfdd,3de12d38,648de7b5,76a4d19f,6ebc5785,1c218a59,76feec4a,7b2aa840,6d3917f9,ab364ced), -S(39f06a75,58e5f736,fa6d85ea,6e55f841,8bf722cb,23dfc3bd,3249bf99,471f680d,6e7cbaa2,923201f6,800a817a,af7a74f9,49a8bfb5,70a8d555,d9588c4e,917cd6ae), -S(e6e0f39b,9cde4787,dfd22c28,154c1f0b,bb2a2cc,f67547eb,18117941,d4cf0b7c,5c91c032,21b8892e,bfec7a9a,21ac78c7,2c32a7fc,63882605,5c2901bb,3b99dfaa), -S(d041c732,d1728f5e,1ba5bf55,9e22c824,275d74e9,f58929e1,4197e556,b8855569,f2055dd,9cc15a6f,95874965,3cfe9399,7ea79f3c,b52ca46d,1f887620,c15e497), -S(35bcebd1,45c3cb47,946deacd,9bbb8a9d,b791f087,39a457de,52ac3a65,a2cf459d,7ef44f3e,bbe42529,5f5abbd6,590f1f06,19094a66,21812331,7d025414,147fb9a), -S(69dfb692,8e0a7fd0,4f26d73,436e955c,52a01239,9382c703,e820f214,3d5153ee,874f75cb,aa5ff884,fb3fc309,b15b36a7,df29ad73,efaf66b9,e4d578a1,1b1936c0), -S(4cffedd4,2e6412a6,5f225b6d,1901d551,4c7192bc,7c09d454,be730b24,fe126dd9,db4e13f8,a050b220,81d998bb,98e11bdb,2afeff60,62b69b20,58894e77,f3272ffd), -S(71087039,9e0a995b,baa637fc,d1a58ace,c3564514,6d203182,60539468,702d145c,4a94877,6fefab05,6380f77a,29ae7d8a,bc1bf472,28180606,a0ebdcde,8918b10e), -S(15caab55,27c3b93b,5a708d42,4fad0cd1,11b0ee7b,d80cf28d,1407e82,abcad580,61b771b1,b8290ba1,34850edd,993dcfda,61321cc1,7874b60f,ca774ceb,38c53658), -S(38dae820,1c973758,7bdf9b0,23044555,d0bd3453,702806d7,e49d7196,2efece73,b5cbaa7c,f83b4dbb,28ea4797,dfabaef7,95167b09,3ec173f3,fa4e5269,48cbb5d6), -S(359f78c4,f840f5ea,8cb0b0ac,67dc7f57,84f6cfa4,fbd3dba1,4bf658ca,190ad431,39d7df87,8c9470e7,61f9ccdd,da1bfc8c,8b34a003,89df27f6,354571fa,66a608c0), -S(fc0ace9e,607d11b9,8945c546,2f210a33,586397d5,131cefc9,7d7b6737,aa4cb19f,61cbcd8b,2131e124,292d0d69,e8543867,846dbb06,90ff745c,5ca5bad3,96596a6e), -S(1256fa76,bc6da2f,9ebfcf03,c05afabd,bb43c4cd,eb0c1af2,cfea3267,3f5127ca,9788b8bb,223f13a5,909bc219,cb582232,8f101016,db9a5799,6fe8e51e,a7e4aa33), -S(52e87225,4890364c,d8b2c5a2,34fad84a,329056df,d3131f84,6282f5cd,231c552c,b3227c4,b8932f7d,aa787ae7,c5ee5122,a0452862,43489ed3,8b9dd191,499ea46e), -S(d7c5c4d0,12f6c325,b356a323,1afc6f4a,13e11fa8,e40db671,c3d9683,20d63a41,31c65dfc,f30c4d23,3a0020e2,dd6f2829,f101da64,88589bab,11d50c5c,89e5e04f), -S(71334288,1d40474,5d7da525,c10fc11b,645bb0df,c92add65,dfdf5018,5254b1a6,52245a3b,e4cc60d7,8a029e4b,1e482311,cb1ae091,4bdb5cf8,ec6db584,2693ad53), -S(f97b9e11,1749230d,b6420cad,db097faf,fdce34db,cfb77f89,596086c8,32158e8d,5ab80620,4b7a78f4,e8b98f62,4b2c6622,9746d840,cb43cb04,bb737403,5cb57d96), -S(ce121ae9,b5128a22,917cecce,c5daa168,bdd61bda,8c17818c,ea678b04,35d73ed8,dd63e534,1131922e,6e5de85e,30d23e9b,78c24cd0,bfd68c9d,14431ff7,3cc237c5), -S(c7344dc9,75ada59,ae0fb974,fcb7e68c,d36d99e9,8bbae0b,de3cad18,fec9fc98,c617af54,e38e7c6a,733bbf11,2cfcd97b,58298ea6,d5d1e738,db85ae7,fb6d8d4c), -S(4b1e37fb,34bc0a0c,f0fc8155,96ddb468,197c76a0,fcd61b03,953d3489,79f37359,abfb2758,4f6eac6b,3a7e3230,f758d775,8cd92608,7280aee2,966d87aa,a5d974a2), -S(187c41ba,25c3d7eb,9a0c319d,c82b1c2a,5e80f96a,1e0f6be3,53891e25,d9d2fdc6,3a211ee4,4ee64261,6f515682,f30ab58d,9edccef6,2f9c51d8,48ef14c0,b1aaab1e), -S(69e6d0e5,494e7ab6,5430360c,c88cd478,fd33c196,d5984d29,cb012c14,e7c0445a,ea292c37,99f914b8,2b99707,b3e22251,646576c6,9669e66,74551217,c0266006), -S(acd53be0,92b10fda,f199b0d3,95e1461,cfbed969,303d65e0,fac52b6e,a9e6ac4,3e08e524,f1f2c044,dd581c81,9cf92a88,1a003981,1a08356a,28674c59,5829bb0d), -S(3673cf9a,1b30bf54,4b12e80d,e9400b57,6680f866,d4f40a36,ef7e364,f112de90,eb5a492c,6c7c18c5,b97a1d83,3c48a3b5,8c764572,7559d19b,a49f01e3,204d22a9), -S(29d36d36,efae37b6,96083387,f15e2300,7a1a8897,6387984e,31b8688f,789f6ab0,5a65924b,cc549712,992bf77b,514e8f67,b5b5b677,90654d14,f2813e43,45144408), -S(1f42155d,6be7d164,a376059,36d253f5,b4657286,c70d386a,ce5283de,a3dc6491,ce04e68,bd5ac22f,5ef07b0e,a0034ee1,1a6eeaa2,19d3f7de,d82a5296,84721309), -S(3152b951,db4f3586,994d7e65,fb855285,9401434d,7f9f92eb,5bea66e4,4783bc01,bc8aa531,f83267a4,84fd6485,2a13a155,ba18d89,9a2c66a6,ded6639a,ec856ad1), -S(311b8ed8,66830c54,754cdd74,a9d057f0,34566b1b,43e40d4a,85236f05,3b41808f,6f1b0365,2443f54b,3276d30e,23967ced,42476347,e9a13c19,419f1ac3,10bb3066), -S(348dd77c,cf08f8e6,d3ec8d2b,ef0ab154,f1cb1908,1a497b49,7c44ab29,c2299dec,32774af8,4e29b1ab,ca10560e,b0909ceb,5815068,d4f49fb8,e5b1766f,fbc23571), -S(632e0270,d07e3855,446017ed,d8753402,19e325c5,40079385,1f321378,b22d1427,ee608d57,3c5e5d6b,a78f90a9,58d5ec07,4068657e,e19192b1,5dfaf3a5,54f930b2), -S(750bf219,84a046a3,6a2dc2e0,351fff5e,25cb20f8,1631c91c,81c8c10c,3e251bc5,59388fe1,6b5a4f6f,59fadb9d,d37bb50c,6993330,79be47e3,344f2175,47756114), -S(1957df1e,4a617193,1f1d0f7c,fce46d02,3f0b3f49,53b593ba,bc882368,bc7ee3c7,62a95912,beee20d,43455ec3,69e0b4cd,f8d017cd,520a831d,b045226e,c7302c05), -S(bd846d21,7e08ade1,833ad435,4b5af61c,f987e071,319344f3,6ae78bb2,7fd3dd14,eb6a2269,48ba3378,4a65d1ef,5b643c6c,102b09c1,d3ee4dd7,13d8761c,a1976a12), -S(871fbe02,37350222,fe698501,e9fb8a96,985b4254,8d4c8457,5a9c1388,c3f24d35,c1660e11,5bfc3e2e,29e3c8b8,461f479f,64f60cba,5e7bb363,2cd92127,dd78d69d), -S(e7aa1f24,b4be5505,1321b35e,6aadf2fd,9cbbb45d,3cbfd0de,b990b032,70a58a42,b5f3e930,45efa4b4,54ca308d,f529c526,487e98c5,9bda3402,531d9ff9,c4f618eb), -S(879ee365,67d03ecd,7a06efcc,b7fb2b6c,8e756969,5f369c07,bca2410d,3f909399,1242e4e6,d7da2997,aa102242,16bd3e4c,905452a8,90203a43,60667fb0,c1d5647), -S(853bed4c,db8d5a90,792681a3,f654d2,c7947e70,1b94148c,204128ae,5296b2e7,d5a0bb9a,5c785ad3,faa3d26f,732ea3b6,ff50805d,344c823a,8c8f5f79,60d11dea), -S(2a40813e,c0c0fccf,8488c8ba,add7a231,7313a0ab,923797c,2abe6285,971a0d11,9552f927,f6e501ee,ecdfc1f2,1cf4001,a39e458c,23d5ceb3,c4cd1c3f,8155343f), -S(6a77953,3f265be4,d6c0de74,4137a9aa,cfbdb479,92093a61,94b3249,2a50f5f2,fd6eab4d,7fcf58e1,d2fe6b14,d34edee0,752bf837,f9f1bad2,a25e5be9,df979a1f), -S(1bf253b1,d971644,ae6bd7cf,b0beede5,c17d16c4,a50ec5c,70b050e5,159f544d,34a466d2,6e22ee07,a38928a1,a0ff40c1,d7600771,e4478c73,9820bd84,6abd0615), -S(8bb4c9b6,99634aaa,a30e6792,3d543572,2fbe69e9,b0c8f4f3,febcde8a,76700ae6,b36ad35a,7b47e2a7,1e35d002,49ca67d5,80c6d803,3aa7b3d3,340606ef,d6b0565e), -S(796cc3ac,1413160a,7f5f4c9f,4b4b1c4f,99acda5,ad71e8d9,e9bb772,dc4b01b9,1a674e53,fcc8f8da,a40badaf,4483ff63,eaba8555,2d1f264d,dfc138db,43c27c06), -S(969fbfd4,3d17cf8c,256d3bc,a7de453f,4fce7840,10c2eeee,6c3c3077,5e08b378,8f38eed2,1b64ecaf,56cb0e5e,ef83e94f,394ce1fd,9cec89a5,e2814ddf,127a3f95), -S(590500f6,ee062164,eebad106,7897f85e,75d73696,39156e73,369f2811,acf60685,71060ec,51b9d51a,aa8b90de,6b1f7d08,f446e262,3bbdefb2,4664f98b,c1becb45), -S(635f3674,4654a3b1,e905bcf3,198e9747,d6c516de,ead4fe98,c2f8a86c,4961f5d3,415b4c90,a3681e72,b8ce95dd,804dce01,b1d6740e,9d53078c,9b8144b6,cffd69ce), -S(68d94350,a15ad103,aec6b0b2,792233f7,b0d83120,ee5b1d9b,b481e84b,d04d1a2d,790350d3,32dc0cea,2977e09e,fce1c669,978a2588,9a8d6082,1f564e5a,7213606b), -S(c96e7e8,ec77ee02,335ca492,7f15b99c,e0f451eb,e07b4506,4c05467f,461f01e6,e9a31a45,b9424ddb,9adc82c3,df3d628e,bb1e9979,c9a0c650,77af2678,a6f95980), -S(7917fd53,b5be089,fecb576a,25aa257,c915f9ee,38bfe4b3,f86ff29f,488d680c,b09ce7af,8c77843c,35c5c621,65b527eb,fb28aeda,9a36829a,de905dc,d6f70ab0), -S(f55b5dad,a5205283,88d574c9,629d16b9,7f937bac,c6929255,55fd4497,38a5ef6e,34201d75,2f3869b6,f8db8a88,bb018f54,cb0a6d3f,9f87e522,e22e2db8,800acc7), -S(a257bb75,eeab4ff8,269c4124,db5a9cf1,71779493,7537b46d,52c72467,f9cec60a,f08014c8,6b355789,7730b437,bd9e84fc,22ca7740,a5cc5e81,618499e4,ac74bf6a), -S(3715ebe7,da86335f,b386a73b,c8b7a4c1,4f6e688f,ed72bbcc,83a92728,69cc52d4,976fb0b8,6a119539,90c05a68,49e22544,484dabac,577bb642,a69806a5,39161aa7), -S(c57384d7,29b0a7b7,c9814a4f,f369cb75,1a3d076b,df00dd02,e87f82f5,3dfd6817,4319c981,2610010e,6283ee27,a72f9473,5c10c4bb,d246bbe5,d6078473,b80d665b), -S(7d09cb55,b1a3d446,77dc5ada,4cb7944,c844e82a,45954ba1,ec2dfe4b,b1f49ef8,72571169,2db1e3d2,217e2e24,992882cb,fa11e4e,56c82acb,a1db0d0d,35c5238f), -S(d0a60225,5b87b479,4f2ddff7,a7b32c3f,693065ee,dfc78f35,f8ee1813,30a5319,4fe22384,42e5d371,46e730c9,7b91587,bef5a036,535e609f,de2f6f07,865ec3d1), -S(ea68a147,c69797e7,813b5279,daf2b824,e12a5ab0,69b18f91,f7cec706,c9107264,218fc72a,8e0faed1,bbd55ec5,d1b84912,a0bcd7d,a6367c4a,e6f68d4e,5d218841), -S(d1848858,d2436d03,396c84d0,3262ec0c,e4898a61,86b66e5a,f4e8143b,1713c810,91cb6ce4,c502af6e,eef8be3d,93261cea,79f102c7,12c798bf,8228143a,bc6f4ec4), -S(10883dd2,d74d3c21,a50a3b2a,1243efbc,876f94be,4f749173,9a76b7c6,c3ae13a4,376dc0b5,7c8e454a,eadb8a1c,eb53cf24,374961b1,203175d,f682c8fc,895304db), -S(4ce880c4,f0d3f822,47cef7,7266f02e,efe9d1d7,75f3e1ce,f6bdc7b5,9a1b91aa,8d8f082c,3e3d305e,91eb4032,adb695f8,51cd3ebd,78c8f6b6,cfe87cd8,6dc645b8), -S(7f43f40d,99228e89,29102200,49f40ebb,89508aa2,2472ad89,9e14d63e,69df3cb0,64bfc237,cfd6fcc2,aa1d8d5d,d709aaba,542db811,c4098d,68f8a123,39291cac), -S(91a6f844,6bf0d01e,298e8890,98866445,96e19b74,802fa565,91ea7f7a,3e01bea4,425d1750,17f81fc4,939abfc1,63aae7a1,a9e57623,3853032f,2bca878e,e53f4bb), -S(c1296478,5ef73db9,27acaf97,7c459535,15ec8dc5,ddbdd62b,d85d448b,747b25d1,72d82dba,36b200a2,4921a696,ddaff7c3,16f6027e,516a13e0,ef3c6c12,8187d956), -S(5239834d,63ea0e88,6df2db9,8496d181,1c7001c8,c845b319,309d8bad,7737b4b2,32e24dbc,d6265e8a,902264b4,345bbeb2,40363c6b,731ae6a,a9fa6194,ddf9ca51), -S(e08691ef,b43e68f9,bf315a12,7d5a93be,effbe597,f8c51e15,fcfbded3,72be397e,f304ec86,55f6255e,527f0c4a,80db724a,f4c5fe8a,e7a8174b,128d09c4,1f38bb56), -S(8ba2d25a,18b66731,5f03025e,a79c4177,24ee484,ad281e2f,a34d21ac,ad49711a,a9a0d35f,e6508408,219f5bed,f8926a97,fc070ce8,3e7c8a9b,9e319cd,842f75bd), -S(40a6b491,c6c180fd,fa4e81cf,ca69e9f,b264a519,55796ab7,1f5e1089,79c8f243,fd51d9a6,35be3859,280caf2f,c494e4d1,141b5faf,c54a9575,ab98faed,c8f0d8e), -S(176e36f4,80e9f1b7,bfece37a,55577811,a39e4390,9b12a8f,75b4ed9b,a3c5a7f8,5253aeec,58dd769f,12583d34,70248112,7720ac71,1e9b4273,b4a567c6,f6eb91e7), -S(72ee3556,e5b22f02,9eed97b,ee54c7e1,e3a69fe7,f2e83e13,401c7ee6,dd4b2b95,9b728711,1ae6f55b,1aa1a43e,271c0a4d,e0768689,62a2166c,ffc996e2,d5d2ee8b), -S(7a1aaf5,616ca51,374d539b,d67c7373,191750f8,fb5c512,5d23ae01,3297db5d,430fad10,6e887fff,ce7f8e99,97cd20cc,63abf2e4,d8783da0,f9551a57,591d72e0), -S(b7c2c82a,dffc0544,8a350835,843cebcc,7c854fa9,1dd50429,f0cbfabc,738f60e8,ba5a3066,1ae99c9c,65017efb,8dec5279,ad99b3d8,fb93e1f6,2292fb4a,16566ff0), -S(872247ed,67ad35b0,6fae570d,ec2d5717,f1aba1d0,39400e84,b4bfb997,c124b13c,6d6020c4,cba3bf3a,34d6c831,84ebd4be,5a19bb63,dc2fe3af,458ad74b,bcae582a), -S(cbc1502e,b44ece8f,c641d32c,1206aaf8,4eed904a,8b00507e,338e6017,d7decfa9,105afd03,4ec01247,27bf7159,57ef0b01,3dd37776,dc40fd7,5a0f4385,e26620ca), -S(15768fa5,72722a8d,b26efaeb,61ce7f71,95c0e10a,99d5fb09,fd1ad9dd,bc597590,8f61c181,98218dc2,8b8e0730,ba7aff7b,c5dc3730,30a27caa,d1b913e,36df0a52), -S(52301c83,5f809de1,7bdfcd79,fe3e9518,a1479df0,24a2caf,423b86f1,c685cae,3d171f90,5f13860b,778e5708,c2e3914a,c911bfb4,f70a4af1,2a1b00be,62efe3bf), -S(8fef14f4,100d0f24,b9dfbd35,12d02e0e,f4365406,8630c899,aab5bbc9,ebd6cef6,dd67918a,27d6a6c0,812153e8,481e6a42,b05ce8b2,dbed064f,b82aa417,1b788850), -S(7a4d8983,ce4101db,ecb3dc62,c228d75c,bfcb3283,d575d73f,6bec15c1,8b5cf1d9,26ae5767,13a0c2d4,dc6d4ec0,d3f8c038,48516436,ae5286f9,698bb2fa,913752f6), -S(aeee0e3c,a620b586,c34232a9,e3bc6b8d,f5b72be9,b1303be6,5c07fcf0,f3507c58,d43e4b08,6424e81f,c2b7f809,d17d9572,83adadd1,2bc2226,a190755c,82d010ae), -S(7c97458,6753cba,49ca2e69,905ea7c7,7a6f28bb,f3c7f390,d75aaf3c,3d1eb924,fbe15867,a8e7aa97,4682180,c9083321,5edfaab9,a7addde5,7e5b8037,acc9065f), -S(9428c393,31d5b775,ba3922fc,43cfb7ae,98a6dc54,1541dbc8,bd77816,1aadbc06,f1be710c,5fcacae2,4e7afb36,353b8417,35cee21,8d73310,4d58a19f,7ddce278), -S(45aee6c1,d86ac7f5,b8434541,9c37ced3,ddd54bda,5d8582f,1ea4d2a9,767dd73e,95962f5c,45c6f3a3,22f430c3,919ee03f,cab243b3,f9feb2fb,9f8b00b6,983a84b2), -S(5ab3774b,b840b2ac,e1595d53,d51c5d92,3f7b617f,1bf07ee1,a091c798,20a6cacb,125f6498,1d82a4b2,ac7b1471,a42da473,da38524d,def91d11,a045af83,89d9904), -S(28966b11,43e4d01a,d8a7d161,a3b6031,9165518c,880fdfeb,bc51e0b5,84c3b9cb,1cf95f95,e8422d0c,cbe87d43,b831ce39,b1f79026,14cb1538,a4eac1d4,438b2c7a), -S(ad71d209,83a14eb7,f963d5e9,aea67d3b,f00173c6,b7625b3a,9fc7417,f49a3a76,a72f2b57,fe593a09,2ef5263a,955598df,fc2266e0,ecda8cf7,573ab085,9a82792), -S(f918d962,ce0cc947,2539b1eb,23482e9c,a69b6254,1d0ad633,5c35adeb,cee0bdde,41446862,e8c749f9,559c002d,c42deb6c,bd2240fb,b5b0d4ec,94e0d142,e6ff8bd), -S(f0706622,6367ff84,f7cfbebc,f389d1fa,e9f97aa1,f1acfdf2,d8c6145b,e3a8a159,53af7a59,6fb697d0,2d01d8b9,b0c75304,ce1009d4,7f3c20cc,94123aa7,9c91c813), -S(800e414e,9789e121,2c8b6f71,33027b74,14da762f,8956f347,4eedc170,4e9442f2,7d1ebac5,3088ecb2,7bd8a881,78318e1c,d0ada6f,9b8f503a,57283c6f,b2039e31), -S(2fc35a13,b45daf44,8370dec9,a43237ec,1d7313d8,1113993,7e103ef4,1c90fb78,ee6b54bf,97a32d23,3755ef16,85b1f212,2e46531e,164277c,8769a6a6,2adbf6ca), -S(1bb58cc6,8606fb97,5ed32c09,f668e25b,b4795ce,84ee0e98,5dee5536,b07929a0,9e82d8c8,b37926ad,29954971,8b6dba63,229e6887,14e03042,ac3a5fbc,a8e9fb0a), -S(2479bbf1,e9ef8b33,b1a93153,47392063,19575393,3b0b760f,ed876af2,a98c285e,e58fe58d,3ca3e0ce,23bed9f0,258214a9,51741872,e5198064,af43e106,70567e66), -S(b396e44a,41e53514,411fdd39,6e1084bb,dcda0750,ae66145a,efeae86f,87994254,6536d014,1d2b6a6f,a0425f70,c7374e3d,4fb6324c,931b004e,995ae706,2762583b), -S(7c1808b2,bb1b46f3,fa79d047,ba65032d,7b2757eb,a9b1f241,2379e419,9d4242ea,bbfc916f,cd41f3f,e269d5a4,38bfc9d4,fec0dff7,739ede5,8785483c,c4657faa), -S(92e5f9c0,13a482dd,6789661a,2eaaf396,7c0321fb,1e488f92,44e8ab96,cc7273bc,e2e815b0,f9f43539,3a265354,f6880193,791a3bfe,dda916ca,ea12fda3,27e67eed), -S(6a7ab088,8ea54626,9422c715,e9b9bb43,cbc565b1,ed885200,1e49d8bd,4a79e84b,dea9872c,2c07f8c8,461d943b,cd6328bb,6fd23a5c,937d5f3b,5a87a921,94a5807f), -S(75b11622,ec6cc4e7,6887ced9,dccc7604,8bcaf51,4be6b6f,94b1d7fd,e35b5600,7f654a7a,1be8680a,d94efbcb,12a4ae65,2b0f1859,5c14ec92,df83e72c,cb98705c), -S(ca26ae7f,2b6b1e1a,1ee255d6,68d85ee1,88c7d6b3,87ca8374,e07eb9ff,8bce3df7,958ac803,5fecf72,a2e89cd3,d54e151a,575eaa9f,2e4c1742,a2d8ea21,98c0d35c), -S(e6109fb0,a6d50ce2,c9eee96a,3f5eda11,31af4f00,8ea9b2e5,eaa6619a,9b023517,92a046d0,653d61de,97ea073b,7be72083,1fa16ea4,cdd1f4f4,ba9e94d1,37e9636), -S(a99f3ba5,30d7e13c,f05c77a3,27754420,50b3e1c8,eb92da33,988b28c3,20caf85,8b73170,71d3533a,37968605,ee80b458,5c77688c,70aa6aae,1e322015,e9647713), -S(2ab7b1f,4b81ed62,9c358544,6cb81e01,77e9b0a2,43a4c81a,58e636e6,1df8f5d4,940c38f1,605f9da9,78c713f3,81d578c,88babb13,b08d7a53,f131e60e,fad6763c)}, -{S(217de5b,a47e8de,cb9d8dc3,dc8fcfd8,203c514b,b9d7bb5e,fb03584b,aa1baaff,c77bddc0,3af15e63,912e51c7,19bd8186,67f999ed,9bd801b8,11bc289b,f12864ed), -S(109382da,7088d834,bb181d52,fa1a54e6,39177311,fae56ebd,eb3a4b43,f3e95ea8,4b9d8ef8,ca4cc192,e6b60506,d9f7ecc7,a91af4c0,6e976b79,a90ad5bd,a03330be), -S(ff8486f2,d5296a82,16567549,7a46c099,56a1b1b6,15577e6b,7e789f4f,e032e31,7348e2f,b0a04014,2e23e7f2,bfac58d6,4e7b8087,2297603,dfca65cb,acfb7be2), -S(ff0252f,e7993b46,9174f525,27a6d39c,4f7dfd3e,234f7543,4aed99e3,edb8b04c,dd53af80,f6148d42,b5c7295d,150830eb,18d5c213,aa44fcab,8610ab7e,495d079c), -S(ad7b6b2d,faa1ef9e,125ddb2e,27fd5034,a576e565,c3cd7ec1,7e329e7,ebd22f52,9e1ca583,7cc8214f,1a694ced,2f216007,9b621ac6,5a2ed803,cb3bbf94,2e68b739), -S(1bcfea06,6ee96a7,63e7592d,3a9102f1,204408c9,7f191791,6b941a31,f2a257cd,c4f83f96,7e80765f,77b044db,e3488180,5fdb1cdd,294f765e,7f60cb7a,a6fa34bc), -S(95afe13,a5798934,5b22e95c,fa65a072,4e3e2914,88528290,8e99e098,2135041d,f94764e7,99b95b0a,180fd6f2,8b77ed34,699de7ba,ac4d5c74,24bc79ad,abd5690), -S(a0c4fd09,b3c27bcc,d3a52cd0,5e14873,7c49c2c0,c07cbaba,1a4aaf88,417ed9ec,1e7cf587,2ec3b0d2,f24b2b9e,531d39a5,ec30924c,44578b3b,ef82e55b,f432b1a1), -S(837f8537,d9347072,8ae81f1d,c58f6118,53be68f8,21571f83,4ea71bbb,34e7772b,7f16e8bc,fc9d7784,9d089ef0,77dd953b,508e5f0d,393ebdb3,27e823a0,c75d3b56), -S(c3637c50,fa14a7d5,307ef422,2444626d,179fa5bd,7a6702d8,29971cbf,d456c7d7,dcc3832e,901ddc80,874a82f7,e586c7fa,3cd79be2,7fbed643,ed926c90,d9b64b5c), -S(ff4d8382,9f7ef2b,b6fb2dd9,76787ed6,7cf062bf,bab5c78a,a26d5f2f,f8b2057d,64c4f671,73a6b641,7d97aa9a,fd6d3715,930c3a9a,fcd2dfb0,55aa004e,84cd26af), -S(76099a6,6bd40c1b,69009fa4,7e3237e9,4db5d6cc,4409b9e1,88c3a053,1ff1fcb6,5c7ad308,bd5ede4d,bd9ab004,38e1df54,615ed88,2b073aac,f7dadabe,f0d803e0), -S(f9f4f60c,11b4361a,ea15dc8a,19e1db4b,5f249f59,61003300,98babbc5,c74bcccb,26c524b9,1339e97b,b1de385a,b9f96636,2be8408c,65e6cc23,49505309,3aecc82f), -S(3dc564b0,6c5899f5,5e2f451b,feb11edf,90c1b843,523b51f2,686ef705,ce9d60b6,beb5613c,891141ee,a6eaef14,d5f0fe89,dbacb245,95d712e,b157ebcf,5d5db03f), -S(8ba520e,fea14cba,b5cfb96a,f09e8798,36aa60ed,ce5064e,ca04b802,78068ac6,74c2427c,42793f35,7ccd3f57,9e97e85c,38ec37a6,c4838c10,f0e315d7,aec33ec7), -S(1a32f327,c37e1617,2cbbf255,67636e65,c3a515f0,47f5332e,8a125ad0,84259bec,ac94889b,d1ba74fe,41ad4eb,5de079b6,321c3da,b76f1a6b,52382162,c8a22ff9), -S(a4fd9780,b897456b,b59da53b,7a0b00f2,54bc7044,7d0492ca,a96ca1f8,7dc3114c,e09eedf6,25923e98,2745d544,b4891cf,f443386a,e41a624,284bbada,38769bdf), -S(3c627056,5962458b,faf569c,9fd19018,1b37f5dc,4643bcec,4fca288d,e08db385,e6cf1f81,30178785,f3347f66,2cb81068,25e19f7,72da485b,79e697a8,fc822b46), -S(db75d23d,794297a9,778c28f8,6da0ec91,95e75b53,98dbe0ef,be88aa00,a64faf6d,1af59d51,3dea8f8e,8e36c811,28d113a7,5a7986a2,b6471f6,d17efd0d,e7922238), -S(9c16da05,b9020404,2a1ff95b,9b0457b9,fbb8b1b0,fbc23587,7d912b17,e11a0b5,caa3dae2,8c1f83ce,c6b69f1c,e2064fdb,4c74f239,e5793a9a,5428f5f8,bc995b2a), -S(587dbe9,ef3d647e,d0e0ed18,c1cf96a8,a1415fe1,8627b5fd,f12f8459,c1d5645b,b6869014,4e9bac2b,5256f5d9,d31fe1ab,feb3a26c,90abef50,e89a8f4b,4e461cc0), -S(1de4c4af,1aa3668a,13341760,2101a007,26268248,7c531efa,93a87d13,7aaad2c3,604efe65,d1c041e0,fc12c11b,c093c8cb,75e550dc,55b2ac,92371101,c4c5fadb), -S(cda8f01d,3c1a198c,27e29fda,c3fe8d6d,72de1d55,b36a787b,538bbd3c,be8c9709,4fe322ab,a45b3dad,db173c2f,ff700152,4faa90ba,65917b97,cb4f29c0,ab65a2bd), -S(df64862d,2c032d38,f99aa05f,372be0e6,3818b94b,9d17230,a45c4d40,dd558df6,860c2a10,68082744,f4c252eb,89eaf5ea,57cc76b3,745e35e2,a3dd077a,a3cff1cf), -S(d9895b7b,6893b227,e838bee5,9316d1e3,92743663,e4a7f917,ed308d31,e733d171,c8099481,d8badc36,11e9a266,89c46662,4a9c641f,6e954a9c,e57e55e8,7a455434), -S(e71e1d58,c307f1a0,d6060ad4,710ca427,ba47f2cc,c5cbe7e,5844e4f2,2d46e567,d34c97a7,68b60ff6,e79eb12b,94fc84dd,32522c45,99274a54,83a22906,b13c15c8), -S(5e36de9b,62a156fb,c10e9d01,5b0d2e90,a3b0b0f4,78fff430,2a58a8dc,aa42739e,40186760,c68286d8,cdd1a40f,fe0bba94,79bbcd2b,151eb361,9fbdb0ee,ffde681b), -S(9dd460b6,42869b10,740abb12,cdb7b03e,ff9b7dde,f6d88577,1bac50bf,3d2de390,66c5496f,fae9452c,af09a7a0,2c969ef4,f075da7,9132949c,e8b08a03,cace8f56), -S(313642cc,cd17e982,b924eb23,13e0634d,1324a802,bd51cb3f,80d90d0d,17d7f916,2d59ba09,e991279a,c18aea2f,bbdc40ad,23988b6f,d6082749,f3f306a1,94ec89ed), -S(6d3bae15,82708fe,61e09e8d,65318130,686af25b,3b73c60f,def2e585,3cf7c84f,441d216e,b80b00fe,15f2bea,42358150,5fd7726a,12605a2,9bd0d0d,ea5077d7), -S(22f1087a,d2f9b4db,28df386,b93700fb,cc331c65,7cc995dc,990cdf88,afaf855d,8f2377e8,9c562acf,78517ee9,917b6b29,88063caa,bdb7fc38,d7e25fb4,23650e68), -S(973d0afc,7dcd4ee2,9f7dd7fe,b12ec147,156aeecb,9218d651,f6fac991,e738f6af,fdc111fe,32d3559c,9df48e26,f8d7a5d9,ac14d12a,c78e5109,e1baf6bb,6f030a), -S(bc5a2618,f46a724f,c295af9b,5aa75cc9,4cab7d6b,ffb16709,c35e5d0e,8115f320,79f1764b,40dec87b,fc26f74a,36a040c8,752f111b,61827d15,58ea5238,580a8336), -S(fedcacf3,fbec5575,5881379a,54db4451,4a6750e8,b1bf0d5,296b17dd,aa396ff8,c7518849,85cdd0a1,3245d3f5,30685653,3e0782dc,a550d6cc,1c091363,879db1c0), -S(6fc31e9b,d5fe8f58,f2ba7559,8caeb21,f9eb8b9d,394a3fd3,3cbdae74,3b20b01,d17a98cd,3f8b08de,b18a57ac,fbd75eb,de187cc3,98b0d772,32acc3ba,41537557), -S(5ce3ac9d,eaae3874,36b13398,80d3f5e0,9ed594d5,70f8cb5f,ff5893f,11b1b419,8cac7f2,f451e966,a87b294,f0df6e54,3a6251a0,b0862c8b,2d6cff43,fb1f2a19), -S(db689f9a,c54e2f83,aee53b19,d7511624,6195610f,8a4bd546,73ecb7c3,23568fbf,2bcb293c,4d303a00,149f4c2,e4d46cbc,708e58e5,3b1f26f4,9004001f,153621b0), -S(6852395e,84e3b9a9,a99f17f2,bba96758,5d597b1e,18c3ee9c,1ffe50ac,d83021a0,96f4be82,c57402f7,b1f18258,109c6ef0,3ebb2163,3dd6c91b,503c34f3,af250703), -S(baa0ffe4,337a2053,25a06dc8,d502f954,9ab54915,2f757ce0,7ab0f19c,975759df,385a0223,5c82a31e,23b4c721,46ca49e1,f1d3d9ae,5a3ef424,da7982e4,d4ed035b), -S(8652c41c,8898804d,f377f192,9e64fb8a,e2524fb3,721fb7c5,b7f389b,f51ac7ac,1dae8810,fc3c450c,1800a806,83fb3cd,18fb5de5,ddbfcc57,72870867,ffcd0c8c), -S(e57beef4,8ab71788,262d1016,d7caf2e8,24407aa,bd32fcd6,49772c9b,dab0f98b,7557bd67,a381c515,a7d2bb84,f5a67dad,17b91f52,6d60127c,23279479,81552aa8), -S(f5d671c,3e5cafc,caa2a98,93e0ea53,b5cae255,1ca13144,f5cdb793,897d74e3,a455177d,a1c343f3,72ff895a,e0234780,f9509169,ecbcd4fe,9bc7e2b6,77dee746), -S(ad4ea4d9,4cf266a0,62f747ac,a3276163,4757ce6a,2cb1b655,1cd91232,36568664,6e20396d,78a8e653,5d915f77,a1b07f71,6c72d5a6,73c51381,ee2cb69d,8b8177ff), -S(3d000a68,de2bec93,9ecd8fb5,d9ab77a6,247971b2,7c33db,522ad3f5,b1348b89,1a923b11,358a52b9,2bcaebec,f7a60b46,b51922cc,b9c239e9,4713e3b3,455a565d), -S(4b1bb516,196f7c6f,d6b917cd,b8cebb6d,56c4c49d,3f44312,b6e54b43,b51f3278,2acf44a,efb6d3e,95ea394f,18e9945b,e3c79e8b,b3825d96,2b96cc7a,58e357c3), -S(c7edf142,aa3e3fa9,91e92b6b,4f5f40c3,1e802f21,5383bac2,5d90ebf0,74260f,9806dc46,c4c040f5,941e9489,3ff82abb,a0bc425d,44625765,ae4cade1,95a683b6), -S(71f0c9f5,7d2e0048,afbab0b,9058074c,3524ad35,1a9dc2ea,430ea159,eb702966,82a5a7b7,b4e5d028,d748774d,f90b9d52,d7086e37,2be2cd8,916b0d5c,2ecca118), -S(ae7fa0f7,275f4f18,15ec6888,4f358fa6,170f459f,442aba2d,10a8ac0e,829683dd,66c93784,6576d531,a6ba8641,772b6917,9638293d,cf4c2866,262f2221,f8e8a12c), -S(50447e92,2eb7e2bc,f96bc492,6072be78,a4f7d17c,6267f8,da513c57,7e624f4,c4536744,c06a5831,3f75787c,4b854b13,c3d3a4ef,ea09e584,93d10567,cb805ed5), -S(b693791e,4d20ab11,bc3d81f,28f5e509,fa45e1d3,9ac658f5,9a9dd7c5,e7cba800,a078ad71,af8d7312,c1b003c7,a17b7263,6f25e195,4813c05c,b4a05d41,2893559f), -S(4c8c48f,73d8a610,a6cfae50,44a31d86,40f660ed,93d306ed,7942d01b,44c5bdda,c747c2f9,400bddf7,5a96238e,17686ec1,b04a96c4,5031e5a0,68523d8e,16d1143a), -S(87af9f94,4296132a,9f23e471,8961a373,d49c9efd,ae7ca312,d3e28180,66e4c1f6,8251b125,4bdc4711,33b7d9ca,7a079120,bb04144e,a6720b0e,3de93705,32371017), -S(ddb8044c,82842cc8,a2cc1462,c803860c,19e7e40,79a4bae3,9dd7271b,85983012,6bbd6d35,264a732f,824c012,6f076c82,6247b61b,e4248260,99d6a5ab,5e208971), -S(17c12c2f,344e5da0,bba8d9,a5a145bc,d1e6a77d,cb95cc88,bcdb18b8,1accae3e,90fb2afa,a634d199,b11d426c,e974f87,e6aa765,bd98b848,dbec1af,e023afac), -S(dc115062,8630d468,d4c06d0c,6d693470,63fa22a,7a76538,d1341c45,4bc8b0ef,3542ff1e,2359824b,29d0390,e8379bac,43d8e9d1,eb5714b1,91dff000,3748bfe1), -S(7cbbc66f,84023a67,7966ffc,231e9613,9e2db2c6,2b7d2d7e,31d9e785,8ebd8feb,e5911b68,73f2e661,b67d7a0b,3aca2582,db9946ae,b925d302,e1e1c3cf,d9a1975c), -S(72cb29fd,5baafbec,9bd0abda,6f8c53fc,918e71e3,d932eac2,a86f5fd2,49b4095e,d14bbe6b,8ae0ba27,4796d5b4,fc6d6ce1,9a383389,a08535bc,9ddb3220,a04227a8), -S(fb809bdb,a32038c8,d017352f,629fc367,ed1b7eaa,97632e6b,f29a6ef7,6b90a6b,5d4c4958,a28fdd6c,c8a698a6,b7c35773,fda9c700,2776ae,b90986a7,2d65ac48), -S(fb20eed9,22031d48,de92ae40,7537769e,600db346,6de8d72,64610094,79581323,c129d99f,1e32672f,2913bc69,e76e710c,399c0256,63056546,d2332e64,fe6257cc), -S(18b7710e,aa95f5b5,79eb6c9,7d95e653,aea6ed60,3f1f3f0e,f4d570af,621a396a,c1830f7d,bc278840,9a54cb6e,f48966b1,40a4ed2b,54a1f0ed,2754142d,7bd02495), -S(dc781435,efec9436,4d4d3af1,58216ad1,c392a4b5,9adeac05,a1ca9a8b,4a196c60,625b2205,45678f7e,36dc1a54,3e9f9f05,383e3590,cc5b7450,c774226e,fb73c05f), -S(6e16acad,951b4ffe,737c6884,8a59e094,a35f9450,760693d8,9804934b,25d2be1,505091c4,8e00b8c9,bcb50e5,c5eb45c1,d706f95b,cd292994,29425b0b,f3e968ad), -S(3dda4d71,9579a27a,a6980e32,95439374,1af56e38,bb51f165,618af16f,8aa2cb36,c4a0dce1,57b2fca8,2f6eac0b,a800be12,3711694b,4b711742,cc37297d,48d27950), -S(33b53cd2,ba2f15eb,db59dca7,d096d50b,2815cd8a,d44fb218,a750dc1f,63c08130,2088291f,30e861b0,3e566d7,149b961e,d513661e,5eb44cf9,1ab808c4,2dabad38), -S(3ff3ae48,c88bd212,f35fb6d7,b06ca581,38d4cc40,24f0c0c9,f6368164,de246f9e,c177b65d,b99236bf,2161529b,870bb558,a5553f62,1da1c2ea,73297623,dcec6133), -S(1d9f4e25,4ee26361,f5837220,3e4c212d,9f46300,44574f4f,ccab16ab,50023fde,1fc1da4f,8567e4e1,fce5151f,648f31d5,f5cf22b,5973bd56,73b967fb,1bf55e1), -S(5815c873,f3a0b76c,56e79769,54540685,1a853fcc,23b62c5a,6a74df64,c90aa0c,d2c66c1d,b75425eb,8c74e822,d902890a,2d7feb27,f95cde22,648ed311,5dcd756a), -S(bffeb15e,4f70e4d6,b16c0027,eff0c9ee,594b254b,43523788,cb54e8c6,57309213,12261851,deaed15,c2eb62bc,92289c40,5714904c,c291d736,470271a4,24d6034), -S(66b01b20,8d891037,bafaf962,98d6502d,fc05adf8,24731d49,84e59425,9cc9a780,1ad93ad1,984b9404,e2439450,c728eae9,c9ad5c32,7be6299,216ac174,4b838d43), -S(db8a04c1,cbf6dfad,3ccc65b5,19fccf61,a9132332,b6786ed8,5cdc4a32,a7c4969d,2a366e8c,ef249745,fd6a3412,2e7f5403,73bf3ec4,21991101,ef7c7650,a5838337), -S(2cbd46ae,663bf92f,87d280d6,9ccfcc6e,37fc8d87,c586e7c5,891e57d9,9815f71d,40312f04,51f4b2da,ce2dac4,f6c91fe8,209fa78,60bb6247,dcdc1a1a,da4bffcc), -S(4a5fa6b,21e4cc49,83620a2e,1c13a4d,3aab84cf,4e4aa616,a4e0b340,dc1db441,8cb91277,671abe8d,c0252252,665537fe,6037a7ac,8aa142cd,6cae37f5,606313da), -S(48b756e6,3bca3d84,475e90e,23db898d,cf319138,a2bf14c1,a820e9f,768cfb35,e4b5972e,d058b90e,f38087dd,82c619a1,59a42a00,aaf7dfce,a89f679e,96d48d77), -S(6a5157b8,85721f0f,42fb387e,b50f9314,fed50fde,59bee2c4,2a12973a,2fb06b13,7d51867c,834fb385,7bcf64,c2d89094,6784d2dc,e635ad9c,6e902525,ed48f51c), -S(2788ac60,8c691e57,e062972d,398be225,16f625d4,f952f37,2c9c38db,eceacb43,6e469eaf,32db4014,12279b66,181003a3,1d6101af,5b3c24cd,dd4cf420,d71fb38b), -S(7659a365,db31c14f,ebcdc3f7,d8483383,7eb7255a,25b38956,fe013449,89176796,9db1f7f8,cddaed52,178c6d1c,ab762acb,11fc79ca,330638fd,7ee34652,35934b3d), -S(317436fa,cc0f540,dbdb8acc,e9c35266,fc4f01be,b65f3457,9655f1ff,dda3ad7a,deaf8c78,33c26e4a,f1eaf83d,16226488,ad2dac5,639cfe17,2b92f16d,95ca71e7), -S(a92f4493,84a1acb5,fc26ddf9,36b59373,bdbe563d,eb05e446,917a4414,f6e0359f,dfe5c80a,b676487b,b334e9c8,c67cff03,905905dc,a0dad7b5,c3604de,cb456d90), -S(fca66bb2,e3b45c58,2499e52e,d0c12034,2796ae4c,466391f8,ccc81f80,cc8b91ab,12c840c9,b9b20dbf,8c24ba00,59db5469,99f9f2e0,ecdfe4cf,e1f8195,31f0802d), -S(d773f231,295c4836,6c012e24,a825c921,7a1b1657,dd0f3ba7,49a541e8,b380284a,b4ef8d00,66b260a7,7b01a0fc,a4e9b8d6,31265f1b,94834e5c,f778dbd1,ec03e892), -S(af63a268,5669fe68,f3c25538,ae3cb24c,ea5aeabb,51bb6318,ae8f3bcf,3d49d198,ad7f1474,606d40a8,5e4606ee,f95c3034,f64551aa,fcab48b3,3de68f1e,eac43a08), -S(6329c0ed,27a5bc0b,b02eeb67,e79b015a,2d58ebac,9a0270f,559b6bad,f75073cb,a5ffb0e8,12e1f2a,b63c5c30,745bcd8c,cc0e9825,3ea223c3,850119e,74cda400), -S(3d4b56c3,5b51c6be,fb380e04,7e3f05a2,2d5e90fe,55cb584a,aa2e909d,a80b2a76,ff0f8a0b,f6742113,c99401d4,a4f2132e,1e6f41ce,b21241c7,986713e4,4215810f), -S(d84552b,5b70fced,a8053aac,63d2cf8e,7e6abc35,88a467c8,1193eab1,63adc404,d2f36d9,e296f0e0,1f01ac9e,30fa7db7,46a97608,2208d90b,60e4fc00,816a9580), -S(b46206b7,984144eb,a6655c9c,8aaf0658,6083971e,5f77da3f,96b260f7,8dfc4763,ef70665c,b881d9fb,c296ca88,10fbd9a2,17288e92,c0225f06,e072bf53,7830df3a), -S(b38355d3,a0b1cbdc,343c0a38,4c7f0653,b9726bdd,1a3bbd34,2614fd54,409b0864,a7cfc80,895c9ae7,36aee67e,aabe29ab,61223e08,deb06542,62393dad,eb9d4ce5), -S(a423de5c,338efcec,58349f16,70e8ea11,bab0c78a,be0d2442,4ddcd2e0,294f0bb2,e9a2e0d0,90e31783,f2d1abd5,a46e4649,33e3f111,b6f1d3c4,d7b8c93c,5975b2a2), -S(54ea680d,959b1824,15e66f4,622b6a2e,1dafbd8a,1756fbbe,d622ea43,e443c673,5d57314b,44923737,9e116877,e6f74a31,63a2ee66,44c74e42,b8617855,3ca7f009), -S(2bf96fdb,32c84cc5,7a37a941,8f5d8de3,67373eb5,a9e401cc,ab2c86bf,c4a265ac,b0a83c7a,e9ba4985,3c78bc14,8a891c75,3c259c16,4c620a73,8ab2bd3d,7b291851), -S(2425f73e,f25aa0da,588e5a96,51e91bfd,3953fb43,cf1142ed,28341f6c,c0d94885,acec2cca,1798f9bc,2b844f62,5212c411,52dc665b,c6e99704,19108b38,dc9b7cd), -S(d387f2d8,2b130fc1,80f940b8,6bca2c6c,d29fed99,2c3129e2,e1155d0e,415a1e98,af31ff4c,8312a574,9d0a9860,cfba0446,2cc8e2d1,6b516511,1225d4c7,7d388373), -S(a34c6211,815459f5,679b5518,5bb311ea,efaff5b9,cc0175bf,ecf58957,f616d49d,c88078a8,b1d1839d,c1941e5f,300f6876,63be4a91,9766063f,bfcb1e35,d81b4871), -S(cf8a62f0,66e4d06,f2cba109,8c3267f8,a435b03d,c1900e47,3eeeb3d2,bc3d7909,1e3bd7ab,5445163d,2bf834c4,2a425414,af72694a,be85a1ed,e8c53910,df5ee50b), -S(c9f930b0,a80350c,c66d2de5,ae6a8165,9a2f80a0,6c01fdde,3436a7de,5da09d2d,79ceccd4,8a9c6cac,ad77a4bc,255e7cb5,976d29d6,a3d814a7,e504cfdf,66b3af2), -S(dd05c586,86b98f5b,7ba2c17b,e3507e2d,83c31d80,eadf33d9,291abbac,e525a4bd,cdce214c,5525efa9,5e3f7dc5,8ef4bdda,d0429ed9,c59a8aa5,d520433c,eee8a34e), -S(d432cb8e,276f7e79,36f455d4,6ee3327e,70e6ae4b,a04c6ea4,9dc02557,a40a30f,d2c4a0c9,4a6ff7e5,c254bd8b,d24862ba,857b3748,9ecf2cc0,74265907,2b5be899), -S(a3b51478,dedaebf9,a5f59c9c,d7b4bd69,158c5c92,9511c5e1,d4ae7a84,b57a5d9b,e766b796,15010b2c,83a69c19,8c524b3b,10780e8b,e4fc62f8,a2ecabb4,f6fe3f51), -S(39f79580,7530e55e,3b985e2b,763fd21,78ff03b9,56b02a42,faaa87f,3100002f,bd3d83a4,e01de784,c2d106b,e645ea4d,5b6efa85,a52f17fd,c82bfde2,79761c93), -S(a3382f,9f706246,7ff434f,54e1841f,a18d8554,c3011852,f4803343,15c6a360,e4b43770,354c7ffe,29685ebc,64272360,8447cbbc,279b7e67,14bd9479,5298a156), -S(6d09fb4f,a6228cd0,93dab47d,99435c7e,9c6e2524,34c59792,bb2dd18,448a2bde,1f047149,31b69744,d6f7d61e,43e44853,6577fc6b,c2335282,109119e0,d5978db), -S(2a55377f,875e99b3,8d7c0afe,eb3e7491,1f8e41cc,8acf09d7,e9bc9763,697dd91b,14e2693e,81e893e1,67045a2e,a2be9a41,faa81fee,9e864071,f672c629,119b10db), -S(da913380,16f20888,9bfb4371,82ec0b6,1efa4d6f,14eb6f3,808c6b81,2336be7d,1776f0c2,f3cad01a,a0582732,2d2136dd,7e6020e,237a1329,6377b1a9,a3f411ea), -S(fd413737,14e6b895,9a289039,3370617f,37437de7,5c3061e9,4bd5d61,d1dcb42c,56b62876,86af6b96,a73e041e,2c45a439,468e5e18,2d91d9fd,1222d732,eaf1dbf4), -S(d39cd710,47956112,3e7679b5,cd14f400,8e1b6524,8d16d1,9b4313fc,8af4b38f,ef65114d,7e747603,b9ae1127,e1fbbffa,f488462f,3aa38844,dbc26e29,abc314e4), -S(617a173a,528ce0be,77371444,9ebf2d76,f9b58ceb,6ac21d58,885f1dc8,693870a4,52715ae3,ce098246,c6f08660,6e9ebf94,14266165,a354d81e,fb48c9a1,13688e21), -S(1350609,6f5c3382,b280837d,e640c142,65ad14c2,d06a95a1,4838014b,12569784,ac6f4d30,443fe46e,236f331d,980ccf92,d8fc5928,48a75841,c7e9f328,6b25f8ef), -S(494ca163,2000b61e,f513c04c,6f0c2e72,565fb1d2,ed371c25,8de1713e,d467531,611b3bf6,6b9efbfa,f6efd046,c426350b,cdf5536f,4134cfb9,1b4a3225,b2f096ee), -S(3fb9cb47,b84f05fe,72df9ab2,32bd4e83,da049679,ae09a93f,4081cc49,660784db,d9628fcb,1f9deca8,79d19c37,59845e55,94effc2,f0364775,9fe3838c,2674cec), -S(496f829e,b09f2d4,ff69b9f,d4e058d,de547d2d,8cff573c,3728cabb,eb59e58b,64bbf6ef,fddfb044,6e20d42d,4b34b3e4,8823839a,be3a0fb1,2654b8e9,b13a89f5), -S(dfce1042,841252f4,d1524b2c,817f3ce8,85821df9,913048e0,21aba64e,eb10799,118a24dc,eebd2a19,df7b2b0,71fd3073,e21c68c9,2aaf61c8,1fe1afd3,13dafc47), -S(2c1b46,91eba809,95ae941f,70cd60ff,a8988faa,e115c265,3c5b94a9,1e26a0d3,6c50b88e,cdd60794,32bae140,90afaee3,cbc38f76,7f7c5463,c244f9f6,54375ec8), -S(f8d91c91,1fbdf774,6829c779,cc7eb877,498b42eb,fdc8dfa4,3c81eb58,2983c45e,b80c785a,d936896f,504215e0,92eb3365,344d9a6f,763e1361,a34fcd5c,9b489f7), -S(cb9e013f,95b3ef75,2a9a15a3,5ff471c6,6d25acf8,66e89c79,f963666a,c299dbeb,3b117868,5c7e93fb,6c920f4c,25e48118,5f3e8f22,552b4e13,10dcbcab,e0e31d2c), -S(6d3a170f,6be4f0d,6c915593,7c0c7e8a,d43def0a,54876947,a36ff7e0,3103aef8,6fc40770,541ef68c,1d8e63af,18d99209,9313c6b6,6e1fdcfd,359c3a88,900f96bd), -S(ab498e5b,49558ca4,2099c7b2,14c070d,8d61e649,73fed001,11b526eb,c3ec6474,189c85f2,b1b63783,877f008d,b2ebd590,37dbd82d,865175b8,5b6376c,b2e265b5), -S(6d969788,f5204548,d2eae98,87cb5e1b,429a8fa1,8f44cd3d,32f36699,a9ce6671,a08f674a,8de23cec,d0c53cb6,29cc24ca,8c5dcd42,4ae8a7d2,8d43f2e7,57c70317), -S(3b5f696b,5d15291c,75f915f0,f043a622,1cd58678,6c7a0ae8,4533c0d4,d4ef7b58,7aee88a0,c4dd59f2,303c8b80,ed337b67,da3b33ae,fdb66c9a,3952df26,443bda02), -S(4905bed0,798f2ffe,24decf40,d3695efb,deb8fb3b,bd734395,3b027e71,9b8d057a,4365db64,4c598c10,6e4e4e91,f67f44f3,bb62140a,b5298f79,2ce32668,69ad25b4), -S(e1cb11ee,ecf54858,85575261,b749e51,db6cc08a,347fcada,da4dae9c,b6709ad0,a02e375f,da9346e9,f2473432,d74debc2,f70f5727,94027b27,6a699f0b,6206cc83), -S(53e44395,533e62a7,3f97e7b0,d449283b,7151a653,1b13d03b,154f458e,c839c5fb,ac3a2b9,c9c3f174,ec24deef,e16d8da7,f04e7776,9599207e,5fb71eb1,4dedde61), -S(5946135b,230ce11e,d28d5222,ae55d780,dc8d2fde,53342755,76546af5,d493426a,198b96aa,f9922a55,5910b8e,b8bdafcf,d700b230,aa926f90,625ebb56,4a8e488f), -S(4a238646,f0d38511,6d1b997b,6085d90e,b79b1289,53861526,55e60f79,6d378304,99da664b,5f5174b4,1dd056a9,9189e563,55d04622,17d5ca49,c61d01a4,48c94c47), -S(7234b856,dbebdbb8,f20c1fd3,4b719188,7d4ae91,3c596418,2a8455ee,d8fa34d0,2a6b196a,2eb98ca4,fa3ab40c,2b96ca16,eefa888a,5cac8676,d4f4680a,3f9c2b01), -S(dda23494,413dfc0e,f09cc4f4,8e5968ed,f9366e4e,6473afe9,eaf26c0b,7c50a347,ed097195,60b470b0,399aa60e,7210d398,eed8d9ee,1f410b36,71e2485c,c7e218c2), -S(8a8c177c,4617c43,3fdcc6c0,8685bed7,3dbe567b,31773907,acf77cdb,d95ab7f0,27adb686,1572821c,25b40be6,524fd3ac,d801877a,f689f4d2,aade7949,fc3b2248), -S(c40b2617,dcf23ff6,f1bcb76b,dd96a198,7e6ba559,1b14b267,42d5439f,653eff49,eb18ff9a,61e73c26,3ab4eb64,aa53a301,97325c38,2fbec2ee,407af143,7e102468), -S(eaa452cb,813053ba,da8be243,c5bb6c76,f3a2e87,97a5f83c,af7d15f1,e07d8088,15fde99f,89d0c428,979e0b96,83cecfd2,52117580,1dc8f7b9,ebbb1fd9,f02199a9), -S(5fdb7a4b,1dfc0d2e,42c10078,25da5cd5,a3b90346,daff2152,3b9b75e2,d1855fba,3dc00aba,890bd133,6ac4d676,9aed62df,db9a281d,2412fb9a,8e9aeafb,58bbc5da), -S(6f7cf42b,f4b09098,26538863,6c24770a,2c7789f5,dd1ffc5d,5382bc1d,fbb6df44,5ea4dbe0,dcc4a01d,4d7e6660,3026fc41,f0dfa1b,893d4934,5d05d75c,6faecebf), -S(1063f63e,51e3aad3,bf91e892,8b1b8fe5,1b941177,6580c056,60361280,63fc7629,6565cca5,5de4a54,777b24b6,7753a880,7155d632,5bace707,dabb9062,3bdb9b37), -S(f0d88838,9ed3ef56,688985b6,6077fd8,63f2e1b1,67cca7b1,e135a7a8,343e6b55,1764653c,86deecf0,ec350009,1f320d07,db1ff9a9,dd497488,386b2006,e12d2ad0), -S(9ccec5a2,869a95ed,ac9e3dfb,c19c552b,5f04ce3d,5478b16d,c28b6fc6,8b8ba0cb,838b79c1,25b010a3,624be75e,89dedc5d,9b6385e2,65f4283d,93a5271a,f896d0f5), -S(22427c29,2f19da5a,3e4a0454,9b3b35f4,901e2ac4,e073943f,5c41c733,69d5fdc,493252b7,a0a13723,baf56860,949490a9,15f2ced1,cd5c4207,9ac64efc,c94c518b), -S(78041b80,76e8935a,986a269c,68fb1bca,66d1f84b,3cb75ae6,bdfc7428,7ed74b9d,4a73feac,2a7058a2,f193e338,607c4f39,41aeeabc,d1126f0d,f4917623,afa180df), -S(ddaf719d,78d58c3,ae253ba,9cb24640,7c589367,af122d0d,a9a38d25,1d1aa757,8f7e649e,ab08bb70,f052beeb,46321ccd,9f8fba5c,e6e81dba,40b7da63,d3aa8c63), -S(3e28ec5c,4d9fac25,17b857e2,2d1e2c3e,fd9d507e,3619a21b,9d957588,769e5257,fe8b4326,fa187a9c,fadb417f,94914cee,b689f1e6,86402e88,d5a8b8e0,d9ffadd7), -S(2c659f7d,37d2ac1b,e372dee0,f6cb4997,c7dd990c,e8b1f06d,79b49aa5,a8a83ca0,c90bd67,dc1faad2,ab4086be,f7a6b310,39592bf9,3a949f0c,5793ef46,d9136fb8), -S(d4afa87e,2dc5a4aa,d001b27c,87989350,1afa374d,85a2002e,e5111bf5,d7da03a4,39d697c8,614df67d,295d7fff,20a0e333,6045bba4,6d565962,91665f18,83816707), -S(12de6449,860786cf,215f9285,a28946dd,668b0ed2,f8a0012c,c785f441,3386271d,39d68f4b,42aa5ca9,99c1953e,c216418a,7a1b83bc,c534cd8f,f50dcb25,2ed08d61), -S(19e539ec,986bc292,c0993b43,e8f03988,81fc72b0,53d530d2,812c971b,b53e35a3,41e96a03,31462b0e,e38f6a2b,774e154c,22ece598,7400c199,4aff2beb,340dcf8e), -S(3a6d63f6,e0083404,c768869c,a180b659,3efda9eb,f2a38385,7bc32e84,5e7a9f63,2897d84d,a8a13aa2,e2b96f22,d97fac13,5e65739e,ce341c1f,1e188d0d,6b29d765), -S(6fbf7d9c,5238b959,1e29dde1,cd092621,86a3f216,c8252b7d,dae85433,b08e642a,7a52157a,6c78af5e,2b9c21e6,64aea1ad,36bdf11a,459e2fb8,205fb818,d6f635df), -S(6bfe3a73,6211e70d,78be3665,fcdca331,a73d6a3f,f2cc9e50,df5b87a9,737b6d1d,1809c07d,7c997a60,d2bc187f,7ff527ff,8f162fea,10475684,6cd95920,5233391b), -S(c6f521ed,441c39dc,23c11ed4,5399ccd1,4b83e00d,524c8163,8cb0c0c7,ecd3a0c8,dfccf249,6223886a,e520ed1c,d84f4663,b44aab90,85ed836f,756a3b16,72775f4a), -S(be39757b,c2537f0f,c4c67c93,f2dc2830,b464d3c2,672f3d96,8051db68,57e6cfd9,30047462,b2f2ec23,2901060e,b05f6697,78fa42ff,ff05922b,2c253927,4d350a9f), -S(8cf591a1,9c98e274,a83cc687,ee992acb,3255320d,e3cbbea6,57fc790f,a2b84d0b,1f2d8a14,66b75c5a,34e9ba8f,6e96bc0c,6ab5e9e,e704919b,96a8d2e,87e29f81), -S(339c0d5e,5e28c33,b298bbfb,73ab7a8d,89f4b1f2,6ee853a,83d9865f,3480166,b63bb64f,7c99b7d1,15430fa5,125552a1,201fbe11,c1b90f69,a539e6e0,a8c2bf4f), -S(7ea652d7,c3309dcd,70f21d5a,e0fea7fb,81790527,c75a51f9,a37beaf2,ce867e72,22974b39,a028964e,97e00cc,7ec3491d,fe9e010,be520d4a,f2e8139a,1c602296), -S(23975673,c1723378,ecf11bbb,90d963dd,ae855472,2321c50c,eaafdde2,2a825762,2d1cd4b2,3aa66041,8fcdafe9,25ad8486,5912b905,b77588b6,deb97db0,effc7ee3), -S(52c0516d,6bef62d6,debd0879,9c96714b,85ade01c,1748053c,2e4647f8,f28e4594,deeea364,bb534e70,b74aee1f,95f528fe,e0b8c239,b6a0c228,1d4b5538,41f0bfc5), -S(a19f26a1,f4fa9b9c,42ca111a,a2b9492c,b95a792d,d23fabb7,e76ad6b5,6117a9fe,10f990c9,e9554447,ab030a5e,2db24dcc,80f17142,aa450d5e,930851fa,8eaa9a40), -S(366786e5,76b32325,1e44e4f6,e5d71c50,5361f771,8e355e3a,558beaa9,52d4a1e9,e76bb0e,ec2325f6,144801e0,d154bd6b,68701212,7233da5,c0daa306,2217c839), -S(ef26121f,f99a553b,ecafaa00,95d9e06,92fac8cb,40ba0331,1eef3b0f,eb291181,5d32068f,a1e9bfa1,487c6993,305e766f,82855bf6,b91339e0,f8804e01,6b6b8691), -S(5d81302b,9d653515,2e54d2c2,10d8dcc4,3a28393b,1da7402b,30410551,21f19b41,5094a844,9dde9d3f,3113ef85,9a0bd7b1,d1756646,bb793080,3007b2a8,f9068fa3), -S(c15513c2,652f8de6,ad273db,67312b3a,6c6c6ef3,7deece21,2703ea2,234cd929,64c2fca2,a392d4fc,ca8402e,146da89,593a1e7,25e34bd6,9c577238,30c4a449), -S(c265755b,5f628680,327c3b04,335a4b60,dee266c0,dd3bec93,708a20a3,c3ac9c1f,1367223f,dae8a304,b32c97b7,505ffc23,21d94115,579a8ca,638959d1,34dc21db), -S(d4acca04,42a53b23,ecc67ae5,d81d147f,ed477480,609fb71d,f0fff78c,20adf544,8b0aa74d,88f9fefa,affc2acd,d36479a9,ac814b3f,8cc3d01f,749ceb0f,9a90f052), -S(2a8cd5bb,2be61c60,615aba87,6df1508d,37f61b15,2429d10b,1f06599,dca26b94,8e6cc5ca,abd1c09d,4615cd80,a582bb71,156be2db,4876720e,6ccae849,5990756e), -S(74d6c1bd,65f37304,360b58bf,c443701e,f2be71f0,b366bd38,f29b876e,954f2f40,4cb209e0,6aa2459,4583b12,8572d25,1c88a2de,6d54057d,19c270d1,bf9c8077), -S(4baf4424,d78546ff,9b28f46f,ab97ca02,94ca48ac,812f13ba,7cc47b4e,ee9eabfc,b4910b45,5e06246a,c99febc8,af1cb0be,807127c7,28e29c16,a94224d2,b633065c), -S(c69cec47,387ab1ac,d20dba21,54625cf5,d42d189,3cc782c3,234e204c,9b7f28ad,514a7b5,fa667f36,bf4df18a,8ced613d,f8579abb,3e90c470,66c40280,85f0de84), -S(7300a33e,7d50b348,c28b4769,8cf8e011,ba6388fa,54a2dce4,7f83968,7b05d5e1,d0ac31f8,1958f36f,9b403154,b6426faf,73078ae2,6c4675f3,19b3bba7,c5c7128e), -S(e989b465,c21d3a2e,60687588,73333148,1e58b3f3,e0bfbcb6,efdd60ae,204e408e,a2d6a205,ada25071,c981db04,f857b005,9f906977,5d607958,7c1479fb,5e44e121), -S(c6afe364,f87a2b1f,92633e44,6b7aaa,74cb626a,79d6f325,263f1b7d,e5af90f1,87197fb9,861d254f,bc8be0d3,afab0831,9064dca1,7e8e1f66,ca55accb,f2d905f5), -S(8a026fc9,1dd4884b,ec8a7e66,cec8b7d8,7b9c78de,127dd3e5,40324032,78f70d22,34cde629,eb1fa38c,d533eac5,fc39bcf3,ae67605a,1ab75537,577a577d,1a75d079), -S(20f33fe4,41217692,124914c7,1750ae1a,86309797,7fb7ccff,93786b98,9e5cfed3,3bd39c87,c3897ed5,52f4a1bb,d8791439,5f1d10b,d827e22,30090b30,7ce9e6fc), -S(47e43518,4cf5e087,3a1b378f,cfa19adf,42abbab4,e0aedc37,2a7b0d0,1033c0fc,aa16a1a4,cadbc035,d774078f,231fe564,53c2b736,858d913f,b90169a5,3951f31e), -S(8fd41b49,adca1b48,574a559d,eb783fd6,6a8c61f8,ddc4950f,883e79f,585351d6,60409c9f,d705fe6,67d796a5,4c0dbd78,41d1b4e2,57f8747b,f69c01d2,7cac9bc5), -S(2091cea6,d9c5ac79,3c3dabda,89bba911,8d96dec1,42f77c5a,83e85c75,d67a5c91,493384b8,83d83be1,b1528700,6f466ac1,b9f5873f,4f99e8c3,b6077594,b8ba019e), -S(ecb086f2,36fc71ff,e455f9ea,3bd542d0,18d6c2c0,9564813c,5da7fea0,81568b68,24603a60,7f05cba,4d10fce,972241ca,f05b491b,dc2f324d,8fa93ec3,99359a2a), -S(364a9ddc,759693ea,cff66ed1,74e7c450,3197a2a8,a743b2eb,b7065e5d,307d4d52,11184aad,92fc83bb,11752b22,6d0290eb,725b5e4a,a2e6e25c,2095ab26,e34764c9), -S(3465069c,a194aadb,e5ae30df,f2d6eff8,1dd3acf8,7a01f6f7,38e24347,b2c6ee70,ded48ab,ac058655,e27a52ec,3ad5b9e9,d1ae3c39,25f0fcd6,b6e8ea5a,f490d15b), -S(ed1ee361,9b6709d7,cf029876,d9ad4ac,3c3bef69,c58476f6,ec719730,1f29eeb2,2c775e17,43f8422d,83b76860,d8a244ca,6a0abbc9,590a3249,1fe6817f,f395fc46), -S(194c6897,27039b42,d9d7a7a1,fc1cc4c0,ae1c16ca,9bf576d0,bab0ff09,c6d478a4,21e309ff,77590d33,9c408879,315c64b2,cfdd06c4,5b744238,1722e974,8f78734a), -S(6e9c1ed6,3fa52d39,74bd11a5,f32c382b,a6ea80c8,109a630b,39cfb9ef,50e92ca,edb9e34b,eb734475,ae167b20,900e86cd,134a2d6b,568db142,22122a54,32ee140), -S(b0db1eff,53cad7cf,ba686559,80c0b90f,6f8f1747,fe53912a,17d6ed61,c696a010,a3f2b2f,110e29e3,8d6a4518,18f04f79,6392b2a8,2d2dafb,6f0a627f,d9fbad48), -S(185fcfdb,db26b6e2,a1ebe2f6,b28b6cef,d02132ca,aa2f53f5,af734cf7,cac6e6a6,754e39e,62471511,e8d077bb,43023072,a52e9fab,d987066c,e5327cb8,a12bd843), -S(434df3c2,cd69896b,fe2ecfa6,6a9c0107,5d12283a,4a34fa68,fa2cd077,da271328,fc13d680,92b22495,fd846672,901e1679,8ec01444,5b25c11b,79ac93f0,423ae41a), -S(c2d222b8,15409db,6a5624a1,5aca06d0,56591dd6,10cb3b4f,bdde456f,608e6849,63a0a035,f5705e5e,17c95f7e,a0a93926,9da8894f,7b4f607d,b47fb04b,bada6261), -S(7c88c681,13468659,d7d89b,477ea11d,5f0443c0,cfa3baeb,6404a383,8be05b34,34b1e4d4,4a29b75a,8f6ba2b4,cf35e7b9,a9953269,30cab213,3f21325e,6f772cb1), -S(42426b3f,833b995b,825bf9c4,ee753d65,ccea144e,8cdf413a,63520819,2f1c79d5,8f188fd7,890baa42,520f957d,a12376c6,23c894ed,e48dc7d7,a8ca9300,77b9df19), -S(560c13fb,86f0a75e,24a24647,11be1c46,d7671f58,fa9c7340,df201d92,5c574518,79f5167a,315097b2,ba5bc761,34f19125,671f67b8,b9b64a07,ee8414a8,f0194ba3), -S(2dee64f7,6cb69a16,aa7245ac,afebd2d,6e46bd1f,4de9af60,fbbdad76,a84f3854,7196b1d2,fa453e67,7fe7a5f5,73e51022,9a7b7539,af0fd02a,b487cd57,46f970f0), -S(31ac84c,e896a814,3a978d7b,ed2a3ae5,d0ce9783,6717ea8c,1f44999a,d6baf5b3,24096db,a006766e,b9be4e81,9d53fb2e,c145b7b5,13cc77b7,8d175cbd,160b86e9), -S(af903e81,1b36c12f,b263759a,7905c2b7,d5bc640,ffba9974,86eabc6b,b639af8d,efa986f3,84f8ea74,2a1be187,55b500a9,22fd9ffd,5a54515e,3e5ce3fd,76d59f48), -S(cf6257f,bca09ea8,34d9da9c,b208eb8a,9d7cac38,5b6dacc3,9863adda,4eaac68b,189b50e,3b68290,ac0657d7,9e885421,e90f270c,3bd0528c,fdcc1857,9f403351), -S(32e61b5,f46e796c,ad8bbd01,41004e5e,81a2b2c2,8446352b,749f1840,9ab2e076,2ad27a1d,ed77dee9,f0ee3ba2,fe97d752,3e974514,ccfd3988,a7f0e1c2,3ac6059e), -S(5079d7cd,fc1f0f4e,decfcfd3,ee5c66cc,beb84197,d1cb9836,e04a7ee8,5e76fb94,5cc95d46,ffcf5873,cfffc0df,6e8c2599,a358fb46,3ea1baf0,225b7fd5,f6a3bf80), -S(b62c8158,5be8295f,29472b7b,b1cda9cd,bd61f9c4,23a085eb,1a31257d,fd72cec6,1d9fbcaf,7fb9e15d,eb992ddb,d09f91e7,f3c9dfd5,d4f1601a,1c303f1a,657c2b7), -S(1c74344e,8088b2d9,1d93f5fd,87a92e9b,9d97a160,2d8bfe33,d8b90b9c,af944f28,a8d98144,3354526d,14d03ae,3a2d2a3e,ad88c0f0,8d9cbad6,666f533f,3cf56656), -S(12cd5403,87768461,8098cc27,ac7e7ba4,9d697ab0,188aa938,483f06e6,7c94e95f,8c0b02f0,1d3836f2,7e5a5028,bb061a32,3389ed3f,fb1a606b,9113c205,9004994c), -S(36abd4f7,7f45d01b,2347a556,ed4c01e7,4c82611b,7e1afe94,13c43e71,29d36406,c160f21c,f4befb28,60ae1ae9,e7da4b16,242b3c6e,f129e309,7b3738a6,95fb9223), -S(199740c7,91588e9a,3c5fd265,19624ff8,ecd4335e,1fdcc482,749821c7,b0301fe6,a316790b,5704bab2,1b6dffcd,19b15604,c30b6057,8543ab6,a3f52de7,ea459c79), -S(14dc3eb3,59ea830a,b8827de0,59db6f55,4319478d,b4750e16,80a21d62,d2d6138d,82c28f9,a3ea5004,7253eaae,2c62df4e,fd4b92fa,17fce544,3c04086d,9038f5ee), -S(6d288843,e16918b2,5895f837,9f75ec44,36ff7559,8a26bec1,bcbdc683,3979c2f4,aa99f61b,59f3f7da,6efd2945,9e09fe0b,54cd2de6,cd70c538,99def857,4e0805fd), -S(9074a3f7,709dc3be,c191f276,a425278,e1d7bbb,a33e080b,cee68373,6f49714f,3eed8639,fdcbdd3c,56ea731d,dd99f99e,77a59ac6,970318c1,7d7c0801,f71b58f1), -S(b9789069,f400101e,6120d9e9,eb95ac97,203bb7b9,701578b8,364764af,d9c4f9e6,afe1ea3b,2634c97f,75e0cc9d,29d9aeb1,c035a048,a68aef3a,7c21bdca,e55c7c6e), -S(55e06b0e,ffe9047a,dd0f2d2f,567b0dd7,d67a589f,50cc684d,88a779fd,c60ebbd6,d0d2b49a,c9347ac4,b8143fde,23b6ab2e,b25b761,4dd862af,3a0d1dda,a79175ba), -S(c81b2c54,96a1db4d,aec6ca5f,b8b0cda0,68a7a049,6fed0d3e,3dea861,27337291,d11e206b,26f9daa0,731b4c28,f65feeaf,8e78f6d8,cf3bc973,873f6d2d,7d2f0d3c), -S(b202ab85,678ad74b,c007535,1016a995,5795ae15,3dc85df6,2d7178b7,e5e37cfb,e6f922f5,6c6944f0,2e643a19,d39c120c,4cb60a44,af353de2,ec653179,9ef84da7), -S(ee0deb59,e956cba8,cb9ca8fe,7c86da8d,33e1287c,616fdec0,1ba68ab9,3de8632c,63af5457,e9b6af60,9b1dc6ad,a19723a1,23e710e7,d03fe98c,5f709c1d,2456181), -S(e7e8f3e3,ca10115e,c7dce3e0,5dbf95fa,f39f537f,b8af8d86,773d9684,8417b28,158c1768,814f518d,a0904747,b96bb7fe,328f8e45,df9c2c35,9f192789,2e7d2441), -S(3b8e4edb,ab45ae8f,17670b3,ddc01fc1,7733143e,208498af,931234dd,c992c51a,e846f581,2a049bbe,94d59a62,dd43817b,fd635e7c,8eb9ca19,80b6bab9,96211c4f), -S(9117c67e,ae125762,75694252,bd88c13d,5aa5786b,2b01aabc,319c600,86b4c26c,c86a9fb,5ec90f3,a2ad0be0,d36061f1,e572e1d0,63034c81,5285a389,2f05bba1), -S(4388869b,17025257,4b754639,a7da1513,1cb9e2a7,b93ffd3f,2b254d7f,430cd1e8,9ce82f3f,4780a2de,f60d4dc1,cfe83ed3,9eac907f,4cf180a2,b829a0e6,292ab6d7), -S(98c583dc,d55186d0,54f3858b,ca84df9a,ff66e333,3fadd076,53cd87cb,66dea0ab,7877ea9,d3a5acb5,553d45b2,55e4ff92,47842b51,4342cdf6,667f83d8,a41b6155), -S(86c393a3,e24b29d4,b26ba9a0,5ce4e1bd,29214489,cde00c4d,1f4ec788,43409ef6,700b9044,8c95138e,a0adccf3,137fa827,702571fc,e1731223,ba1b4ea1,4a37d06a), -S(25d6bf73,6966cdb4,6fb06f43,83c64965,d462e118,258c36e7,76d4e193,13c0cf5c,99a98bcb,d518d7e3,7964dd4d,d677a735,8a886225,28df1cfb,f6d0e999,259e680d), -S(4e3dc2f9,cda6d077,bab34d7b,3dbfed33,5c3f85c,b350f895,5c8811f7,60c61af0,4f35e49b,6b8137e8,58c6b2f3,81ece9dc,de81b5b6,27e6274b,53d6a0e2,c5e01652), -S(4ce8d8e3,5f1a301e,c2dfd13d,43ad1f20,ae756b0b,34ef7bdc,a8f30c70,194f3f15,7e2508c8,324b8e31,2a603176,b1fc0a33,dec501b4,23e73c2c,416aed6e,2b19a3da), -S(2744cab9,e7999a7d,901b91b7,4d221bf8,be41b064,396be42e,46c80536,c5218267,db9b4ff,80782ddd,d0701665,43d94eed,ba19234b,c1881bb,47362cb8,8d90a0bd), -S(90381b83,5adc54a2,d7bc1e27,2f7a0738,dbce1103,db2b21c3,3c45242c,1ac591c0,a3c25f2a,333d8cdd,256f6f6d,d5a7e34,3332e527,50a12a2b,fb00fb37,3213d22d), -S(abdf4e8b,2437703e,6125dfc3,a33d41d8,b7ea311f,fd9b62b0,7546f6d4,8ed7af05,77a66284,1cdc961c,ac1b0990,5877f7a4,28213472,5e95684b,461bac1e,de6bffe7), -S(9f31c9e,6fe48e14,1a9bb99e,75486eb3,5896f990,e247bc05,cb648452,75cb645f,3ae168e8,b4ffed16,bec4422f,43385c17,a83597aa,692b6097,e48e542d,98ea4932), -S(2801ae6b,2083f345,6840a79f,23d638a9,a878d689,39651668,ce82c0f2,e77bb8ac,66f4fca2,c2fc9926,36ed5d9b,5b070607,f0e75d2,8474a8cd,256db66b,d4cd0d39), -S(c307afc2,d2de5ab6,3b5c5d6d,4d25c03,6278716,37f20fc2,175f6631,55172255,6f287265,4d518555,1da8c16b,9d0dcb2a,f0843b68,a3a756c5,5b6716b3,b151da1), -S(e0d0f3c9,866512f1,f78f58b1,8e573d98,6c5d978c,a5f6e73f,75509808,b2b90e6e,3c766220,204ee2fe,9d65a7c3,96e37c81,cd2de736,bfdb6c89,48f59394,38df3cdc), -S(5dce8200,28630e45,1b754c65,8946f4fd,9e4b15e2,e40116b6,acfbd145,29ff8a3c,af743c2e,5f578bea,2c9a6323,32f8fd0c,be7d385e,1e84d6e2,ccc52574,39ff3e41), -S(cf6f6b23,5d10351b,73664b8d,4e2f407a,38fad688,fd90662,29459b13,cf84acdd,c20ede1f,ca2792dd,c5a0d88b,bd8befc1,746a137e,d25defd0,c8b1c5e4,7f3bde93), -S(e73f238c,62efe49f,97359a82,467cfaa7,a7fa39af,35223bf,dc2e82d0,6162b6e6,14ad9128,d74bd306,b91df3c3,c846f203,dabafc11,49d2e8c5,99841964,954b51f9), -S(2aafc65a,f573533e,8d8e1ab3,19c11cde,60a02481,32296117,1455fae2,4f5814eb,a083c95e,cfc67a96,1f3d8b7f,ed66e2f3,c3f6175d,512a38f0,b6d974ba,cbaa4509), -S(f278ec4e,b0d210e3,24abe42b,d1d376a8,244d28d8,614b1260,e48214c6,8161b90b,507cf667,3bbc53b0,d507ff6,cb4a1c79,745b483d,487c6934,4fb4401c,275f4a00), -S(29bab26e,23fca95d,beff49f8,e5b742ed,2b32eece,f7f4d696,4a88b4de,d2b773e6,2e1b3d56,7afd6483,7bb7af1c,7be68427,bbfdae5a,43907e0a,d1f4d3c3,7ce44428), -S(a3a41ab9,8d2804de,81077a4b,73fb3832,f90edd3,40118b32,44a08633,1bd21c5a,5e292792,a0cc3fd,1df5f1e9,7c639cdb,f33b0f21,cf536e64,a2354757,ed523641), -S(3b84dce1,5e9b6ed5,b40cd906,c22a08fc,5a637d96,71c91615,d4038bb0,a3e6affb,7d2729c7,94a19c44,18851c6a,9b813735,f53bba0b,111eab88,b29fa27a,1d189b24), -S(e1a1de5b,2893e1b3,fd7d434a,d22493d5,1479e56e,2bd1699c,30fc8ee6,58c6c13a,c41ada21,d2d07fc4,f26035e5,b4d1deb2,15bb4f2c,d050b300,2d075f86,516a2ce7), -S(23b7c994,1a9a6b03,50707c20,3363b025,665fe450,bf5a89c9,d0dfa7fd,84ea303b,ed7e3e90,c09805b1,46f1f365,45fd2899,ef75f01b,47d12fed,275936b7,e2682da6), -S(56cce967,aeb8e65d,7f2897ff,e881e695,d0260f40,fa8facfe,38c0a050,19e5b160,aad07728,b298e06,ff562b76,70ec1717,c80f136,3ef477ac,abfb3b78,fb655b77), -S(8bd02de,4abac82a,3b50d1bb,7c721a38,9cdc2812,2dfe48f3,fcd30969,4d0f4191,5be841df,84a2251c,e69c2f39,690dfad8,92620119,7ba36028,861f6c6d,d32a93bf), -S(43b066ff,fd91b621,fc9b062,e0f9d362,bf02e492,f764381e,ba49a4f,2fad5662,3fb10c39,cf37eafb,162efc89,f548c8f4,eb5877d6,7e8587f9,4b8b9ce5,9aad7164), -S(89ea2a07,bfc99034,c3e9e7af,ebf87fe2,2d9b23e,e62e038c,321cb2e3,dbb8c7c5,c3069964,6a19d602,7f3dfb8d,9008556d,f969f576,61e562fc,8356c3b2,d3159a50), -S(6c382393,553e177e,164c1f38,d403df46,d05c856e,a41d7d71,3ac0cbad,1f202019,2a716067,37801041,46212c8a,4e6f7716,4c57ab39,df129e77,f31631bf,3206696a), -S(aea725d7,e59c8ce,b646ffe5,d4791760,988e4cd,d23e38cc,cbf610fa,f7066223,e0e7929a,980ca7f2,2fb46dd5,4e1b879d,3e77358,f42208af,d1a3a003,3ba0e593), -S(159ccc54,b888fc90,1f75e688,def8712e,5f79491d,5d47712d,ba3b0c12,ae2f4c84,c1ee2b1d,ec27ac4b,9f8ddcf3,74cf8696,6b353204,690b4467,d752edad,53ff5804), -S(aed9251,982bbf59,d7cc815d,fcdcff0e,76adfc30,61a042bf,1cb5fb3b,60acedab,6e90b10d,a2b23e6d,9a2abdf7,830906aa,d286c9a9,65f28a32,ab9ced92,5c966725), -S(4d669885,c053bf77,f1126cfa,f8db351d,3642c916,1a01d76c,8fb0a20a,3a54adec,6bbbcfe9,ac74987c,2e50e036,74e4ede3,5ea37b79,ab8154a4,396a15de,dd02865d), -S(1240d1a8,a04fb12e,813feea6,d0a6601c,9e6caf03,64df94e7,d2a5b522,5994ec2f,bb502ef,dff84c2c,17dd34c8,909e5a4a,cc1e6e64,aee237da,b8485004,9d09c5f), -S(7ccdef5e,4543615b,a07a8dd6,419926d4,47fb6eff,312d638e,3f5b0363,7d00a96a,7ca83bd1,3f056f7c,c46e6f2d,41ac1e9d,846c5f6f,570d956f,4c9f91b2,8e95a5b), -S(5c30be59,1bdbd093,321d2fff,ec167539,d794e22,d4b2cb53,d33c608b,cac23f25,2e44eb7b,d6a6a544,99b28ea3,865db2c2,f53de940,17e8a03b,e34ed7c8,fc70b64b), -S(fd59cf82,8f64f7d1,10c7137c,5d091b3d,7fbef206,1d2ce5e6,addf2157,c83c0578,9edcc796,7515edda,bbf4e048,5e70bd50,cb9dff87,6753d41c,6f22241d,824bd7dd), -S(5be3a507,ef4b75cd,75158a2f,aec4a5a2,d4cb85b3,92e7ccf,506661b5,5c77e277,92e45bee,9d914f7f,7e687de2,f7eb0004,5e9f9628,3e9332cd,97f5fdb9,a21a937f), -S(d1c94e0,473992b3,307b9031,93785bc1,d2c2d14b,ace6ff4a,8fc7b251,e629d3a1,9cb04ad2,8525fd34,d8fc59c7,280c72d,74fc9f2d,6ab1a5a5,c186f7bf,fb14a940), -S(7db048b3,4c03dca3,7c53df3e,6a94d789,f53308d6,a57f347e,d32d5b3d,4ab3ab03,4a7be537,189997b9,1f420593,add91bdd,fe7fd47d,6684dc21,afbc443a,68a879d6), -S(73005a1b,1ab1f7a1,ffa38625,e0d37dd1,8b54f49,34d38e64,832a78ca,c51b7e5f,6f8b689c,50fe7da2,27cc8be8,cd066588,30d4a2b8,1e80365f,526f590,96508640), -S(34cb6623,26ea9b37,c0f47c45,acb2dc87,92471834,84f9357b,e8d4894c,d4d3dae8,ae989ad4,96e480bc,375d3df,61fb2ae3,a18e6100,cbe1a40f,d090c5ea,8ebcc0c9), -S(ef5c4b6d,cf92cf9a,cd00cd86,63a44223,a49120aa,bc439f72,e6a6a7a2,13e206fa,be4790e9,d1982dfa,5e037c81,ddfdd6f7,802718e0,ebfaacf4,685a1f2a,ff9c5c38), -S(32cab877,84d37189,5ea4e2e3,22586a8d,30b86c1,fa5ecb76,573d5106,bf5f16b7,bcd4f788,20807923,7e5f1487,8d05e2aa,afb2049e,aa4c1dab,8985e413,f758de56), -S(bb183eae,900fb0ca,80e3f021,64e2291,4e40eed6,ceb4d7c,89539ad3,132d628d,94bfdd19,e0bba445,d453a0a3,e95423e5,c7c027cb,fd76df3c,93532317,fe9381ad), -S(605387d8,51ee5aa4,f39288e3,a656addc,72ac4251,5ca1c4a8,509341b3,5819c1b6,55ce59b6,8d58b114,f8a6ce41,86f8a390,9698aeaf,e1576bc1,af37713e,70a550c7), -S(2d971b20,46f30b55,9e8c1638,fde42108,60172bf2,cc088ec6,2c845f0c,4050043d,762ce259,e63f1da,7bb80d4,b23a0368,dd0ee680,aeb90a54,a0ea814d,904b1dd5), -S(5c89b962,e56d242,53a98bbf,14a8e0d9,c9a0a908,635f7717,ec2f2a0f,6a5c3641,28d38188,1e14e248,417dc0b7,5561a875,6163e1db,8517cd4f,f888df08,ab7f2974), -S(3210dcd3,617fd3e5,3da2e0f1,a6d23c20,ba27c0b6,920aea90,bd87a732,8a8fe963,171d81cc,64f4e8a9,ef43aa77,95a1821d,4b672eb3,20555016,dae40ae2,2cf24cef), -S(f00dca15,e2358867,6c9a4b9a,46706b61,af249336,99572f44,ddd87ea2,33b8b6f,3e2e529b,3010ab9c,66c73021,f28b018f,57b270ae,aabd4b4a,a2ec2a32,952125b4), -S(9d69dde8,d344fc3f,74e9c43a,eba9753a,fc22cf58,df6a430,b86b560d,c952d62,2b667455,844a1c5f,1ad56133,99e28380,d8f2b7dc,76f80817,a72ccc87,3f376e4d), -S(4fcfb13b,7a0c8f3c,1c2e943e,806ffe11,850cf942,bc5bade,5b4653c8,9f6a1cce,21e53c12,102089fd,1f010e1b,d009ff34,9d5e4d63,f299d613,d4492763,278ff580), -S(9173a3aa,b16ecd8d,5c3f2889,ddb1ee1c,2a4681fc,35926b42,7411899f,ed851a03,532556ef,794276eb,779b339b,9131f8f9,bea01f29,2018498c,c77ff751,dbc2170e)}, -{S(761cab41,3916a1f5,e131f337,e9023519,6199f789,87ef390b,3f2d8bfa,b0e9bbc6,f10272df,f7e91c40,3565da85,17fd3011,bde7b797,526d3c3,f00fb28e,f26dbd91), -S(c20afed,99f345eb,7ef90636,89598022,d06191dc,7e376b44,71036b03,1e6baa02,471f7c90,681c42fb,b2157f8d,629fafd4,87285270,6a4ab39e,c57f0de0,dece8837), -S(c1f66d62,532b6a50,fe1c1712,e2ef2258,4c03742b,7eea27fc,efad13a3,de1ddbff,49001db5,c9b8b3bf,7206526a,3a868c45,1b45eae7,586c3bcb,4685810a,52a62978), -S(684aaeac,cc13fd4e,d3dfa9a5,ebab742f,c5b9ecb3,81b49fdf,afc37edb,3b165ee5,78c2a82f,7e8484b3,9f808983,402c64b,4329c656,49bbdb29,1925baa4,89992ff1), -S(9a5a9331,3591b8b2,b3381f72,7dfa6c5b,343b9e3a,1b1c9c4,c6c9859d,e82fa566,d23e49ad,5099ba1e,58d800a5,c2e658a5,8be77b8e,ee9ef143,c541921b,671bba35), -S(37cdb6ec,c924c1c7,7fd0ae7e,d9baf38e,b46ea5cf,a161c78e,e4673968,f3eff2d2,fe025569,9a9e1ece,42619791,55cb0241,a3d16834,ef35500,7fb55080,53b161e7), -S(7228ef6c,4acd1d3a,d377d924,46fa894b,6f29926,564b33f5,6fc4968f,f66e8ce7,d4818780,533a52fa,13043159,7b22d8f0,b8ee64da,703b9422,e903595,c78b8a11), -S(78555ce1,101d40ad,88c9eb43,292e8d8c,683dac58,fc8779f7,db22d3f2,e2855ff3,9fe09f2e,660886ed,98f70203,c3308dfa,77476e27,e22c68a4,e43107c2,75501bb), -S(b078bfc2,cb4b10fd,31ce86ff,35770aa7,9979973e,26595e95,913016a9,850b2be6,1bfa79b3,f43ca2c9,93572d28,858a0301,716dfd04,eaee12b4,4e13bf79,a73fba72), -S(c3425e34,3ccc9b6a,a260cf78,7a5e15be,5c698894,2370f66e,826fa1d4,8f60a8b0,55f8dacb,54052f3,a8e42190,e5031fef,34c0eb5f,83bb252e,ac7e6eb8,161a0ab), -S(a8360f0e,4d5fc0e,81598e83,6384a5c0,6c871ff0,d1303179,e5c1c0c4,18a2b7a6,1497e874,db0af96b,35a5bbb,e3097ba8,b6fb1bcb,4d30be17,fe7a5a21,97d0dbab), -S(e02a7309,9807dabe,ee04fef8,36624471,fadbabe3,40507d0e,2abe4468,9c384458,59e707a9,416dd50f,fd07ad54,29d686fb,2402e768,3995c25,2ec4091e,c221582f), -S(fce6ed5e,2293286f,a976695e,8871c763,20af09d2,14964d31,318e197,ef80a398,168b9d4f,c9521ae2,51228f2b,f8de1d2f,8b5b183c,a918ec66,3f37f62,497ab2f7), -S(69616788,b5161a84,80f1b464,5f950703,af731632,ef807400,eab00ee8,581adf57,ab0deb81,73ae5e6a,c35a53bb,829acac1,51db1254,f73ebe70,f99d3cf9,7b3499cb), -S(2c1bdd6a,699f2e02,66d68c5e,22d8a504,8eaee31f,b8687858,555d03c8,1633ad2f,ae63f080,98a21f05,f1017956,c9bb6746,7b2d21ac,f3057151,9fcadc8c,c97d270d), -S(b1e45413,b39af497,da71e953,bfd13826,91ef295,da20be6a,2ea82d57,dedf0c32,a3343fe1,563fdf86,22f93d5e,75892e58,cb927f6f,7d3ddc6,68f87a61,96fd8ff5), -S(f1a182d2,994fa6ff,b6a587bf,a8780f4d,69b2259d,456d10df,2e73eba,4aa83567,a3ab08e,99488c03,939bd170,b4c1a7c4,c0cb8e18,1a713c1a,26f0eef4,8ab805b0), -S(840a512f,e5bbd665,83520649,efeb9284,e25fe4f9,9252dee0,b228d360,c8e6631d,899b91b7,2be1b494,1f5035b6,5c85dcda,4efa88cd,83995cf,42674fcc,486dd4de), -S(d920a9f8,b6ef812f,c021d511,ddfca976,436dc216,36792eaa,736be182,fc5ccfd1,ff26725b,21de311,d3359297,97bb6efc,479aa492,a366a1e,a4de8d9c,f0caf4d8), -S(2766bfc0,aa717b82,e7ad53ee,1604c5a6,2fb3bb6a,c7e4d6d1,4c71165,49b3b2fb,7a52c07e,70feace7,6ad0f704,e1d95215,b29b58df,9ba733d3,8a76f349,2c20b5bc), -S(a503f2de,116e492d,2b8e9cd0,e02cbc7a,56ec245,5ca27f48,7d25b316,65374cff,36a0e6c0,4e8092d6,f07fa375,c7874ac5,5c24119,7a096489,766d1d8b,350c260), -S(c2601313,43856496,92fc4795,ba6eb8a2,f6d052fe,5a8a37a5,76e036ef,163b6f6d,72d27995,ee8bbec0,de1059ee,65b8d4e9,9c828bc0,665c76ba,ff333ca,6a619635), -S(43bfab90,2f3a90de,ab1c7fbd,92b1ca9b,577c51ec,d0a5f1a,de461c84,98eed5e7,42cd4d0c,62858547,4852a2f0,7003fd0d,e37253f6,757f4c67,c2e2b22a,2aae375a), -S(3a6befed,24635ded,c7e2a341,64615858,d3b3029f,99a3f257,fe23725c,6a6d0e2f,5101cb68,d4f1c0ed,c4e33e61,e3f3bc1,99f81564,5aa9b81c,ee94e739,667b37b0), -S(67805b9f,4f6b6813,16940582,7197df9c,ee1b9307,5b4ec69a,61ea52c1,788deae9,a2f64de7,3019d67a,5db36099,b40aab16,d87ec8c4,56285e01,49e382af,81b68ba9), -S(e079dea3,f48dfbbc,ad661a6f,1c0a4627,17343004,cb18e5dd,5a7bb32f,a0e9000c,31706c43,77bd9a87,a27665e,12a60711,bf6b5bf8,acbbb29d,33318a8c,df29c11b), -S(f530e1b8,197ba44e,b7e23206,98a43b13,f05b84c5,5e4dc48,aabc3b16,68fd41b7,12995e58,aa0dc86d,15c483e6,5d01cf7,2f6a6cf8,8b53a983,92f4dad,6bb5202f), -S(974519bc,e9037b7d,84517dc8,a0c45ee6,a0e86ae,947b18c4,3dcaabee,7aaf246f,8fb156a3,cde52064,2f03f5b2,32c66fa3,12946f83,5ef77ec7,8739ce7f,4d45e6a), -S(9cde11c1,233c56e2,37e93006,cd42d785,acb74be2,e7051037,1db72065,5a6ef178,6cb6983d,8e86413b,36049815,3e2c8256,16520a1a,aa7a0370,dfcebc03,9c5da20e), -S(6e67fd2d,25a40ad,df954c26,ea452770,1fd49aa2,e7ba7cc7,17bae4b6,1fc11385,a6d2b87a,5367518a,6705af46,20ac9da2,f4c84c63,bfaaf895,449445ad,5ac0bc1e), -S(aec9f1e1,d101310f,a682316d,bb6de79c,bac5a3d1,133051c1,2a681a97,549aa904,305ed459,4670a52,de8066,9c026bc4,993b7b9b,559fb9d6,75ebd333,2608db68), -S(784d5905,e805d9e2,35e0828b,ac0abb12,7d1efc7c,d1b2f22b,304e142e,10132562,d8a6b329,f29221c9,344718c9,35b6cd3b,28aa5ff9,440cd4e8,6841c5c7,1c97ece2), -S(15e2a17c,6ddd8302,71eb8b67,e2cf6b96,2c75f28b,b5d32ef5,639ced1a,b3d6253c,55ef6683,ca7b8cb0,42ef9f48,fe5788f1,4ab256ad,f6dcfc80,d212db66,a0ee89c0), -S(4b003c6d,f6935da1,cd9cdd9c,4d4ab700,4646cabd,b7921125,98265bdb,5e2b5b36,4e621d0f,55d22df3,89c0a5d,13e3717a,eebcebb0,30d94de7,8b205a14,da58654b), -S(3fd57470,cc7d0704,d551224,5a10125e,d94d393b,3a8eaf0f,b18fdc58,e71eb1f2,2612769b,7528f3bc,9da5a240,f603010f,272b5966,c59a7bc0,a9c751ab,8f72f7dc), -S(aed36630,1d7f9738,dd439355,8174e535,de668758,b5b9ce90,3614562c,58c4fb0a,499e8a8c,befd7d93,a191d702,b39dc61c,1a7f6cf6,85432975,cd3fb006,e62a1bf6), -S(2ba768e6,da7c827a,f5456916,f0015e7c,15baf2bb,ec1e8c6b,936e37e9,376bb32d,850c242a,ae59ad30,e566e244,4b0b58c1,2b5f297e,7e200e29,3a8dbb83,9c5be04f), -S(1ba79c71,f162d72d,65821a17,6d97ee10,9913fc3b,8990d45d,5d6b2e55,4a180765,62258299,6d4376ca,5659a7ef,1771e26c,5a672521,5e69288c,ae16d819,4a845b37), -S(fd54543f,f7e27a72,e3747953,368085ed,945e6e1e,8b16032e,351fbcf4,643efc6b,e2619d2,ee6d935a,cddbc0c7,1727a9d,f5aa2a73,ccbe655a,44a1ff7,b362d55f), -S(ddea80ce,6f9e0bda,4d39337,78136c93,5293885,f0564b23,3c98a5ed,90ed0905,8218bacd,e6049f51,b3e36832,145230d6,776f0158,7c275d36,e8bbab59,c47c40b1), -S(d3dc0b5e,bb26fb78,914b9c9b,30b9b42b,69f20e94,fa8dce28,9f243a64,e53fe5f4,942c3ca8,64d9a7b8,cd21a3d8,32bccab1,c9c9b297,b53a8336,45aa4356,8b1fbb60), -S(30a0cb,8e510a1f,6ee8bdfc,f46d2dbe,be3e43f5,dff3df9c,75f96c9e,a14751ca,f43efc8f,7f47e83d,c940b8df,ab9d413e,bc4abf9d,8f8eac87,b392dd01,7946fb0), -S(1a0fe79a,4028b017,138c1649,dd58de09,7adedcc8,c57d4aab,2bd35b36,91566b2d,340eeec,d2028765,e00dac93,ebff2589,ea9bca7e,f7b7857a,783e5855,2a0cc60a), -S(ccd61837,a08fc389,25890e71,b13fd588,58995bb4,49e9b3d,bee6fd82,12ed1d66,92e1236c,7ba39599,3e71d1c8,44cac95a,9a61347c,b98622c9,92fcee9d,2f593ce9), -S(3b706e43,fd96a62,24853ff7,99df5f89,8670c268,263d27bb,1be885c3,be98a8e7,4319b438,ed6d33fc,c9f4115c,1a91a954,744dffd8,804281c5,df713334,7fb2cfc5), -S(d0441778,af56e7d2,91b83760,e024646d,abcc74b9,7e86a390,e060113f,4a01cef8,300e8744,ede079ea,eb52dfe3,f6373d25,6bb3efc3,26d80965,d65d1307,6780c1e0), -S(bd2769fb,3257a88d,4a5f4ce5,e7fcdb59,7e665429,ec9ff117,54c5bcd0,dcea9509,df765e2a,fc7006de,2459d6e3,c7ee3823,bd8bbda2,dcbbad18,7994b09a,5059d9ef), -S(18cb57b5,eccb921,50c8d8e7,5bbbbda5,ce182f40,67197079,3fe97b50,6c51893b,35b98a01,7f4a620a,172f80e,871e95df,b3dc4d,b30f317b,37809f0c,ba9f2b52), -S(81ec0ee3,4d91b585,b7153a61,2201fa41,fba04c7a,50ea2910,ad33917e,b1e524f2,a53e216a,d069520b,b7d4604,9fe3ef35,74c7bba7,2cef5177,11b6810a,a36f7ace), -S(f9a54c96,729a23ef,ad5e51c2,b8870b51,c68843ac,656b1107,49b23f66,fa013e87,ec0e8e0f,1a16aae8,c2f954cc,ac50fbbf,ed9efed2,25ecde21,dc629c0b,415fd93c), -S(c92adc3d,c2b5101,e9ad2ffd,ea2c448,3a39f563,c767e737,a5a34d1c,e84f2bfa,3e3f49d2,10b76661,71d9af9a,51f72edf,e6248022,cd15afe7,f84e6982,a5525720), -S(d0239502,2a0d5c8,f87f9b08,97daddc5,3a9300d2,1e7aacb4,d72dda9b,4564f418,4fb09e9a,3cdb4551,e56c2a0b,9e59f056,c500e390,e47b5d28,fefbb11a,4791678c), -S(593acca8,29588d90,13a41f35,8dc5e41b,678c7411,164c27ac,895fa933,d1db7978,af3c448c,bd72faff,8a52768a,23c9fdf0,68b5855c,d9f022e1,6eb26ac7,454709c7), -S(6a168acf,7b4f3a51,e56d8924,68fa3a96,d0ea4b9a,e191b860,5a6b96b7,d6834b05,f54540b1,f84d6bc6,4dac1240,ebb61fe0,1f160fb5,c00a1b24,8cdddce7,7db419ad), -S(5fbb8d4f,4b3b8d54,a51bb96b,7f58672a,5d2d6145,dd864799,804ef496,17ed6298,a87435cd,6fc5fc1c,93c4b38d,d7b2e565,88e99f,cc32597,9fe0de65,e8af034c), -S(8942bd97,115688a9,ad84039a,3dc0d80b,bdba443b,8431a530,60560745,876c5373,9366058f,5895e83b,9db6bde7,7da94b22,fbeee36e,b24db502,706de359,a81f74c8), -S(3f7a1620,f93be626,690308d0,ce5a3dae,8eefeaa4,63534032,8c3adc5c,4d68643c,9fc70963,c9b068f2,f6f8813,da2691b8,de3d3b07,c7bc1390,8f8c22dc,135d0bbb), -S(29b4db5c,7224201a,9563fc36,eb7b29d3,d6b0b640,b812591c,af21180b,9eeef26f,c8dcc8d9,8c411723,1db961a9,ea3eddb,46a21aca,b47d90e7,e10167e1,f5fcb81e), -S(f05c4970,392d0487,d8ebe570,fc5292f8,685a4895,5a9c75d1,bbaf2a95,49d0a557,f012d939,5ac0d2e2,f694bdac,dc7535,e126431f,34b8d440,b9aaab34,23774ea0), -S(fb2c83af,6ceec5db,edc822b3,4f1bc35e,90bc388a,5a45ae9f,7c256045,d8daabe,cf9e3e2a,30fa7ff6,30e221d5,7fca78,d4f59145,f4e1c063,2798c471,93a3295a), -S(b63db89d,daf39301,f1243a9d,72ba57c1,31fa2cf7,fd0e486a,c39b8190,a48a3f9d,cbb7ebf5,dc68b80b,6fcbd4f5,90162683,cd8fb0a9,17142da5,aba30eb3,1f83205), -S(c3fd72ab,c247874a,c682a44a,938c3d8d,a7ee950d,722ae51e,ae24d6d7,1ec211f9,23b0ca13,998cb9e4,216e26d3,ed9cd144,bbd2bbb4,b45b1514,e5110fd6,bab1bff1), -S(83f1e25c,209153a8,7fd7f4e2,13328ed3,97a93191,311219ae,c36c76eb,f35e2a9,b93a7947,a553a6db,868451be,96988dc6,7a569d6,6237c110,97f132e0,89c73398), -S(1dbec6a7,32838979,b4e7f03,bf791b5e,614800bb,39a56f68,10af5c09,f10c3eed,f06a2e63,c35e3168,4508a3f9,39bcd071,1892b16a,762bcd6d,85c590e2,92bfa06e), -S(56e98c,c2b21625,e9149fca,61e159e,140f9808,bf781c0c,3159cea0,f7bb51ba,c5e2636b,6bede1c3,a22a03b0,818ddb73,5f073c85,105876c1,4d8f6650,92a61563), -S(a6e497da,d0347dc1,dcf24181,efdc40c7,fb18f480,64803a6e,ab9187bd,deb4d305,88983af5,21f10582,3dac18f5,c6badc0,19e724a5,b748159f,1fa20863,9db7d6fb), -S(bd7df6a,1415e150,9759e259,7abb9edf,cebf8e42,97ca092,60200e4f,53ce53c0,90029a06,2b77274e,7ad517a1,44e3355,f08e23ed,a9161e25,e67511b4,9f32d6ef), -S(dd7a6f4a,c529d120,64d1e89c,b6106d06,8d17502,7f6ffbec,411d38a6,dc327745,bd2caeb7,19d6aa06,c97697af,1eca622f,86cf7083,9e425ac5,b7cb23b8,761d9c48), -S(5220c371,8714884,402f11e5,f93dd80e,f8d10333,f9b054a7,14a1d3a3,9664db0b,3f1fe980,d62ffa5c,d50e3ac,d88aa07d,4c9a91a0,373f1541,cca46699,6c0d76e5), -S(177ef38a,cadec4d7,d8ebceba,53a1b938,f3db0579,7c476cc6,19fb208a,1cb582f3,4f33adb1,bcbfeb1e,b9d91df,c6ce7da,6be73016,6148e3c0,eccbede6,dd3a6a3f), -S(3b99ce03,762fbee2,81bff40e,6c67ba55,fa97842b,b175673a,7f08e362,1d6bd97b,ea6ff097,77f095c0,ad161d60,20f04381,b49cc469,c2e54ffb,1f91ec9,d7523108), -S(5864b293,f81ea7ab,688bb9b0,89f9f1ce,244fec0c,b1e2db6f,9c83f58d,5701f79a,7f4f8900,b3b2a552,e452093c,20436189,d88d4493,12883c32,8ad48678,69aaba61), -S(9bd29db0,c45326e0,3ce95b3e,8a1d13d0,ed868ec7,bc3fbacc,6781a4dc,90695798,7c3fc6b9,462ce670,c1f0a604,52c8da1f,47644c51,e56948a0,a4f6c6d3,34e98b4d), -S(3a4143af,3f07e795,2eedc5d9,b3a8d87c,a52a16d9,9839bdbf,b5b80770,38e03b17,aa749ca6,9b2d316e,650384e7,19d775fc,6a1b09fc,be5f17e8,741fa129,1cc73a34), -S(8b668df6,eb568b1c,6608ec61,b88bbffe,3103a9bf,c4dafd5b,16eb611a,d3d626cb,efcb4ac8,ab30efc3,94db1c4f,2f0476f4,81789d34,2db7244,a8f34266,13977aa), -S(d1b68e26,5936b365,67c11adf,259e8bbb,2a190757,86f2fbba,a76d72ff,7cbfd9f5,57328a80,330997e9,8c8598b2,33ba682b,e6baa6a4,69acad09,6ec3ef2c,be6f6304), -S(84281721,6eb15d31,e2c6faae,1b2140dd,e9ff5419,c0555ff5,d0edfa8b,2d878506,75b6ef23,821def9a,912a7c88,74da9c7,6e4fa036,14dd8fd7,9acc639c,ade2cdc7), -S(e2da1bba,3a895d07,fc86b9b3,dbdd657c,b1ba523b,bc498ac0,eeacdaaf,22e4d77b,aeedcc86,52457101,86cbdec4,90850961,9cf09530,15faa353,f22605fe,2acb7142), -S(9cd8c718,34088f1,7f94db0e,50148e4f,81fc4c44,4c9fa34c,8bfb384d,f9c5e24e,440ef0f0,e8e641ac,ff1b2264,21975338,f711ae9e,e6c7e4ca,54d0d177,244c76d9), -S(6bcf2ff,b6c2e3be,54980550,1c8eab96,e27c814e,9b60ac42,2557317c,10419180,88af1c74,ac893eca,a43a0e44,89ed9ea0,c9e3ef4f,d8329de7,4b09eb36,9e6c8f83), -S(79fa7473,a6699efd,f0f498cf,11c40195,c1288549,d069d451,b05ecab0,fb94c8b8,53a59b8c,fef24cae,6c5f324a,19b8c30e,ddf7311a,b76d5266,ce747a90,1f46f568), -S(e3d80881,849cc86a,4d087062,dc5277a5,388f3d16,3c34503d,d6066eb1,69a5892,b6841ed8,c06ebd0c,e99bd851,afc6e2ac,5752d2c6,2a75a30a,ad1ceb1e,c7a2e70c), -S(5a6759a4,cd2529aa,8c656064,f5c5993b,8c4a90c7,4bfcb2d4,604900b,bbc55edc,5670533c,ecae979b,ed06412,7c9b218d,2f880bce,fc3939c,2db3f572,d3d3977d), -S(2c96f255,368c227,46539a06,303b328d,d8909991,a83cb991,204888d4,f48d38e5,3f8d2f14,61d1f778,83c16e42,dfbd33ed,781dd563,bd5091d1,8dfcea20,4e1eac82), -S(534f93a0,1b8b7cf6,28b721d8,af045176,45667ad4,8bad934f,4df6cefa,5327e4f,25c4e7b2,6716a3,718b9e8d,f9233f46,8e8ecc5,2e851418,13930bff,db89c0a7), -S(b21a8e26,f727f4e4,7d6091fa,1e9f3630,688f031a,fd2a7dba,6b1d682b,a87d6f6d,5bf9d718,9dcbb1e3,84051f7c,df28e4a8,2dddc440,fe8e4602,3f67b018,8513a4ea), -S(7d6964a7,3b5bd658,5bf9f92b,b4462e90,39801914,7042048d,8a55d9c7,13e39477,c4f5059f,2aa5a3df,2556d6eb,9172df43,7229a33,c3fc199b,de7395a9,41651c48), -S(5f5067af,90544909,996efe0f,250ed142,de02bbc0,315427e7,27942762,34d3286f,498a6c71,c77a4aaf,7a5db357,3a3379f9,3c9e0120,8ea82f50,936708fb,298cb60f), -S(1a6b6f9e,4d46ea18,2a4edb33,4873ba99,11e28cce,c0607b65,b716623c,e0372e80,84b1b569,5d3d68aa,5e6d514b,71ab31b1,c7d7196,ccef7fc0,797382df,bcb1f968), -S(361a14d7,c66fcb1e,109248e1,568a9ebc,de67e87,40388cb4,d2c1c0ba,aaf5516,2f3b5f71,3c150080,4af382af,e76c7f7e,f42af72d,fa83a83a,b6aa6688,45577afe), -S(b49601f8,50bc8d0e,7bc1701b,82499b2c,4a334c0e,2d8c1960,c7247300,af4a48d9,b5e2a9a7,ef215ca3,de3b39d5,853f4f22,45a4bd92,70a6f193,4c141a1c,841a7ae3), -S(3c509b32,d8095e48,f5a3087a,6bad9223,c891ce6c,fa781f2e,6c8e7d2e,8803e4ff,5945b1da,102127c5,c6dcaa04,dd00d591,57adaa12,2a3958f5,bb4b393e,b82196e9), -S(936331e0,14fc93bb,1f6a13da,3280d955,3f388e73,1ff74be0,ce36f738,901bc8b2,1862e7b5,6e58670d,5f212886,f91cfd1c,be3572aa,2edd865e,1ec2f254,9d784710), -S(9401e6b,c6183186,d465447e,adbdf85f,45e53eec,b1966dda,1493a387,55092e43,fad8a635,545c84fd,76924675,a328bdc2,61add731,fc63d3cc,57e4b274,24cbc2cf), -S(6849a7b3,6e018d2b,c0f9cc06,539ab30e,43c06fc8,6138dac5,751f0fd1,f1a4484f,ea62553f,a9fe03f0,a8bbe82f,c3974335,8bba3744,8d8c950,fabe4c5f,f20e2bb8), -S(e1d750f3,b3ea7a80,b3a42a39,487c6662,e2e73722,91d06ef8,c38b60d1,e0c22abc,8c59f043,5c12d792,8542f488,2202b79c,e792de21,809d12a4,bbd28675,57d827d4), -S(dc2436d4,268fa173,9fefe9de,81c06975,eca56d51,adcac9c4,2d7696c3,4c4fb4d1,86203b1a,313dcdde,a15f14b8,d3fe3894,e45d829e,14a00991,134ebcb,3a2e6673), -S(58892b5,10923690,2c82f057,45e55487,aa469535,984e350,1888218c,bab6e269,5a93b8d0,2633ec94,a2976bdb,238234f9,dc5ea84b,e3da3a7c,e4cfc628,d7cd9b28), -S(457138fe,f2e48bb9,73975346,80cfcd2b,3b8eff0a,a46fb460,9b6cdd96,168d71e1,f7cec976,ce010d6a,c9b558b4,3a715772,dd707c65,a810b900,2bc9cbc,406523e4), -S(b17e576,69ae6db2,88e6035,da4513e9,d5faf5d6,fc7c66d7,d68cd290,416c4449,2c1087eb,ef93f7e2,3f434394,e0146ffb,543f0e72,9c14c34c,8b22fd26,4f1aeb0), -S(f5ad8e6,968da1b8,ad2e400b,878edabb,77078aae,880938fb,59407313,68e9d809,17f5aab7,a6e19529,39294470,1bc75cdf,3527373f,dd6537d1,781a3e16,338e4b61), -S(f3f4b339,4f876752,7e3e0087,80bda1a6,9cbf9027,cbe131bf,c5b238e4,3e4cedb5,fbca590a,86e7d2d3,c784f04f,b8f5544e,8af59e82,d70549e4,dccc2d26,dd5f74fa), -S(979a2c6b,c24a9fb7,36d1ef74,f177f574,a0ec8220,5a2c3b5a,1f62ed2c,7766bba6,e69b9eb,96c2b65e,e91a5274,94368caa,e1480cfd,12711762,2212257a,cd6ce5b4), -S(b6301e9b,512e74be,92695c18,f18b57be,fc0ff988,87ee39c6,31f067b9,13f62c5b,96d8c690,7b48e6b,c7826af1,486c6ac9,1a3e1818,f7310562,86c995d6,4b0fd835), -S(1b1bfd50,1d5c0b5b,8e778ca1,fcd44b9d,c60bbc43,59ea8cb1,6c69f3aa,3a37df80,995d106b,920df44e,3120dd3c,16875e6,d5abe7aa,62c5d956,ee6baba4,cb77273), -S(b2fdd8f3,9a5f8e84,d75d8bca,d8d483b2,a8477bf6,9c12d250,188d30cb,e7ee289a,b0d183dc,4d971b81,51c6487c,39282272,2365013a,c27e3ef1,c2384ee0,2ca97072), -S(d6e43ada,76252428,bac311dc,5b49851c,79b7cfbc,dee6312d,ea051a88,8819639b,8dc6ead4,53c9781c,d297bee2,56c158fe,9aac410b,d7c392ee,367cecc7,5f86f5e2), -S(9de1baf1,ed24b6e,ee76aae6,566b3da0,2124f7c9,d526c3b2,ad15bbc8,3ec90c3a,e299b84a,acea081a,66e41b0c,5e9c84f0,2ef3bfd6,36c5a99b,4b8aac35,b7f71d9d), -S(9d6a8c3e,2247af1d,394ff76a,ad61dc9e,11da8d15,465bacf7,5075a348,681abc7f,880080f1,89cbca1d,460361e6,5388d177,da4d173,b9b3120a,af9dc8ab,2d7602), -S(6a7186ff,70065f7d,540fd40,f3e8428f,3ba6f0ac,678fa642,653adb41,3684a613,1097de94,8a2e3d94,dedff154,11d35a2f,2f75f9a3,2d65d9ac,2f47d174,24ff9455), -S(64f47f87,f05e4b03,d7d15938,1e81691,e337a08e,57169533,2f34ae8c,901760af,14cc2fce,17eefea,4981f14b,1a24a60e,73f3dd79,54ca12a9,64e1065b,c65545a8), -S(37112309,3f6bf796,11d5492,5978ab39,7e4df483,8f96b51c,39ad10f6,fe648431,45d08953,42004dc1,2cd39ea4,e1365116,b51b9ce1,b88a11ac,16295ca5,ad0f16dc), -S(9b2be865,6be732c2,9fd73a9f,7ec74827,6fc9e5c0,992ade7b,df5984e8,c7c67b2b,1cabae89,b28ae0a,6b58cce1,d9881a05,b9ae4847,5ffc3c63,eb145fa2,cb7182a7), -S(c0206346,71a326f6,5aea417f,a13ef7e5,c1054c57,ff7aa6d2,8bd7302,89243e22,ba986e12,86eb62cc,ab595158,7731c1e5,2e420b11,af4c4b9f,7e7068b7,2e8532ee), -S(cb278985,452e2fea,ec881f24,3c43dff,bac7e2e6,e8af62e0,f1a568a0,f6c67de8,b0d0c6b5,aabda249,237f86b8,f3d4aeef,ff32f9c8,2b349791,a090d5d0,4484a496), -S(9a092478,40008754,1cb7db8f,63d00d68,7a991df3,59e71657,984f3303,2b90c577,d8e49ebb,a2314b8b,2da2a1aa,49dac713,15942701,d264ff9c,e57a8abc,49d54fdf), -S(43e63cd1,d6d96399,724cae75,d5ae4fc5,94b12170,5335a3d7,b12afcee,155560f3,36d2c315,93b939f3,e7791fb2,56ea0cb,ff0374c3,be8eae7d,ef015e42,e595f962), -S(bccc009c,4012a2ae,58ac20bc,90ab1c3e,662fc7d5,57eef6be,120b5da2,25aeb10f,2a30dfd9,7b558c12,ab897ae5,5e3cb4de,3df9ffc5,326004e,8da8586b,364ae92b), -S(1753b47e,3e777908,376103c5,266147d9,2334fc29,a3ee15c4,edc9c8a5,38319f92,eaed6e86,c94a0bdd,f85cb9a0,d32cde01,c6ca2bbe,85607b56,fb363111,fed28447), -S(53f163f8,fdde3cc,39ce973,2c909ca7,29c2c5c7,415b50cf,c03a653d,1a9cf505,3ec19406,c26c6cdb,7f327e0f,1936c0e,bf85908e,49ca6085,5c5c2276,b2511473), -S(5e0545ae,f6d3ce1d,90300f33,827fe4b1,ef9277ef,17d5541,597d6ba8,6f4da13a,5207724a,a83bbaba,cd52b920,e5a6c116,552b010f,21cc8c63,d7fe518b,fed12e32), -S(e800d78b,a04fb045,a18a5f94,de52eebb,640b2ec8,a2159835,d2ecedfc,4bdb3b5a,5f3c4f8c,6bb039dc,150aa758,b4957a30,12e2eff2,657172e8,4e76328,45033b0a), -S(448d9559,94569d0f,9fb5ccd4,baf52bcb,5ca776fa,f49a3b7d,e9698fa5,50c5012,f0a64077,c97f82e4,be4d23f9,17b82f3c,6284c71f,82adc6ca,fee176c8,8b601613), -S(a2550ca7,bfbbff9d,4162360c,1274baad,bcd1c213,1ffd1714,7938fb26,cdea3b4e,4f50424b,1ebf6486,c6c5df10,4388a22d,8cdc707e,9485c87,851beed2,45c7f3eb), -S(af94b7e,f5984caa,2a14ccfa,2acbe4f2,70a0cd31,2caef778,c88b847a,be86b9e4,dde4f647,ebfccaa7,d23a5ac5,28cab9c5,8462a761,844bdbeb,e3498494,cbc16b95), -S(d434b5a3,a3c096e2,19f9e18,11f9b7a9,61ef6eff,a09da242,b595b824,5e8a4843,c068f8e0,30ac02f7,69555f1e,5656ca89,71bab03e,d5e6f865,94b3e4d7,37087350), -S(fef398e2,961ac682,8ee348b6,274a1782,7739420e,7bd36925,3a66e468,3fcfad86,ef1020de,b8d58a4b,be7b39e3,5cab7ef8,4e3269fd,248cb80c,85e83081,8aaed35e), -S(5052a736,dcdc83d,35f65bc8,d1eb40bd,7d8645f2,93bd88e6,aa2c5643,4fb77af,4e203bf8,1632f8cf,8c54c1f5,8f0342c6,612399f,348e7ca5,f9d3fb30,3d8ce1e0), -S(4fb4a757,246defcf,3b8752be,a32e819,c11a239b,97aaa45d,7bbdd92a,53a6cc45,9e6e2cb4,e02bb3d1,14c59aaa,c20150d9,3077600a,257934a7,935ceeb7,994f075), -S(518bb638,148f9d12,f0c9fc04,693745f0,656064a2,4d448224,b60d55ee,a405efa,f719e2ab,16fcc1c7,d110d68,3089a1a4,4fb5823b,db814a93,32456534,995c84d1), -S(8a8fc859,6dcf731,3b700deb,3bf9ddd7,f2732bf,e5928752,236df0e3,a9fe4c4c,896502a8,3c112e5,dbc87e63,c5cb73f5,d206e980,c017484b,999513f5,d5a5b4f), -S(47875c9e,86043157,3bc346db,d8076123,274c32b8,9baa353f,56b4efdf,8a5e7226,45174b75,7eef6f4f,70dc9371,40e72f14,832b9b5a,b44c384a,4c4b6063,1df05942), -S(48644f61,57f3099b,5828bb5a,eb886f51,1515191c,5be0dd69,32ec6618,c3870d61,8804fa4d,b44ed648,e398c863,6eac7c25,ffa3a188,71e3bd6a,395f92b2,259f5db9), -S(d5bbe7dc,9efee9ae,392b735f,b2e250da,a03023df,df0d07e4,ec84f829,bce69ec8,b542595e,dcf7e1eb,11b639dd,65335588,5c3d2491,f4db62a8,e099b7f,9c808be0), -S(ef6037f9,cf9770e7,ae5e9eda,9369caca,c7cf8101,d21c4130,cc119219,f2c3a6c7,5ccea6b,22073857,adb52256,1a37375c,b5f4c574,8716e2af,b26b190d,af69a43b), -S(a5b3fc5,2801baea,1f33f9df,270a1967,dff54723,7d7620f3,70a522e1,983ef747,8399a63,6032cb17,3c648480,74227374,dd19d172,57c74c69,eb7bd6dc,52d071f2), -S(a206b95,e51803ef,40ff83c1,8a6ac2f,553b181e,55d03f13,2536f947,7bc426c6,9149110c,5ba91d60,c25c522a,e5aad669,74a34a40,8ddc9dc8,29b5d976,f2c65867), -S(ff9c9766,f459a87d,c07235c3,3ba55ea7,25a33791,bc851645,d289b53d,1ce6291b,51706cd6,de0d2807,81b1d8ee,9ba5ce53,f6395264,6e509654,def0c037,6015313d), -S(ad502070,787ae242,9f4f9f55,418443e6,4386ceae,b20af7c3,7282399f,9f748994,b428a363,32d4f518,56f81274,d7fc023d,b03bbb08,5087b4bd,8c083c0d,77e1c7d), -S(e38920e9,3a1f1b82,f2ac5f01,ae02fcf,7b9cdcd7,d91fe7e6,14be6130,918746ef,cb55c04c,44e66359,db9a17af,780f0040,e34de88a,d10fe04a,a44da778,dcdbb26f), -S(4c0f9c54,ef982c9,be46ea7d,a380897f,c13ea12a,13de7de8,249c7483,88b30747,5f5da3e8,338e9907,c1b71021,b2177b5e,d90db096,15c78ca9,74445d49,dd5f68d2), -S(c9de9ee7,3aa50f40,b5b7b02a,9cf49627,df5196db,e72d2c58,738e5a0c,61725cb7,75a8ae6f,eb47b5f9,21aecf2d,a4bb8e56,7d4588db,2967c612,a53e1c4d,f392ee8e), -S(ab394e81,140e69ae,af0ba047,a6843253,e9875e48,b61f15e9,fb58d3b2,c61206f,a70db392,a3c6f12c,971b61e9,d92dc2d1,1bd086ab,67475e5d,6977d638,110adbc1), -S(39938f5e,24111c15,253646df,b02b4957,84a578c5,2a982a51,40d36d65,8b492cdb,a5e4ca99,a95aaf09,c3dfb75e,5c9591da,c6711e81,ac5d8fd5,891342b7,24b71598), -S(8b6785b9,82dcc8c3,2b12e79,582dfb2,2ea222b,99f3e5cd,dad2df89,8e621571,319495e2,79101993,ac2fc1d5,1770e668,16150e6,ba4fcd20,65beeeb9,169e6f96), -S(5b4e3ad,d62b1ca5,12bead13,113db6f5,52632ae9,163a4724,6fb7389c,e2775815,b8117dc3,5bb1939f,31c93f33,160daaa4,3114de60,df3db6a,a422a677,51d3fa6c), -S(bb1f0da3,ebe501fd,761e2b01,2711effd,70cd1390,7340b800,65c938b8,c938af6,3cca83b9,a6349423,669abf1c,77ca35dc,5c3c6c1c,e3fca31,6a85d66b,7da7c2e7), -S(deca6934,7ed75676,cc85c372,a0612ca9,c3a1ce69,ba67a7db,f6c92972,3b5f4e25,152adde7,67f4877d,2a9df65,8f86b090,2f2550e6,92fecdf8,9574e808,ad4fc510), -S(1e864048,c9d2a9e9,22bdc2b3,6e21065c,6dfbeae3,77712c02,ff015c61,8f65ab9a,cf00e85d,575641e8,93cc385c,7fa70aa1,22530e4,8f111035,6a50555d,ec004bfa), -S(71af1234,457ecaf3,51fde7,894858c4,90f11cb5,90fd0af,2a854597,50a33ffd,36b78c67,2aa4580e,d9e562c1,3dec5d81,bffe55ca,e5dbb208,5ffe0407,b7809ff8), -S(928ea175,c5b56f9f,a3a76080,f87389df,9b541fdf,fa409fae,8583b5a6,25f20421,5e9effe8,4fc42b4f,4e7647de,a1ee4770,2d436ae1,595bd2ce,6db80fdc,30fe2f1b), -S(28f7f51c,783ae428,73e4067f,34cf5bce,b3e53b66,d319fb7c,7165cca6,63e7d152,86c5d540,629a05b2,1583a470,3e9ecf9b,8f5573fc,ac3d04c4,9132c5ba,f6068196), -S(1d7b9551,af89db75,d2e93d25,49553373,79896eea,2d3cd7c8,fd2b9375,b5a95df4,138bc305,58a1090c,8b85cb0,c15130b1,ad375c45,57437232,a5e6333c,9dc0aaf9), -S(9b03def7,22f1df38,dad6f052,e054faf,9852a74,508808e8,38962518,3043bbc8,e9a6d8be,fbd144bc,bb23fcd7,6620164,82667553,d55a8a98,1b9f8f88,d4e5cec2), -S(c158478,636792dd,e24abf46,926ba57f,4d00f7a6,78efe168,5711abb2,beb3bb62,b772b20b,be7f1d8e,643643da,98b6389f,a28a7846,17207748,6d276d08,5bb3f6df), -S(de68187c,c951a366,ebe2de2,8f676a04,266aa791,f3705229,37ef2e19,fa1d6293,f9f28e1b,5ce0f88,66a04e,b967777,bce1cb,76ee297f,4942abbe,88b8461d), -S(1aeafc3b,f66681f3,fdb82d3,f128b12d,58432fe7,f18c92d9,dfcf272,9cd04262,aeb3fea6,b9568a8e,4152e022,83f60cee,7a8fbf42,ac3c20c7,7e339dc2,e6d5a246), -S(1222eef8,39569e79,d101b6fa,c63bc546,ad9f51e0,e27ea0e0,48da9453,4d8d4bc7,9a4790cf,4b561d6e,3143b80,86911de,49acd2c1,3ad7d975,5dd845c8,fb3bd86a), -S(568e3bbe,91d1ea0a,311018a4,b75dd711,45a6bed3,4b3f7d3f,77c1892c,a7e74fb8,24f9853,51477a98,daffcb95,5b157df7,7a8b6005,84a67fc9,7d427b29,aa74ebe0), -S(cc9f0cda,6a3b96ee,5c74785,dc4a5b97,31d0ef4d,10f97401,6935db23,12164399,bb7a50f8,6b530d0a,73162e59,4334dfca,5d1329cc,b31bc05a,3fa68c7,15c76818), -S(bfc084cb,45fb39b7,db0d16bc,fd1ba13c,a133b6ac,691aa545,bbaca6ec,dcc4bfd0,a528dd00,195c6409,6a9bfcdc,95db1c09,b1e5e0e6,6944616a,2334c297,1be07f40), -S(29cd9485,268288a6,4b1e6491,ba211ac5,94289ba1,199d1eb3,a1c013b6,f5d305c5,95283c31,38a01ae0,7cc119d0,58e8b81f,d5fba6a8,8bb4cde4,11268613,86e20a81), -S(c9aa4323,afeab574,a25023fd,a5775e33,8d216391,b10e1d10,31042e64,21f5667d,31f77398,3699d879,a5d713aa,d9b7f2f6,febd54b3,1a69afdb,d3f52232,a72338f3), -S(3a7d733c,9a73b8d2,4acb08f5,48031cd1,b26845a5,837388d9,68427a97,4cbd234f,693e8214,6e219fbb,b31e048b,8dceb28f,d5ea9b51,cf89a40b,d4f8e935,dffe4dcc), -S(2ee63f80,ccfe610f,7e6db9d4,af8defcc,b24907a7,d49d24b4,c3b5a976,73ee9968,de2bfef,b99069cf,fee3cd66,7eb2875f,3660870e,f61c70f2,6ac6b942,4314af97), -S(e1942251,ebbe37af,412340d9,2900a06d,9ced681d,48d81075,d04833f3,9f72acde,85f78728,4017fa63,28a3aaf3,c6e0750e,ac989642,8ed92993,4cf27e41,d3c37035), -S(d1a6911e,72ddf575,d81589ed,b8995e40,b0843840,72dc1df9,42ba5695,8a759b,71405cfc,f836adf5,b8e8c77,e376a7a8,ba0d4478,a30c6600,82450ba9,7264228a), -S(e02062ae,8b2a4522,4ab441bc,7e9a00d5,4b97a9a7,cca4e2bd,8dc743f1,931b81b5,5b6371d4,345f08ec,cb6db1d2,dea7b9d0,7b49ffdc,d50e9b63,23fdf855,e1cd2243), -S(7327708d,b7d3f037,8bb261ea,7db74eb0,222d891b,e14de28d,2defe3eb,a1f64a93,e71c99e7,627440fa,ad4bd9fd,3fe1a69d,5a8c109a,5165e54f,20113643,3d8baf66), -S(cd57d3f9,a726d2c7,308132bd,bc7401e3,f89d1449,57057bd2,14edcfc8,4e25e560,9e23e46c,3760b31,5c117006,99c2cbe4,319e483a,eca1641,b1a29e81,37633b6e), -S(87dbcc0,91c348f8,593c6807,1d0df231,9421e732,58e76672,e03e4d63,d4073660,823edb4c,fe506e04,49403b68,e4a69101,cca82923,82589a99,a9fd3908,8fff07c1), -S(e3499c7a,cea737f4,8359512e,98a9e5b6,2d27ca35,accb8c2,cc65c7b3,ffd28b8,3a2c7591,f0c91dff,e01a243a,986dea24,fbebc8cf,dc0387f5,78988cbf,ffe017ce), -S(5ac29de7,70553d51,284cd610,b360469a,fcc4ef23,bcee5936,942ef27c,b805779f,2a32b97d,f3e8713e,809d4f79,55525e45,65a60581,5fd582d3,82d7088b,5966523), -S(201ee48b,86a8a93e,8e12b084,2fb9cc37,25e4478e,b9d6d10e,cd1f220,c4a128ce,390e0cef,e6b561a6,6f58c07f,3569e8f6,6a467d2c,cc548281,cbd656f9,f7fbf73b), -S(8f64a6ee,3ffa42d1,e55aaea4,9e00f260,fdd33f21,394aa31d,c17a4328,87ff50cb,867a0189,2f55cc74,6e61a5bf,46796ebf,6c0e2932,b8f9d1df,a5c48af7,e491ef83), -S(5e38512b,65607ae3,f843e223,ec7f95ef,5af4bf35,edf9068,96fa76d6,c302b75f,7adeb25b,bcd0bd27,646956a4,c4a659f9,1db48f2e,532a84b5,7cba0aaa,23e28da7), -S(c812dbf1,732134df,1c459c81,f15cbf3b,4a97f959,18bcc0f,48062b04,bf133649,d22eb1c9,27d57ff7,e0baa4ff,c3b9f74e,116c8a43,ecb10cb7,32745d9e,61e708f8), -S(3f0d8071,56f38368,91a263a1,5177bb12,720eb46b,d6c9abff,5bd2d2ba,ce377b39,348f65fd,f87f7f2a,1dec49e4,8e009fc3,8f916c40,857586d4,e6063772,704d70f), -S(da9c23d4,e4fc5a12,f80b9d65,c2536366,c75a86c8,fd4fb92e,fa5e360b,5ba1993,eb01f616,fb20b8af,522a108d,b81d92f6,3b161963,bee3427b,4a49353b,928da25), -S(d266b680,fa8f6b70,4f8ece54,e52094f8,be493a4b,9a4f396,dfbefba1,4887e18f,564bb0fb,f63b5054,6a930ebf,df1afd93,7f0db851,e460c8f9,67afd274,b735681), -S(b9859cc7,2b573a92,b2752b85,692bf02f,be1f176f,1cb8be2,e954a00b,33e314a5,fb216130,8bba3bc5,cefdf81c,c21981df,2dbf0a83,d98d259,62c879bb,4ce6ab87), -S(8e52468e,486dc34c,c53cc59c,b8c9360,62935ec5,4563b9e0,8daa0a95,f8787f3f,2e3d5c59,90f228a4,e7133352,837eeb62,892e28c,7f8233ec,48ff18a2,d6564c9e), -S(438a2203,af978f12,d28fb3c6,af10ea2,13a954ef,7b0974c7,2b1113b3,e6d03b65,d8f36c0d,d6d4782e,d7194631,7b0a5745,6207517e,379c29b2,ab30cde8,e8ad33c9), -S(1a4982a9,f06bf158,9e395e10,9873ec13,1ef4a00,6a6d7b83,675c3906,1d61fbbf,93e2882e,676591ed,8acf2e3,ff22284d,abe2fab2,bdb99175,5ac72631,c5002747), -S(6ebec1f3,bdd0f019,3bb9a7a9,1d59dd92,5019400a,575dcdf2,33156bf,3e88a47a,c341309d,b462016f,afabbb56,5d763ba6,9c8f2f98,42812afd,fe0e9941,53283ba1), -S(599dc439,687d0dda,a348eb2d,337bd2d9,76a2be69,fdf5e064,1ba87e91,61f45351,c8433a55,411fdd17,ddaa9a86,bd2561c5,8b891c41,d868e764,13e5f3ee,3b3ecc1), -S(5a63cd59,aa9aedc2,91a0d50a,c7d01214,c3788f62,7e3c60ea,84d09ddf,2eb80840,3851bcf3,51ce55f0,4f92eaeb,99b3036d,a06d1f38,2a759217,50e4bf39,7d5ca685), -S(86e089a8,9f1c1644,a2e94b4a,722c6f19,9bb0403f,9a112b59,66191e31,e750f1,91ca06bf,fd48c38c,272594e7,1a113083,f6a4b275,7f279a75,3d70b984,a552e391), -S(2f2c3b0c,dc0feb58,620ab813,c8182510,a2a6f14e,9127153a,358c50f,31238370,7ee136f3,35f076a9,5b80e0dc,a8dfd8b2,691ce9df,5ce0f1b5,5dd9e3db,e156a360), -S(4e2e8b40,8602701a,2d1081d4,e41f81e3,3d9b8465,9959532e,93aca00d,9a70f005,5ec80478,d44bc01e,ad4b544a,20cc58fe,2990c0d2,4d08fc4b,2f9e0a5d,913953a7), -S(98c30f9f,4ef0aed6,17a8fee8,92934d56,10267d6c,e14832c8,b802ca00,320a9c7d,765958cd,15907b0c,dc0ad9bb,217d647f,6c85da72,49260d4d,11ec062f,9d818639), -S(f2b87023,7841e053,a20f2df1,efd265c9,f58e9132,9c280502,61f8c6e3,d6ca5afc,bdcbdcca,67fdf622,84fadc6,4ed6e727,5e82d40e,efdabad,c3d1dccf,fbd32dbb), -S(650f0256,1031a2d6,7549959b,7c358191,cf3fa7a6,30010f57,1006d2a5,20592377,2c4d23a7,44aa3b0c,6359149e,c170866c,b5874045,900b2010,d5a80dc1,e6b2892c), -S(76c3e87a,c72dda23,7ef119a3,9a128507,eba08e31,9f1a7512,5c4dde61,6523fe40,822fa37,8e7c8f19,e02954b2,5faedcda,6d2e0123,ea0b10de,70361487,9a0ec110), -S(472f9e0,9adc7ba9,179a6e8b,22985721,c994c51e,109bdd04,eb2afd6e,fe471f8a,11abccaf,296e7c8d,98e1c3f7,50069ff7,9552ddc8,5e5b55b8,4980ea03,4012072b), -S(4cbb2b87,1f8b975a,2ba257f4,340074d0,7fa897e6,7000795d,d5312e35,cb9453a2,4e31a79c,d842f6da,9e45664a,2878070,1dc87cd2,eb2cb25c,2a7833e5,4e2736e9), -S(ec70b3b,1a95b593,431ac4b5,5825e6a5,2cb88276,27165195,83924921,30805ca2,6092c54a,165bd710,a0e1f36f,18b4e4d4,cfdcf6cc,2f222599,761a9efb,e4d7807), -S(a6b1dda8,e0dfb484,60209710,69cc5398,4e4462f5,a305af62,6b7ada3c,bed5e1f7,e2c113db,21680a63,8f0ea442,52421c0c,41958de3,c7b4a24e,f39546fd,19be201), -S(4a18e595,4105c269,25468ebc,a0c9accb,1710b854,d618cffc,72eee0aa,c0e3f296,1e7cad8,cd248d4c,5dbf0207,a32b67da,2db8c8dd,4798a17b,52ae6445,728e7f6f), -S(eecb1dbb,e2451a48,53054f45,4cc640c4,3e38f20a,3957a192,c2f5827f,9384d11d,a889250,f8bca4ed,5158a55c,197459eb,50b7f10,f74158a1,75180856,b4de62b0), -S(8949f6e9,5e3143e,653889cd,4d57fea4,657aa42d,76e6297d,d20ceecd,d5def67d,e08d4e90,fd929ac6,ac3e87c8,5554e0f2,b584a31e,1be841ad,827c738,3cafeb54), -S(e85b17a0,dcdf256e,51a605c3,1859773d,a0e52a36,6312eb19,9a789246,beb7441e,3505403e,1ab0f77b,984f41e8,a8462c0d,e9d5b500,d0a8f59c,fc83a75,ee063720), -S(c7742a95,6b5c8298,bd1600c7,b756f777,bb4ab2b1,529c8419,d124d402,2b902420,a05ec2b5,8af28f9e,35a86b,4db0634b,5b7017d,7947a023,3db01ff0,64bdecc1), -S(5432c05c,814aeb02,c82e651f,7d1f7b89,e294a76d,17e5ddd0,9ec8140f,cf5a62f2,5902ac55,ddad39dd,da4b35d1,5b84f43b,c13420b6,35f28bce,a60d55a5,78d3afae), -S(39075a61,15bd6870,d1406865,4c8801d4,b9aef508,c880618d,397f9bb0,6674b17a,8bd2702c,96604b83,4114c489,367c3d3e,5e6efd50,c15b8bb3,4b2cb686,b08a49d9), -S(df43a136,af0f754e,599659ce,63d0d48c,73993927,6eef3442,e505c93f,acd025bf,1378d4e4,763c6c79,483597e2,f90824c1,830c8850,fcd32c69,52dab9d9,cd0802a5), -S(840a24a8,314f7e0b,9b3c33bf,7f6cec77,3052a0c5,54a1e180,23772bf5,1d7a4a6d,6e1be7af,f02c4536,f44db655,b859383d,5eabb37e,92b4b896,7ec1acd3,859cb1ab), -S(55d1fe11,49cc5e08,5e9ff19f,9c0823aa,9ecbc1c3,62385bb,e5d33d8d,8156628,b1b96f77,c27f17cd,df4b223e,7343f140,1849d049,4351b2bb,27aed7e8,79b686f5), -S(a8ab1f78,3a7fd00d,f5f4a814,31eed1d7,b767417a,691f28b8,38238da0,cf8fd509,2d747fa3,b164ec83,de89aec8,746781df,f7fcbcd2,67230a85,4802491a,e213a3ca), -S(3cbe8f71,c37679ad,d61e0453,3a1ebb71,99618a3b,9e8139a2,cd751d97,d4a212c0,9216bc42,a61a9734,750470c9,1bdb3fe4,510a5f0,9fa5858b,29eb7b8e,3d19641c), -S(cf1fb09c,a6b5ba69,93303a5b,695ddb27,3b527ffe,9a83e88f,9b5d45d6,b0a8f94e,cea6959,943f7e1d,f1e85391,e08fbba4,b9d84b00,6cecdbb,16f576c7,dd89c814), -S(1854629d,e22365db,5382ddd8,b6840e03,d1e12236,d31c7d10,12e8f83d,3ce1b71a,b25fdfe7,4fb81669,a24cab4e,eece5fc9,689ea40e,205b614c,4a0f250b,8f778b15), -S(6d1ebd8d,69fe133a,2e6628db,70cd4f,15d066db,2b0f42c6,2fc70dde,eb2e89a1,313ee8d9,750c0164,ef561df8,6125e72f,cb5c2233,ea36f971,197c7fe3,acc429ed), -S(29ebf614,7a918ca,371b5121,9efa033f,ff2869fc,618aec33,a4fe7aba,b916e46f,f1d5c067,382d76f4,74c159c,e88ea702,f90ad2c,5b268a7d,14ede7ab,40e11a22), -S(8e2bcc39,f60c4c62,591cd482,8125d08,4d26fc92,2e6ae30f,51882438,93dc5a40,44e3fa3e,64e14ada,e4a0a616,10862503,2e109dd1,c863814,368d423a,f96e9e56), -S(27e17225,1f6a9557,39aaa058,bedd91af,1e920758,cc0724ba,42f44f4d,45e99efa,7dd22a7d,6dc604c1,fe2850d5,41b2392a,b3c3d60f,2e712cd9,179fc5db,5fc179e8), -S(4fb44a50,574d591c,1391dabd,7f40f7bf,14514f65,927466b,2c643f36,d85063d1,fea4e431,63c1123d,9764b70a,cd843281,e108f04a,6fab19e3,da059f51,4c2a73b9), -S(929112b5,19251a93,bfd2715c,6107e5ee,d3283e0d,1849ae37,d110fd4,8eaf6be4,e382b859,a7de2309,a4dca649,66d0b744,9ffe9ba,383379be,d12871b7,19c653a2), -S(532c823a,a090cc4b,128938bc,69adb5c3,3653fc33,fa07d598,36d25ae0,808c0b70,61ecaf31,30a852cb,46de2616,f7bd24ed,8d9e1ad4,efadf570,d08a463d,b127b455), -S(7c7ec9a0,aab8cf1d,36b9447f,d7d82549,d425c217,d25cbea1,3ddb8d5e,e29a38a0,5441d917,1898ee1e,3cca969c,acaa074,62cd236c,a5cccea6,9436a086,e08142a3), -S(a81c85c2,54e52aee,1de1ee45,b79cd027,e1cc6414,4fe99ee,8ad8c572,82c0bad0,1be62473,54bc2bfe,1dc85c68,684fa9da,1ca55a58,6dc4ebc4,3cdb050d,e7acfd7), -S(38f16bb6,da377f25,aadc90b0,7fd21078,5028aed7,85dc0b07,5ad9f04,4b0ffcd7,9563c6c5,531b64a5,d06a5181,d7515b61,4a74f8ba,6226b559,4220282b,b8654273), -S(ea7a49cc,ec294031,87fb5f88,82deef27,2dad9624,76dcacfe,cf128bad,732e1686,49de39f7,5d9a4302,221d9b96,90019013,1ce39a7f,dea1c801,cfc0a2c0,b9a16995), -S(85019851,529364d4,5c84b63f,7f119f20,f3245547,2aa84b42,1ccb239d,fe536868,91b58064,2fdc0f39,284706b5,5b8e4bb8,4e112d5e,68379d94,465c3ac1,8e37cc50), -S(17e41364,244d8f16,22059363,be73839,75ad528f,f1db3390,ee65b106,beb6fe40,e90412d5,5e1b6590,e0d5968b,88dbb0bf,393ccd6f,96748e5a,205ff1b3,2f18a0f0), -S(5b49e7d9,fcad56b6,8b85d934,1b996ceb,6a555ca0,78f8d12a,e58e79f3,1d91caf9,32af7ff5,de4445e6,4bb895c5,316b171a,d911d8d7,81b16115,1e9643ad,4ce21885), -S(42baec78,86aff012,13d9d182,6e031b20,85724be0,268790e9,968d01fa,63e0e366,8298f68b,32e5caab,b8e641e6,720db67e,4150ad69,ebe90143,23f7b981,1ace8d4c), -S(5201710,64afee86,14c28123,5279e1a2,cc2775cc,85a5751e,158c66e9,2fa55d51,d12195c5,a0a08b,7cdca2da,fae86d15,d37427e0,1d266609,dc9c1adc,d5d8039b), -S(bc353c2a,8ca16349,fd021e60,8befb9a,f85c9ebb,b448d732,13220154,a02297c5,88850fa3,a61383bd,133c6fd4,65d12756,37878fb8,84bd3c31,3c4f92a,2b620edb), -S(9490256d,3acd97c2,848b24e8,8b8b2a8a,8635417a,1f228d6f,dccc3917,9c0fa397,4f4ce298,cf1dd296,b7704f9,b8f0a0d5,be42923,80bb917c,5fd49c28,55d3b662), -S(a963e733,ca168104,47ecb136,bbd2047a,97ba8f49,9222736d,eda1c7f1,75c2fff7,5385ed6b,93e6c27f,568566a9,5cf31059,de4ac850,1809319e,ce216eab,c8dc181a), -S(fb44e6f5,eca57845,76439098,2ab24ad,c84efb0,715c3b9d,df0b7b2d,a165702f,a62de478,678bee62,891c5241,9c8e77b9,d573fa6,95b0a2bd,fa5d9d61,c4362e43), -S(c1de1705,6bd1f0f6,8912dc20,29a41689,efb21e22,e24f3fc5,ff5c4498,f4fe7ea6,6297c6c2,a30e8e3c,43f534ef,475c3b35,f2a9550a,c5b9c733,63e117a4,af2829f2), -S(8c78a7cc,e7084890,8ff122c9,108980f8,b2a2b9e2,80e5536c,34b5e13e,61f8e133,459a70a1,5929d848,f8def6ef,ea8f42c,905fddb,3c0153f6,71a17b4a,b7c2c1ad), -S(5204d397,bf3ca5eb,988c1ccc,d23fe613,25202fa,88421157,cc7e7fa8,91b4e612,c02a009e,f89c5b88,b3f3a7a5,40d30ee6,75f94247,60e23fd4,8d8ce1e7,6395b7f5), -S(3cab1091,a0dc43c0,b90c60ee,44d31ecb,607da086,fa6da814,9c378acb,99c67ec9,3bcc5297,267a2da7,e228c7b8,c1677407,93feea54,bf31e3e9,f8e270df,e8d1fd19), -S(e0475cb9,9ecea30e,94ad6292,5ca5c3e7,77c30673,9d9d55c4,464a3e85,cc2f10cd,484818b4,d0f72e79,79427904,9f9aa4d4,8aeebcdb,f7f55a4d,97ddb03e,4f6018c6), -S(1165d67c,11327a34,e702775b,40a9d7b2,deaa423e,7e4d3dff,869f4a9e,3fe6ab73,63c55abf,6943f35,171595c9,63ab061b,a1c9f605,c2ee4970,767ab1cc,1bc691af), -S(f0ca20aa,59ecbddc,cdbd3f3,6c8830bc,9bedd29,b893ff74,48cc523f,bec962b2,6b2ff156,557d16a6,47453361,c4bf9f4f,41bf1e73,8f0c5536,a3dcd50c,ab88a086), -S(a3b01fa3,8e743e32,b623f2a5,cfb7300a,75457d46,6499dd5e,b1453d16,a746cdc7,19fdddaf,28030237,7310920f,3f982394,db89f510,a4a73b08,cacebc6a,2d417c78), -S(37ef5196,c8e2d69b,cc0b26c8,2bc30b9d,650a7ca1,409c77c,11e0a338,c5065ea6,df890a8d,8cb2b669,dc74c96e,19ffdbf5,abd5d898,46240fb9,18c297d6,1275ea86), -S(d99abce,1ecb8415,eaaf50bd,66f4b5f1,a5a4e5e9,d6959735,629d624d,adccbc88,9da9b4fd,2558c726,c44d10ee,f72c4699,80069045,a8660cf7,58de00cc,67be856c), -S(f77fe49c,28595198,7abfa598,915684c0,2af76675,5e2648a6,36f5c955,a78aed61,a764861d,3a8dfe39,92b2e897,ad4bebb0,8c7e2b55,e390efe8,21ffb60a,cf5e4be1), -S(88f6ec1,2aa65721,3f672e10,9d406472,7b89cf88,74dad08b,a4b54747,2bb767f9,8b6253db,a124b7ba,43fdbac8,55f8e9d5,9da23b49,e450c8e5,675442b5,f822b8dc), -S(a13a7136,640d1507,9ed90b77,12a9af52,e53e75af,4583a149,f78c2840,f383fc55,435fa5ab,6454ef1f,ede1b33e,475ffe8e,10dd5a94,4f96f340,1c184642,2672b310), -S(20940c7f,9d4abc67,d42884d0,346551ef,1b2aa54c,d8a1485d,1e23758c,e207a7fa,de5eb4e7,b619e600,3cf9c0f9,7e944f55,ab57fe23,388dbc73,66bb2120,e5aaa793), -S(298e00ed,855dd2f1,c0aef293,c55d859c,3db60fe4,b026f782,1c07d534,cb087e0e,9c45f376,466da662,583ec25b,5bdea3ac,c624731d,4bb62b2,2345fbb1,bf721990), -S(5153ac16,6b837bd3,29d98a22,56a576b9,821376cc,f7e48cb9,24e75f59,ffb6d7a,3f5ebcd5,d5ec2073,f1e43334,7ab4780d,f19a2806,d87a6477,bb73ed09,bec6bd43), -S(78c909a7,c94bcc00,b5518df2,bcd3ec09,9d5d2db0,d15321d5,b3135953,e8e1d195,735e4b40,519f4757,32042f20,410d8699,d1af7a33,94062791,b12e19d7,85ae42ea), -S(e4a4b24f,d9f7ac92,8a888507,c6d21ad4,fdaf62c9,2bb920ec,3ef96d64,a70a8567,b62c1cb7,b0e49cd9,8001dad1,52a2206d,6b397952,be03113f,7ff764cb,505502e1), -S(ca3b64ac,d4aa25df,3e7d4b64,6d5c8032,66809507,7f7f60cc,1e3138a5,2eff4800,92972d13,2f370aac,680f2a2c,feaf4e93,73199207,7f51334f,37553a04,5af089cd), -S(58e22f4b,a636677d,aecc727,d58a6ac5,77d85e31,2d41d56d,1c09c859,749798c5,cdcca924,549c867e,1a11e4dc,27bb00ae,99e0a356,5b6b37dd,26acb58e,f29f3bf0), -S(94dac55d,da61410d,926841a2,4b5ffb24,e44e3ee2,3d42efbd,8afdf3a4,3530363,4095385a,529965de,b01b9a3f,f9647b29,8f3d2119,9bdac924,5aa54df0,7e8d621a), -S(639ca66,8d7940b8,8f41c4cc,eb50b60,203b6884,c8ac9c0d,c33bbf59,926d417c,447035e4,5c9bf80c,71f8aaa3,9f9356c6,672f0db,fa01a4ef,5b1b7400,dbb70a21), -S(a6a9f38a,51d8e82a,7e04f667,e8cd638,af4cb7aa,c8b0ffa9,255f472c,c5b30250,fa935a10,4796943c,1880e3ed,d9c2504c,7e6e4bf,46036119,9458e23a,b0b025bd), -S(60179b5b,cb4ab099,b74f6a9b,853a50f1,582362ca,fd28b288,e2b339f3,27671a8d,5ef8f881,54b7b4af,ba287388,6c09d1d,c12d7070,6b960d0,b0453767,7e5d283d)}, -{S(60b01067,25cf781d,e78ba725,40508697,3f2ff6ec,1511515,6e19384,1fddda7a,624ccf87,f0ec21b9,82efbc4,6d4db878,5d20fb8e,dfe663fc,46660bb7,98c96eb), -S(74164670,d214bccc,23e32dd5,b4e7f093,c95b4628,b7b3448a,347980a,1f9b0323,827aad3a,23a648ab,e0ffef7e,d8a6d6,800e07bd,7eb1b5da,50b5dc2,8994a20c), -S(66a60beb,feb1eb8c,39857b37,158b48c0,93a90cc7,8d8aa58b,af183975,b12fd461,62f95a56,2db16e47,5ef65451,4cf82fc7,1a4379d2,cb4224fd,695d202d,8e85fbf0), -S(77272c7c,cb0ca53,17e660,adfa236c,e062992f,a59c7164,71d89755,f99ee448,a6a2d5ad,7ee9dbd6,d8a9d8d,157860a9,58e3d766,da5b82e1,5bbf83eb,7d987f7d), -S(eab2ac49,209ad561,d3beb05a,5152d5fa,f1af52a8,12ed0d40,c493d611,bd78c73d,c72f5b65,dfb7f960,a8bcf355,b80918ec,a9e8c3b3,985602d3,7ac0cae3,54645f6e), -S(ec184bfd,27c2ed17,25026464,4be6e557,db93ce3e,90ff225d,fb0cabda,cc124952,b4ed4a46,acebcbb3,9103f99e,cb65e208,2aa5990c,eba9fcac,cafdbe55,6a08a516), -S(6f5e0f0e,7c32165f,183f7834,3e12c845,86745ad6,d02d4f29,bf16ffab,31b1de93,76bf7f22,105a881d,6d190e20,bc7b5d89,ad0ee9ac,c1df6905,7035b6f7,6a9d4f61), -S(b3d820a7,466f3cb,d955acb0,c8baa787,e7f0d63f,52f9dc9e,87c6138e,60b9279c,6d769d76,91c1e61f,41b9cdce,949828be,7d17c1d,ff0c5041,7e2e3b79,fb873753), -S(ad92580b,575d6831,d2332a72,f3f888a4,713cd659,bc439870,7c000318,8e7ae426,eea9afc8,471e88c0,22463a9b,c8cb22c5,d0df87f9,201aebc0,519fb7e9,e2307073), -S(54b8cdd7,3204abb4,22d870a6,c5afcb14,81d4f117,a673e60d,155baafd,f3c5d4bb,6aadeaf4,94823ad9,df8d2429,e42a1d6,8aacec78,bf973785,a56120c8,28d23bb0), -S(ef2bb94,f14272a1,e235da4d,4ce4b043,2037c8dc,7ad8d559,958dc767,e0e75f5b,3af91f78,54bae661,9702996e,1defee92,2c0e8c3c,5fa4d37b,261c20bc,14fbed93), -S(13b87d2,8125e63f,1259b1d7,4b79c395,25bed045,256e8b00,84024bdb,48196b7f,139b380c,bba0404,463125e7,a455d454,ce7d811b,c7c14e10,90cef0ae,67d8281), -S(34ab008f,50e1a525,8cc77331,3dbf8510,7f3fda60,7ad5dfba,9aa464fa,856394c1,19178d3f,f5c51bd1,4c6d424e,c42591ea,414de041,7a3f470d,7c35dcda,77e57860), -S(7d872049,c080936c,54875ebc,49a00c41,b837b71a,18de4e70,adcb8369,95c2dfc,b572a6cb,58a2337e,2453110b,eb877a02,bff2bea1,d542714a,3a115a59,933eaea8), -S(72a2644e,2e6d7182,9f78274a,eefc9f15,9861b031,56d20d69,db62b4f8,57dd34ea,82e158bb,dc2d6100,bb5b300e,467470fe,606ddc1f,e662d3eb,3d51d9df,8383263d), -S(de81a355,37cbb00f,76aae7be,d3ce5362,c51426e4,ca012ce8,5d5f0fae,791c106c,10137d33,8a6532e,95917e92,31e5c14b,10551f6c,7bb1cd4b,5944e772,22c0f0e0), -S(f8499694,38918109,b0eced18,766add3d,8e21a5e1,a6eb640b,e4794e21,20400de,9d081c04,cf130095,fd00af83,32408bf6,ab4e262,e5150e3c,9f43a3a3,704b3d8d), -S(a5786625,1f866279,36233299,283e5dc3,838a5d9a,6fc30cdd,cb75ea90,9f3b2e94,57d57841,f173e1e9,e2959908,7e535dc6,a848132a,d6fd98b1,ea2a16e5,ff8c60b1), -S(533053dc,a24ceba7,f528c93b,bf62d61f,ec640ac1,40848f7b,9dde2ccd,f2465df1,d501e49e,3291919d,3c7a280a,1501258e,325e478e,343ae766,61cd9cfb,b856a316), -S(b85608de,dcd5543a,a90fc566,9fd94d52,b041e434,2cffc394,1cce3f40,12c23ebc,dcf01862,1051bab9,d1471d26,99f5727e,705ea2bd,8e5ffe71,df7db441,236df5c1), -S(bd1a08fa,d7d7fbd2,b46565ce,99fe28f9,635e0c41,a8b6aec2,31d949aa,a70d52ca,1a26906c,f77d43fc,ec656be8,5db770bc,65d05482,d6449f52,e23e1e70,6ac2aa15), -S(ee4e9976,9517bc1,2c7adc6c,fde381eb,b385b1a4,bf918268,5f175db9,949c99c3,738250e0,5dd8e427,95728575,fe5733f2,6b083705,301f9138,d736fb24,98c34679), -S(bcbbc6ea,2007057a,1be80335,3d086450,c48e432b,6f80ba43,bf03bebb,c48f9379,10fd6383,b5857977,87d8696,9525e0ae,b1842c23,974353f3,4eb515a1,5ff52435), -S(5c717940,e5e9546a,f9ce9d6d,c260bbed,fb678923,db861b41,1f275f0c,b18b6e02,d9144751,3ab535c0,603fbc12,adf52285,560f029c,266cda2d,69b29090,f5179f68), -S(7137b160,a5eaf92e,fe5f5c90,c3d34063,333f8204,5dd83371,31f624b8,cb7173,3025534d,6303c9a3,6ae38e66,57acdd29,48bfec24,d5ba7709,be051fb3,4537c2b8), -S(a6e79e0b,54c083ea,a6e37b9e,b54c181b,ce397786,c294abf,5d1cf475,fe34c030,aaa6aac8,4709fb5c,ac6a498,c0659da0,e2506e5f,e890c06f,5ed5081c,bd737c71), -S(9a143958,23cf2096,d81677e5,f804bd5b,790ceabb,4b15da9,b35c01f8,c6b1d81d,61bd3e2b,642e9948,50179f0a,947820f3,f241e53d,8222ec73,3ceb8bf4,cb7f08fd), -S(a51aea0e,4039ce66,b3e80814,4582aed9,d0ac0be2,95105a8b,23179025,4a2b0429,7cde7f91,96e8f417,ed7a075c,c25cb694,4e996997,3ce13a4a,941f670a,f523709d), -S(2d79629a,1069878e,76cda780,b9291c4b,45b78b7b,ac98fcd4,3ebff7b6,cc2ad200,cb01aef5,1a5fab94,ec29d73,6ff2370a,df866d45,d977fda5,2b7fe32a,e1d9a3fb), -S(6af74994,feabdaa5,fb0cb613,2f346490,bcb1a70c,7bf58e44,2cd46670,12e050d8,627e7f3e,b4e66be0,672b8bde,f119177e,f878e80c,a7b5661d,d6a9d19f,19729e9d), -S(c367583c,7d2d5d6f,3f00083a,1218645c,568a85ca,8fdc708c,7e8dce2b,c72c3ceb,baa36c7e,1c86d194,ee03efb5,c5e11b47,34bfa6,c168ef3e,fbb78f07,51a7ebab), -S(36b2293a,2dc956f3,47ef5874,9504821a,c9197e25,1716c398,f5c9dc61,c63fd5e0,95c93401,be8f3500,d971ca82,ec97def8,7d58d64b,5e4753cb,4f2cb608,72f2950d), -S(78e80bca,805183f1,76257399,63e9cf9f,a1bf2b88,eaf4147a,17d83057,bcfa32a8,b42e40aa,f852c738,fe1abb8a,e5dce499,414c2113,eb59cd2b,2a3f6c42,fa96812), -S(4f5b3550,887d9ad1,1254333d,7203aadf,d202fe5c,845b3c8f,3c0094fc,e4a32628,a4842bc8,c793e4ed,948dbbd9,cb68b7c9,3bb86827,fa9d7c3f,acfe78bf,670eeb99), -S(8f880914,9dc553da,4ed0b371,70850bfb,c305fce6,d5e7be9c,640be999,8df19b1e,f020f82a,eff490e9,fc7d4d7b,519e780c,21f86f87,5a547693,86524483,ec776674), -S(ed7f98f4,90be919d,d1f570fc,cb565424,c3537bad,d8d80e61,87b51f8d,9ebce164,d374e45b,c81bdc9d,63c824b,1bdeb2ff,5c9a3453,93540ab7,884053b7,107d8066), -S(754d2b67,65625067,14865f65,a89bd0c6,6415aff5,644d37b7,e7437e03,372d70f5,e4b5855c,14ba6a3,360d1519,98358bd0,ec2bd109,ddee46d,7a95050f,5131a9ae), -S(d0778425,311ac57e,b8ffeaee,2001b9fa,89d6cb36,49be46aa,365b81cc,c8bb903a,25e3a484,5f1c15e3,ecf6a654,69a78893,3c414b8d,c92587f9,fc8f54c6,eaf065a0), -S(c7c18e4f,7c8772d4,37e3e861,584d24f7,f428c06f,23730347,2dcfd4d6,80352ff2,6f5a02d8,1c6ff6cb,32e85004,3375c865,57f8659,83e76e0d,4f42a69a,b02ddd52), -S(96c4e50d,eb86020e,b0bfba2f,ba3da698,c7bd031c,78959022,341aa1bd,a19b4a1c,8cd7476a,78098ae2,ca166d9b,c8aa79b1,ffd9f8f0,943286ff,d563008f,6f3cfd5f), -S(3f462649,9a5e5ad9,f5ea71a0,9b4e6b7b,fea33c80,c786715b,15200580,cba306ba,32624f0e,9a3b0413,fa401f8f,6f32995c,74ab592b,792247da,970b89b6,90545bc4), -S(a1495fc5,2c642d7e,da16d1d1,289f2eef,f4993882,f2843128,6d17d34e,5949e2f1,66ce7c4d,611421e8,7f049ceb,11e9f99f,9edf2592,9da6bc45,91ffbfbc,3c73c87), -S(954ad30c,15a6c5b2,deb98983,ba7125c8,e216f1da,5531d258,513b7731,4fc86c0c,39378c22,527387af,e75d630,fa69dc8c,44586372,96e4526e,2e105fd1,af7ba0b9), -S(5692830e,c3ab78cf,6721b604,31abc539,ab14318f,cdd4d6d4,1586772a,bce39a98,5d1d9619,c335acef,22acc9a8,d32ae53e,9b227ede,50ca613d,d67065d1,252c56b8), -S(1cab4f2c,73e452a4,de0e2591,1ed22364,803a060d,ad957184,3c81258c,6a4c518d,27617c5b,d52b5d06,8cd9c2ba,df266f8f,ecdeb4cd,41bd6e0b,a2db6a2,8f4c7f3c), -S(9f1834c0,145eedf2,53211dc2,3339283e,5e7daa72,fbf6b69f,d5642a63,c551bfed,c1838a49,b3289127,7c3365f5,9f69d34a,27b48c6c,8897e9ca,f40d8753,d467d72f), -S(58988653,8035c13d,2c538f0a,1c587f2f,fc08405c,e6a1d7ad,828aef75,43b4ae8a,c4b901b4,beb24774,598bd2b7,d3450791,f2cbb37c,939594b6,593fa592,dee20590), -S(d248754e,c643d300,6d81c5c8,9e91b522,181921bf,627e813,1acab8bb,cb97b2be,76b94631,6668e319,a057648b,2369d781,c2abc77,6aa8805c,43734698,671174e7), -S(f849ae76,ad1bc714,4c2fe13c,b0ee81b3,f9abcca8,d940a161,74a69c0,b2cbfd0b,239aab7f,c1b6c054,a34deeb3,56da4e14,e15643a6,63f40642,b2a43350,80c2883d), -S(561b12a6,2e2fd36c,ca92d85b,14baafff,864e99cf,315d8902,72f81dd3,27d1f04,c4199633,801df02,b34ba9e,13462533,7bd975e3,ceb19673,7bf37bb9,daf30808), -S(8821c52b,c13c4ca5,bc7712da,9e769754,c4ab00d7,83dbc018,b1c5b383,9c41c245,63edc442,6347d646,5ea5c046,820fef62,89a28c47,df834a71,cfa9f5d4,6561444b), -S(382b0dc2,c54b6fcd,dd8ff070,6edf8f4f,2ce34daa,4f7dc15,d7f1ee0,b0ba78a0,31e1e109,35d8c994,3ed05b5a,57d91bce,81ba0f4a,8da1454,98a18e70,17f2fa39), -S(3b4fa983,26fbd82b,59a938f,1aa9d30e,2da395df,f8ed1aa3,c75f0969,b3b85712,57653c2a,8a11d192,4116c658,5b413feb,e8c56142,bda13d6a,175244c4,4b13a396), -S(5ea8db07,47f4f7a4,db0f9494,3dbf8b3b,9b04855f,93737d30,9c7ab27,8c2ba4cb,805b0db0,1d883e3b,a8f82de5,b6bc6c3e,3b05b3ed,4eb16d34,db8df937,19929403), -S(21386763,58a655e1,e878aa8,984bfe61,bbc7f1f,c16c1881,40e2cf21,63431d89,b62d321c,82082b74,4f8817d7,dc464804,c1d3e9ac,220dd1e6,a94f17d8,2250d06f), -S(934eaa8c,bbd3fad3,44cd1996,86b8a7c3,bb0ef384,4e085e55,83030bc2,bb52148f,4613cf3d,ef424be3,af392f4a,6fc474c8,3e3f2d1a,394431c6,5ee6e224,4396774e), -S(99a5472b,e9d06621,7e18be06,d9a1c1e6,a649a5e,61f3726c,87b21a31,7aac5f48,1e5a68d6,de4b2958,70cdd340,8b3d66c4,84eb4002,9d41c1a4,1d30bc97,beb14693), -S(3411cb09,5d5dcb10,49e8b927,5788779f,11516882,cc09ba6c,dac69bae,2c63362,6a3b3241,e6c3c802,dd5105dc,a1b82a8c,6bd31e57,aaaf505,fc41553b,2ac08b4e), -S(f7a6f695,824a413b,8a916cd3,c3403950,38ccc3ba,96803c71,6a498b7b,384d7fc1,7acb457d,3cda4738,bba35848,8bce971,d584ba79,e7432224,6619c0ef,9cff3ed1), -S(d4737f3e,6bce15f1,7ae3a133,bca08f13,434f25e6,8fd36a62,5672e6cf,983b1084,54a81a40,9f08a597,ba4e312d,f8789106,19189132,40f97ae6,b360d510,4a0b47b), -S(5b1e76c7,3f9c8353,b7f3c63f,ff2e48e2,d3bc05fa,857ebcc8,84e582cd,83845327,6024ce76,eaffe03f,951ca26c,a1550d96,f468385c,157d9a79,eb9a20fc,fe841e2f), -S(d201ad7a,72d692d9,e87a7a83,e865965b,48e90ae9,1481a927,34c90133,f725d589,310661e2,9fec5d37,96484ee1,bc6a6f76,e8da9e1c,f10fe672,6dfaf737,d78119d), -S(cd1f2c41,55b8119b,c5b9bc31,e5817a8a,b2268a8b,a526c005,1a3e23a7,abe8bef5,35b8f656,8b84d979,64b29050,77f01e9a,c2024236,29614688,df077aba,1b639048), -S(89c74b7c,e763801f,41ef6dcd,a452fc7f,a39f621b,39fa1061,a2b4bd4a,9649c9db,d5cc7a8e,722df783,82c168f1,91142df3,e15c161e,3a8471ef,236afa5f,a98a9f93), -S(ffcaa11f,317a856f,300df9be,1dce6c40,88bd5c28,b08861d3,87f3492a,d1004bed,ccaa2565,1ce602ba,72c899ad,f5f9be23,910ff5b5,1e3fb1b6,e2eb975b,c43c1492), -S(35903c6b,58659353,391a50b7,1a9c8186,a4dc7ede,f3455ee4,8ecc1470,263e1b8f,d44d9022,a5cfb61,4f56b02d,a83b67e1,4c3eeb78,caee0a4c,7f404471,77ae7ee0), -S(f9138261,2bc1de8,eb9d7062,80ef2b2,fa7fcd30,d157130c,784d7698,dcce5183,4709a971,d0008021,37a9ab87,27a705bf,cf1aacbc,822dab5a,d9334bd5,bcc5fd5e), -S(244ad0f3,26371ef6,f6c29f9b,7ef567ae,98a2abb0,cfa1561b,e9dc7f15,1e8833c7,53c1198c,5ddb33ac,37af979a,f40e321d,e87304d8,62efc794,2c944260,65de386b), -S(cbfeabdb,c93dee73,6f54f500,b33c2d0c,8c66b5af,68dde61f,c820ed3a,1ad2347a,f1416c9e,bc04c0a,792a1288,a20d0544,b7452aed,33f77b86,77b806e7,567914bb), -S(714246f7,3eabb0ac,af298c16,1bda9c3f,11f8fc8e,78b9616,2591242d,f0e870a3,94d8e600,cfe23c05,c9ec81e5,2c9e440a,af477c70,590f5470,31ece7f6,778edc56), -S(d776c80,63f8102e,805317ce,8e0b31dd,7b8b094d,6137c865,184ae51e,e07b924a,e66f3ab8,998ee226,f1259e4d,25d98d35,918b2cfa,abfe56,4a10c8fe,663101a1), -S(ef99b2bf,80bf084a,6483e319,9b4b578c,800eb85a,8634222a,197700c8,92a05310,94fc3ef1,12d050f7,e7d34ade,e89faf30,b651e10a,6931e4a7,ac2ecb48,fab90ba8), -S(c84a0ac1,8b659ffc,ac9e2dc7,57248e23,3d71fa98,90327e76,9441231,666f3790,e0973e42,73cd51dd,7233ca34,43dac778,3cd53c25,6816be1a,fbdd636f,936f7fdb), -S(b5572cfc,61db791c,d8b19da6,6fc11df6,e8776505,c016e6ed,96f17b97,c2edb89e,608ed024,b606b10c,5785811f,8c333fe4,95a726a2,ebe56680,b00b513c,aac4e0b8), -S(68447029,864934d5,92907821,5ec5ab99,3e00bd52,fe4994e,42978327,bf35a6f,31521acd,69c57644,ef35bfa8,cec803a2,e825c740,36a9a3e,fe831364,d00fd897), -S(fc9ee8ac,9fb265a3,7c26358f,8bff851b,d2a7aeba,2dc2a19b,153f649e,97d75605,cde1f563,b971ba67,dcf3d759,2752221a,babd8ab8,1d8a5a4f,3dda35ac,44c01d5), -S(7e86c9a0,d024eef7,91758bd6,899eee23,ff032336,9221f3f4,2b604ffb,33c473f1,2c15df40,6cad3479,841ffa5,14513883,978af93e,42aeba3e,c8ad64f8,df60da24), -S(e2b33d9a,8806ccd1,7d34a916,c4caa169,ffc9673c,e8eacde,19bbb286,85003732,5610c3fb,f0a6b39b,ec5c8cfa,db9296b5,86c6677d,61220ce2,b1d19bd5,9f44f72e), -S(ed6b2e3f,eca9b628,d98e663c,a3c72b0d,b853c8b7,a9cb9c4e,9247b8bf,84b2f3b3,6e45aa3d,f766a732,fe91f124,9148a96b,169e3b88,7dcf90ac,f972e91c,b25ae9cc), -S(78ed22a,c278758d,625e0439,3e273e7c,24acc72a,3975b497,ecad1314,df2de65,a2991712,373d669d,3afa81a5,c1e043fa,24df04e8,cc8fd13,32025186,f459913d), -S(3f3e7509,69153c5,378f64d5,7fce5aae,689f20a,8deb05ff,72077c72,b116996f,63d56b8b,92e77496,b86bd0ef,8bf803fa,f1d040d0,cd42c975,c7a08d7e,fd5056f2), -S(2540390,ca25189f,381b398e,3fd46acf,d5918215,a8bf9a17,d25179aa,fe75c1c,1c6f1725,5cac59d2,ebff7c4e,322694fe,96f5e2b7,e3927c9d,56134007,fc6dd9ec), -S(ed668903,3dee44be,80e9792b,b95408bb,5d38b016,d75490fe,2a22b118,56524fce,1a5c61f5,e738180c,cb533faf,ec9d3def,913ec31a,8c8463f3,df097f81,36375093), -S(a1a86dbc,2061e047,6ecbc303,2d25c159,414a6860,fcd818be,202a0f28,ef803224,ec9fbcb8,31f6720c,1735e505,276acd05,d957ea94,5b3af60b,6e1a2ccb,ede5b706), -S(c6064cdb,4feaaf24,89c35475,54279d3d,f1e96556,e97f1ec3,449fc747,ee8d0a2e,661f040f,ab90e5d,c9931a8b,297f2e61,9a24468e,432fb2b8,84acd0d,5cee7dea), -S(25b5f3a1,656c75ea,4ce2fc9c,bdbd2f36,78ef6e4a,9c2270a8,8b8dad5f,6f55fedf,8c48ac45,dbe199a6,5c9d72c8,7c1940c5,f17f59ca,d0c67211,5c2af898,7b142ec6), -S(b8e77df0,e23c94f,6f982ac4,37540690,441135f0,948f019,b79088d6,9eed91ce,3105acf2,23c01ac5,556b665b,d6b1919c,dde81dbf,7d44e18a,17bf67b2,833265af), -S(2a19c0de,d617ce9f,ff906686,a72bef9b,3ee2200b,ce71aa87,e18c2767,32421500,281d0c8d,dac57006,6c8d32f8,cafa5f54,404a6676,78ae9a0e,a0d19f1d,d0d24a6e), -S(5771b96e,c1a30ad8,d2087016,45df9b92,759c312,cc542ab9,126d3207,827e68df,ab4feadc,4b37a329,bf86e4,81786a0f,e1648794,689d0fed,183d7b48,fd53f760), -S(183fc4c8,62788f1c,7b7036d2,96bf7193,cdc93d6b,533b8c9b,ea28a9c2,9a5a9c10,2c019a73,5cca1086,e73948da,5d15f816,cbed1945,83014a64,24a586cf,501ff5e3), -S(31ebc0ae,656194c2,ee49f25e,28af673c,c65b2224,467ff0cc,920d3780,2dcfee7,d2db8690,89c5f10,b76d2d8f,cfd707d5,db7b3cfb,38903b6f,c4ebabde,47edd669), -S(a843fb7a,af70c96b,e7812f89,789b05c0,63824134,33476cbf,2a2b31cb,5a8d77fc,d0091386,435d082c,38fffaac,671129ab,f5e3461b,dc8295f9,9a064ee8,9371f70), -S(76c82448,6820236f,39701ac0,5290315d,a6f30e30,91d086e8,b3c934a7,871c038b,a4cc0e55,c2048935,c5c11b51,417950e9,dcd4ac6b,839b850e,efd2b890,17f5b4f7), -S(61653255,b4fecb8f,7fe9e6cc,179ded3f,955b359d,cf59cc70,1ee85750,b31a1d63,e197d8c5,d2571f03,931da039,b59989ad,390cac56,4982952b,a17e4d47,56f57582), -S(eaae448c,9a862f27,b55784b7,b3275e1,2d99d369,2aee475,dcf2d3ca,edd500d6,3cf4149b,351205e6,5ce2593a,282264aa,127953df,7da3cf9e,976af775,6be084af), -S(858c766b,faa67e75,672ed7a7,f0bf9b58,14217fca,bfa31b77,326d98a8,f6c7ec83,4d019482,93b2a3e1,d6f16dd8,8160efb,d15e29ae,e4c6b7f8,329127b1,7d0251f9), -S(cd384125,aa1dcc88,fc2c237f,2ff68117,c9517217,5b8c4f9b,a677ddf4,c2ac23a7,cdbbfc3f,d65180af,6a52f3e0,79f169a2,1dbaa8c6,bedcc4ff,be67635a,a1d51e1d), -S(5387bb96,b91fa67c,823e41ec,8dbece4e,cc1b6182,d50fe91f,44a02d74,90088659,bb7baeba,2b744ee6,8ff6ca19,64457de0,62a5e0a6,57edcac5,d6019bdf,caa25e01), -S(31ad9536,a6c16f44,c00189db,ecc8c527,304ab3b3,89bc7425,47fff91f,a088c01e,f48cae34,98357da9,5c47a41f,bb07055e,2061d037,35abe3df,8ff2fac0,cbcc246a), -S(18741256,6398f4b5,d2c34711,fa0e952,bf4de5a0,338bee49,a93daa3a,fdf29a47,5f96f31f,870511f1,a390a0bf,f9d9d383,2a7e3bb5,e8c515aa,f6022437,add8f159), -S(e1e5b96d,cdc60b81,19ca3138,9544c7b2,bfd587ce,6f42188f,115f4ac6,99e60793,cb5d9f4a,6475154c,7a285cdd,b0c115f1,765e357c,f51d8388,c03bf829,9a6720ea), -S(5184ca38,33208dd2,c04279f4,de77916c,fce7b4c2,1d45aadf,293842cd,56fdcd39,268d16e5,59d8488b,a076c82a,9587834e,87ccd65,c98feb69,9ae33005,299d2ec6), -S(d11c12e3,6646124d,c2602f0,b68543f7,e62ac955,8505f479,236ddc03,e9e6251,9d429bb2,d1378d9e,8e986f9f,a3d1349d,607df6b0,c48de566,d537c48e,10aecdd2), -S(d55753b4,93da41b8,f01da15d,ad5e71a3,655de4ae,b56a6fb5,9df058b5,f6636a9d,ee5270ac,db3d0e8d,6b46b948,9740311e,24925894,114d6c4c,52dbbe1,c4118013), -S(3f23ae1e,39238fbb,249606ef,d47502fb,30255e87,97148a90,5e3bf259,92429eae,845208cb,c6420538,410d5b2d,aaa28712,a2b77fdd,5241833f,124dd025,38d515f1), -S(837d504b,7f244155,1003c511,4e905b7,2bd9ea37,c690d9b7,381b2084,9cf7dbca,db355b5c,25d9b17,1167d31c,c5011a6e,2069863b,eb12164d,311e483a,21c2ff), -S(3d7e0c2,dab7f97,866a591b,f8187705,e31b7b3,bfea09c0,502b7a0e,c0037b5c,2a71d18d,f997d233,5a405ecb,d1ba09c8,8b282049,69215d7c,8a390435,8888a41b), -S(99f2faf7,8cdceb1a,70fb3076,3c19d54c,e16aba42,4e75be22,89f0e521,c73f3f23,778f4a0e,25c3844f,5aaa9082,cc985aef,dfe6e692,ab40eac2,9ddf668b,b28d0bee), -S(32dbf023,d57b27e0,5be2989,bbf1637a,7b3133e2,84d434f1,df8dcd56,70f9ec15,91d820ab,7a4f2350,49814592,ed2c46d9,fd7da87,a392b5e5,9dc309e8,ccb863ba), -S(2e413a5,b52d61f7,1290f182,9d24cb58,38339ebc,1b6d46f0,3c55334c,61ff64ce,474be10f,a3afedac,b9c6cee4,640424c,d7d3d6a1,437f2d0e,79e0b20a,8bdf2553), -S(955e7565,6052ab57,d05beac9,fc586758,780b8979,75642db,cd11fbaa,8e9deb7d,9276041f,cab762f9,929a6f54,a619e6aa,9613a794,96d32fe7,2e02ecfb,2a22045b), -S(1d6ec4e2,cc1a1dd3,f116845a,3173d350,c9607bd2,4e6db8e1,64220217,9208d805,2b6ff084,f5c42222,e29ab094,6f82b5b,f1cd6f3d,6d01a2ba,4d0744d7,ea95d0f0), -S(6ba994a7,9090acef,e756192f,91e97d07,82f393f1,c59f3b7a,786beee7,63ff0ec0,5c800150,c9464bb4,57190378,88247938,e26e54b8,93d25b7,6ef7ac83,78733f7f), -S(8b914ecd,2e19697e,83aa0196,70e1f955,530364fa,4f592638,b241a7a4,e07bd8ed,aafab68b,f3587e6d,8a078717,27e91eb8,4d327ad1,6fb89154,52a954af,e85f332e), -S(295e4ed6,380b91a2,a6628b5,820c11cf,ec407294,379b718a,5d4d88b4,3a2f9fd7,4e617c6f,b89074d9,818815e7,2a13d34e,58702106,f1470e80,ffce03d9,ddae9dd8), -S(efd76a5,217fca77,80aa7871,3dfb886a,f0b18e91,857ed243,2af704bd,87cb6187,e8f4d552,5e1e84fe,b89793f2,12a508d2,4b7ad2f2,903c38f0,d6729be1,6449cb1f), -S(44acefc8,e7148bbe,3c634bde,b8e4eb7b,618a135e,9c1b0ec3,6b160975,87284364,5eed55e8,8ba8ba5d,afc804a2,3cd5e1a,c161e4b,69d9bea9,da22b9f4,d130563b), -S(1e7d7ba1,475ff038,1fe4f0b9,71609d3b,d315d10e,329520f,3832418b,541b4174,887863ef,78a7ae20,acde554a,dd436aea,3f61ffc1,24023448,ac8f66fd,5e206869), -S(6fd945fd,d8043a74,c7c57341,a0581ea,c009ac76,1eef33de,277b7205,a7a248cb,6bb15fab,559c4d8f,32fae6f6,fb65c15a,222b022b,c8c57c06,b60f7b05,65f2760f), -S(34ccaf74,39ec22bb,2287400e,663350e0,1bfa2682,2fe851c2,faf4aae6,941bd5c7,91782420,76a254e1,a30b3ee0,29a19110,4af5fc0b,dbee533d,5c62a90d,2d9766dd), -S(554384e1,90581b4f,1bb6d971,9632e002,4476c913,30cdab94,5d8b86c0,491a8362,190ee656,95a73bcc,4faa6dd,9cd0113,ffae600f,fc13cdb8,14b2189,779aad2b), -S(75bc28dd,cf96c6d2,55981f0b,cf08df49,e48b162d,baa21046,89924a39,5db3386a,cd49b1f8,ead093ae,a554b9e4,d2fdcd18,ef614118,cf0baa2d,c83f2c37,92c23175), -S(4d094d69,15e92b69,b36d98d,8bc0e31e,ef6d49b5,d3d11b63,95bdd831,47cd679a,2aeb7bd9,98bb35ca,4554ed6c,91d92042,9945f775,8697684c,d0c63887,cb625264), -S(38b35099,7cde0af0,61ef1a3f,ab9e038e,988f670c,b06b39f,e611a5ed,227831ff,f0531e87,deba2ee2,117bb773,c933b780,71b2b8f1,956dcf8d,af99ee52,d69d67cd), -S(96bceef2,da234989,f4deec66,5a73ec91,6b284242,2a813a3d,f78c131f,4ba2165b,dc844f47,7ac5ea55,114aa18d,65950318,8b6592db,dfa62c75,d191e7d6,bbd70de7), -S(5badf11e,b896ab6e,f49de6bd,7b6adfef,840a0261,b173d89e,884bb453,5d7def8a,939707af,ad49890,2268485f,697d95b1,8082c75e,7b9d379f,4f7143d,27f830f), -S(ece21ae5,f5981e,e05869,fa9e581c,12773fa0,2b463515,55ded999,ce8acdd8,7771180b,9fc2d3f4,ce5d2ce0,a5e15c0f,4c29d135,62eee682,f80cbf26,fb812c9d), -S(650d7149,30417468,cb918e91,6234ff3b,1bd46f06,b90184cf,41d9112f,e472d26d,1f746358,4fd816de,89c86e9,39eab19,62a49305,775d8a86,6eb1ad35,edf48961), -S(f344bbd2,7ae90f73,b6f9a152,603dbcda,f14da6f8,f9ccdadd,88631de7,286b95a8,ae254238,b63ae9fb,89bc5be0,3e36a0bc,3bf15159,27094287,b9278988,b77a8ea), -S(982c94e3,a9dacddd,c1ae1394,cf93f8f4,91fa9261,ddd81e09,826b68e2,992c01f9,7527ad8b,39813588,6000a328,84b4f108,a4d6791e,2fbc86f0,b0038c40,ad280ea5), -S(b9885add,38946d2e,170d4bc2,361e44a2,859f2166,8577a099,f9d42c4a,170ff9db,edd69b3a,21836af3,a68c9e76,a7d62c47,3ee0042,3606ea6d,477126e3,b88f04e2), -S(4b34b984,4f57ae76,8bb666a2,b610b4f3,dc71b651,e23ae7ee,7eb2faa7,73a99e4b,4f4ea965,ccd9e929,b1d2830f,3bfe37bb,53be8f2a,a7c3a67f,9575d508,39cf2580), -S(ac8b24e5,9aa829ba,a7ebc7d1,4a25b14d,f770f0f1,158bd924,50b6e448,5af3bd7f,b25ad04,4954b659,8b8edcda,bc3b28d1,6b42a286,82602977,87c95360,ab2242a1), -S(88ed52a5,29858067,59b3ffe8,c1de8453,29d9c427,b7825931,57d8c927,43f1732c,d9dddf46,92f3d20f,7a99a3ca,a855a272,9143ceea,28c887fd,c054c6f,bfc25ba7), -S(f189d8af,9c34afb4,4dcfdbe7,996375ef,d8b9cac0,86230acd,e6972b19,1e1bba41,9a652729,1209b68f,722ff77e,38af6ff8,8595be0e,e1433afe,787716f4,8c69cc70), -S(6eb98d26,50dd58cd,8b7ee6e9,663585f5,77ccc3bd,3199d34e,2589b2f3,2deecd91,1c794824,bef31b44,b7497bd6,3966ca73,fea5ad7d,f640630c,37800e59,ac3d4afc), -S(75f5ea53,2e89dbfd,cbebd051,c129cfae,437e70e5,ae3a2d89,1b20588,94184ad6,faf379ae,6645548b,573142c6,8665eaee,882de32c,dfdc358,c778ccb2,dbca8107), -S(d62f599a,f29209ae,c7818548,f833ffcd,4d232d6,e297df96,4329d5a9,e7300c4c,61bbc3d3,79088b3d,ae30ad32,da25aa41,17b63b17,84bffd34,9cc7a5dd,9635e587), -S(2dd9167d,388f551,839fcda0,8c0b2f99,5bfb4fac,2f31dfdb,4cdf6822,72389b08,de646ee4,2a53c47f,11214ec7,cc46bb0,31ecd599,5d02935f,d49d9e0d,61c8bc4), -S(5e244f2c,87e222cd,70d4c4db,4020593f,ede6e3eb,fadb2d7,c260a12e,61349323,336b3413,ed5f1f7,f82db066,439e329c,323b5e68,26bd57a1,1038ffd3,2b236d0e), -S(9ceb7373,d13b017,1d1dabb8,4d22a756,52ee75ce,5943238,6784f06,4fa9dc80,80bf893,e4162d17,c7792fd7,d89e283b,7a6f3e88,fbccf0ec,251f09bd,93e46714), -S(aa4de7b3,6d1990f,5b2f2afa,4fa71caf,bb852321,dac68f81,c65cb997,306bf020,6cc882d6,577e5958,8d5a2a8e,ac18f0da,f29cdb84,bb1f6ec7,19b53600,4621196b), -S(dc1db767,2e425cb7,b1dd376f,37bda82c,6fcd98d7,c9dd1831,5368c4f,2e95f5f3,fdcdbdb1,926c987,81c0944e,bd13f28d,97fb9a79,2b7d4b96,8be1cc0e,a1c20b75), -S(3ef39100,83392f75,8a78325a,44dfdf2e,5083d8cb,396d2b0f,1e4fd37c,47cf799a,f057ff96,da3779fa,f9c66fa8,cc59801,44ed2dda,561370f,4c3e1800,d0dabbdc), -S(681c2240,fffaf870,ff80b853,ee1aed59,c2c6d435,d0319354,7c4ef991,1e2e4a8a,16eb0138,56342438,57d3af9,12403c06,6cc48eca,92fb6614,b839e46f,8b939450), -S(8d013629,1912293d,c39537c8,3ebfe514,3e831e69,c844a076,c227926d,e5f9a774,b422e532,e989ac8f,1369c95a,63bde2c,20f02ead,254699d6,bf3d4a76,375c08bf), -S(bdd10d52,da3d9deb,e664ad2d,e020391,665f32bd,7b236e02,adb6ad1d,7dfccece,201ee4d9,76d70c3e,cc06784c,a33b84bf,ebdaedaa,1df478f6,70128198,f1b8f66c), -S(2d34aeca,2ee9102c,bad92b30,2802386d,6e7af432,8aaeaeb3,939e3435,98715d2d,2c372a9a,4a4f0daf,a32acf6f,a40acacf,be6c668c,1306b93e,b27fb43a,a82e0083), -S(717776bd,d8c65a1,62ebb2f1,cea29ecd,9a843d5b,92f91278,3cf4c819,b26158cc,bec109f1,29997d51,e032f8f1,f453e222,4e2466ca,ae89fbd0,37a119ee,45588f), -S(a03bfc10,6f13c570,be92a85c,f72cde29,caa157cb,8b434ed5,c958f2dd,3c69ae09,8d76f55a,959eea82,c18d7328,2d5fa91d,d747fa13,67e64b0d,3d0b0a94,e58ee0e4), -S(b3516031,30e3198e,4a158cb0,108c8187,88c59939,bc813423,3bc51ca0,314832d4,3a5a4dcd,9fe0c5dc,bc17a082,396a93f8,36182c7e,2e26670f,d64ac6e5,8f022c27), -S(a927baa6,f7cf01fe,1993e1ad,c435edd,c806af66,6c9d2168,44a86bb2,2d7a8951,489734bb,4fe191bf,4535c812,a0e2d3f0,fd8020f2,ddeabbfe,c740fafa,7ccfb468), -S(54df921b,5848a4da,22c4dc63,c46876d9,53368446,e6106389,55ff00ee,61d75a13,25de0b92,52968196,18d606f5,d2c54e7b,fa6c1980,bdacd4a7,54a9b2b0,4015d8fa), -S(5822acdf,704948e3,c9112d0e,e718bcda,98eef3e,bb927d14,a1fe1952,1d64361a,c8bcb245,d5aa9e2e,7d527508,38db01b4,e2487197,a3ba351a,f2fb4b3c,19d03895), -S(a58c52f1,ca6983bb,cf2e8bfe,592b8d9c,b2a78dbc,e1f77931,14c95253,6a2d65c9,43626050,9c114db4,eae66452,599b145b,4d16b14c,cf7ce807,9a9c531b,7f3cc46b), -S(2db642ec,2bd88fed,7e624eca,e8022f7e,453cbfe1,1a6b00ff,726be4d6,89a72418,e3e73ef3,403e341e,e032ee00,e99b1f26,e710571d,81ac93f2,5855a8f7,32265440), -S(45b76e7f,65d895ec,24756195,187a4612,7dc9b31c,5e3e5376,e3af20de,b7e69a8,b2997f75,7cafe61e,f8a67043,a624e55,c10dc237,2f4b9d60,9692b269,7c616fac), -S(accc62eb,bee83904,c01a32db,e4af9b0b,50f3064c,bafee18e,eb49bcba,d53a41d3,34054eed,c77ef0d5,e865ea30,f505ba8a,ffc94474,5722651d,294a2520,fb7f4f0a), -S(1de2f5de,b1658f6b,6d20878b,9adb8a4f,6535965d,63bee989,fe23e4ed,a77f07e6,96762a16,fcb2aae6,ddce8f55,39c57f57,fbb45d09,26738e6f,82085d3c,ff0f20de), -S(5c51b67b,d4c0df54,ce75b09a,c399c293,4fd7a991,607a0aa4,a0f6629c,645f57a5,d1082c6f,66cd1aba,86df3edc,39b2e579,6e6975c8,ca018310,385173e8,5878914c), -S(8d7421b3,af8ad663,e7155f89,25bc9246,af7b3bd9,3c6a1097,afadf84f,7b041434,bdfa5121,e17dff19,6c105c34,b9d0bb18,8514a9ba,7dfee6c4,45c7855d,556409f5), -S(5608f4f9,f6d1a0de,64f22794,7fbdaefb,24b797e9,1f6db6ce,f3986d65,f0d4836c,1e03f309,f4c0f432,eae951f8,6e876f24,35364778,2249c36f,cd7115b7,8248a1d1), -S(24fced9f,ec868343,e6d6482a,1017853f,6687da3f,cc8e19d5,240a0991,6fa61791,8884a7a5,c742149f,88af0fdb,7cd59bfb,d318d8d7,60015afa,6bf0474d,eca7c214), -S(d9f8bde9,8bb83348,33783e9c,5d8ce8a7,85b9e335,6921bebf,281c97d7,bd000fe8,59d46892,a3d604fc,a378aad4,9645c747,2ecfae56,8b362e15,c0acb755,af7103c), -S(617f21e3,af5d65a3,a504fe95,34ce6bcf,71384bda,272ca49a,1c36ea32,d367c4d6,daf8e0b0,4bed8f7c,2d8ae9b6,afed54c0,904c6010,9d0c07ad,5f57178d,2cc037b3), -S(e1bbf189,83052820,ae65ac4f,e5a6d4ee,5b57c3b4,c0b2cc06,9f84b25,adccfdfb,3cd52ced,d7f04a93,86f4845c,49af86e2,c3a86984,fc4c77f1,3200017,ea68deb6), -S(83f82dc,7c709587,b883f1c9,e6cece13,2cd510bf,3664aa79,220892e5,dc2dc8c0,24c2a1f4,7c4b96f2,86265605,d9348dcf,8261737,56c5d91e,2d1beb4a,a857525c), -S(5ccbc6ff,c4362b4e,3d3a72a0,76ecdde1,1c1b07f2,680ac16d,63cca8ed,df924085,d54095ae,f357dbd9,5c12ad03,78f428c4,beaf44eb,23724fb6,cd0726cd,e1f04fb7), -S(c83a798d,c8b1ff5e,41ce6563,f35e741c,a6020a80,319b5543,1f81726,818307b6,c9cbf8a4,747baee8,2e156cf0,4b0d7762,2638e8da,7731f4ff,60bb9ad5,62b7588f), -S(c15d6466,c7f0bfb9,ab8a0013,300dc6a0,aad45c60,c2fcfbf6,7c9ca24d,7d2a21dd,cd5682ea,b41b707d,9b787315,8b4e347a,7ae682a3,cb950e1d,abad3b0,c8c42bbf), -S(e9606086,63b9bbe4,35826c1f,3830dfb9,f8479216,5c57f28b,9fd28d5,7a277a0,37fb1f6a,6d3cee79,ee2eca6d,c499fcb9,e2896942,f17fe885,25d2d57b,11c8a198), -S(f8a3fb79,afc8a94d,d69998a0,f4889dec,200b4b72,d2900c75,59371ee4,412df0d5,d5e0f5db,b4281cb2,ce21fb09,9176362,90351fdd,5961db25,ab677dcf,d4fbc0cc), -S(17f3cc7c,64540e31,ac6db6b4,ae67d100,46b7665,450cc011,dbb558a8,56a59b2e,9d815416,553ba751,79955382,12e988d0,eb0e0493,f880c217,5b90f423,5763b624), -S(6656be68,bf528239,51d7a392,ef22b258,42fb0646,8908fa1e,fd91d89e,a54f6150,741d5373,7da163c5,3e160d5c,b3f9f118,273c59af,75aec2da,bf788e8e,e870cb69), -S(67ec8648,83ad9ca4,22fb181a,2235ee66,cdb74f0b,f8e5b808,c37ee314,35598cf0,8da1ae29,4f37153c,1ad165b4,474a8f91,e7bdae4b,54b227c6,57e2d3ab,f3bf3fb9), -S(c9e8a673,3680fd41,83005ad6,97c78a4f,abd5d048,1f9bcaa,7c8eb209,68240412,fbad52cc,a0e510d5,e5c813d8,13ba4559,716e0787,4f48c20a,f783a807,c1848eae), -S(dc11b6a8,9c6b324a,f2d67e4e,9f59f32f,8898dbdb,d612f157,e0f24cee,d2709dc9,8c20a8a3,c273c882,fc6a59cf,ce74f115,1d0421d4,bc84a11f,2def142c,f2a8b080), -S(c5ec365f,7c0aa7e1,94fb5a90,ccf8fe3b,3c90e413,f3b24947,d8246024,7a2cc2d1,c5b39d08,b23bb1a9,c5886e51,abd1fb2f,d55ff334,81f020d0,6796d978,8801de79), -S(fcc03866,bfbe3215,9cffee9e,bd6874bf,10a5055a,5e56826b,37322559,5381650c,99cd7d3e,66e65f1e,5eea297b,f957c699,b844cc35,cd19dcdb,2d3a5653,f45b59e4), -S(7c96526,7ade46e5,693ecf09,cb052ae8,2a4bbcac,d07f136d,86df45c5,bf20521,db8e1dd7,3c961137,23325d6b,fb728dc8,f0a85141,ad1a00f9,53100aa1,5519d444), -S(39d11c0b,2169d3fe,4b5001b5,a8da1fe3,a7b14ae4,e329b931,f7db92d,86acd02b,46fe1f3,65805c5c,3b731dcc,d46ad37,1c2fb6f3,b446e466,ab80aaa2,5200302e), -S(3acaa37c,4acb28b5,6af7f970,ce279372,d2b998e8,5ef20932,492ba5b1,7b79240d,6effcb72,4a7c7dd8,b8bea6ca,322a8540,f38cc5df,a06677c,181c45d8,c4e4a4f2), -S(fb631a1e,25daa546,47492d26,fafddec,6f38c08e,e67e67d,af1c57f3,ac3ac79d,90b04e04,c685e4bd,4817c367,22892881,fbec8c09,1e5aaaa9,7fd6a163,b68f2eac), -S(3edc2ef,2c609f0a,c77ec4c8,c035a537,3d4ec7e9,6addfd7e,87f040d2,df98aaea,7e549063,ba715cd6,35719b86,c0b6eb30,68a71420,7f480f93,6d78f0a8,d9251d20), -S(bd4f2218,7a9f5164,a864dce0,2bd1a89f,d283e62,64255b0b,21d2f6f2,62fc419b,d5eb78a9,d2337e68,3e3a77ae,b37b170e,69f1400a,2383b339,64dc6726,7c5db5e1), -S(434d9881,70badfd9,5ab26ab,90933eb8,89bc6a88,60e6f412,1e5dee2a,f82341e8,c6af879,cbd7d5dd,16c3b06c,810d0263,2853986c,ffb11fd3,aa2be2ad,db55c4e1), -S(9633c8b0,653d8010,e785ecb3,d710b43c,37ddd97b,20f26c4,f9f41581,cdbd991c,13b53adf,b4841e2a,2590609b,46b604aa,3bd6e758,4d443db1,6a7ada9f,9a49fb71), -S(ba656a98,c63d18f0,c4aff8da,3bf05cf3,e3781cbe,db5d9083,a8828fa0,c2fbabfb,90ad3738,f28fa937,cd4149d7,90f8b4a6,d4989c5,5218023f,37742c3f,1814896d), -S(cca5c935,ad4a690d,893b3bb9,cdaf2e6,102c44da,d9446615,2a39206d,777ca72,3c060ba8,b14da1ad,41991c64,95e14465,9361c724,d895a0d3,a3694d45,56c7a146), -S(b22a22de,c827e8a6,dc630b1f,11229bf7,ce8a5030,608392e9,b03093cf,47afb358,b10c49a1,4b30449c,200bca1c,4a0f3df6,7d978988,1be46597,c1e5334d,5b5a2e4e), -S(b4253d47,beae6a36,1dc45090,c358275f,fb8e0696,11e51b3a,1aa7c2f5,273ef8f8,c0f4bbbd,e98d0960,f9a59809,83d8c4d1,35eff1c9,2ddc9f2a,6ee05146,eadec66b), -S(60d75d74,1a85d65,b9edd2de,8a03f6a5,5ac6d000,d39ca913,9fdbcc47,fc3da6e0,fb138bcc,da55de59,d496b784,9532d99f,44935e6c,b08be8dc,beefbb7d,74e1fe7f), -S(ec63d10,e66db9a3,7cb5b88d,811f2f6e,aecf51a9,e39374ae,92df325a,aa560a85,1066615c,d2fe8397,d2dd458a,f6ff36fb,60547398,29e6d6bc,74525c29,8c3d3c53), -S(8df7f52c,8324b50c,fac3e27f,6f230e9e,e4926895,c8f2785f,560ba5ca,98b9feb9,6832846c,a78a18ad,3747b1fb,d8cb6a94,fb3b4977,3db3c0b0,c873507e,f1519480), -S(f17e21f8,e97bce5c,2e63285a,f9e361c9,4a2e6b45,f437c1c1,a1310988,b63ea49f,12690d42,bb90b05,2fa4b1d7,d517f7bd,f6721a82,e0a9059d,caa5ed15,a7acf7b0), -S(4b0e0297,729ceb7c,4c6a4caa,73d76ee5,9d8f8547,9f582fa8,ec678339,58c023af,73f6affd,3afe58da,5ba3e0c0,9a043e8d,100f1275,dd9b9dfd,42ef4f47,a1aae067), -S(203174f8,fe8427ab,42bb517e,67e9c13a,3a39700a,158c3581,a0c5bf76,79f950a6,ac630f01,6b268772,72e422cf,b74a3a1e,dd1f581d,bcf2a1a0,54946a15,108c70bb), -S(ac34d445,cfa711d3,fa7a8c5c,bff5206d,d6dbd22e,737c5b21,6e6801ca,362c4b35,91a0a6aa,fbeeda5c,abeefb76,f1bd4b23,e850e1a3,9886344b,282dd0a7,f0b6985c), -S(81ffda88,a45f8b82,e3e249a7,457fd1bb,34ebd35,58619855,6ff7ecce,73dc7998,eeeb1a42,125877fb,640b160e,4930ba7,3f1e22cb,51e33946,3935787b,5d6e353b), -S(1a281d34,5b4f227f,2a6d4139,db2e29a5,7493b1e7,f099edca,ef68b3d7,dde37dc6,63baaccb,8a5c1de9,f1aa33bd,2fc19189,619a71e3,f9b290c,83fe7643,bcbfcd25), -S(ed9042d9,ad110ff0,6be64aa4,cae0422e,c9a8aa79,4dddc1fc,52df6098,8de1ffe3,9ede1c43,5d6b8a7f,61591d37,e166485,3071c894,f18f85d3,d8f145ce,98208b95), -S(1f5b14e6,1453557e,f3ccc7a0,1e2864ef,43dac2c1,ce737ba3,ffefdf2a,3de9622a,c0d40622,5a4f8b24,59ae2d22,69908c81,5f901125,1e46a683,3df83659,f2a474e4), -S(218e8943,96fa8e79,2f29b53a,de2f9155,94d95a50,1eb1a1a7,c8b01b32,75e8c117,2701de34,af2aa192,79dfc9fb,391532e7,56824da0,38c60624,3771dfe5,aeabbb96), -S(d6ec122d,463c0f2d,a994bc46,a968693b,f282ad19,6a6471f7,6516b5d9,2fea7303,57f84e4e,9d439701,19f58c6d,426265c1,25734ed7,c10db0e8,e5b87ebd,d584981e), -S(3ffb48a5,58fd6f85,b1609710,1be54107,6182a7f5,a5692074,48d82dd3,e8027e40,aa410f17,7c08cf25,a7a9e9eb,33f2b83f,c83989fe,7a737e23,e0aec6a,6eae2ca5), -S(c8c69bfa,450cbd11,6dd51750,a5fb2f0b,59b4f489,cf05c670,91a49f13,3963a50b,879d8a2f,a1c26933,5719a389,d504ebb5,498318c7,acf103ee,348d27e,cf83886e), -S(86097033,ad0a0d7a,982e748c,bce06089,2c6b55a0,17bbcdc9,d26166cd,b0fc1e81,9fcdd6e5,17916ee5,ffa48a50,a0df8ff,98a06,82059d92,43a2194f,fc89dec6), -S(37cd256b,7502a789,10296144,bd41ade8,f4a158e7,68b6ed2,723d3e57,cc5bd099,5eef9bfa,6e5e1bab,8d8170c6,2ad90725,afc38eb0,db145f59,35520a7b,7518dff6), -S(70aede0e,f89ea93b,702fd3b9,4f81a48e,aa36cfbf,f4775426,37b0d00a,80abede8,b30aab37,206b8c1c,2f852ed8,348cd387,d676f6e1,2baf457b,97fc49d6,91490f33), -S(2504fac6,acad5f23,81cdfa76,65fd1859,85e3b32d,d1767394,85d63f07,500c963e,7a455f78,9cfdc25f,d6ef9c01,8e44e6cd,2702ee9b,fbbad8a6,7ee228f3,fbc56d61), -S(b8bab480,d143bcd1,838f7f2,d13b7a54,8f7302a6,14c03cf1,3e4fa971,5478c280,8d1939f3,abd45a47,686be62b,7c079fe1,2cd2a3d6,78478afb,d21327e1,3599611b), -S(19370ea2,2e6937c8,b7d600e8,cfee9b54,e1b527d0,85d3a17b,ea2daf7f,2e6a410,c721f3ea,af20344f,98692ae1,b88c7ce1,8655a4a5,9c2c945b,aeab2756,a5ea546), -S(5e19f6c5,10bb512a,798fe39b,cb37ea2c,da70c76e,d7d1c828,9b488e9b,84ea224,ab34bc16,50a99345,772aabb7,f47f0b2,f92fdfdc,4ce7c9b4,f5bc14f,5b946b39), -S(e97888a,cd62f21e,76f5247e,fe64291c,e69b8b1c,b331a2c8,292bca63,f3dde54e,286dded8,ec435a9,2155fc1f,18688e5,e69ae21d,eff79a6d,c534e18c,3e7b114a), -S(4361dc3f,9c039f2f,750e4172,88ba8d7,36158f28,d5e0869d,44207ef,f587a8d,b05b54bd,2097d8dc,c7ded5ea,ac07e6ac,a7974500,8337891f,4b5d6c71,672cf759), -S(8e679eec,8bf365e,e5324330,3437dccb,768a3955,3c3135fd,3c168109,5ecacce4,b6dd115c,d19ecde8,4e7a2fae,be358448,3d6277d1,19ca2aa8,3bb68ae7,f5e94f49), -S(e2d80539,947ebd32,8716ce6c,74e5f09d,eabcf539,2e84dfd1,2e33219f,de8b77ec,d4515668,586e8753,74406b32,65c9727f,92e71263,b0f77447,14de6f0e,732fd175), -S(a2527f0,c754ac94,29bb5dc6,18efc820,d88c8490,df39cf13,a25b0136,37196f9d,bd16d989,90676eb4,36e735df,94a5a5d2,28aa4185,24766ae3,2c7bb12a,e9aa0508), -S(bfa67870,6db9cf88,139ce56c,4f5165c8,38a5830,d1673a9e,b4b0a218,a3a66319,f6eb6944,dd30d6af,a360a7cd,b360f58a,c17dbe8a,7eaeda38,f3b1eb2d,83c02e0c), -S(1d5bf7c9,9255f96d,b91a0f5d,82a3119d,f3d491b6,859f55c5,59389e90,a2f533e0,132b1468,f460932d,7e0ec514,8ba77405,8b8cd4d,3e47acac,e52ec9fa,618139db), -S(44f90837,9b8aba17,44415980,aec15cfb,4edbbe4a,23ce6885,9e4ba880,8a67025e,9c4f9d97,6f1581ac,29818a6c,58c70ad9,ebb08f3e,83dc1b3f,667528bc,3a1968c8), -S(f100be57,1d4ddee5,291e7123,cab57bd5,c5ecb8ca,6c8a90c4,d2f01f73,87b175f,8899a16e,3a7ad5ff,f0e3aba5,fea86e1,974dac4,d736be38,6c2ad93,8020a6dc), -S(e26927c2,f3cce898,33a60369,2513aec4,ad0d8f63,2bdceafa,e5f6900c,716be2bc,c1154830,52dc4674,238758c7,d7af495a,f32a4d01,e0c316ad,301606b8,d3136383), -S(e3a3fcc9,8fcf1ce8,fb994b68,f92b2fc3,c114f2cf,321e89a,c3ba7886,43b0f2f5,214f38cb,7020f57,ca4bd953,16960c9a,250feb38,7519bfa4,abe025aa,dddd072e), -S(59ec03fc,5195e0d4,a8df03b6,a96938bb,d5fa5a40,161f5ce,2480e205,dfc0dc3e,71421a9c,b58aa65e,180c97e7,6a90454e,d5d8a2f7,739eeb09,be7fdd80,47a4ecb8), -S(a53cb7d9,3dadccdf,18d4d01c,6217f39a,be621089,821aa92,362db85e,71cfa358,1f989a47,77a2837b,f797c249,4539069c,a24a23aa,8f1e5b35,fc401dec,69d049c0), -S(170b9efa,13e1c948,a5ea39ac,e688408c,1cb2a57a,a55aee52,e4fb21ff,2f7329cd,f092c60d,c4f8492f,d718aa74,fded9cea,426b4,7277d724,710ac0d,53ba7039), -S(e1d16c75,893035c0,63eb41c8,36bb8bcb,770f752b,718a02ad,24e688da,79ac3a14,2d58df,7b7bf0f1,60a091f1,b0b209bd,ce5516d4,53f8b799,5707721c,66ed2681), -S(d45a1024,78595ac1,abd9a582,a3afdd8c,5d33c7d4,caedef2c,747450a0,fd2d675c,8faa7ee4,3923474,12012dc8,cca109b3,dd19efc,52ae73b7,508b23e7,1826732), -S(d3f355bb,b2ecfa66,592ef13e,fe983e22,b2b90538,ee2f0aab,ee1fe982,62c336cd,ee99b839,7d4b97cf,a7851de9,366d24d3,70169091,81b5a10a,50fd53ef,bf549812), -S(6ea90fb4,e58f1eb6,f27dfba2,acd645b1,1c7cdb0c,dabf2d49,4fdbb4f0,8ced2c56,74934a84,871dc011,3e18d5a0,aa3207a5,e588a3cb,e8a3f350,4a06bb73,8ef93abd), -S(de4eff0a,ccb612a9,a79d0983,94e8a883,da348aad,74bbbea7,d477e45,c2b87436,9b30581f,b903cfe7,610429f9,f6ec1ba0,df63038d,db8117ae,ec67d7e4,1a28b9b), -S(4ba09b19,f129b3f8,db86d780,4630c6fd,9c22d620,677c66db,ce60b69c,c3bb4772,fb31e85,ce50ea1c,13af1c7e,93d9026c,e5f39474,9e91d049,1b459970,c169aa77), -S(7fb3c3ee,7c600ca7,6a2bc674,a497bfd6,67b0124c,f532d5e8,55aa2c90,c4b4826b,29b970bc,b8f5eaa1,616f3695,5a1b17c6,60b15b1,219388a6,b47a55fe,6cad1eb0), -S(ac29cbb5,dd2a95ea,5a3b6f57,8c2111a7,6bf2b060,267b467d,5ee8ed2e,554153dc,89d4c22e,acee2b3e,7e7872d6,5d1daa52,54a1a00a,f6b0f7ee,16d84477,45d01c81), -S(fe956021,e67458aa,c6fe2cea,730f272b,19fe7de9,18c98a40,ba475dca,af3142ad,52c6b42d,6fc03eaa,3ec7da94,5ed12ea3,84e16d0,590840df,6b714a59,d4bb814b), -S(336491e1,dc3fd4,8d63944b,2578a415,5727daa9,6e853935,a77b7077,d61984da,e9b8db61,51fe90fc,9bfc0635,5b9676f2,cecd1321,292d2a8,c6e30e9e,6b1478c6), -S(245c6818,aab65e40,806f8cb7,721b7dd8,b0e3854b,7daeff8b,da5827b6,4d294df1,4fc22df2,e7b93b96,b60f2ce1,a659c1ab,1a06c7be,18e5c80c,91e4dd2d,75bd8ec), -S(8c89eac1,d9ca6c06,8229986d,6d22bc3c,817dbb6c,575ff654,36653101,1a60de8d,ebcd4867,323bcc7,f8dba216,4d827a48,8b4763cd,aef0daf2,5a1c1437,d6379ce5), -S(afdaa93d,7ea7f666,e737a379,914d1b87,6899cd9d,5202e985,e365d75b,806453aa,e3e9116e,8abf33b7,ad036291,2a3dd016,2aadd1ac,902a9448,30248a60,6760cdac), -S(d447b974,fcecfa15,1fcf7ed9,8762283,7ae28f74,be8a2a2e,22c3bbf1,d9b23071,a3e79560,f79524a2,e206e9b4,1cf961c6,8f6f898d,43694114,a3f89495,6ecf970d), -S(53525693,be8fe724,c970f4c4,2b46141b,321e79a,4ffa411a,5d947bee,ac235674,5cc74ddd,7a74afe,2026885,1fe180c8,dac3246f,8c4ba44,2032d584,8afa9f4c), -S(40e60cea,6008aaf9,fee64781,b5adeb9b,f23d2db5,94f9fad,b7394481,da971273,fa32f2db,263c1f7c,987671f5,68c714dc,9d3ecca1,2b20655,2b23e5cf,8a365b65), -S(de59a6fe,1fff672a,c4655e87,f6440e4c,bfec2fc9,135f1049,efe173fd,d666acaf,205e5ac0,8cb9c3f9,9023b6d6,795488e0,61ea691,439a22f6,48bf0da7,cccccde3), -S(89f718d0,23f80ba,df0625ea,260f6ca6,dcf8fcf6,e79d35ec,67e535b5,e9cd06a8,6acf9bad,6dcc053c,f7e193d1,a4c432f5,32211761,aeffbb4d,1d53d737,6b3353a3), -S(fcd5af97,603e0558,76f24ab2,eb82de83,3c8cae9a,f19ed307,f7da1da3,f1fdac3c,3b7ea3fe,bda44592,abe9240b,8b06cea4,3a8a0ab8,aa862c85,36a17b18,fc911ab2), -S(208419aa,670256d7,94712f59,bedfe025,ad9ab43b,2037783,4e4c8f4e,9473d6af,b6171d6a,20da4ffe,f46a49ae,7233206f,d9ce1ebf,89ba01ed,9b86896e,43c9fac7), -S(d7ca0446,88d411ca,c3f3acf8,1bc3f3e0,a9feb9ef,94bf31d7,8a15563,cdfaece,3a361b1b,2ab89d27,6e120d38,7c31f97f,c4d5880c,6ace1813,b4eb95fc,37db069e), -S(30b96bd4,b284e36a,f790695a,e2c8aac7,672a0496,2f9c92f9,694780d3,92b60bc0,6e2c7f8e,d1e0d081,a34ea062,591e1854,6f79a9c,60daf218,6513e4e2,621d4852), -S(5ca0493c,3d516b44,46723477,fe8359d5,6a2e01b7,28afdca1,343de88e,92411590,60bd34f8,7d4bc12d,4179da44,3595b48c,17f34f19,b03750a4,6904a242,93af0e93), -S(de3486eb,22faa1c9,ccf774f0,e17da3ef,3ab5f7a5,ed6ba58e,bfaa2c1f,cb5c0e58,af8666d7,57c13f3d,3c2e6b02,1dad5ee1,ee4f4c82,97960b5e,84135309,4188936d), -S(8075138d,59a9cee9,5320cf41,cfad010d,90efff9b,ad50f2d,dd3ac7d9,234b4576,ea48ad8a,6a8ab6d3,5cea84ea,365b6a33,d3d593ca,9d27c5be,2df2907f,8bc5d91c), -S(5328a0d7,17f0c7d7,9b8838a,abcb0875,77eba66,eeac756a,6a365657,d4d710ab,7f33d5ca,84206a66,a9aba1,2dad6805,9aede27e,2b38d755,53756d14,9b4b5a1), -S(9fecd234,d25771f0,aee9dfa3,2286697b,faf4d34f,83eb7135,a581b225,791ce0e5,3e364215,d2eec5a3,632f01f9,9699255b,e90303c8,eeb0e8b7,56cc239,20b2dae0), -S(7084b279,e89d0f23,967a1635,96a1090c,4264504b,c2895b07,fae5f128,93150c02,481d6078,35628b54,783484e4,d4f299cc,fa3e6f5,bad67457,1037797f,b3fb7f96), -S(bbd3583e,8b7ce417,88cc23e4,eb0c331d,c8970d1b,7b186ee8,9b4cf45,c83686e5,f94d7cd4,392a9589,77ab3956,a91024fb,b77a608e,91147a6b,4be6cafa,69b9193c)}, -{S(a707efc4,89165c75,7edcea3c,ce729b44,91f04142,3fc6ea9a,704f52df,c8a0650,f2e7657c,6c618494,c01c5a90,d06b625b,c9416d63,f7b8f809,dda5076f,74fa2c92), -S(8282d8a0,cb008916,33654a11,fbfe16e,8d2dae0f,ca06175a,5183ebd,de06ec8f,44128945,d39e1b71,cbc914a6,21c95329,b6ac0b45,1f1921f9,725ff10a,2859af90), -S(100ee34d,993a06d0,cdcfeab6,3eadde22,7be8aa84,a9458fee,61448911,1bffe20c,c891d347,c63acb,c72a2a8f,c0d8d41c,2c32a9eb,5742ab35,e76b573b,3817b9ae), -S(9bed0413,465a899f,37770b6d,6e847223,28049001,73efb872,aacf122d,4eb12f1f,745eb015,938e3ce6,d38068f8,90ad253a,b0b1bde2,de636162,c0442b66,6e9e1e61), -S(2896ee21,34276bc0,131a10aa,5b0c9b39,ab5aca5a,3ceed61,cf2d27a7,5404d264,cc51d26e,ad555071,e57bf3e2,dafd77db,4f58b6ee,b844ea86,5da39b09,ef3ecc6f), -S(b95886c6,e569d641,b8e32555,bbaa562e,1f07589c,5a8f3810,d4bfeb4f,e58711f1,3fe1536d,551770a4,cd816eb6,46f2b864,77d565ff,3091d916,af8597e2,d8988b6c), -S(b32e3e0a,3ca6518b,6bdb2a9a,e3471248,5387cc5c,ffa32cca,976be3d7,ebdbf1a1,45d998f2,828248fb,2f97b503,8de02b38,493f5b62,ab8b0d7e,75cb96f3,305680f4), -S(8a760935,8c3682b2,fe8f5b8e,a9c76c61,f66ae677,48294bed,9d3c64d,702d3c47,77110a33,eb7562e7,95032a0f,5027d162,28131575,323c8f9,8aa0bcd0,9328992e), -S(ef709552,f80148fa,dc1f7007,174bfd85,81b03db8,189ca3da,96b3e749,b1843ed2,b8e9393e,c3cba6ac,2cdd2d04,6235f7cf,14965616,3722225b,9010727d,94b610eb), -S(5071af8d,2e37c4d8,11225f8c,543863f2,3d5ddfff,be2576ca,42630f38,1b967483,37248038,487113f2,74ad07fa,7dee36bd,295971d7,3a30cc58,629dfc68,cf65533e), -S(88c9a5f0,e76871dd,3afc4ef4,5643419,95642dd5,c8b1e386,b71c2471,c591a3a4,a77afc95,71af8ce7,60148b15,1e1fcdbe,c48d3b2e,580b9786,9d80196,2ce6549b), -S(fe643b36,a0ef4165,e591345b,5963d37,632c8fb8,97114b60,c4ba6f6d,c07f9033,e3c7bc7b,865c1d,4c496f36,9a79e6f7,1f79f6,e6929f26,63615855,e9509ef4), -S(d35bb10a,a23d2bc4,d2aecca7,51f1cb24,2133fc16,9f008ce3,4a29b93c,7ad21f3c,57265f67,dec367a,7addd6c3,fb23fde,f04f42f9,a291e291,3f2128cf,df041f07), -S(e3c8d76d,1ff5e0c0,21668bb8,f425487f,b7bd3a3c,eb3df289,5e4806b4,177fedcc,abbca449,95abb588,3e0a6959,6c8108c4,ddf8a50f,6c43e507,59f85556,be49efc4), -S(b7e31e11,cebd568f,658eadf7,ac57f265,fc94073c,9a779f21,5016e5fd,705f2580,da4dc770,742cc6e7,38d05ecc,6deca283,9c06125f,bb911cb6,16f0fedc,84dc2815), -S(bc486422,ae3e277a,d24fe096,120decbc,4a735e57,8bdd72a4,b3f9006a,859276d5,ac246a6e,a145a990,51c62762,dcc47fc9,ea9bf93e,7bccffd6,c82228e0,49686165), -S(79d0a8d,61039dbd,1787b140,9d8109f,3832112a,8e1ae97a,346ba122,c9f66eaf,9bccd3e9,b9b2c673,c465fed7,b774bfd1,833621e6,87727a5f,a8959528,9ee034), -S(c58bdd36,646e3dd2,ae3ab0d8,8c9b352d,c319d1de,c132493d,11f2942d,1f7592b7,ab923ba0,2cbb4bf4,35212358,66b0a420,41677486,3d67cac7,ec5e891e,b2415f6c), -S(3865f065,42ea6eb2,a0741658,5afce76f,d87646bc,a086ea6f,5838e9c6,55171a85,8c7b87af,c049de66,8578c89b,e5a49c85,64ab35b7,afa39588,6312d680,837415b4), -S(10c1b93d,f7ef0d97,4583889,d07b7680,b6ec858d,b45f9a2b,c36a2f68,9d77a4d8,3ac497e9,15b7470a,f9bd9c43,1ef3741e,b61cf7cf,a2e7fd3f,e1886fa9,4211ae45), -S(1ecd15e7,3905fd66,a86a96fb,16118d4c,a6da82d7,672f2361,fd101a3c,7203c90e,4974d5e5,9b8ce7fe,30671eb1,7bcd4d04,97c57b78,a4202261,28eea45e,b3b8131b), -S(808fa8cb,40e6440f,ab60ef45,65caadc8,f86618cd,e1c0d900,587dea31,f49a589,511ccd1f,ee3a53f1,bd12f1d1,13098694,34579292,74d13973,b0aa29e6,91d889c3), -S(e1035b36,290782dc,9e578522,ba51aea0,6621e7fe,8d5cc9ba,af0d131,ee00a6cb,ff12d04f,1d5c1bfd,859178e4,368a3a0a,f73e125d,35049e60,342186c6,ded5a753), -S(daba0ff7,a9f3cf3a,2f05cae5,b2c6a881,ff9ad5ad,9dc1f853,ebac7384,5a48e230,d4ae471e,2ebfbe0e,dde343a7,83d9fbfb,87c3d179,c72da83b,8524479e,19bc23d8), -S(106e3bdb,beade62,e8ec777,bc4044ef,c6a04d9a,5a3b5396,44ff98a4,33c94b92,1d461e65,eb1bc8f4,d3aa5773,a5cfef37,2e55dc46,45f8be3d,f53adfee,6e7e7d75), -S(82424b42,7b95dd6f,5c9bec59,b1ab98b0,c7fdb4dc,fcd1f8d8,574f4b89,6c8d359f,aedc4fba,825c48c7,4c466738,1cddd6d2,75748661,89499c96,297829c6,27945de6), -S(71213056,13ba1e9b,8b8e6727,74b718bb,2cea1e65,ac944db1,9050f9be,e6c90c84,98c54a0b,8f0a6d3,d7e821b5,907ac930,b79e683a,3ec49a39,f5043d28,acae4144), -S(6dc2c201,78620ac5,d99cb81,8474e5e,de8ec3ac,2366bb8a,19685ece,bde25a8f,2f1dc21b,abc65601,fc706aec,50b9aecd,954bf039,e3b066a0,54fca082,287b026d), -S(e7239283,2f6a23ce,252e2493,5726a774,497319c0,9f0fd327,59fb594c,6d9c8257,165dfcdf,2b117b5b,73bc5096,26b47ea7,c8d5b8f0,24beb2db,bc0f993c,d30418c), -S(5d44ef96,eb90df1f,488375e2,a3e75459,34169a9f,5bdc7477,bb7d1bc5,1b3f4ef3,87da9f1e,3346fbfc,6372637f,da5c1e13,eb561d61,ecc68e03,8167eb82,d2d05bda), -S(bbd86c11,dce2eb2e,d7424033,aff54543,2f2aed92,5b433436,f93ad8fb,57816732,f415eb1b,e921aa07,6b7b52bc,773c7e9c,f89ef076,95aa86df,92f4b72,38507c8c), -S(633050b7,3000259c,42bb380d,815b2219,14e78d79,e2a7d979,29ca8ad9,cdc40fdb,efe2db3b,16d1c829,ba0add4a,c07e7ad5,f021ba2c,9e53ff12,c93a9c36,4021779a), -S(70c4392e,d4a1652b,ff89db4d,6b1eaee8,870e1957,f98f0271,d7fb430a,85c76bcf,4d0917aa,96368ba,45a567f7,c05505d6,a349faf4,b51c06a5,848bb8d2,1fd80f0a), -S(7abb4651,6baa8c3c,47fe60f3,6ac3f91e,92d6e09c,cb8401a,a2a3095e,107df5c1,d8445036,8eb5e86c,37ba9b12,f812ba0f,f88d166f,fd1ebd98,67632a24,8eb9f388), -S(65c27141,24444b72,188eb222,650e99cd,13ae852f,e515d452,eb757225,17f63fd5,5bda906b,e1dacf0d,e65e66c3,23ad6dab,15582561,ec4faf17,35de87e4,a53ae7c5), -S(416ebda3,baf7eba2,877f312c,f86c6517,9f422d8b,8379fe9f,29b5115d,f1ec3364,ac46579d,ee0a19,bc5d3749,142f42db,6e934f90,eae78e80,d96df9e8,f932907e), -S(3d94add2,7a320b3b,da7f03ed,ae29d1d9,cf022b47,b7a0ea03,6081117e,60cbebf3,8fc54299,9bd420e,96f464c,8c3a56bb,2f1719e1,20eedd6b,37084251,f406206e), -S(4f0a9e32,76447fe9,2fb48cfc,c962a0b7,b7c391fe,16c41c8b,21a6e563,53d7c218,441e9d39,db107e8d,d8f0a99e,cf791c,2fbb37e3,2ce1d821,9011a8c1,60345bba), -S(17165596,c15ddb64,83b4d45e,8be57fe1,2a37da06,a47ad7d3,a190e88a,9d58e0f8,ed06f5d3,167dc12a,992dee28,ef331ee,443f6c9b,7e485386,7a2f4daf,c0aaf64a), -S(62f6ad56,5d8c3ede,f50452cb,4af3866a,9b40b729,ff1b66bb,c566ce9b,b07b37dd,b790cec2,a2fe6264,5913b5f8,4e2f2ab3,bb45537e,e7783908,1d8928a7,484ff315), -S(c3b43bbc,522390ec,353a2a4e,47e04008,475731d,1fb4c67e,f91eaa49,8553d857,82e45f4c,81adc79d,5a7af4ab,36cd2628,416f1229,994d6e69,d260734e,55d02eba), -S(3a943612,ee8e0359,4559290a,7d55a549,f8173b03,b04cf28e,8abcedec,38c5a81b,d63e8faf,90666215,5f74a6f7,6509be2b,c5aa2b83,b75b18b6,1c1da05d,f6c55ad3), -S(5f2291b3,1aee7ded,21c3f1a6,77e53e7b,e101be5d,a4fc29f2,680cdda2,fcd94be,fc0b1162,7dac2084,c5ad479c,671564f2,b2b13e60,f101af4b,5e7959a6,70b1fa0f), -S(4ca0b91f,9c0cafd5,b9f577b9,f1b84515,70b0521,6a4f0c9d,77c6c106,99c1036f,b254845d,cfd558f5,11d5125c,68f1d65e,7e3bb173,bdde887f,d9b48718,b45d9521), -S(6ef57d2f,6f1eaa88,afba085a,d5882c4,4d823f74,f65d16f5,4bad3bc6,940d9985,52f44465,be358f70,3d0fc3cc,3c3373e5,56be7d9b,6b0486b7,6daa8519,f2ab521), -S(dcac3acc,a1fe2f5d,e231a6ad,74da4a52,7ebbd474,d3742cc7,8f0ef74,172017fc,e0b7be39,4d422b45,be66848d,b8fb6d9d,25ece5f9,28d2b97f,db0a491e,145d0340), -S(da9601c,352fae24,9d92bcf0,6403a08f,5b85ba77,a26dd30e,851027d2,f2def143,2bbf855f,996b6358,30481f7e,794c993c,e8e5afa4,6482602c,f12ee666,ca5d24f), -S(c1f8edb3,fdda602d,ad4a53d6,5e1be6ed,cfbbed8f,12e593f3,470d0485,e4c4a3b9,51003ac7,1cda53be,7be5c073,e530da8a,551d69ac,ee40faba,90cf5c20,824f28e2), -S(71ee3721,ce03cc75,27c837cd,88018278,f2a6f05e,a70b2b4f,323f9fd8,1f8a8bd6,8a9e0467,a7ccac5a,f5adda8d,7380c84b,80575e31,90335247,41abdb94,c1fec726), -S(eb5604af,d835b055,ed67f5b1,fbc145c7,d04f8ad5,f056f13d,2166e6a1,c2eb8c98,85ff6263,314129bc,1902d56c,f76395ca,9d70ff24,2bcb8a0a,b612d46a,b6b2ef3), -S(7cd7eb9f,5edc9246,e33d0734,e2c63c09,f23fce37,cd6c084d,c5d370f1,42f58f21,50485ab7,7ee6dcc6,4d1291fe,b08fd861,f954f35b,1f64a4a6,ad4e30ba,5aeff269), -S(25674f3d,532dfc3c,10d33f39,215b9656,4ee87199,c86fb142,89ed917c,a557be9d,74d20685,274f832d,8406633c,29611fd5,f288fbff,15f6c9ef,e21b911,f26664f9), -S(106de86b,33c9c46c,f0846a80,89a6f140,1e614599,91191ea3,58b877f3,9c7c4e1d,7ab4fadf,4b78c6ca,3a11c0a1,4b47738c,2ea53040,73b3f4f6,7cdb7b9b,74ecf74f), -S(b901102c,4a27cb1d,bc8697d5,156c4efb,8f4a1eb6,7d1af30,28fe2094,5809a195,2fde128,5755900e,3d87ffac,c3fd368e,f84b284b,e30e6122,c518ec69,96b2b56a), -S(9b4d7f5d,5cc3b009,45bab53f,400e942e,6ee7a1f0,915db960,e3a319bb,2d573da3,81507aea,a3fbb6ea,75f42bd5,bc044ba6,60e89279,a0103ecf,2d99a03e,5fc447db), -S(806cb351,48bc2e18,c2261d6,22bd1113,ac9037e9,90318085,b9c46082,a19f9b83,187da40f,a8d49de8,5a6d2f66,831b8b33,5f575c39,c7c95eec,a9a30d17,dc03966d), -S(16633996,fd30bf59,f28de170,7ed7e8c0,95971754,ac04677,9e525b3c,9541be27,27ae75ff,ca485585,c6277177,7f727dd7,bce2cf00,205d9f49,43a74278,b8a361ce), -S(166f9fa0,b7930124,38912819,d2601bc7,e24b246b,9b19f53a,64f69f24,43c421b0,6289f5d7,ec71e262,822bf209,5855a7be,b2b248b6,2dbe3133,221e1ebb,84a3e7f7), -S(a656c927,7129451d,6ee2d455,9acb3c8,b15fc7ca,302adf2f,3b250a8a,499e13bd,b812bf3f,fc2d1777,6363227c,6ae339dd,39120131,187bbcad,2cf2f792,877a7993), -S(8e3275f3,4a20d2df,b236d99d,40a704b7,ff23eb63,2746767b,75e6a9e7,b78245c2,d2f08f58,55d400b,fb3f069,1124915e,547744dd,f0933f5e,c8e8e5a5,28236533), -S(9c53d1f,93b60aca,5f008d87,852a7425,c043e9e8,b0d337a,23304b51,bf763f10,460cca10,cc2768d6,8d19adb,c970d4ea,55a27d12,f2c0566a,6dd433b5,389e8059), -S(12fe0ee4,5cf521c0,a36ab1b8,970314bb,f0cfd20c,ac2eee26,bcae5b77,661fa370,6b75c75,103adb98,dae0fdac,e2b8e40,aa3eddf1,bff77d7,703ee2bc,c6eb0d4f), -S(2e317981,e91c4238,b5760ecb,90e4ddca,ddb18a97,2015eedd,30794744,dd859a40,33d11a2f,8c17c132,972a8a6c,3529a98c,50694b74,fc501db4,382f7423,772eaf76), -S(492b627c,d368c638,b9c13232,79bc34c8,f765b14,c54ce0bd,6ce655b7,20370a84,1650f188,b118104,9a18c474,a4e3fdfc,bd68f2fe,747c7cc5,fc45982a,e2533aca), -S(9c95a6c2,6684b3b4,e31d87f4,53918faa,a0d45e7b,45bf74e3,542038d3,a80a73fe,7992441d,5497a94a,14e2d0ca,acad069b,2b802584,ccc975b9,f895b8e6,58d8c580), -S(20a55d91,38623cbd,445b576,264b4129,8614bbfa,f1da06c6,c41d26b7,8639098b,a214ac95,fd6a325d,b26f0d1a,768d0168,c035568b,76758a38,a6f8feea,c8405b12), -S(813c3b1e,32812e27,27677a03,1bb3d63f,7562d127,8b62ab37,abbeebbb,51a9ddd9,13738be2,f0f657c,e6776e38,d40196ed,2dc669e2,1c281765,286830c1,4587ca2e), -S(bf197179,9e604d69,79b752f4,28e07c65,2b3727d6,837e140e,f812035c,4be106d3,8cfee411,1fd9a907,5bce32d5,54ebe54,892825fa,22b46af8,633a5ba6,d957cac5), -S(26f0847a,8e057fd9,9a625d21,df2e034d,960d610f,39b50c5b,a7398ea2,10a082db,ccd4008f,f47d05b4,47c98456,7fdbf173,fe3ca96e,596ca4d2,6dae40f9,f40d4fd), -S(716b7bfb,781d71d0,93182b2a,d72540e3,8c83a6dd,e6bd94ee,f2ae8995,1db45620,69497305,986fee26,2e2aec0,57e02e1,d396509b,7c3cea00,77d0c21,5101ee46), -S(6f6730d1,5f7377b9,6cdd97cd,91a4fc40,92539279,124bc3cf,c62bdfac,897e796,3c193854,3c7e5dd3,57ce219c,fb20d8a2,c87ec1e2,45381004,ebff0add,646fb0bb), -S(65f8ae3e,1365b723,fabed346,b3953fd1,463b1974,44972c2a,df37fa00,ab3337e,5acf164d,a3730a6c,125f9e2a,5416e7f2,a233ec0a,2c87f24a,a0cfbcfe,63f222c2), -S(b15b96c3,8bcb453c,756aafba,5726cac3,ee4b455b,ae346a79,87e42815,5758de8d,c7274128,ba2f8816,18540ee2,e9dc7de3,587b6a,ff76cccf,74dbe598,42cd691b), -S(804c9c6e,10622728,19159f49,eb579ec2,2e59cc8e,6504ba29,cf725469,3a3e60df,8f765c4f,f9a27d7a,415c918f,e501713e,20b67dcb,aeea39a2,c873a4d1,3c8d4dd5), -S(9754b3d6,438231f2,326ff09,da4554c,15888498,f2129ea2,931c3dea,341f33da,97c5eadf,adf25ec2,b3ee40b,3526a522,104a8d02,1028a5c5,57366571,e83ce032), -S(17721368,b5c35e0a,2a8ca72,f83c02eb,d1c006f3,5a3dfbe7,3adb134d,aebc69ef,b9ff7e6f,803294d3,71c72dcc,73e257b7,f2762f8f,ebc30af3,e0fa3a26,3732096b), -S(aa271646,f30cc43f,ab736d0b,2526a8fc,20318e53,785070de,35197dd1,bdbaa749,e6e4f4a8,d88785e4,de06845,714c5c31,d9c55e8b,dddc6a2e,4519555,15013462), -S(9a496db3,832fed07,8ef217ff,31ba0831,21376977,426e649,79609b23,9e5f96fb,6e37e2a2,3aabccab,452c0cdb,ed0a38ac,10e707bd,5858e9ca,610d74d7,5a4036f3), -S(c3c856b7,ed01305f,a067bf40,c78f1f4d,49af3ac2,963eebc8,94c5ce1b,13482630,956a1d62,fde75fd2,f9f0754f,f8f8041b,d8ba58d,6da21e47,39150268,5b1380d5), -S(94776b33,9b5f04b7,f3c6211c,cb925dd5,8945c761,b74df28a,79c58460,b49b9f52,97dc32ee,c164d32f,2e896312,ec07cd5a,dc51e89a,646a04ee,16bd0268,bebd08de), -S(2aa84c41,ac10c480,38c4b277,18145f87,15f992bf,ae4f8d82,1114b83b,c2fcd505,c9e4571e,be171081,cdea3858,c84999dc,e21cf638,6c03308,e9e5a36d,67e05aee), -S(5619b104,c7f5ff8e,7f3c9744,4457789,5e4fe608,b44147de,902226d2,14a614ac,73b45ac2,d6c678a8,636d68af,f00c1222,354958f9,e41b88c5,53480ecb,57a7bba5), -S(6ca32160,74987f30,c4542eae,f66abf56,2ae32531,7d70ba81,9bcf4a6c,56d29223,d81408c1,4e899b9f,62fb4648,77f5217f,9b32f028,f50be839,a1fda23e,3d6ddcad), -S(2b0de06c,802d4478,de84b508,f9c73a7b,8f6d4773,452e4599,dfc4f8d8,428ab718,805bb316,34a05f0b,919e998d,d3cc22e5,8fc684b5,371e6167,7f1e01d7,c162915f), -S(e4d4d1d4,bc074de4,884c510d,261096e4,ddb6206f,acd67c86,97f8846f,3ad11e41,aae414a1,40cd804,900653e3,1d92b947,efa2a206,f90a322b,8f8e4dd0,66667c61), -S(68c0473b,d83936ba,39f896e,ee7f6e7b,bece7d4f,77f3dc1a,32ddeadf,198df39,988095d8,e45a8ff5,ddd149fc,b8835bde,aa95a392,5ac1e282,5ef7c2b3,7b8bf708), -S(91f022c5,40ae514f,bbcb1400,67bcdcc8,d0846305,9676cfce,e5039e24,d4b52151,c57a96b1,f77156ec,88ced4f4,4401e955,10a00ad8,bfd828e6,4d9c3b52,b97325f3), -S(8e140056,3ab8bcf,a634adfc,bc9dd508,b49348d0,61d0c0c0,2b63e6f7,c56f08ea,754cf682,54a57e08,bf607155,cfa5ba1c,7cd56a1d,3edb7e82,8b9bd54d,f5f23d0a), -S(41f4e6a8,691d2e66,8efc8ad,aff3fa85,5d55f8a0,127990a6,27c33af,a2442d81,ffff7626,6d75962e,e49c042c,16086e89,13dae3c4,f75a78c3,77ce1856,ca49e3f9), -S(7d76b7eb,82d0e161,b1a97b9e,e39defe5,11d7c6dc,6fae0255,318d7bfe,5bdd197,86bad87a,21b0bff6,780eaaa3,6a30b7db,bafb4740,369841dd,da734af4,2815b2e7), -S(3a8d019c,ca085837,288e6cf2,18494433,f55c6e5c,f58513b3,6ac698c2,8d5e8c52,292ebbaf,921daf15,c7c93d5a,4fdcd646,2238f650,4cc930bb,b9327d6b,9ef4499b), -S(b8daa085,7c7c7ff0,7ee79541,55dcbfbc,749c927b,fdc74422,a281f3b9,c4e538ef,41061f31,f0c411d4,8a206fb8,bc842900,1c82c3b9,79fe3cf9,397000de,6cd89f03), -S(315b3e39,74d7644d,75a453cd,c2de9a90,423512c7,18379b38,cccde80e,c95e9da9,e8e82e5,17289192,fc9c9fa4,de1cdbea,477cc013,25060dd,2a766bdc,5381f282), -S(cadff522,8a3a947b,8e122ffa,234baaa,e7c23f13,59f18c63,49b1cdec,232c9048,bdba6e3e,15e09ef8,2f06fdef,64b20c6,f6656505,e3f06551,9bb9e54a,a671bece), -S(ffb3ce58,e72c3c41,a0dc7203,27e4b557,c524e4c8,d724f7df,7742cc52,eb74ba38,2fb99e81,f1927389,bcc94dec,e0ead426,e8631a22,a25140f0,cdb88ecd,34ccb2e4), -S(56e4455c,369dcd00,d8987d5a,46578fd0,44b9532b,2e86641b,b5260502,5ac0b9b9,d54ebdca,e2f22f40,76af78e4,448b6c6f,8d06899a,bbf5ab52,a616ef2e,dfeee9c4), -S(7740cd7b,fb64a276,30948a74,c510e0de,2c63692c,e1c9ff2f,86349bed,bc856421,c866667f,b04e9b04,638057df,8786d549,bb7980ff,bbb87799,37f9f345,ad013106), -S(ab9df6e9,81b1462d,23595e7a,6749a2ba,4fd1c579,b73435dc,de879f02,c85381b4,8258aad6,e81b1e62,b16aa87d,cd0db00f,53d46ae3,ff92a866,f50ddbe0,b919b9df), -S(f5eca856,ff675ad9,aded3baa,83465964,714a277a,58d5dec0,f08e85ac,5ad16ae4,9b8e6768,f6dfcbf0,b6789239,5a2cd72,562cb14f,4224c3b5,61c1993,f49326dd), -S(9732548d,85f535c1,41792440,bd369270,827d888e,e8f8ca29,27f5cef4,b29395e9,564e057b,e5fbf2db,cc698d28,34749b9a,6992b2a4,604ef4d9,5a42bf50,282aed8f), -S(8bfc3830,eecc3177,b6559a01,7391f883,493e045e,b6e5a173,643bd4f1,b4c42de3,7820a218,61c9ce19,5d9ae658,aaa74aad,12bd7db2,4c5e2aa3,1ff6cab9,79fb751d), -S(6ea9bded,744eed27,4aa346a7,3542bf8b,4e93e14e,5e57965,8a5d6a24,beeab56a,a4fef266,b9743c35,935cfec3,2495d6c0,c36f6ddc,b249c256,d17d5646,55278afa), -S(ff15c8b2,ce43a5a0,27817821,e556d021,356ce795,bba2c632,17d6205e,deee9116,87cf8fe9,3618a6ee,63608a4a,99bb27c3,8905b955,2df4bbeb,4b21b9c9,f3884cc7), -S(eb61006f,b575ee16,865ce8f,5809ecd4,28187875,91d924b1,5cc15e9d,a8ebe9d,8e51dfa3,c7494b58,f4447e3f,90eaa595,106fe0bf,d31eda0b,961f758d,3e01e0a5), -S(14d141e2,5ddb4621,7d99580c,918d45ca,51a9a51a,2d7917d,a39624fd,dbe87a6b,ea964fec,b49ac43e,45de4592,6ce9bc7b,f693f945,f6447649,bbccf4ef,3e011ca7), -S(36241c8a,b9b7a9ad,217c0a81,fb33281c,7b48afa9,ba1d2897,389f02aa,19cd964f,a38a1e69,2747117e,71654fdb,fc427acb,39531231,4594d08e,5a32336a,431f3b92), -S(8cd8dee1,5059932c,3c94501b,e15565c8,7e04d705,908c4c6,a2311085,5e5b261d,e949fc1f,7fe429aa,cf0c4b01,1d88e9f1,f5705ec4,2953a49,2c4f31d7,15c04380), -S(232136c1,5e76435e,333ed3ee,ceeab24f,f101cbb1,75bdb37e,5b8dea17,fe5b34df,bfc5f9cb,66063be2,7c090421,e5cb603f,f7a5c860,f9c460f4,220c10b,512c792f), -S(178316ff,4abed117,effb70ec,531f4b73,26124ac0,adbd66d9,e5a5eee6,7572e1be,5d88cdf5,90a3af33,ff5def9,1b5c8bb9,be36d3a7,a331a6f6,b4533685,ef2dc1de), -S(9341dcf0,d1b0c5d4,40004663,c56e57e2,a792cf05,a51f000f,1d192cde,6e81320b,54215ad3,3824b655,72204f8f,a9603007,8280621b,8162cbe0,153ff094,31becede), -S(e5399547,ea95b6fd,d1aab09d,b73e616e,593ac82c,6c4b030a,56b775e4,abdfcb04,c69e3608,b7202138,7b1f2a32,d445c809,1fe67869,7feca054,d94aec0c,14fee6d1), -S(da3a4d99,ae069bf9,9d65e041,69db4dc5,d9ab7482,3ac1c1d3,85d37290,807dc652,f4096d3b,ad811fcc,48faaec8,84633cd7,a7f5552f,4c7d695a,7224b0,ab05353e), -S(a5b6bb89,4594a91a,679f8d0,252fe38e,d0f8a544,8d05108,eced1e4d,133b79ce,d6cdb4cb,813a4fe3,7ebe9b33,471f619f,9d45c295,6b304491,4162417b,d0b206dc), -S(12d9cc50,8d90dc59,dc92d250,3a88424,e720c0b5,56912ba,57b8f00e,c9a4a63d,56992d51,780762a1,312f2bf5,51b657f0,5bf34f58,19d23288,2093e478,b074c818), -S(d5bf7f47,77538811,4921894e,2985b8c3,8cddb376,c9245c5f,6f1308ae,3f228620,693c17d8,40a58ab9,50b4b374,18caa8de,e0a49ce6,b471bade,43387523,30fbfc64), -S(83f06119,88ca1f4e,75490777,e864415b,abad972d,d5f4ad1b,1a295b4,205c1a99,e893d1d9,2416da8e,5fef7f76,389c59c3,94725241,4534cc86,d8518b3c,6cbb3d07), -S(fe6995d3,78e80a54,f3b1e8a7,3837904c,2d26430e,c81e5b0,11304e56,50f95f41,26a96933,8ad90a9f,4a15db70,28df1628,2214f822,6bd38a87,854dcc2,f4d490ce), -S(12af3d09,265b9f8c,fd5a74fb,62358ad6,a2cbf782,25b73a88,c5e56d29,508175ad,e28281a4,36b0476b,37588e2f,7fcbc4cc,bd88d96a,3806022b,75a4b5c0,8569cd6c), -S(1bebbb1d,3141cb9e,3723fde4,c0f939c3,7e37b67f,346fecf8,9ee9c789,7f25d89e,4f2835f0,4b875fa9,bccdb338,32ee53e,80360b6f,30e139ae,227961ef,426e0c06), -S(ddd3bfb3,173aa6d8,7d867d95,aeb66535,173c9a6a,4f34cc67,cebfaf7d,1ce4ed4,d7cf7542,c6e93a03,e3b37402,2c2877a3,65387e99,c9956071,beeab06b,69ef4d51), -S(81ddbe22,10125e0,32b5826e,651548cd,ba44a5aa,e131c0a7,2b1f48e3,7fdea8c0,80f9dd6,957aa45f,6ff32756,f87bb9d0,fb145b86,ba0b6890,5d15814a,f42b8ae4), -S(f4f5f53b,fa60b009,9317ea49,5dec1044,54352b89,5da6df0f,707d80f9,7d698da5,454cacb8,999acdb,5cc3e5d2,efac913b,4b967755,3ab998c6,8531b2e2,5ade652a), -S(b232f345,16c572e,f7d89d46,679a0458,2bdc84a2,39f35292,855ae063,fee9a1fd,8e480fcb,d3361e54,a128da49,6a2285ee,829ab82b,7a1530ad,e0f7ed1f,87ace8a9), -S(9f5a306c,c0e7f392,523ed44d,c2a74f62,cd8912fd,292feae4,493a9a90,53e43be6,d4a1e25e,46cbe19e,88b342a5,a278feb,9b9a0523,4636962f,b9697931,c47a848b), -S(4d5005c5,4b079a57,3ce42e6e,87cbec94,cdd520fb,16ff9d49,e715096a,a5ab8301,afadec78,c911fd4c,1248210c,622f17f5,7a34a6f0,1fe07abf,89ad8242,a0340732), -S(6b5d7335,6b80d4b9,9ffd3d6f,5b8376d4,6526753a,2367f046,5ed19550,4e732cb0,c0d10b3c,d9eaccf5,1eea0088,fde2ba55,17f85214,2b46fa6a,99b35a5b,811f5435), -S(896c9047,90f3a428,20715852,9b710560,bd18e038,a8dfb710,fa2bc910,ce25ca9,71ab7cc9,ddf7fe7,ea77e985,d438e0fd,34270829,1c57745e,decbb0f9,b161c4f4), -S(2812d428,7e3c5961,808326d6,8e79c93e,259c3f31,e02449ac,e2b72484,8ef7539e,eec93ec8,b2cd2b18,9ccf8d1,ec8d490a,4ea565e6,ab58eb78,3aca8f5c,b92df37f), -S(d7de63b7,421827c1,ee84acdf,c82a7e72,1eb42aef,7d91fc66,f725e8f9,dc42554a,d6dde944,ec65a85,ac0386a1,eebdc69c,b8793ee9,417e4e1e,8db8087e,bf1b6f22), -S(8dbcc742,a5856bc3,e29b009e,46985a7,67800404,82b06681,3c63a27a,667ca60c,f414fcf8,50b82712,cfcb7d3e,d92bdad2,958f75a2,9f5e69c0,67b3cadc,10da9293), -S(8f046e5f,7ec21b77,3df1015a,19a7aadd,bf5ad912,b5020ff9,b574fc9,7d442f4a,4fd50026,6f8a63cb,d603e3d6,f3f81aab,52e79e94,cb0f7159,fffbdcdf,9dba202d), -S(fc7c51d3,7e6dc2a1,bc542bdf,dab38775,54bb6787,dbe5ffab,471d79c4,8d2a0a58,a7297795,f7f9a558,abc67243,900005c5,2c619c52,bae08a62,5de66bea,81acc475), -S(e36ba16d,81996e80,36b3edcf,67136ecf,7b5dc68d,526a34b2,45843fa4,6a078f0b,25b39a4b,1b5d6240,30fa90c3,558a1eb5,df7c44cb,698f9d76,40432983,faa3b003), -S(c1c817a8,43140681,ff908319,a24684c8,dbbd179f,ac49cf4f,428688bd,3eaebc23,18e43b3b,ced5d5e9,530c05d4,6156fb9,fbfd60e4,58048825,c2d0dc78,e9575594), -S(787e110b,665a8db7,40c2ae0c,206ddfde,4491768,9aba8ca3,de737283,52b70d8a,7e22a27d,976262df,22c60307,ad61f435,b4b27dfd,85657f25,72899d2c,5fd005d9), -S(e1106094,464cd775,85b9eb8,cfe44b13,14b4e87b,54a609a9,c43dff38,995f5e27,8dff0b9c,d97f2779,fee262cf,629ab48c,483e8c09,c05657fc,6b0c83fc,3c64006e), -S(16f72b7d,9b9f8490,2989e9c1,8d067f31,b5e6773f,fc03b2b1,bf026b3c,a45ac92f,6260cc27,6f616934,9492c169,a9f97bfa,b3ad1e16,2b6a529a,7b637ed0,828f6a16), -S(1566a7af,1c3cd035,29859976,8dcd24fe,3dfd07a3,c688d048,c45f9170,b790c791,23319b6e,b9f84cae,f9c6ad8b,1c0a9c2a,6574b84c,4abef9ec,29754a1e,b3a67e2e), -S(bac2ba4d,96be7dfb,425e1279,8323068f,2a42d0c,564e3466,92a89730,7b90b66b,29291264,4e71cddc,7e78d20a,dc026e90,637eeaa7,36fb11e7,25d2e9c2,17b3c8e2), -S(b26a1e6e,1099aaee,14f3ef63,28ed7ae2,d195e04b,1d55e394,d0e11fb3,56807252,2f3566f,f7aca2a6,7e3e8e6c,294120df,86a92193,c2a0a79f,fe22c549,3385334f), -S(9a7a18ba,1cadb917,b68dc78d,119954c2,1b5778f5,a1445238,8cf7f481,7f49cf0b,14e484d,d3fe5242,1737094f,53861ee1,27a1aaf,2da7392b,f03127b0,d0d86a41), -S(49b26479,6efdf6b7,76f70672,d40644a3,e390ed50,1baaa862,1340a08c,649f907c,ca54a985,c3ff23a8,bcd6baf0,ab223fde,65b358d7,cc237b2c,3360cc53,fb7e62cb), -S(a27af3f9,728319d4,248af74a,a3e2d249,947ca87f,3e2d3293,9f574e9a,6da03f9b,226685a,8ad2073c,e8e32133,b2fca804,918d1247,ec1e3053,328e59db,70ea26d2), -S(de13bd9d,3544853f,10768f3e,8cadd376,f36726ca,5b27280b,de12a8a0,1d38f876,6fb4310d,96739a32,3b48e9f6,f215a0c2,f270d272,519e0085,ee72f325,73adb0d0), -S(6680238c,5ca916ed,5169ace,3c2e7103,3a3a26a1,89cb2cc,4420d23e,b9a98e5d,171affa,b6f370b8,c06f85a,928916c0,f6b45c1c,5ca2349f,4469aa25,c8f9b6e7), -S(c1787989,1e100300,1facb000,c41efa43,710267e3,554e0f65,f954a1f6,191388d4,68698007,38cf474b,e577d109,576c6984,cc39da19,371dac87,ae462d2f,2129abe5), -S(f0010a2f,63b6d832,256fe7ac,7b885d1,abf60db2,982b8cdc,31a8595f,23f9328e,cb3a3e15,ec21bba7,72a720cd,3f9bb93a,b0796aa8,c5ee119a,f862d5a4,e547238c), -S(2919f01f,f25e9171,1db684fd,a25c8a89,caf84f01,9caaa483,704e736b,92219e2a,f374dc4,8115ed9c,97efbf21,936cb5eb,814f40ee,40c8f97c,af29f3ea,d46c0603), -S(b110c17b,786e9b64,396003dc,3e0c9bd8,8cc4d060,e7e442a9,8bb3a1ec,2edd6663,6eeace13,a43c6cf7,33bcb313,e5cd7781,54c61fce,e4864924,f20bf45e,5cfc16ac), -S(1a41b8c2,f0bee447,3a085941,4479767d,b2c026c3,6ce0283b,337fa021,87e98435,88a46621,939d903e,9bb60506,3684ecea,7b2fba43,4f5f437c,f94c42e8,b4c274ac), -S(764fec0a,7ef7ccc1,ee478e82,dc122574,6bb18158,cac61402,fdcdae83,8177407a,b0090a4e,fb7da4aa,a54c24fc,75948587,3e1fc957,a475167d,5bfd85,7dc16f7d), -S(e9a521e,49b18a0e,1b226b11,d0397f47,8cb04d92,c8eb4cf4,4e70a0d8,c27a2f8f,b0fbbc19,7e70e9d5,765d85a4,1acfd3d7,84f06554,4008a89b,440f78ac,63a7adc5), -S(da01400,c935873c,1bd0a05d,2eac5595,c6e18682,2db4112b,b0a7af7c,f0b291f1,3fe8c281,26fac7fc,b629a6d8,9ac945a7,566f3414,d46f5e3d,3995ec40,e6aad876), -S(ab69b97d,a15898e2,d77440fc,35c31a4f,7f4930be,6a132e6e,66a529b9,b60b2796,7c80faef,ce1cb7d2,77900d17,e5887c0,c80dc0ad,b9c33fe0,5decf40c,f0c77e3d), -S(8001a2a7,3938254f,fc3a518b,2e9dc61a,bc7dcd1d,90e55812,72410380,2a91c2f,985191d5,787d0cb4,809923ed,b87dfa5d,60c18938,8e4529bd,2353fc42,9a061060), -S(5a93eede,e37ca03,194ddab9,2f9c7cf0,ae230a82,d489a9bc,87ac7180,93165e41,15c6cc54,72f571d0,c78ba2f2,8519115b,16a2256d,17ba055f,5731edfd,822220cc), -S(f0853089,da262598,d86771be,ebd4b38,c7060e9,ae9474ae,f8ba683f,1b70bb1,6508e3a5,b709d0a6,c6505be7,cfaf6744,3b741d9a,5f9adf06,7eacbae6,23a56819), -S(182a85e2,3d4af778,e652cedb,1cd6fabc,81bdb345,ec7daac9,f717249a,5d6aa519,a509c2bf,1df249a0,e477d3fd,e924146f,c9e7ff78,9f625174,587164d7,1dcc259c), -S(dc1f61eb,da442680,5dcc73bc,b6c59288,383301e,50c62a86,a9274a72,8c49ccfe,4d99f11c,be55738c,a2b889db,dee2e3dc,9d3fb44c,8cfef36c,5357396d,97c52cdc), -S(88d959a3,31bc66c9,c6aac8f7,ecc91ead,83591749,97c60a8b,7b11ddb5,fb8253f8,53eb97a8,b3714975,263bf21a,4ed923d7,39276e3d,b4cddcc9,574bc96a,f4083855), -S(53fd6fda,a8e04a9f,89fe1adb,90704589,8fe453f8,1c069b0b,5d5a9fb7,d77d612e,a8325053,95360123,422b6419,109fd9af,397ecf9b,71a6d322,b91c9c1e,ec236b4f), -S(fad9c66,bf453615,ba53a597,8e60eaf1,13e07192,1e820399,6bb850bf,237992ea,8a3a6b9,3a127d70,a36eea2,78668168,34bbb025,902cd3ab,aa499d38,8e24d657), -S(e4b96c12,223f45d2,d7bdd8e9,7ebe545a,16d23dce,1a090b3a,5ed6c9e,65512a65,57fa0c7b,39a473dd,20571bef,80a7c738,cbaa67d0,cfc7f64c,ba0be2cb,123d49bb), -S(7750e371,3b25a5eb,923c460b,967d9dd,1f00e791,cc3b52,9d3ea331,fa1010be,eecd47a,496d6a13,98e95c1b,9ca629eb,49687962,5d690434,ca41279d,a65c605f), -S(93487b6b,25ec86d3,59ef5bd8,e2cd397e,d618c2d6,98d9a6ed,28f3817a,31ae6053,f66a87b9,3dd96064,489537dd,1f9e693e,af0219bc,2b0f752e,4f53b9f4,92715fea), -S(f58b9a95,4d873bdb,931223d5,4867d818,d8c4a2fc,773a1552,35c6b182,aa8ffde2,752b711f,735bbdce,e772dbaa,89f7a95f,d81545c5,5ed25c2,8bcc40ba,4d82ff20), -S(335e471e,8756d394,8cf43e2,b32d2f7c,46147d2b,c467f089,58fb7541,89e4913f,c9e5bf5a,37b19ffb,41d39f3b,8f69a8f0,8ba01a52,559d684c,5eec3549,7413f3e), -S(e6a7d3a6,6ada823a,8b0cbf90,af3f0788,39ebeb9,85017182,74f29f58,1b9f29de,ff850986,71962405,edba654,1857c858,ff948c7e,4bd2c5fc,64afd2a6,c643720), -S(785e6bf,d3c5ae31,932304d8,27aa74f7,783277ff,fb27df66,e1596a07,705b2de0,1166938d,9604a7f8,2485ab74,af763876,2271ee5c,5a7427d8,2d8569f5,25f0008a), -S(228644d,5c0be7d4,59dd5aea,e4019421,83ea6770,ea40cbb0,38b3d1b8,f0d4cef2,1c489d4e,a1595fca,693bf7fa,d6672701,a23ee40f,b9278b1c,566d4faa,5d799c00), -S(a5ddf933,8e477ab7,fccd9344,ad45609f,7be754bc,eefba823,20f1b8e1,3ae9c15c,3e115120,5de4a550,c0f65848,804ac964,168481f2,12b2156b,544152ff,c9f39306), -S(668b35aa,b4799dfe,dca25a50,6c32ca97,3a5e6c3f,51676f82,e572602c,ec3e8a2e,63f33101,d9be94e,7d8971e1,4deec0b6,3406a621,77d5a044,bf43415e,c35a9234), -S(fae3a6f3,f9aa47af,a4babed4,7f366c09,da8e7074,fcda3f92,c74c1bec,c73aaf64,cb38f70f,61bfaca7,76fdc581,a468b53c,69d21815,11771cfc,698a9558,209736e2), -S(2fb68357,285d4ece,96ad8a3a,9c6f0f27,468c9569,3c2e1a9,8864a64c,757c754,b74b474c,133e0a4f,a8ad5032,d08acb1,531640a2,6dc09af5,6af1c862,91c06e87), -S(9f073149,dcbde92,8ba24d3,c00e54c0,c334b958,f124cf91,467cde94,9ea9848f,21e1474d,c43a9d33,43c120ad,a751e9d6,ae6c9ea0,986fdaf6,fbe6bdcf,23085d6), -S(bafcdee0,c0ad4fca,3bf95576,403dc2f7,e28884d9,b8d5f77f,4d7049ce,965ccb4a,4578e9c1,67b07364,f70d8cd,d6dda3ed,28b87cfc,b8d5c8de,48034eb9,5ad3da08), -S(7d909f21,b79fd78b,7b65abed,2da2b831,c7dd1794,cfd32f92,a4fbfc0b,3b666233,c6f2f069,f4f7aaf5,fb263dbb,389ff7ff,86a5f5a8,32c9311e,cfe31af2,38313e5c), -S(5d4ed232,4e24ae92,2f3a1aec,5a8de0a3,e7eac523,58770697,cb45c7eb,4e6730dd,878a1b35,ce2f6880,5b4786fe,eb49480,c6bed243,8e2cfa3e,4636af5c,649056b0), -S(8a97e97b,a3767b06,a9bf75f8,b7d62a4a,b22903ef,7d7717bb,7165155a,b375b959,6997ee31,72cc99b2,8f447052,b75b5615,db7a5349,f1445c6b,bf04ecf3,c8ef9f5c), -S(905aa389,b32cc33d,f9d52e49,39ad4799,8cfd03ad,bd4ed3c1,7810c0e8,8e1e064f,7102cdc0,1d6ea4c2,a426ba6c,1d4565de,c4d0f3b6,458108e4,e0539069,ff2f8a78), -S(510c5aee,f28f8345,2ff713,eb0dcd89,6d788763,af8cf565,dedd4ad2,c32f60cb,ad1f4e3a,549ba056,c3214148,504cd177,adff0933,bfaa07ef,dfad12fb,74609537), -S(66ade073,7a0510e2,40f13ac,db8337f7,80adad8a,9bb68b56,7f5d5d6b,da7cb44e,a5ce9959,f57e1e2d,8cdce9c1,33f6e684,2975a933,8bc8112c,3d68ca88,e668d19), -S(cf51bf95,42cecae3,59ab97d6,1f35ca91,a28bb48d,14ffb958,b4bc95ac,aa5b4e48,7db91cd8,306252b1,aedd7afd,ff94b28f,1e8a39e9,abfe26eb,9189cf0c,37fa5e), -S(fc409559,404b55f,27503803,9a1a36c4,bd42fa53,ab520417,94623180,57ee0622,79b14cb0,5b5f7e30,bf1ef45,cbeb10ac,a05d0819,fa9205ba,3e9d8952,afc74574), -S(832bd5f5,fd0d8771,80e65a02,6ee3c1c6,f44735c8,ce69677d,546bc2fe,fc0e44c3,b2430cc3,7d68fcd8,b35ce76e,229592cc,43ca6ba0,4c2a001d,67ccf5a0,2bbee37c), -S(d66e9431,bdc39c9d,d598c3cb,2ef18d8b,508ea830,3fe5db36,9262c476,66384bf3,b628d1b1,fef2997b,779b5f95,28fcbd,e6ce77ce,c752d83e,cbfcc05e,ab05f670), -S(1dd1514f,85d214f,4c2480a2,22cf00c1,f1ffe62d,ab452dff,6cc7f61,6c66f74,ec70290f,1eafcd75,d87e84d,cb86c460,1413175c,9f18756d,e92d6517,2f688fb6), -S(8a6b21c4,44ebfb6e,61023622,52165611,bfcc2531,1d0d59b0,49f25eeb,9894dcbf,95f6a81b,177faaff,25907a4d,61a7c323,4d7ae932,2b9f862f,a11c86a2,5c894699), -S(48fa5a8e,769fd471,122e6061,d7da307b,2a700a46,bab0656b,7fbaed37,7b997112,e4bf13ba,4456de5,b2c07597,c5b82111,ca05d178,cf0afdc8,9afd5df9,645671e9), -S(8aa75f18,7362cef5,91c58d4d,d1e196dd,5fdd9c7f,91685fe9,d4bf9025,fafbe0a7,81df12ad,b9c543f2,467c4c04,83c1358a,af08fe87,96b01d2,5e26719d,d8c06590), -S(fe10a4a2,c81f5155,e8f23469,c3b537e,b2f45237,8addbbbd,8a224a33,2c7cce6f,95abddd6,e81a6b0e,feadf6da,6bc37e93,f96f8826,efac71ce,8b36762b,dba0cca4), -S(4c29b630,af2a77ff,ed3773d9,a3d66cdf,fb100d67,8a7db0b9,1f37f6b2,249d1a6f,58ee018e,f5055aaf,c39a21cb,a68f4f46,6d6a25ae,e07440fe,2f00dbe9,103b5fd), -S(3bad5249,20c3ea2e,fc16ec86,4502804b,394f3273,5d42e047,c0cf694c,b4350adc,c553a54f,7462f2be,c8fe478b,cbdc4c2e,f693d8c7,6164f513,7e7a7a12,4c6ccd23), -S(8c087953,8616060,cf0deb02,1f46d60c,d1bc3b4,a8bbcf6b,39448603,59a2aff8,5f24e4e3,3416655c,cc35b47,633c9231,bf15443f,132c2df2,ed3d1534,52aa732e), -S(7e080d31,fa764a8b,92e74bf2,c69ee7b4,a7b2c2ec,6495814d,8901908e,443f72bb,f34e979e,c41713e6,b98d122c,a7c0fe5e,89624941,d2d6b44c,c65c4244,3f6a9094), -S(a5acd6e8,50f9b182,162ce14,3b19874b,b9ef6d4d,7c042eb2,c4dc4e21,eed6baa,85d55adf,7220b662,c5b88d63,2f1e7b40,4aba5158,2b93a22d,b3e9457c,b68ddbd1), -S(5149e4ea,600a6dc3,de6c91c9,3dd43a5e,a5e64245,1e791841,39f31749,7fc15a0e,7274076a,9b177600,85446c25,ceb68e34,217ac3c,e4c8c232,a673b0f8,496311ab), -S(e6548b3c,46de74c1,40d9480b,b01aee17,dc6dafa8,5843ff8d,e4a75878,a6ab057e,11704026,373c6c96,30da7f2b,7713a313,e64380ab,4f35d290,dc789f75,29308f6d), -S(80a85ade,2372d7f9,74bbdad1,c6e88df5,4d671f8,7447884d,ef186155,d223183b,24a1858a,5fb6aede,1a36e16,7d25b3a9,2e2f6639,64d60349,7c13e9b,3c14c7a9), -S(35ff436b,571336e7,963ca450,fcc41caf,83307da3,65468dce,28014914,7760b8d1,565b63a0,546379b6,585ba675,52fbe796,ed68a9b8,35431a74,e8f4b989,2027d8b7), -S(12a46621,fd5f9ca8,f8830338,4c150e2c,1df12e06,1dbff329,d3157638,4d67dab1,b1e29c72,e7ccf360,e8863c3,48aae396,2fc989b9,15debc6a,514da0ae,67ff38af), -S(2e4b50b3,b072a9ad,ab9b2438,bf554f0f,bdc06d62,f601bb05,7640b7c5,36949cd9,16c7ebe9,3dbf67b0,fc716d82,3f6a8fc6,4283d7be,513df237,e3afb062,eae6a10a), -S(3b893c39,58a4a0ad,49e3d2eb,b53bd3a2,fb9144f9,d46392c0,93a9affb,3d21bd2f,c965097,99ec1519,5877cad7,4ac6ac0,8c55e9d2,df34b4a6,b1758dff,c5faefc5), -S(195c553b,6de4ff4a,6b9ab252,f28f202b,504ddf2d,af69dda6,1c3d065b,592944d5,9faa60fd,79b63de4,cd3946dd,cd3baf8b,c5795e3d,e4018d7,c1733e27,82ca397d), -S(e8e5178a,c5b76d6,68cdad1c,be01cdb6,e9859609,84c05666,dc8021b2,12cc15bc,ba4eb10a,342d8742,504a468d,f784af91,b8cd1def,112dc8c3,4bae99ed,d855b0b5), -S(a5f99556,4e8d722c,a61dfc74,2cbc5ece,6f654cee,7c716335,5cd4f5e0,1decc0b3,bdce6c99,c4479cf,1547f394,8e9bfd07,ae066d7c,6baf7cf4,95ea2037,191e1594), -S(98065d45,270d94d3,e43b8c46,fc85570a,c72043e1,285d673c,ca1c668e,6373e4bc,a45d5f7d,3e6a51da,8e95333c,2333e7cc,aa938335,7bf7933f,b8004682,599db967), -S(bad7e989,8b6a97bb,98e66b9b,a2e533d4,7d33f0c4,d71c280d,efff5570,660282d7,3d3379d0,b9ad6d70,51002395,bd01c3d7,165e1f2,d61a5ce6,12dfb89b,8e4bfa45), -S(c914752d,4c1bc92f,f9fef612,77bd1633,840f9f74,2bf88bd0,d2fa2698,bfbb6377,ff8a4aa4,b0a3156c,7224f499,bc6147cd,d147aa5a,69c1c225,ce19c663,da7864ee), -S(d58c1fb2,7235da86,8284ab85,1a6ca2e6,dfcb26c6,1c544060,a0bf9083,1471aa50,8e4c5ae8,28e2ed6d,1fa1bd69,9d3a01d0,377e4fb4,bc692ab9,f2e3ede9,13bebbf4), -S(25e409e4,8a8f05e2,e0cf11d0,5a389206,18377447,cd0294f0,4a92eb02,1cbcb500,e7702eef,d40c5cac,4bc2f99e,93f0bfda,509f2409,24307664,c99fda52,a18286da), -S(22d1fef6,4140e996,9451dfbc,32f0891,7f600102,3f9cc11f,88ece53d,49321ad1,5a6c11c7,401c99a5,bed96396,9af7ca1c,bb612d1a,e1067cc9,ca4a1785,408bd79e), -S(ce176236,a9f48b50,7515532,ef8e172a,f017c5ad,87ca2f01,1c8b4ea0,64d44b89,a0266107,fd7d38da,53536d75,6e7b63dd,372566ce,643a4b1d,881e31e3,8a699508), -S(3080fc65,9c01951c,f643e315,f7d48339,e8134e09,5c5c0e21,f7b9ea35,1d859dfb,6355c53d,d8147cd9,b31be789,7bf2f65c,e3be9535,324f41c2,850b9cc5,ba607472), -S(e4798722,a4b284bd,ee6696c4,3c67aa50,11cb3616,7dd7b21a,ebe50ed2,e7d1a253,3d524d92,5dda9fcc,4422ff7,981136c4,4f373ea3,a41cfb7e,e1f068a2,466f6ffb), -S(c82b6536,1e8d8282,9350fd86,e17e63bf,75495dd7,51a967f9,51f4b7f3,eaae03a7,91b896e5,d673cea1,e6fa536,22737c68,c701e2a2,db8a4817,3c316006,b0b84a9e), -S(e911dd65,724fafff,55943a21,df3517dc,cbb3c236,e19aee86,c3f3a5f1,66e3cde4,a51bf72a,cd26179f,839e721c,1de0ab93,cf221a3a,72202b53,d8e552f0,2fbbdf97), -S(ae759e42,cf0c0935,155eb36a,5f07c251,bd4923e1,31b0477c,fb7ea478,9ca797f2,3c12355f,e7dcb9df,73362daf,d0ac689c,a6a24965,ce65fbf4,e5f9c6fb,271a8a85), -S(5a443113,c04b35ae,bbc16401,f2abf9f0,b9644cef,6e8222b0,b67fa109,a19aa3ca,6c7bb7a5,7dc10e2f,140601ad,6c1a7f3b,fe122e80,3531848,2a2495df,a7cc5221), -S(62fbf303,ce5055e4,761d6ba5,4e965e0f,cfc46a4b,e0dd885e,f3803875,e0152b31,14dfdf1f,33941493,d9bb0956,8f8214b3,cfdd18eb,6d6a79f4,c33abeb3,f6aaa86c), -S(47bad781,2ad847ef,471e3483,480fdb67,b08b5679,74f7619d,9f6b4de3,f3dae3b2,79a7976e,568e5220,8bfdf6a1,95a7d16b,8a4dca64,e53ee7c6,c8123d6c,839829a9), -S(fa4381f6,e09f9a19,72d7dc12,76fe579e,f8a9ea0e,c5ff06de,390d150a,fd3cd49d,ff76e0b4,b3f8408d,5c4d79ad,8ca85789,30692275,1d5d5d96,9aebf6e5,2971c307), -S(b891d634,64c7cf77,2b1c19f0,835869a1,50668494,e8889e85,6081ba35,7dfb0d6f,8d716524,65dd0f47,b39bd6b3,7f6efc14,c0108992,4741ccdd,71fa9a98,19e5f05), -S(eae22d01,98d6f036,5d3ac227,856633a9,d0ff6dc1,b6d5d1e5,a1b2e4dd,c7f11466,723a69f0,b551fa41,221e3a31,8fd2b60a,4baa0741,c6127e67,b542be14,9d255074), -S(765b7989,56393611,1b182aca,fa7a2a60,ad89f6da,fffaed17,ead51975,242008a1,e630c87a,91235862,444891c,42dff3bd,320a3272,2d43757d,5ee46eb,af5412f0), -S(ff77d59e,b5ef78d8,49496995,b20b98cc,c847ab95,253b3a6b,9d6119ef,5382ac12,b7791936,e1bcfad,8bd5fb0a,1b547261,ee0bee24,5c1e58b7,3fca8015,195d2b1e), -S(fcd78964,e8e5fc94,f575fea4,7d61abf2,c89ab915,2683e855,d48c6828,b95eaa6a,9f32180c,683b465f,203d4d9,2f2eacf8,396966e3,2bece1e1,413f2111,f000b000), -S(38e9c6b1,b2495801,455e5ea0,ddf4bda2,432b84c7,4f9303d4,c9d6e30c,8e87f564,ccd32af0,603f27c7,7cffff6d,9203167,3cdbe4bf,8662e224,498168c0,5e7eff1e), -S(9de95ac7,9e8ccb95,7b62bdcf,f9942194,4a691b3f,5646d800,68e2e7a0,976d944d,9d99c259,d5fdc8bd,7c29e2ea,651b4abd,354f8ac0,758077df,f46b0896,a25f99c5), -S(e4d34872,1f8f7fe,d81d810d,8fe26811,87d0eb93,5f8eb6c9,2735a55a,720354d1,1b95fd74,ebbed926,55004026,e2110fa9,5bbebf7,efb6b0b6,d7e883b8,34677cd8), -S(ff0222bd,d37a7b6e,45b182a6,cc744545,d60fb6ac,8171f625,a29d215f,1af3ed80,102d4fc0,c3434443,6b8ed145,a5a19426,247b5969,3755d3e4,dee475c5,1211c755), -S(27922e13,f03b2f70,bef94a31,589c1e7,9017c16a,9e57ede4,4af93c38,174dc1c,3f268d7c,3d9aa22a,6277ccea,c36b9377,52b94658,c44d110a,e276e560,d4bc18bf), -S(9f995f1f,76ae01ba,38b02cdd,a7f99b53,883e035,afb35b20,324fe6a6,bb65db6e,ccfa6f06,daf16088,7f2f8af4,18a5b107,cf1a83a8,12f117e1,7e938e4c,73ce924a), -S(c1b2bd23,8fa1db5,814a07a1,d6db2ac3,4f960dfc,c88970a2,9dd21c34,3fea87d0,e912dcbe,ff0391ec,7987f901,c6329c2,a070d64b,53131c5,7e99e6a0,27465f96), -S(789e932e,5665aa8c,24e2f0cc,1039cd89,da928d0a,1b4b03b6,b93fb79b,f40e04dc,25315b3b,bfe535e2,92519e89,b63da55e,f4c16a1b,d8af3394,b280ea62,3d0953a7), -S(19c54824,5815e2b7,b31d35d6,740e660b,84613096,60ee9bd9,6df823ab,1e7bf39c,9c0516aa,79e00ca6,8330d267,5b104e80,3660fcf9,4d785216,90a319a2,44885987), -S(2e73f0d4,de4f920c,5a5175bf,32e6b98f,5a49d1c0,a7af2b98,a6c6dd60,52477bf9,12dd835b,fc93af9e,680aa191,bfde6cc6,f307dfc6,aca349f7,c2affe27,40f87795), -S(5b711fa6,4463434d,d7c824ac,2a56d02e,46949ed1,d8e530b8,71e70a82,38ae224d,14329e12,940d179d,922b97e8,d2a2b7ff,6da66497,6879a790,1edd6035,f47593fe), -S(a34546f7,aded19cf,4d83329f,41cbd292,bc59f37,f290eb7c,ba28aaf0,a32a423b,9a2631a6,cb6b2989,fd2ba260,5aea7f73,c08f05f7,e025493f,459461b6,5ab24dd2), -S(850cc29,8dcb42ab,613b2974,57c80ec2,d98ef5d8,562af745,d4ffcfac,7e9c0853,b07a0e85,5cd335c2,728338d2,8a1c32c6,e3a0fb76,58b8bca3,f6bc02f3,de68a2ed), -S(8de69064,cf3f8d04,bc20a995,7677427,7b712ed1,f77fb7f7,9c361dda,2c7e8b30,34f6938d,750874d,573bd5b0,c11d9c93,b6260a9c,6ae833a4,350dd779,c515f16), -S(69d1e613,852194a2,b618483c,29517029,b3fdc8da,d679c07d,3204261,80f89170,a70f4654,8b7542b6,5da14788,56de6c5c,e06490f6,176794e1,a4dcf25e,4337d570), -S(f238036b,d55e7b7b,6d0835b5,2c3d5c2d,cdc7e6ae,6295e19c,2a0d6a63,669656c3,b401cdf1,15e8c93d,f5e230c7,a3ab387c,687fa690,d86da5e7,d038319c,468bfbfb), -S(ccc74591,1178eedc,76c98013,a52911bc,1da8f9ae,10f40277,ae51fbeb,2b6d53c0,d4cc4eab,60cbb4f2,9070717c,d6151c24,2914069a,c3a68d20,7982d758,3ecf0445), -S(ab2080d1,f6d6ed76,cc713c8b,46474648,c7d1bd31,fa6ca6a4,39d0eb8e,ec4edd4c,8da5323d,e205f2e6,4ddd80be,679dce01,3d1f2813,13fb16f8,e749902c,16362b0a), -S(96ed8ce7,36e0d3d,607e7b1c,fcf6316d,1bc60122,c1e2cfc5,5b20d379,621c564b,841b64b,af84d76a,45afd86c,28d32f79,115675b2,9a15c9a2,50c328e6,2a79695a), -S(b41e63b9,e3fff8e2,d89f2a69,b80f1d38,60a8fabc,20290d41,657467eb,9eef61bf,674d416c,82e50cbf,f001a44f,3ea4108a,c7cf8747,3b7cf851,ce9a9d1e,f5b90dd8), -S(7300ddd,4d22e101,a5ac174c,96f1ede2,e5a8af97,e4d7a5a1,e1f07be1,ec9b72ca,edb4eae6,e9d20683,6abe214,aa95cc75,a4246e14,86b05f23,ccb8c4dd,3bb18888), -S(5d152ede,6e8055ae,14c8c67c,3eac3dbc,1f080dfc,59d0f1d6,16bab4b0,460d21de,e615d095,b3ecba8c,dcede3b2,bfad0814,781b3afa,2b631928,74020df7,b62e1425), -S(bb8f9d6b,1f81a373,32a25eda,b4feaaac,9d82086,8297eb80,c1bf6c4,5f5c7cb3,772be893,a029961b,35f7174e,72dd5c44,e8c745a3,423cba1,2071ee89,92c604d9), -S(643730b4,dd3bf408,2ae96f7a,f3409b8e,690cb09d,f379e3a4,9e8d09b0,de30488d,55a68bcc,54be84a,3d79af27,e2d88740,e9e1eba9,e2149aa6,1cf4d7b1,de6f1e57), -S(82dec11a,c2c7a667,336c5d38,2224a5b4,12c7db82,5fb9adad,30552bc9,db2dbbce,7f7044e1,49f03a78,ea93c129,6bc63541,8b03e06c,5cf24bcf,7df70669,54e8ca26), -S(349382d3,95677d5c,f259f280,83c88ec9,47da1351,d26710bb,4a21d54c,cf770331,7e81f343,a9413313,91b9e4bf,e680a41f,bcd13598,bfa2fcf0,a17439f1,e8215e31), -S(4bf9f078,cacdc26b,5862aeca,d3cbf4a8,3c4321c3,62a562a9,eee4a8bb,5dc66125,6d38018b,4441d376,dd9f4bae,6e22782f,efb1c3b0,2642021c,31495b5c,8ab3fabe), -S(cf319312,ce28b168,ba4b41b7,8f06e0d7,849e672b,21aff86b,5865d32,4e0aa0f1,d1caf763,6d277e8c,edb4e03b,b676718c,7318e29c,e756a868,6932ea74,cd10a84c), -S(de892197,d6db602e,13a9f3e8,d36509a,8e79fd15,f25c9cfa,4e610ff3,eafde1d2,e2454f06,569b9b7e,121534cb,31becd31,31856640,16d5d266,a98fedee,f4026ec)}, -{S(6efd8760,aed4f239,bd97a00,63794c4,ef14acc9,f5b94862,4c7f8b51,3ff35278,74acac29,694c5307,aa221b37,f2ea068a,a269fcd3,c6d85aaf,a8c8eac1,17d7f997), -S(7b466cab,a5820335,bd6c9e51,7f31e735,d3e9276,18c36e6f,861d032c,f2c0efb7,12e04a7a,953d1ecc,c0cb9cab,6e06255,f909bc3,e0b9f2a8,e667150e,1eb879b6), -S(7d73eede,ef4f9ea,34fe9a3b,9555307c,5a8a0fcc,12bae70a,34e90b07,fd3c36eb,e4f4b5c4,8c1ecd05,e7110725,c7a39a61,9f66203,3b6a6373,fa966017,2f5c611), -S(a8d37fa1,c07cdf9b,dc6b77b7,cb6c3e5,99930870,6a2307f5,c7cc2e3b,333a6d1e,665e43c,58bec5db,c87595,8acb5fea,89a0a742,641f4df8,f1c8b238,1eee0774), -S(1f4a4126,eae02858,86df6ce9,3d6bf107,be37564e,66048131,43ff65d1,48ce4ef4,b64de137,1bc84933,95058a4,70a7135c,6202e5d1,c7406759,5269cb98,2e1159c1), -S(5f963c6d,355346e,9feb82f,90921c68,7df67c3e,6d0db15f,ee46d58b,60bee0fe,12f8f5ef,326e9b9,68ab60cc,1331fee7,11c9369b,e887067c,4dba63b4,707cf1c4), -S(93cb2373,e9272b3,378d7e29,59d7d935,e6395529,5b2b6482,15afb9b3,9bc5f573,45bdc11,d37edbd,51e816e1,5d27715e,2f50fb19,ed9a0190,573adc61,2f38db2f), -S(4f231e1f,caf63030,f596cddb,7afe9fbe,2ba93d0,e8b18213,79b349b6,7f8a3ab8,7fbc097a,f61f0c69,9b8b2660,51d332c0,ca8134c3,1c4ac6a8,d1a820f6,a389e9a5), -S(b3ebee1b,ccd21d5a,e45bad73,85779014,216cd61b,7cac39d7,5af121b6,b7438a5,a0c1a664,379cfa7,2b3a1ba8,6c6ec9a3,a62712be,1df870ee,df945b9e,62727b08), -S(9713f024,1e06a7c3,7953fafc,1fe7df85,4bef044b,28358dca,bcd82609,1a9adb0c,439c3a8,9f48152c,2a1951bb,4b70da95,3f3875c7,82650643,92717640,73f1a34c), -S(42ab6939,246a9574,185a1c12,89824dc4,87bfdf4f,bf960517,87a441b,5977d3cd,e5e24a17,416cc7e3,a4fca1f3,7666d42c,a8b19e05,28940a07,2630f668,3babe748), -S(8080c977,bc2ba584,bc40b6b7,50bec750,cf80e367,a45f64a,6639d15b,5fc696b9,e5e8290e,917024e0,5ecf369c,4e2fa4b0,76b19aac,d41f6424,7353a2b0,846db72b), -S(300d9c06,89570a8d,5066039,2a8fb68c,b84b6f7d,4629ace8,51e6aefc,5f88632a,ce1009c9,4fdd9778,50f2c2a8,f30732a3,253053ca,635b34b1,801844ea,90137c41), -S(42ab6bd7,b4a48239,3c17c778,ec1423d0,ed684ad9,41b0eb9b,ecf5090e,51a2aef5,bcd4f24a,9911df81,500c2a76,98d434e2,a5f6ca84,ab4d75c0,7b7f3460,82624b48), -S(34c3d12e,1dba4daf,aacbd46b,7a2b5506,874c150e,1c5b7f3c,3ecc3db4,b4234c60,647d9374,c25ad658,d5081ea7,ff6eda03,61cd55c5,3c8cc862,85a83bd4,17927108), -S(ed822bf1,85d879e9,94b40a42,b000b93d,8f3439a8,e1800479,fbc1c3fd,61a045b1,5e25f76b,5f44666,d94eeffd,72278034,e5414f7d,c12b3858,424aeb73,3b84e4a8), -S(66b6681d,683c7d09,963992b3,b7965df8,e152d1a0,f296a0e5,16160fa5,357c6230,306c1d1,a4e6fd30,2a9d6581,e9b1632a,56eb67b7,af92a8d1,4cbe33f1,c34f1098), -S(b80b913d,359a179a,1ded7997,f833894e,6a9f6e6e,e2d05bd4,aee84b17,13ec6369,dd03d2fc,83aec2ab,9cb999cd,82a015e,3720cdf5,a9016b35,178ece2c,a51e4ccb), -S(54d6ad3,34f5eb7d,cab082bb,e188eb7,185f6054,e3335e6e,200f8263,75b930d7,9c1f066f,bd6f050,3099adf7,e9fc7960,86353a6f,4ee8c25e,fda4bd34,81db0e67), -S(c782fad7,aabecff7,d49e45b4,495fa462,168fbd90,fc14bca2,a216bbf8,daf7f344,e94dcaa8,ac3a9363,cca59110,d42375c,988016a5,b41e64e,770b36f9,87eb23e7), -S(f8cea4a4,b451df9f,89a4e9a3,8f586d04,5fbb1640,3baa242c,4b12f7a9,97aa7b59,da610c68,9fd0ecb8,4b0fdaba,3c34a25d,70d0883d,3b686a2c,c3c257b9,68800ddb), -S(79a15047,b34dad08,500e67a0,8ba08225,31bea87a,3fea2b1e,223c2aa0,4d083e92,4e36831f,183cfe2b,5a6145cb,716ebacb,5c29c71e,2c76e51a,154db94b,8877a463), -S(c8d6d0dc,dd1dfbcf,e4d90d9d,8320f5cc,c9a141ce,7758df3c,a3252045,ea8f4789,f0275762,5102db48,dee39985,e7a91b50,4ca08125,b42de955,f3f6421d,62e29548), -S(a619ef08,787410d3,aefbea3,c6d53427,20e8359,f483a8d3,2f588d99,ece6b51d,f96dc23,1bfca372,10fc1834,8734e4e,28cfa3e2,fa5bcf82,2576714d,363d46b2), -S(1ef02ccb,45ef1e3a,bfcbe970,2f839ac2,845f7c4e,d1b2ec5b,46400db,df4665db,8aaf2a3,8dd2e57a,df53071e,4db215e6,a9885803,29c418f1,701dca95,e37f9ea7), -S(ebf69ecc,320d1188,80c6518,a05f824d,2f8be63c,77401447,fd57e381,76f52f6c,996e43a1,647c018,507a49cd,3867e73c,e0f82630,d36c9ea2,6c38bc57,41aa59a6), -S(1ec42d6f,eca86040,877404e,370d21f7,9497ad3a,2e527bc7,b6ebcd97,a5407c0a,f8180e23,290c3285,b8eda149,d26780fc,8f3a47a3,284ed732,e57e7c6f,a1629f9e), -S(f8ac97e9,a3c152f0,c71098d1,816011e4,644bbfa0,3578412b,6f03f5ad,5495cd0c,df74b06,a4ee84e1,a55836dd,6ab1a681,7bf951b9,cf163dc,70ac6cec,e286b13b), -S(557b9739,5cf5aba5,676ea063,1d404c9,b8abb95b,8672889e,d385bec5,6bbf5165,c7df864b,be165b82,5bc10790,20306b9b,8f3cd384,67edc2fd,bed045b8,fdcd09f2), -S(b44a67c3,4d85856b,62db523d,b15e1efd,b882855d,c63a7c6c,17decc01,1cbbdd4,d224fac9,dfe6f504,296703de,a7d67da8,6c530641,46823fe1,81d2c994,753d838d), -S(c9df9666,ea8eaf4a,14c8847,90e0e456,35db94d3,4d5f0680,b1727c8c,a863e398,10917719,32d9592c,fb272952,2c1a1cba,25020f33,95a6ada6,f85c92c1,996906be), -S(e56736f5,2c77db45,66bb0c10,46c8554f,444b829e,72be61bb,cb376b64,83e28683,2f32beaf,ba8a5aa4,5fc33816,ec2432c,9fe6c76b,172afc7f,8eceb879,f29651c0), -S(bebffbcd,bf56c1cc,8e42824b,ba8f0b4c,35cd732,d1eb160e,96a8ec55,13082be7,5d84e045,a5d285c6,be65e663,b51da6fa,acd3787,7748c439,73eefa88,88263df9), -S(c30e6d10,a518ff5b,2537c8a,89d2e447,c0d7518c,529c4dd5,b9575536,2d9f49f9,92da3c0e,f9ac9946,eada43f6,2d811aa8,26da78e9,849b847a,9fd0b0e,5e71d727), -S(65bf5bd3,ca8f5dfc,9a1799d0,357f24e0,2bcc4b5a,7706a454,3d08a,34512abf,7234a79c,a6c4598b,c2480b8c,5a5a8ca8,f343c41c,514054f7,42611d68,80277041), -S(680c6de7,ce4b261,3698ef55,185b7678,3d6ae7b,9587bbf,89995034,ce361a03,a22146e,3e025e43,565b5243,89bb57e7,6af1b740,7769be7e,6cd29b1a,1d472765), -S(83ffcd78,14a1455b,501381f2,523a675e,92a3a688,aef481ed,aeb0fd0a,14c37671,d780b968,b263153e,e1f5657,de678f55,6e43b840,e17e6eba,694ac093,dc9e8e7f), -S(b8c2376,6ef2d21f,5505b265,a1b27cfa,f0f5a59b,54b31407,1fa9ef5b,2457762b,28249c7c,25068a13,ce473b0e,896ece13,65a23f57,2626fb7,e5ac1e33,7976aedf), -S(99327a6c,b7606c32,92d98fb8,799f5f64,cfa4b0c5,4fba99ff,aa309287,d034bb1d,aa09fe57,4883ab5f,6b07830c,d5c12121,de3bcf52,68f8dfbb,37ccb8cd,61cfe55d), -S(3a9f4dba,2fd6493f,bbb21e8b,d36644c3,d4da0699,faf8029d,4ac7654f,380a18d,3c8c87a0,6bf2315,32a5bd1e,e44ad483,b44ada12,63d4750,6a55c567,7121fbe1), -S(65aff743,11534071,2676c7cb,2e5762ca,297acce8,535534bc,e495e27e,2b6f4353,5b11d44,8b7e2593,b8964f7,317f78b,5eb4d169,d968aa17,91259135,15087ba0), -S(457e7433,e8a8b719,e6e6b506,cdc1654f,574e5020,4ca22877,f36770ab,bf855eb0,949d5089,389f939,5e762659,53aec631,e369e8b1,38e6168d,b6528405,bf144ffb), -S(83253254,4261c8bf,b4a32676,3389afcb,9ee3d56f,44c70c08,e9e70bef,fbb092b1,3ebfdef,f0bd720e,611f0c8d,85028d87,8ffbb5d,7c19c3c1,e7a0832a,2ccbc0df), -S(98ec0257,7a1e4b16,369ffc2c,f17b0ff1,82af8b5e,25ae498b,e7acdfb1,b069e572,e2c72d87,67d16e14,44315c3d,9dd3250f,ee7c5ed,73337d03,ccb8a4d5,743537b), -S(d4b815e7,1e29d5d9,7e96c122,7ba6fece,60779b1f,574adc23,b53bc206,99c3ccd8,df98ad83,9c4a9133,d78b0d12,a8ce8765,61a3530a,29707357,65ea402f,72db0cfd), -S(88753aeb,3045bf8f,335a59a,9bd4287e,555a9005,5940a0d5,895b19a4,be237ffa,9740f21f,4abb4d3d,ae4b5f7e,9b5ab141,810ef2f3,9cf2d98d,570dcd1c,4d330ae4), -S(eae3895d,f081044f,6ea4a9db,73dd1300,b4a53f5,2a5429bc,fd60cb6d,733efd9c,4a9a829a,14149e0d,a629498,a3e03cbd,723d807c,a47a16cc,de5b9c1,a443995e), -S(752b1e2b,761e8633,7c4ec063,2fe7f626,e7038632,d93ce2d2,ea789825,97ea0d44,edeb1b08,a076b69,9fdbe919,e20dbee1,223c33d5,ffc6fdeb,36a5d1fa,4399b8e7), -S(9854c41d,104d82d,840fbfaa,d4da5b51,40c1aba7,80bafb5d,24646e10,a23f8a4,c170757f,23eb38de,5412e2ea,3a040c8e,cb10305e,69290c20,32e2719f,e26bd499), -S(81d720df,c9396536,5d977db1,410d4a5c,fd5078e2,21e368e0,5a8faf83,44097d1c,a29c17b5,518001fd,775afd10,693865e,d84cf3f0,f7bb44db,c5b3bf27,b192be60), -S(555dbc1b,7809b8d9,9db97d6b,c9c75ecf,4592fbae,3784e2a7,2150bda0,e9c8cbe8,963fb2f2,9277580f,9ae5668b,f31249c2,7429cbe2,5bbbd296,81574ae9,35e8d443), -S(31dd018d,28c81808,fce67b11,f621358,71be0366,b04d5f69,73b3f11d,df2b37a6,43837cb7,c56c10ad,1fcb57d,91bb293,aa91740,a8c5427,3f10bedb,560ac06c), -S(8c3e7d99,cd849afe,4c3e8ab8,af410bd4,3ee951ca,10307e05,4f569854,e8752d48,fd4d3081,69dfb22e,ddc706d2,36bb1918,7ab455dc,eb44e362,eea2863a,3f0341ac), -S(6fe0f368,f918ea70,b130864a,60e6541d,23daac99,49a28e44,597315f6,d85ad4f5,e30fdae,7c6731a5,ddfefba9,ae685a43,21619203,87b66a2c,799d84b2,f2d42c98), -S(f181faf7,623f82da,aa7730d9,56dfabc1,b4a662ce,c94282fc,dd3852e,8a43b91f,2e148d3d,9c470d9b,ca5be26a,5e191154,441d86f7,d6234085,203e944f,529e7256), -S(8cf18f22,23085bce,a35c8406,d9322ade,97eae156,4f741e36,2d3f57e9,e86867cb,e5123dc3,c5be133a,f25f90bd,de7101c0,6b2ebe44,cc83b7ee,a267a3a0,6a2c2b4f), -S(72cf023a,8d20a4fc,3ad5937f,cad6f47b,1030e02d,9ab0cede,58794a3e,f5c9c6dd,a2d02506,35402d63,85d0fc40,af954464,15fa929d,3dd95c,d4159edc,300fee82), -S(6c87417c,7e9ce90,b67c0ca1,469d91f0,98a9e67e,850ec140,fd489ab6,b4477ec0,7aaec9f9,a443bad9,89dd08f4,8d397d3c,35d970b,6cc9eba,df64513e,57227106), -S(54ffefda,eeb2a69e,8de97265,e8d7ef5a,576a4f1e,df7ceba1,7f94cb3a,a83a96ca,7d76707e,cf533f08,2c3e63cc,eed8cd18,9bded8ce,835a37cc,549b550b,5e82a3a5), -S(9dba00a6,d186dc34,a21207af,9aa597e4,432b8fb1,b1fbbd30,6caacbfc,4db25e35,259faa28,e791002f,138468c6,34e0c20,c5555b48,a1b8a35,6d68accb,41d8f7b8), -S(2728df39,afbc765b,38f47b21,6aca8cad,33b5b2b6,363cbdc3,3ed434ba,5c9201bf,de91b280,6bddbef0,562c02bd,7d7bd16e,7551095d,534a2566,9618539,5e22a4e3), -S(77a45f41,2353ddf2,d8cf7ac4,afeb1a3f,df6d20df,702e8207,f29286a5,c3558ba4,f1f5003f,510959e,93be5f5d,7d4f9498,70eea705,51b2383c,22215a84,8ff83fbb), -S(a0da4abe,d0890614,ba574a88,ffba223e,71163293,b4ed6df3,8b5b6e6f,997cab0b,3f542151,36570288,344391b,d3144b50,55545b2a,90e78b9d,20f894e4,2f43bff6), -S(202b20a3,c8979884,9a275f6f,7fcf6e11,4a21309f,2f340387,f663eea3,e1121028,35001416,97ae4ada,4e7e0b01,e9712385,ad971605,6e6c0cb6,c1cb6bdc,b12c3363), -S(7288cb0a,fb450439,2ce2867d,3ff3d2af,71344402,a7ec2198,152aaa40,9d85aa32,e39ceae9,6d3fb740,91531079,9770ffda,fe11434b,b5ce8213,deab8b43,c9426006), -S(de1e33bf,bf324b9f,dd8b305c,1d77e868,61dc6402,b083778e,b488275,1609417,bbcdd28a,13e3db76,e76f836e,93a4e54a,8550a389,5d02a03e,a99e80ff,cae1e3f0), -S(c88f921c,c2dc7aa,1b48d681,319a259b,33313e5c,c31ed767,737824dd,b99fb563,66ac4897,206652df,fb7224a6,771f32ae,bd75e318,21164444,62419320,d45f5e1b), -S(adc40ac3,97458429,6277e8c1,3f3b0e15,d8ab082a,e024f8ae,901cec70,36083690,f0497ce0,2c79352c,19bf649,4fdcb631,60c993b6,6d4c81a3,679a8006,b6e31779), -S(f72b6a10,5599d35e,4f5b107d,a2f9e8de,f1ce7211,7c03c8a2,5695af9d,d4a42926,41306d43,7d83913b,fdd51a1b,3c9cdbca,5d4082b1,756e1f5e,2c2851fd,b50ceed7), -S(f8bf4a89,b8577191,98efcac4,a695f9d5,d9d7f017,c9c0ad26,ce8301bc,575d8771,ea762173,96b1873,843f07f,826d6d69,e985d38a,119d7923,99b20484,cb20d8d3), -S(83523352,714c758e,3e7d1627,44e1fbe9,991b0c15,efa1345,fd9cd41e,ae84fcaa,d209aaf9,e7032525,e8f496e7,7b22011d,e20e2c0d,901e835f,2e64fd4f,d6b44e6), -S(12f7f577,31b61df1,a2f699b0,ae85b95e,92ae1fa9,7caca4a8,7b7cb6ac,4fc19145,2c52d855,505de067,213e3054,8d7416fa,ba042f93,27c21cd5,b47086c4,d01696e), -S(48254fe5,aae306d,54a14098,c87a0bae,4cbd0540,c8d36ed6,9c19abd8,ba0738fb,6f37a602,ce702d45,549ff185,338b150b,17bc868d,649ba4be,b99ff744,5ea70f3a), -S(5212fbaf,dc8a9270,fee8ca9b,ce872a3c,b875c3b3,202f92ef,b5327a4b,e466401,73fd045,69ed0d82,4169c191,8ee937c8,87824719,120996ec,11a9fdc0,ce4437a6), -S(855b8d00,c3f84266,6af52981,284b5845,36a06019,3b722fd1,483b8dd8,2880e0b2,5b494189,5d3c558c,548ee414,47327cc,13ca4e7a,5b8eb7ec,7d5da63c,7f89006), -S(49faaf81,850bfce2,7752768f,4808c91e,be1a8999,f4673650,52099584,37ce9747,6eb4c92c,a2235629,c90339f6,d7c5f136,a2329eaf,f26d6353,da9d4679,f07f8db0), -S(57afce1e,5164670a,7b3a8a8c,cbcd7261,a8775833,1f74fee,7b541174,9844bb5c,452fcaa0,1237bfb9,f3d97bed,4eda5fa9,ed72b580,c2b95953,8eb227d5,60252fdf), -S(9537b024,4e19fbbb,c17e42ec,9ac4c5ce,51fdba4f,51e7bb28,ea53ba77,661a8728,43153797,f2b3c74c,ed3cfee9,c9609683,36f2876f,2332e95a,cbfb6d5e,84dc9f3b), -S(bc816077,c64469e3,a663409d,5e175b45,ee14adb1,703e2bd3,7692b38a,31d49c6,7f5430fa,11e07543,f781482a,f95b30d,d58cc8e7,e8107b6b,54f314c0,c8e77e64), -S(dd03731,e07f5b55,3178ae07,7df0930e,de774e47,3e52e028,b7f39a5b,583f1d1b,7cdc1846,fe08633b,f9fa470b,7710d02b,8ee07902,e38290f5,788094a3,61174168), -S(132ba7c,e36518c9,195ec6e0,cf3aa576,1f0d3b76,d2124fc3,b43fbdf9,bd196170,7b59d248,388297dc,9f72b75,b8aa607d,327cd873,8be5c1ff,e8e035ba,611d599b), -S(798b3663,8f3758c3,93f93504,9584d055,e52f9cb9,abcab568,477f3265,68f5dd80,f270bd3c,5b236c6f,92bf2937,5ae4761e,1e5418a2,716326a,c62707b8,617c2f1f), -S(1db26d05,f64a6f1f,4b6911b8,3cdcfac1,bfe57344,7319baa3,8a539fa8,dbae42e0,8185bb2c,8d009b27,c7edb12f,d1760a13,e2e97747,52c3b961,48e7cd0f,2c0ca28a), -S(53600f43,411155f9,676fd005,ece88e90,ce3f68eb,bf9f418c,b1ccd460,94fb9013,e87314ca,ff3457a1,ef3a12ab,3e8f7a54,b80b7e81,91cf3378,cbeb9a1e,bb02caea), -S(31445cb8,39f9aa76,4fd46b4e,b39f0fde,18178467,81a4b1df,e9523dd9,9c37a732,58ef4007,d56b3ecc,cf08f220,d5b28cba,d9e6ef50,cf878166,9af25bd1,16239ac9), -S(3968d2b0,80d50365,b4df89e3,a50ed48c,fb41f5f4,630a1fc8,67a072cf,36775c4e,15da358c,9a674846,3fb6d243,8e8569fe,4d9ea766,713ad5c7,15461485,c876f215), -S(a040c7fa,1ddc8d42,efb964af,ca365776,99f200e8,d23cf93a,653cbfce,ea24507c,7bb2fb2a,57f4749c,83f696a1,4c974781,8af4ee58,c42c0718,1fdeb867,f54121c3), -S(2edd58db,873d3d57,42bc774d,97ea6197,152a57ff,b0f747ab,1d26f577,b8cdef89,82ec3302,ed5ea5bf,79e696e1,d67d762f,9573f895,ecf3a891,755dbd61,c11a7702), -S(b519f379,8949ae1e,1138e3c9,9a9486c2,77f44ee,1f9aa34e,b54a34c2,6f394313,5786b86a,7913b9c8,e38b6bf,2edc278f,2d4807ce,834c30da,ac3f5222,7af4a458), -S(d3be1b71,d03703e6,194d5ab8,ceaabdff,4a970fab,60caeebc,13ffadc5,3f973757,176caa0b,f46c299e,33e5ff06,294bf813,530cf048,fdd0d98c,dfd3e9a0,a42c33c7), -S(85a03707,c13f7b49,878abf34,cb77fba0,62d3d1e4,2b00f7eb,6e159c66,48290fbf,487c50b0,c811356c,499ee9fb,5fb78a84,98d70194,62a15417,c0e883f5,6baf6f45), -S(fddca890,694d87de,a2e0f92d,1e9b9e9c,7420b4da,bb5d2a89,3d282dd0,53d45a15,8a896375,7558132e,d1137feb,fc9c9c0d,4e6a6de6,1e75a8a8,ea79664d,893dcfbc), -S(d7cb9e4d,13e2b747,6f91a951,2aa93ce,c954a542,c6acd5cf,ad65bdb4,63071664,2880964a,13083d03,8755c9eb,9c2c8f57,b68660d4,a5227ab5,261d6ae7,c9ba708d), -S(98f619e3,76e7bd91,f5387e58,b57ccc84,90a6fd68,1a569cc2,caa253df,86b6959b,59d49098,67b3c6b9,8ded8edf,a67f5c4d,4ec7e,8dec78e2,68314f8b,f941867a), -S(35f36793,f5dc6d0c,c8adff91,2db459c5,dd405272,ce45031d,bb118383,d108519a,568f7399,aec63e71,9c63b0d1,480a9afc,662c8920,4bd7ba30,71b0eeee,ddf3ac2d), -S(c7e043b,b02f15ef,689666b3,8ed29704,a5059027,ae23c3ba,f75a2a90,642934c2,cb5e67d,551e180a,42274149,127c75ff,2be6113,bfe56f46,47008ff2,d6b72578), -S(cf95cb09,19655249,f16bb911,9488af73,c74ff5e5,e508e322,2a044f2e,1fb87796,d476c517,3df5b269,889ac45f,5b095db4,97c63334,ce233da9,4daebef9,aa2b88b5), -S(b38ad8a1,640c2aa5,b77db077,8a7ef7b5,b9795e36,20612fc5,e48c3ac,6fcdeae4,5e97b2cb,8dc7839a,d1f80df3,a9a7e203,140898be,6a6301ee,c3aca617,366edf66), -S(d39404f4,c9e59b56,41fbe43,c0abf3ed,4ce9065f,6d4d0224,b1cb1b33,aa97d3b9,573e8e27,44903ffa,8e1efbdf,56d3975d,23bac9ac,de0f758c,1d018e7d,d049e49b), -S(9adce43a,9f603359,5424daaf,c0ae565,c468df8,6beb9b49,ff533af4,496fcf32,e2cc9853,af216c00,4d71949b,c55a2c44,38655847,75cb2d00,ed96c5a,6f143f01), -S(66d1438c,8c9202a7,aef7d11c,682fed36,b88d5978,d7611a06,5d2ec2a1,b5aa8bd2,d1cef3de,eaa43df,617a7fa8,3a22fbcb,f8aae418,5de59e00,1e11b37c,d34cfd05), -S(442be1e4,c65e3e33,db17ed63,d852e62b,f8ff33d3,589a99c6,8d2fc4b4,dc8bfaec,63ed32e5,6bd86b07,6fc357,cd556c62,22402d35,5272f42b,a982a496,1f7889b1), -S(9c80efcb,da724a78,f6dc4de1,618b0d39,cf383c6f,d104bdd,2476147e,b6fade3e,102a9767,4ecb12be,71aa53b6,b0f353e5,6a06f1a7,b14cfd31,d48993e,4e766b86), -S(a2d10bfd,bd01700f,1c105396,bd78c7de,7baf91de,ecabc8,94938ec5,b4d99951,4a7db817,c4ce92c7,eacfc287,91992398,3042412b,ab017689,9c4113ba,6ef4bc3e), -S(847921be,b36c0615,ae10e9c1,b9791adf,667d1896,3af938e5,365eedd6,f888ee92,c4ee9b79,91ec9eac,9c08ceea,f610ec27,b3a0be64,6684b3b7,8ad1c17d,380d99ba), -S(60d7dcd6,879f9c5,6a44cc9e,26f5a5cc,6a6500ba,99fbb676,e5992457,e611b840,c4128d09,7ca3a257,113aa74c,29f063ff,52e39bd8,c8a4bd68,4c822cd3,386a652f), -S(e3a4e2b0,5d227414,38ad53a1,5366c13d,7d377dca,fed5be5e,61387448,1e3cd263,fab9bc4f,12cc2130,5b0afc2c,275cf3c2,c12682e4,1c772776,568f6219,63fe9c5), -S(af13018c,89c75180,af73b61b,5ccc891e,b42592d0,f2345c39,926a0ea2,402d6e87,eb122961,6a01567a,1d69034f,e8ca133,136694b7,761f4500,25754951,c9e38b42), -S(a3a7b943,c5304cbe,d736b95,fdfc2283,f54164c3,bc3d186e,7b017d1,dfbf9464,7b779d12,909078fd,9cccc9c6,73afaf1d,bd206420,44f941c0,4a676aeb,e2eefaf8), -S(ee99d382,c6f590c8,a9e266d9,9500e9ef,cd685630,71052e95,28be0aff,330e5476,541966c1,1cf15028,a6448de5,5837bd73,6aa11b70,bdaebc1a,1e8223ba,7a69d146), -S(142ba015,699ffb3,e6e02bd6,aaf084e4,3d100421,c5aad92c,f636691d,dcaae138,94fc5a5c,cdb79bb2,1cb733b2,50a0d4b5,cf37cfb4,75ae290b,4c53cac6,43ca7aeb), -S(75f254ae,9f98f3ea,17d9e574,5820a2df,16ef6027,d85ef056,75790b92,b345a144,63a94cfa,2b289f55,300729ce,77f9a5d3,681b944b,90719028,cd8de938,2290137b), -S(f6db52b0,1ac4f26e,80ac7f49,fc81cf48,9ebe7df9,d2085d2d,e08cfa7d,3883627,ed4006,f6c6d8c5,2bfc2fb1,8014f69b,7fce7868,7c0217cd,3d813faf,8518152a), -S(5418d34c,61fa1981,be925614,c56ac5a9,651b90b0,367cc6f0,23f4ad3b,3455798f,ec800abd,42af6eae,3584abc,cfccc4b7,14e98700,539ba36a,925da30c,ef57ebb1), -S(7ac961ec,59031427,8bbb04e4,4e79634d,a88f7cd5,d26d6ac2,a6605273,7adc5c1f,5ae54a73,cbfecefd,5574b29a,4ec5aa13,1912ef14,491ea386,85ca63c5,ade7e914), -S(eba2daa1,67aa43b,9d8d1ffc,b0784ad0,8bc563f6,243401c9,79d13396,bd9351f6,ece65820,bbe5bf06,6300f1c2,e16af4a,4d05263f,f4da582e,9e3892d9,9063a1b4), -S(bc674e6d,62757b5c,f079229,8b624c93,d1765e8a,44ce9abb,84047873,c62cc601,8056031,468638d,251fc37c,751580e8,29dfb130,f34c7f79,31618d3e,8c3b0ac7), -S(d76792aa,b3dd3405,45cd8374,958ee104,86b08dd8,1e1b99f4,c02b387d,b9cc3c9,63e21256,6b92c21a,378ce4de,cbc28dd5,2b563106,cb5afcb6,95f2aa02,fad96eed), -S(b0f0830d,80cb007,8c8f84b0,d753b059,6dc0f1a2,456cbaf1,bff5716c,158eee33,7d229908,b8acd65f,62a4c9c2,aaeee8b3,a1355e40,492552ce,1283fc52,d512fa4c), -S(86ed6a70,2cfbaf34,542ce456,b589a492,c9e19b4d,b18f4a73,3f257e1,2902bb3b,ecb26bfe,700e06c6,598bdca7,d0eb97c9,5992e438,c6d490b4,b2907af5,3850ac79), -S(fc88d9be,fe183b9f,3d952f51,79d0e2a7,2c56b79d,2a3c4408,948f4887,bf5b6113,c8e6d8a,91329b9c,c197c41d,8f2858c0,eae74ee4,5fe259ed,fd93bba9,fe3cb7e3), -S(c4e1983d,e86d3856,5381dcdc,e11910d9,2c96700d,a67bf713,3a6bf601,7461d444,39af034a,a1f8caa0,b01e4a32,2a8ae84,8e93e9a6,9c97fc9e,f8e8df08,2b211e3e), -S(6dd8075b,4456919c,bc97417f,7a94f6a1,bb9c07fb,8ed54986,8deb955d,bdc65eaf,bccb1ebf,57a86b87,2119eea5,17346eaa,bdcb5fdb,b3a71930,7bbcaf27,59781a9e), -S(a4ef5a0d,1e9a65dc,f4310820,4a2ec8f1,72aa8a8f,71604c8,39b026d8,a3a3983e,a7d682d,c7dfc382,a67678ee,12eae6ab,b6cfdb1d,7646f4ab,6c1d9269,1fbe338b), -S(9a250997,84509b90,f17c29ad,2bb39ccd,42e3147c,ab53c2a0,a739a65b,de4814cc,fd746694,ae6abc3,6898bf52,e0e6b3b8,a63766e9,d2dbc867,3f9b17c8,9135e4ff), -S(9e7b2662,58b0b90f,707211db,a9d4610d,4f49d08,c553dd00,f58c242e,2082c095,ac8fd168,bee47d4b,c8b2ffa3,72fa3ae2,657c435d,4d9f4da3,67c8c232,6d4b9820), -S(65646ccc,5f53bce3,edf35c57,137b7f5d,a49e385b,f101c5c9,b6182035,c45e0e0,6ae3b77e,cd3f9837,99287240,6a70ef79,c3dfb8b6,c3704f3d,9ba248ff,e6344092), -S(15ce9fd4,a87cdf9b,71e435d,b2148927,7ebf17f9,218d0d57,af3c632e,e227e2b1,47857e6a,2f5a9710,2c082dbd,d0edac51,65d949bb,cb9a325c,4f164958,a2413534), -S(ff44a162,2a259be3,512f234b,dee87a16,bb9d7739,cb84e527,29d60fb4,4d073fae,5ada42a4,9190f1cc,e16cea1f,392b01ba,89969695,8926f16e,f7aac2f9,a9cce2cf), -S(a5f68def,8670933d,907d508,185c3ce1,a67c62c5,33c3d65c,3c199d08,33536f99,d859eb34,2bd36baf,7e9f36de,f1dcb7c1,db6f0e19,12e7c9fc,2799afad,d210fac1), -S(4666bb71,c1e24ae6,d6c0f9d3,5a100fa4,309f30de,cc4c4935,9c937f51,243571b5,aba13ddf,96be4e04,97e758b9,d0532160,cbe62077,78297e4a,30a2ccd3,459c9e36), -S(131fc338,b0acc38c,b817a182,fd4919af,8bbaa00b,e0d80ce9,b46c50dc,8d7e972d,2761b62a,bada1136,4bc7bc3b,4fe7c0a3,b6d8be3b,d05bb3ed,dba2a071,188812b4), -S(5232eae0,3b377985,7e57c34b,4f9ee30d,a97714c0,bf33b63b,d520ec60,9bb18557,c243b06,ae8404cb,a01ab038,da6b8708,ec6698ee,f6d0f555,85f5e0,6d8b2330), -S(e95e4da8,afbb1484,ea1bf378,642ebd59,de13f70c,53f2b470,252eaf5a,c01823bd,dc77ce77,688e13d1,4083c7d1,d91fefc6,bfabde0b,bde46657,d3080d15,51cde44e), -S(9f3a7cc6,759db98b,f6b45257,8aa1a8ef,a2601d64,64028025,ddeec5a,c6fa8b6e,e5db2c3e,d23f72c,47d9d5bf,8bdfbe98,b9a1e97b,57d8a9f9,60f10fe9,8056a4c7), -S(96981f2,a1e0c0b2,1eab0a4f,fa56283a,5555bfe0,75ef938c,66dafa26,8f41d946,ae191f21,841ad677,420a77d6,ec440baa,c1426dc,dc2449a3,eeff6f7d,94e4f012), -S(d805bbe3,a8771fb3,3a22c51d,d73ad400,f7656107,3767fedb,3babebd0,226a1244,5bad82f9,ed6a1a7d,ca0532b8,87c7d7fb,1280c05a,f461321e,9065e11b,5c7aec51), -S(ae3b990d,32ad44a9,874da8f1,79e4f7e9,fca965c7,d7281f07,1df80c63,2b9dc432,3810d68a,b5cf8ee6,af08c822,d922621,8197cc39,194ba913,492064a8,5405a346), -S(69fdac,1c5be33e,fce9fb73,49f936d9,ad0d9afd,e1df6d00,df6599bc,4870b6bd,2fbb05fd,3e82f2ca,8c0340e2,d43f0d99,98f12f1f,c433046a,52aba97b,9d30ff3b), -S(1b0c0ecf,b0e9e6b2,238ee645,e33b44ef,5f102985,77df53e9,26fc2f82,d1aee964,9400ea2e,ba2d25f5,2607b213,8b30475a,67e5dbab,bf8e5ca3,38f84bd3,947adade), -S(7e2e1b2e,8f69a883,9d9e3993,312c9bdd,78a2390,251d4a1c,209b0caa,47eb0171,674c4c18,e61fd02b,660ec735,67fe7340,591c2db2,924c9430,bfab3948,d3a84eef), -S(d42acdb,d02a6a9f,da7f9d83,9d8c240c,7ae50331,3aae1d56,a0e1798d,8e668ba5,2c54cff7,bda5ac87,3d044272,b7bd52a7,dda6a14c,c9bf9e07,3b0375d6,6489e70c), -S(6a746102,1f9780c7,5eee2394,823354ae,cfdef6d2,46892b1d,c7150863,1e6f4c93,f7957ef3,1cb47e0b,9e3563e8,1fbe69fa,1e687e2f,3e3efe50,d21cc4b7,26053d29), -S(ad164b38,d21a5211,84b6d47c,be01953a,5f5b8a97,7f0d5888,b9fd9495,691f2749,5709a9db,404b1a06,5f965af1,7ca7a2d7,f036f39c,556af11e,9a0a7340,52c2b5d), -S(867099cb,84481d32,d9a4f46e,2e3338cc,9d5f14cc,f65d97d8,441fc8be,38e36296,8688faf9,7a3eeadf,8a42e884,3e0ac108,90f7f417,8620c0b0,49d13e44,9190ed8c), -S(d52d12cf,3cca7ad6,ea0ed7a3,92c4da04,8d31e279,63b1a9e9,ee5e9d07,b3ceb2c6,fce207b7,1aa22562,2f589efb,750f984b,b52208a1,6c07990c,768020e9,9711a80), -S(da5ccb53,c4c46a06,1ffbb2e,4814520d,ea373d68,1d426071,c9ca49c4,db5efcc7,28b00c21,4cf71f17,601cd24b,4516dd20,4f12fea6,c7fac2a5,43a2176f,1f150aed), -S(3e8a38b,505d7916,8e518d17,39198d6e,65139b44,edb38001,72a92b0e,410c4174,f7b82a9,62980288,47e06c3,e51e1a6d,f2ae9cf2,e2468e01,8ef79534,a8d6e0b1), -S(42a6d29e,4952ebd3,7169a99f,fa59742b,58bc24a6,c861dbff,ce79346d,78b7bce6,e6da3768,2124c365,878d577d,d1358dd2,b39a4bbf,e25f8bb3,dc97a533,c40ffa7a), -S(728aac39,15d078d7,4b687a75,6b166e05,d9636a71,bfb1103d,aa78fd2e,b8f22519,db2159e2,a71d66e0,e68e504d,40d60bfb,34f8be08,838c1435,f9018ea6,bd88c876), -S(ab5218a8,a7c5ef3d,f7538035,a1812787,f6cc2019,798935ce,92d9fa34,be65f3d1,fcbb8182,d8cc462,7ad1082,795c7b87,3932e97c,6bbaa7f4,2af231ff,67dc7b8), -S(e655414,ceff2752,990448ab,9159c7ae,50490932,a356bf80,d1669a6e,ad808506,cc0bf966,9915d938,219c197d,37762c8e,491d7cc9,48f1c993,c4406dc,384018a8), -S(9ee3eddd,519e44e4,c53bd4a5,f7101964,ac47a421,c72fe25a,96f79516,96c078c8,31f39cb9,f5441d,613eb470,5e9ea328,ff1f0b74,3835e7a0,f9b6ab5b,bb9de8a9), -S(dd7893db,e0028143,fe5739a,832e4aa1,ffecb200,d13f7b1d,a4877234,4330c15e,a38052e6,e03f06ea,d3c3f712,964457a7,52c7eef0,ca315f56,4060022a,66f6ee3e), -S(e7ab0025,d07507c6,6cd34270,8c0a89fd,53195b4e,ff3ede18,69488886,9eb91cc4,caede34a,6f8cda34,77bacb2a,935113f5,93b69979,18102777,bbc26128,9b0cb112), -S(47f608df,6d649b02,e55fdab2,a2bb4743,2986b9f8,61460cc7,c4961f51,89b57e91,179f29c6,6dd174de,bfa95876,22434b35,2e48f45d,658bf7af,d26a19a3,50333560), -S(3015cb0,87376de7,a18e7349,556b2351,72f27f37,e3a217ea,c7a43762,bd3e57c,a2e673e2,6b0f1888,14cffe51,2ff43eb0,c241e239,1f130630,dfab55a0,e12c844e), -S(aa7f171d,463433c3,93139c76,71d1a0cb,8b7745c4,3f3b1f1b,1669e3a9,75120ded,b8c9d145,9f9e9651,bee3a7f3,fdb71bb0,6deaafdd,1912896f,4b6a0e74,6869144e), -S(1847e63b,ca44c694,9ec3ac84,773af743,337d2dd7,46b6c5a3,ea9520ab,5af25469,ac19fac4,e3dd014,349c44d1,3436cb8e,465a754d,eb3f3c2,ae71eade,6c5a067a), -S(c11064d2,f638bedf,f762b481,719c85ca,7797e913,79cc3d12,3137ae2a,7a273179,7f74f429,8b47a566,bd3b6eae,80b47dcd,38e8780e,2ceb8833,dbd74462,c8f3db3f), -S(de6928c,f298091d,d1a42817,22d8923d,de25c954,ebfb273,80e17943,c641cbee,b02cffb5,47247542,be586c6,e88536dc,f6882d91,e76aa7fc,8769c2b6,5c585cd6), -S(2b8b1dc9,f379f2fc,a30d1f28,7877b47b,42f04b20,214c0beb,13aa2d28,83c52d12,1f660659,b7ea56c7,edd02c57,d6daa12c,d13671f,b657dd02,e75905b0,64d51d81), -S(90b39618,3eea7012,c537b000,f5f1ad28,e0416fe,6b1b874,effbfbfb,b963be57,bf37d7fc,ef9ca5eb,6b9886a3,b6b87f3e,976535eb,31cbc0b,464e69af,fefdf9d), -S(4fdfd77c,a033de11,59fc95c,ae07cd03,c570380e,ad2a376a,957bb26e,89bd4a8f,a1b30601,245aef10,ee891ce9,83cdbc66,390baaf7,b9c833bb,ecc34148,79f6a866), -S(7e2c3510,9c0a3eba,7b8b9d4a,c3c8d1e5,31304e45,25404814,fd66c3f3,3f12a1a0,39a8b59f,ed4d9d3d,29d8d1c3,130c1fd1,dbe7f2ea,cbc0770e,fa18e76f,3322a107), -S(4b80ce19,a7101706,b4bcc308,a4cd92b6,f8177a97,e2b2b6e6,1ebc2ca5,32c4b48,b72eb80f,55486930,94c8bbb7,bc6985c6,29c85d10,aff7d243,e5ead021,2b44587b), -S(8b07cf,264b3d2a,21705a59,dd82bc7b,573508f0,597831e0,336db2c5,c3702e3b,1b992b9b,8fe1a29d,d9781827,edb8ec89,49f6d412,12fe7e24,212f805a,4c4ff0ed), -S(3b65c4e1,d3171be6,67b01021,55644627,d64f9375,bc36fd3d,2c2a4fab,47a59e68,573fc9a9,1a09f5ba,78ed796b,496e1d68,a3f529d6,d0a77095,5ad16baf,e7b1e047), -S(baa6b559,e674ace6,a0378536,8643b0ff,42d8ead5,1c8d937a,7b1de152,62956003,eac99c3f,696ee584,7080f488,3b112c7,f6c69b2e,61a6e20c,135f5933,86289a3f), -S(e6453682,6cb25506,4107be9b,b0c2c225,5038c11b,96226fd6,5f8db8ce,70e32fe1,f74e605c,71912ac9,5e2399df,4f3ad24b,1c3a23a4,4b5ebca3,5ab8f31c,737d9aa4), -S(1aee4f20,a2db8e58,f33a8eaf,4a8218a4,b93212a2,60aea21f,64acfb56,3c8c5e83,3fc248a0,956a3136,daba7450,49e6330f,845ffac0,c2ed2f93,36ad1862,eb8b331), -S(8810ec79,33613ee3,49e0dba5,4a8ae34e,67a01322,46830eb6,41dea38d,c47f5941,c9c15ef8,c6a57a44,e9ea1832,c1c62dd2,c8aaba21,48d2153a,6e5a9001,281a273a), -S(cecb3ed3,a3380083,c8217e07,4cc0473a,3cd2c9f8,1ca8bc29,4494b01a,fa1bdcee,8ea11818,8b25ffcc,7d83039e,af605c9c,4132c83d,e97cb207,ca83f43f,26a557cc), -S(ea24fc58,d19415dd,aa780932,f7fded2b,e88987f9,9387d43b,24773ba2,1b810bc5,5176a2d7,a5d955a7,6452bb2c,49048329,b83ebcf1,2f3433ec,79573c14,4446e149), -S(facd3728,c43fb0e1,7f03a1ae,a7997e47,615706dc,3427039f,b994e14a,9a06d7be,ebe7826a,fec22f08,3108c710,9b944cb4,c4427b62,11f1f85c,474da8b8,25965d11), -S(439fdac4,66739dd,82c29854,fa9d599b,6fae190b,18192065,8a6cfd7a,1cbc9a5,f8bba187,677d0d3c,d50ee132,3cda2daf,d75aa6a6,1fca861c,2836d096,d1e3ff39), -S(167491d1,34593c79,6cb90f5f,868cea3f,56ef9b1d,e36a010f,a9d90eb2,9818d9cd,38303727,58f84ddb,ad5733a9,ef131555,14c314fc,4749efa3,4562c441,201d506a), -S(31ae24ac,8a76f509,2b721ef5,102623d7,eda96598,84563c1e,8177e3ec,6abf6ae,c3dfe7bb,c8017a0,e2f501a3,c5f11e04,d5a64dd7,ba2d0ed3,2082b7cc,fbeb2e1a), -S(b51857f5,526b8179,3e7bc5ec,7b74062c,57dbb146,1fe68d3,48dc3d55,d1c2d66d,f4313526,d268b372,5d1368bb,d40ac55b,d5f43377,de17bd6d,efd8f536,7c346f3e), -S(ce9c7eed,356d5ae3,b3334031,550f375d,35cd6e0d,eaa760b4,aac1141c,bda83df8,560b3067,c53c8f79,5916c5bb,34d99c02,efe4e5f1,f4cb47c6,f0662aee,2f07807), -S(1a9dc184,362a2f5c,58c53c53,160fde7d,f7b4c64a,e9753b7d,2d98be7,8c91cb33,bf4f3c80,8798aa25,bbca244e,1a070a57,c2ea26a1,59ae4ffa,84a4125f,c3b1823b), -S(3b3050a0,724a3c3,746e5bcd,832799cb,875758b9,2302eae4,82bc3c22,f17cd341,be5afdd,5fed6544,23bb069d,6dd96cfb,1b82cd9e,14dcb35,e0d7333f,54f924a5), -S(a4493930,c44f988c,fb634d59,5a0defbc,b6e9b809,133c0925,5c8ccc06,b93dca40,da27ecbe,97603604,2a559942,7176dbd4,fcc95ada,beedaa43,e40d5ec3,de5c4770), -S(47667272,59f47404,5fefe2ec,7f266c25,f9583c16,ca8fd4da,3149e8d1,bbf7dcef,526f565f,caa55541,d31524b,e942ab80,a895d270,a8cfdcf3,99dca02,75cc0f0c), -S(82715959,aa92d89f,91a7f53,af2d7e2a,2a3e8b85,2e30003e,caaea68b,774bb918,85188269,f1c8e6b3,328f1e04,1e4b79f1,8345dba6,49541f76,30dfd9fd,c1957b9a), -S(caff710b,8a246b27,1b7b8cb7,aa0eea69,3a1ab37,e58612b4,efbeb2b9,f1d4c1b3,7d20c6b4,5cc53865,7485ad82,43e7757,131528d3,ec134a13,b009032d,bae1ae23), -S(6270f6ce,665d2b6f,7d6ebcab,f556a681,78da916e,86b543c5,97771fc3,bee9efa,700f4b6c,b1487e66,af0ef5e7,9e98585e,b22c8e05,66cdd93f,db0e6ac2,809c4271), -S(f5d502e0,33d809c2,32f5eeec,bb4fa68a,97d5d231,6e06442b,2a3e5bc6,fcbdd6af,e802e5e8,ef9d6c91,ee5b858c,f6d62ccc,302eb555,2529cf5a,808dce72,14e3644c), -S(3a0482ce,c7c453f9,6a4d6f35,d8e3e51c,5f94b58f,a68e607,fa09cd44,ce09ccb5,fdd0d694,5601b9d5,437e587b,ca0df637,e17e7ea8,cedf9a6a,9f6f164e,f979e523), -S(54f22100,7ffff6d9,d5886947,8f164fcc,a67cfe3e,65986be4,bf9bf65f,8af89959,3b9af1d6,9036d3d4,6a6d121a,9653452f,61c3454b,2c786fbc,c497f0f2,e0ff792d), -S(7049ffd7,46bff6ed,c29f2e5a,d3dd5397,e96cc7cb,a1c30eb6,e71994ff,2036fd97,6e127611,95338ac8,ee94c953,5aa13afa,4f79d1d7,63994baa,e932b468,729501db), -S(f79cc302,7b4eb747,a7d67fb7,b1bda0ae,e47dae79,b410a6e,dcfda1c6,8c69b1f8,81d75d83,a5bc0e36,25d6aecc,6319120c,1c8df3ee,eeaebdbf,50ab9629,47715a9f), -S(fa0fba16,15c8c22b,3895ad47,8a8e2ea7,3438092d,150c86c2,8527b38c,2077a9f5,5f351702,7e1a8231,1eedd70,4cb519ad,f550dc64,dd1321f,705fa6c2,54a18947), -S(49b2fedb,7acc5ed9,7ab5efa9,e5b35377,b8dfe602,a0fa8a2c,5294abd8,9768aff9,f6b7325c,29f5f6b4,f3b18c9,366a85d4,60df8b78,ace02604,8af1cb1d,972e4042), -S(3623f1ae,9e3bc23b,7e9d758c,4444489,c3d9477e,eaf61b08,37f6ed,b9e0978a,f2176087,f401aeb1,f245a2a6,962afec9,fa7425c9,25cdff19,d137bbd9,f756885d), -S(67ada72e,262c36b3,cafec765,ec0209ad,c926b367,e5b8730c,b5d4db5e,37741312,7b1d7d71,511d4b61,450f847c,242ff70f,9729b2aa,c2e2d97a,4083e7a9,c07ca08d), -S(aa61ad71,44db1e8a,7d8a2f4e,80b471ec,bb891cec,7d16a8de,99ae20d7,9a11d00c,b344fdaa,bbaad87e,56d9093c,2fdd0bd,59316f31,2dce7a6,344ffdff,84ea71fb), -S(5dcce9b5,ba254153,bf270d61,494776bd,84f7be8b,f6a6ec2,9c2e3189,98e243d7,cd3b40e4,6bb08d2,5797da0a,6afd9066,63211e04,fba739aa,6e4f7f1e,d3068746), -S(8fbd32e3,c91dc619,ae0863ca,47b95a2f,3d8ffd91,1e41ce5c,b9bdf529,2504b1a3,b89f6d35,691e8155,703441de,b0d2d726,83247df2,ea46357b,ef5676a9,e582f29a), -S(dd31d01a,7af2d173,ba0c5c1c,ab7e59ec,cf8882cd,47904372,45d8a786,d1bd3480,91b2ec5c,59193d1b,1117763f,8c913d87,af40f6fb,abe53ef3,3e7548d1,eb211155), -S(1a9b64a2,52ecc6b4,4c17f134,cf32dead,66e4344e,44c200da,8c261d76,838a775a,1a2b618e,e96fc285,6be86b09,fa6caf61,4f7ee3ce,3bc34ce3,72c522e1,4a95905e), -S(ff9613fc,de744879,ce9a7c85,11508428,771d9421,b760d75,39adc805,61db7678,9a736730,5df91c31,9711c882,ede59e77,c09e2c6,f8b05232,2c0f79d2,77a4ebf), -S(3f29e50a,f584e0be,71247373,be4e9e33,8fca36e2,28f8498,ab57bf37,31deaed,b41490f6,72bcecd2,7c45a524,ccec1502,8186fd1a,759e4ec3,ce2e4a4a,abcca36e), -S(66457fff,d8836522,26260eed,4d00726d,ab8a56ae,26c68feb,f6ed99a3,ce782963,511b11cf,9237b49c,ab1bffdf,681f59ca,957a8182,ca2827b3,6cc962ca,d2becb29), -S(cd369d78,9ab5764a,a42dbd61,7fa711b4,757b17ba,fbf012c2,17a30cd8,dd42fd6c,42299f3b,674dee41,655ccb47,7783b8b,e54e0ca1,ffde384e,dd4cebd3,283196e1), -S(ad9bb10f,622b22d3,7c25ed15,323f1675,c6d12016,3f059469,6a8f508c,318c045,73f1883b,ef27a26e,a2dd4ae4,c399be8,2101c1ef,a6e67dc1,77dc343c,c56d66db), -S(2bf2ef32,e0277bcd,5ecafa49,910eaf8b,f107d591,fd0fe0d7,77b1ceea,c600c42f,6b8dfca5,f91f53fd,5fa8ae2e,53e72c95,9823c44,d2c4e7f9,7badc1b8,56e6fa80), -S(e7498183,bd8f01e0,c272e36f,1581c1da,907d7b06,8e3d6cd0,3d80c051,30dfdcd9,409fe739,b7f28ef2,4b94cc71,8856c99a,e67aaa3f,bf3bc8de,d71cc22c,9d4e4911), -S(b3921311,72c00c5d,fde1ed00,6aa50d01,9353bd2a,9e27afd8,60a71e02,123e7887,486cb8,d742f42d,9e00b8,e82083ef,bd1b8334,9babb4c5,a3a85c2f,9441fce1), -S(6cdd0e5b,edda536b,9c747302,4c3a8645,ee929f54,ed7f23b9,7a1cfd1c,77489e24,b190166d,b0ad70d9,f0b422f8,e5f0a0ec,91bd9cb5,f8bcdfbf,2c7594b,71c19e1e), -S(51bb4ad5,379c8dac,c5e6e19,6735c84e,9dde67b8,bdf4457d,35bf937a,3d726a8d,49bcb2c7,a0d6af45,8544b9da,674449e4,c099a56f,d0dba507,6b02a9df,5ce294d4), -S(c57bbff0,297f3040,3b81de70,fe524300,5b7456f7,997f4037,f6206e0c,277c74f0,316c5ab3,95b66038,ec5772e2,7aa2f7b5,b54e5511,6ff35e0a,5c4aa11c,efa8d05c), -S(ae2607b,d956ff85,12b5554c,b188978e,e0408c13,82739be,4e68b9d0,7bdc45eb,294424cf,51378200,ad3eae19,26f89a73,ec3398ec,8af9026,5ea556bf,83833a27), -S(95671646,1c47678d,5012d1e6,5b918e89,c96f699b,a7ecf63f,d6eb275b,1fe508dc,abbdc408,a59b2e85,95a7a2d6,fd133767,849888b2,f17070f2,9e827fa8,17bc66cb), -S(e98b0e03,d1011075,928809f0,aa62f238,40e8319f,b0108be0,2925a291,967c7702,ba34d7bd,138fabe2,11ac56a2,2d385316,4cdcb1db,ee647cbd,73493391,a87027ba), -S(c0f9812e,b7f529aa,fe875709,1928b262,1277a751,73011d63,b0c92efe,a02291a6,ed5f2cd8,5e85ce14,9f59f50,f3a6db29,67095adf,91b08dc2,fdacc0d1,d3d56391), -S(fd4dd84f,75fe56b7,543a60c1,7a3ca1b4,6f7b9b3,6d6d5c4b,eaa18a6e,6c4ec6f7,cbe12b0f,c1bc2973,ab395480,50d768b0,8c9ff86a,97f2ab4e,942cf095,a10603cd), -S(f00052f0,700d99e6,4d94e1a8,a888abce,3b15b52d,1d08f20,3234e5e8,9ee6cdaa,709b247f,f1daf175,ad7c29c3,bb5ec78,1521c5a3,3e4674bd,d97d9891,7efb07d5), -S(44d51252,7024b64b,f6d30ed2,9e176fe1,fbf22cd7,5fbbcb13,4aedeecd,5ed2c023,eca73cf2,b90a0f38,2745a43e,64048010,259c0c74,1deea6fd,bdcaf497,9b1e2f2f), -S(15651366,b6cba09d,9409023f,964e48fb,422f3211,832000ab,6e84e1ec,faaa1472,bd79070b,a7100d6d,63795ff7,43a26834,85996819,e9bd81c8,b08dc473,5e6bab6e), -S(f8ea84ac,35b6e596,5b6ea25,8411855f,71de79ba,ccca4ef9,b79eec8c,c9e098a4,58da08b5,26d6d3b,22ee2b0f,7e04d2b,ad902b8f,9f4f1f5,454cc0ec,fef6a2a7), -S(f4be9c47,94b6e479,8ba892ee,3aee0fbe,b0cd7ace,1c9d2f4d,ac03d92f,3efa405,e6828465,7a6e2175,361a914d,4d09eb7,2468da10,d72dd3b8,47b71e5b,6c8593e2), -S(65cbda31,ff7780f5,2b31a743,ac03eabc,4f2e3155,8083f198,46a03ca0,d582e348,b8433ae9,848e425a,603c4591,8f64288,fb58c184,454c6c1e,e9d8748b,c3a546ee), -S(e1bee56e,3f500a9f,4b5e0557,157bcdfe,9223c357,2d70ccef,8b8542e7,f24bf9f8,c5b84a5d,395d9c19,8f1cab7b,3a9cfbf4,dd129a03,e9fb6019,b99c48e2,a0d574fa), -S(7de38584,d12ff024,a179f361,5c44d704,c4dfcac0,4939a8e4,a46d1574,7b6eaff9,2797f251,ce328323,e181c130,59ff6d2a,261a12f7,ebcc0dd0,55771a4f,edf812bd), -S(5767e926,fd4ad964,f4bfb7b1,c6326e55,97f9cce3,ada51a20,6b4808f9,e8abbbbc,64a80f76,8a89806b,98f0bb01,b370c200,149c5484,a9cb5f3c,af8e47a4,27813693), -S(828bdd32,18e6f809,6c1fb305,1e797ca8,3914f9d3,ad051eda,d2964cb2,dee88c6e,5a7f7cbe,166f2cc7,b747a1a9,3e3de1f0,3a0da8c4,82eaf9e7,d5ee7e7f,e4936882), -S(617fc9fe,3af26495,bc6277a,86387377,55398b94,1665b70c,32d5a2ae,3d8d2909,278aa70e,58c0ba89,f44dcefc,bcaa7212,e52d8eb2,f3735772,11e864f,2d522ecf), -S(1f823558,2c08ac8f,f58648db,194bd6bd,1f3659b5,5fccd0f8,67c9f11,86e20634,bf356f2c,fa221b73,bb118567,518147b8,f0c8f19f,b82ab45,41e12b1e,c9fbebca), -S(f6229866,82530e4b,301cc0cd,576e9fbd,a65bd52a,d85a3ace,6477bd57,af52c718,9d2cb0b6,ff327470,e8beeda1,1e2d390e,28917515,a8bbd587,ec303d77,f57ed72f), -S(423a8b60,fe61752c,95353258,acddc1d5,5ac7f226,695d1e73,984ab059,8810f220,feb12e01,7501fe26,72059bf0,dffd41a,f952a4e9,84491463,29a4d294,895eb654), -S(f55b2c40,6ff6f463,1a2715e9,d1471c98,9f3df537,75e5980a,2a48032d,9936ff12,67888b7,e6116a5f,94380503,d1fe63ea,a3ea7f71,64e79500,a0db1201,31acc6cc), -S(cdff1ae7,ce2ba4ba,8c8aa999,aea60f06,f6dff050,2e802f6,8f27a352,edf9e3d4,81cd9da7,9fb9adf2,31243148,623906ff,3e80d730,a4977dc4,16539452,58d8f2e4), -S(ba7cfaa5,96502414,984b4105,739c5fdc,a77c6eae,f8b96cdf,8b8e9fe6,f7f62819,bdcd7dfc,ab11f75f,e5eb04c5,5e7d8f4e,b622ddd,8134e668,cc9f27cb,bdda688c), -S(4a7b5b47,865e94ef,65ee1053,ffb75ca9,8a7a01e7,78d8c9f3,9a8d5c9,ff2daeaf,c64ad5b9,2a5b9995,77eb3a4b,5347ebee,99e5bc19,15b1f43d,5af38361,9050e5a6), -S(26a13407,1f6b82b,239bfdc8,ca2a7f94,110a63a8,b20ed990,71d63e5b,938ed91a,14fab6a3,819f4bdd,348ede08,397d7f81,d514e99,cd777fb9,f42917b8,4cc80b7d), -S(154f8ad5,405cee5b,42ea1910,427ccab0,1861c0e7,29a1ddc8,7e8307a7,5102bc4b,37c6a2b1,f7532681,7621f58,75db7b09,18118be9,6259ce12,ecb15459,3231209d), -S(184496b6,b31e534d,ea2a9712,f22b83b5,a82bd14c,2cb90b8f,b20cb735,3d4b9e39,bdb92f21,7807d1a8,82912dfc,50b3af67,ad9e936a,6409e263,961a82f1,31fc4c0f), -S(2d781eb,a2253f32,75feaa51,fcef2a34,413effb9,2f6523b,371fbe54,3f33789f,5c0f0c47,b11b4b38,5e8d2d75,eaab2d02,39c2e63f,125f21d0,17d34fd9,d1f6a91d), -S(cd6fb1d9,790c93a8,3813fcd,8036c0c8,af3c431,f21d334d,8816001a,41eb83ae,15f0f885,511a12b2,804c90e8,cab5d209,76db1e9a,9fe18326,9d1c7570,5bc24f65), -S(97f9ed25,9852a72,3b4bd360,681d52da,fc7d17b4,5e7656de,1448e499,ceba2aa8,3c609c78,25553260,a85ccd6a,3fea7b00,aa87e76b,3e0e08c8,2f7c3fe9,ce760cef), -S(72765585,fe283950,cb316f48,d847132,8782681e,54dad1f1,c0a0a50c,c4086767,147e2389,3ad0d7d6,a3472bff,2c6560b5,93b554b0,e6247618,3439c576,205b4fd6), -S(fcb0ecd5,93a00061,2439cb19,f7e5f71a,4612ec9d,1b9b825b,8ca322fb,daddcf3,5e9f5967,f7131ebc,1959da85,94069704,bab1d58,4a06cc8f,78cd4140,9f532eff), -S(ad12b476,ef630659,2fb0fdbf,522314cb,9f185f2a,e420b057,880068e9,7fba5539,38ee0f47,57ce8f0a,bb6cbb47,ecce2e86,5ab84597,f6aa91bc,4c4c6b52,68755886), -S(372e498f,7ac9618e,3850fbdd,c9c01995,d96747be,2183e472,8dac7ac5,a1c7cf65,4d5de2e,940b12c5,fdc8dfac,69c7da20,4b92e570,b59a8bb,2cd930e7,42b76cb2), -S(dd613209,fe9e2699,9371509b,5162b3e6,e3557515,c73eeac4,800f6e28,28b56fb,fb1c28bd,c0b4c0c2,bcb53557,5b3b4377,c9f29786,31ae6c65,490ef38e,7fcbe1c), -S(8da18bf,6f680ffa,bc4104a2,4b397a87,25240704,287d7532,72df2321,dd94402d,46ccd8a9,401c4fb1,9c81a737,43330fd8,d3a60361,b94e47f1,68342280,373e7264), -S(1800dce0,a2f3a3bc,29d40690,ccddba47,fe8a71df,e646fae1,15d4a784,391a13e3,b333eed5,deb1b43b,c6646a2c,909012d0,21c0796d,c14c90f7,d49c6b68,52e1920d), -S(b6041277,4cd089d9,9c3f4434,2d328b6a,bfbde44,11a60f38,ffdab086,74b834a9,3157019a,32bc8cde,344e60b0,970b26db,4be7077f,956e98bd,39cc7915,64a13f2f), -S(8be5e638,5fe5f9bd,813449e3,bd76b6da,b4ed7fec,ba853ee3,a302270b,556281ec,e114a14,136a7341,5e8af8bd,23dd589c,cb10441,aa173eaa,21c06ff3,c03ff1fb), -S(1ddbdfad,990c5764,ab076a62,27497400,410f5d84,3b9f403b,d4f51e5b,f0736518,b2688561,7ff17294,9c8f89ca,2827f0e0,a1483e8,b856a659,a009dc68,c5683f0), -S(15458735,4f122df2,18c33929,8fcd0bd9,d032411a,cb76df93,31345ba9,668413c9,1b3d7e33,cda314fa,fb90abdb,b1ee2105,27b35732,f0b77f39,69c942a2,fbc54195), -S(925114ed,22625dd6,d4d947df,87a2b63a,a97f3a6e,d47afec6,9e11a1b3,3b798630,55e48dbf,a47c887e,e3ba5758,4f697f6,7f6a1d73,fedae7f6,f63e4592,cfb33e03), -S(9111ec73,d2e56190,7db6c07b,e7324fbe,ab51d18f,8423d484,cb6a0d,a0a7ad27,f7317b13,4befd605,a28b6549,1b2752f3,26c86370,f5042832,1dc22b0b,9240c8d7), -S(f2d1a752,ab206393,7f780a3b,9f39d87e,9d257c22,beb1d286,9434256d,ba9dc3ea,39d4603d,e66337cb,f0b9d39c,cc40c16f,4835ea6c,aed5d7b6,2cf67ccb,35d5e752), -S(2588d10d,a854b844,afb998bc,23aa3742,76938d27,b08ddf70,48605df9,ad55fd52,826c2422,4d95ae53,daa562cc,88e44e52,5d3ff878,ae350e30,c1c633f,219824b5)}, -{S(2def7e67,7906cf3f,3677e7b6,1b0a8f8,985fbd9b,23265ea7,18a5c16e,139f0a8,650a89bb,df8c8326,d364fae7,558de827,a529780c,9b7bf8f1,c6925632,7c59c74c), -S(6e6cbdef,4d5cbace,b79293f,ecf1a4a4,5de81e3e,97e4c30a,ccd6cf79,5668a013,729e4c49,2f454b35,4b127cc3,788bb93d,fd83061b,7f7f6ccf,c24d3fae,d96a7f6d), -S(29d56adc,c1fe441b,123a94e3,fb8df47f,d8bb8565,40c1d3a2,d8e7ed35,c4eae6f5,6a3aed22,6ebdde19,d2bafb8c,68656edc,9e3da959,f2af9872,3ad29a04,8a549a33), -S(c243cf24,3cc28801,e120fdc7,ab6f8ad7,531a5053,1094cc2c,3a9476fa,e0491344,3decbb31,22c91c6f,502eb3c1,7ac22bd1,509643af,3bbcafa2,ae2b6eed,18decff4), -S(2d2bddef,e75d43d4,a8b4ab19,b2259a6f,24bfda1c,11fedbf5,a12fc353,f0039157,215173e1,1a9ac83e,b339dfa6,ed66efa9,da876aae,5d1a690,4c8ea43e,63b683b6), -S(d2796d04,f82115d2,c4849c4c,be608005,1a2dca90,9773a524,56b2fc44,8bd6d7e7,be176139,829c1b69,352e502f,23b724d8,1181ce81,c447e253,a2bc132d,e3bee967), -S(48cda6ae,152ca92f,287a9cf7,ae9be740,29cb8e3f,afc859f5,31f920da,883eb4b9,55fc18ef,af858cdf,a098c4fd,8e3f41a0,92292093,a3c66866,1361edb1,c07956be), -S(702bff16,c5121a82,cdb8d6ed,fab0e741,f76c08a1,70bdddb3,8ff191bb,3a96ec64,5525ce00,3cbab9fa,58b60b7b,5b5e85a1,e208517f,91b0caf4,9adc0c5d,ac0e6e23), -S(98d066f4,30911d2,238cdc81,5133563b,338f9a28,2da63518,6635af43,fcdc27d5,6f10df8b,7bbc5ed6,a64f1884,1087d5f5,6cdf8df0,f9dd493d,23f6996f,ff39e065), -S(44e69b1d,5b7c3816,af2aa890,dec5e389,cbdfe5d6,44d6c0e2,f36527a2,6127b24d,1ad0e960,7be9fbb,efde8dc3,6030d3a6,41e325b9,48129ac2,b26cc1bf,11b331c0), -S(adde6eeb,fcd63063,ce995ba5,3641b01e,f0797d41,d9e18f78,43972f89,9d7a518d,7002020d,f2576876,2d82a067,139387c,7956680b,65fd70ae,3d75bfd6,fd0f77a2), -S(f0f09803,b43d4c1a,f187d94e,3dd9be54,703cae52,5f15fa37,ddcfbf24,98c9c24f,96f4a35a,40523728,10ebd243,ac6d1419,672fe0d0,c013f1d3,460089a9,2457f7dc), -S(dad39c7b,d3edaea6,3ff16c4f,a9a30a9,36d7e447,939327d0,d4a7fa4b,33d7126,6a927d43,3237ff27,f3f87631,c85e4294,1b188fc,d5ec4780,a58409a,cc95d02), -S(b44484cb,b4dc709b,4c21cbbb,2d7d94a2,c5435cb5,1fda7dd4,c3b787f,55df5d1,70e35874,be7a22c3,1e43f2ef,8b4eb222,5c1dc3a8,cde5fc0d,56ab9970,bf4db709), -S(84dd9c05,3cecdabb,b3ecf8f7,c8737e22,634fea44,80c03148,38d6bd35,6a15634c,7cc6a067,81eefe79,d565946a,96114b52,8a482eda,a9028c5c,b925f037,a75335b1), -S(e45d6bb0,50e66a94,d22b770c,9500d960,6f529222,441bf9fe,7856899d,edf3537c,5ec38fe5,7508aac0,eeea33ac,3aa44dc3,e600d184,a4ddb9fd,64acd359,be96336b), -S(25f043ae,b509364f,43ee5ba0,291c95bd,d442fdac,3f00e338,6397fd4b,295416ac,42456a08,64245a0e,5dc9d06e,1f4aee74,b4ca1c80,1281bdf0,59e319af,f79c7ecb), -S(77c7a59b,64cf6153,275c083c,ebecc3f3,59e66002,3bd2344b,a465cc5f,d44b6938,6415da93,e98298ce,60d96880,2dec1899,84badce3,642ee36,70558d0f,bfddce01), -S(1930909f,61cda446,a270581a,2bfb8ef8,14af75ab,aff6db5e,c9235020,af199c3f,4b7d06a9,5a7f72b4,ad189ff2,348a63c6,522e8b15,38309e97,cbbcb121,50f53498), -S(14125e3c,7fae63,cf0103fb,8bb86de4,b97572ce,eb872dd,5d850825,c1c5b43b,dd1327ad,8570188c,1817ee7e,37a164b0,9f37fa90,88784d96,f91704bc,e3e50b71), -S(c8e7c8ae,b060e8e3,1e768fe7,779ea91c,3e62cfdb,80893516,825d13cf,6636face,e08a5ea1,9b5a859e,6f8f6a1,43dbf751,854fd9b4,2ba6c1fb,80acdd9d,9db87987), -S(3258309e,4b1682ef,5622aa75,ee7a109c,ad650ed2,93edd279,55fdb064,c35abd92,4a192aa,838bc722,8c0d7fd0,200d55b5,241cc762,d252d138,dcfabe8c,e2ffbcd5), -S(42a5f570,4745968b,a836648,373af34d,d09c8f86,536004a8,6e043c9a,4c11a57a,2bff198b,5e8bd837,3011ccb0,1fa54719,7030f47b,eaf44ce8,6faaa86b,166ca642), -S(f0d3e1ec,fd41bc71,d2950d5,d6db5614,e1b560ea,f8119175,f7286a8b,d9c6b563,f4c2e948,a30208b3,a7943bb5,564747e0,50e079f7,703a0d5e,f8039d8f,50acc8d0), -S(7f918a96,3c4b42f9,17c61ed3,f4be8d22,c9055005,a5a3f02a,6def60e7,305ab89e,c5e60518,189e093c,62d6f7bd,de1d723d,878683f1,22b9ad69,2a300a42,c5ce9b5), -S(c8663293,f25331c4,a42b1e16,bced09c4,bf7407ae,595e1331,24d0f7ed,99cf422a,df5f065f,d7ee1232,8a3428d5,c8485a28,d882f31d,e66856a6,ee4aa396,79d978f7), -S(778cb411,8c5128b4,8641ca54,2cbed0fb,e9240380,ad3736c0,cff889d7,1a6cc639,8a1d3417,6f2fd7b0,20b46be0,7905b963,cc1a3970,c2bc1995,daea532f,9ce8ecf8), -S(11e3d37,e28172c7,de168ff1,2fcab6f3,3441c007,1e562bc7,d0f13392,df64d0dd,a811db15,8e49072a,7a238be1,128618f7,d7ed2e15,bd437aa3,69cd2a8e,3d28d95a), -S(d65b7bb2,143c9f85,c5c43c46,57cbb87,3d9df9eb,876fa72e,a1f1a221,37a370a7,f2823561,e19c6208,64a1e8ec,ead2101d,175b7255,2ccb63dd,937a5049,3033b986), -S(d02ecfd4,74b5d84e,96111bbb,c88bca3d,95498de1,4d133893,2c4c6068,9f19efe8,87c93642,866c847a,d592a36b,bfbbfc8a,68b3da63,a7d7f380,ce472b0b,9e0f1325), -S(978310ef,548ad9fc,1872bb08,dd0f9ad,98889ea7,719c5cea,fdcf1bb6,9853e2f,d067d57a,4e7ebeb1,f05127c7,9c4ba3e2,fbc3c2ba,9cd9f2b,66182d69,2c699e21), -S(66d8712f,a2221e85,3f4301c1,cb8b1413,ad9288cb,bc64a778,4881de9b,bc1ace0e,67f8a70a,475e9208,c1fe988a,e9ef79b3,67295abe,9ae283a1,5801260c,f916f8f1), -S(da8b079f,280a64db,a73ed601,2d183e75,175534e6,cc295a63,477f6905,15b3daf0,c55f2528,8812131a,99a89f92,cd6204a6,26a7681b,e4460ddf,9a1940c5,8764f43b), -S(1a2bb7c8,96722b4d,54828c68,8708bae7,31937165,daf08d98,eb02fe0a,a59cd00a,f0cada44,48f88668,e46425d0,f64452f8,42be2fc9,bf33002e,fee5cd76,39e5d581), -S(2a55bbff,5aecb50b,97b974be,f0cd3203,34752370,957a9e60,37f2930c,e11a75af,69f9db00,b89a2063,1b4097a0,f90ef087,a9f7cd81,ba15c60a,faff63a6,a4add6a), -S(2fa92f18,83e0ab3d,d6976573,83734908,a4873e8,bacb0577,c44bf104,5500b6c3,bc24564b,d4f60723,14aa2864,216c6984,22caf8dd,afe0e4c3,a86e12b1,5faed4f4), -S(5548afc4,b095db29,28511e52,bdd99a63,18e5e15e,17e99da5,b9e0ef0,375b0999,784726b1,d2152b34,4b0c1a2f,b90893ec,80ffca3a,85fe3f65,7be4a850,175982e9), -S(d4a524cf,6659a1a5,e24a40c2,8e4c9cf7,da607f9f,c209f88c,63c35dd,4af282b5,a73bd4b2,599d92c8,395be7eb,cb70d741,154291db,151e988d,9a7a4f84,b277b886), -S(e0fb0973,32dfe006,54ea1a3b,858d8d6b,30c26fcb,c4339ef3,165b861,ead90352,43ade413,92521afb,1e87f477,45ca8b61,23775ed4,9a1c789f,49a2290e,1d032def), -S(ec03ed52,bcf2ed6c,c7fc2a19,c95a53cc,3b66e344,4d35ae06,e5d17e2a,b6311f0c,a83cf9ac,89accdc4,667686c1,4dd83d8,d3633ad2,6420da7b,321b3123,4d8150ce), -S(dad8eb7a,a7a8686d,d78c18ca,7f0d4d29,edb8ddc0,4e5dc2ed,4e0f0694,1551aec1,10e00983,af99a823,a32d82f4,2d7845df,d3828133,963ba48a,19497860,d975c600), -S(c883f469,e74f4434,9b4e1459,5fccb517,7e2c2f8b,445feece,901dbe96,a2556ee6,2bf2b62b,5b1c3415,29a822e2,16ede0cd,b75419b7,d212774d,7cf3721c,4b9d496b), -S(8c71d17f,cd711b3c,4e2c1214,64d9dc47,c36db06b,c877a0c5,8a31cc25,2ba585a6,9b248bce,7f4899db,4c8e250,c642d24b,20419ab3,a65cd4cb,624433c6,37aedae6), -S(4be86c17,32474f86,f8331f50,b316e0ce,d6591d47,49875e5,33e1b825,7b5cba39,c4ea74d5,62489423,45aa7cf7,82bab029,8fe58092,4943d3a4,d2fc6f0d,7d0fb590), -S(f5eaf803,98fa27f8,27771d6d,50dba53f,32beb3f3,40d6c045,cf8b4253,644bbf5a,32809769,fce5eb19,f0877c19,317e6200,11303b0b,7ade7e37,abbec95e,fc83740a), -S(585c8726,bdfb440f,8cee9bc2,4461e3f1,8cc7431c,e8f1ead9,af2525ad,8b32abce,3ffa336b,a5bde184,676f33dc,e46c4114,4dc412a1,8db059a2,d7c6b021,7728c62e), -S(9175ea6f,746ee2d1,bc893b3b,6faf835e,ef72ba7e,588128a6,56cab59f,737871d8,83cd907d,b0d601f4,88cca1eb,283cc2d6,99913dd8,391eaf27,cb18ab21,6c13cd8a), -S(c5898c32,306bebf7,7a89cafc,29b49af3,d1ab7fa6,95072cd8,6a8c2bd6,aa8f5d14,2313c593,c67e797,49e44600,7181b257,dbc876a7,e3e04747,c3db35c7,d8df24e9), -S(d101d707,76661eda,ea604ac2,2e449d83,57b638b1,aae03a6f,2683ebd,f6e2c413,7186ba53,b8b1d9bd,b4dd2fd3,7b48c3c4,144bd996,f4254291,3c4316c5,2a98ef87), -S(72213fe9,8e8c62cd,bbf8264e,6ac01240,f3dcde5b,b5f71b46,4d8d5617,6fa65efd,80b256e6,21a5041,63b31c96,7753adfc,9c27b4d8,cea73e91,dda2d5a2,7bc50fd6), -S(274c0fa9,f1dde789,1f88b202,4c4e78ca,ed19ec00,7c6c7a05,6028fae2,d8ca3f2a,d5557bdb,96e52182,83cfa76d,f9f0f83f,2619f951,a7bffb66,8cf3732e,7beb88a7), -S(7d3a1d16,66c2b5e0,4f7ed96e,3762d04,118aa293,69fcd8a9,1cd8bdd4,6e862e2e,a004e644,7b49421c,af6c82e2,1bde2b4e,84d663d1,a39ac9e8,5ba43b4d,73e7010c), -S(77069337,2c31713f,1108bca1,730e3d0f,927d0c8e,4ce7dbed,c2c02a60,b3e54d0e,a935c735,18c40ad9,5cbc8b51,9c859f7d,b48be573,cf45e6f8,cd47b8d0,1546372c), -S(ee44b4ff,e008f122,b4ce1a11,d98cc674,e340c874,f0c5c0be,8008624f,b13a937e,90e4a82a,8f002b78,7fc34998,cf015340,dd4854f0,78d87641,bfcbca47,df06a728), -S(61c0e32c,e6615b09,304ee233,90435b99,912b6de4,766e0c14,5345956f,af9e89c1,7531bfb8,414347fb,650127c6,b1f78ff7,97a092c3,2c37d358,8e612cda,9faeb851), -S(bd7026fb,b47a72ea,d28eb317,35ff8ab8,ff244b96,51fe4205,adff8247,2b9d0aaa,6dd60501,40359152,83b7a16a,3d0481e,e8c7b99e,29843068,28c41727,28f21b9f), -S(8fe350c5,b5882f87,ee976108,2ef77b55,8355e02c,9ac40ed9,76d45187,9e0fa902,21b32a84,f2f31dca,9072b843,6c21ee47,9c02c710,48642a62,2c485449,b907f6), -S(93226eea,b65a86e7,c0fedc1a,f6b038d8,7f587823,a9a2ab13,a9975ad3,ffc8bb3a,d294880e,867877d9,b5d87b20,3e7d7860,71167666,fac09b3e,9fd82033,84c4d904), -S(1fee0dd0,4dea34c7,fc6473ab,e89c2e43,215c5dda,6918e089,50d7005e,df1e21c7,dd7b1dec,b1a85eb0,69cfb830,be847f89,8012321,549e2611,92e719fc,2ace36e4), -S(e6304e92,38fedcd3,580cbe51,564589bb,18ad3cf1,3846dfe1,ba40786a,bea415ff,219302d2,53133378,ab25b331,bbfa4ec0,e88178dd,c2a39378,dee7ce64,4c8dc6af), -S(91f97b4a,11051415,7564c8ea,2a60303e,f6f5941,7cc5a556,ff244e18,444ea39a,80fc4cc,3d57cf97,6c9e7794,d89e1b33,d5849b02,72d3e544,5f73fb5,655d54a), -S(7ff60990,34769cb7,5a697d0,418ec2e2,9c5a9716,9ad6d127,ab106518,9fb7b2de,d7fcdbaa,8aa89058,e1f0cbf8,409b9879,6672b305,b6b24a61,42562de3,2b1dc49e), -S(a418647e,61276567,84939f3c,2375d1cb,82871b1,b8004a12,1cda8826,1eb5595,62797683,2528565c,78a7f4b9,d55fa782,bc97a3cc,598c7579,d48b136c,eeffc022), -S(26d408c6,39f97be2,511b4816,5e862d13,f6aa816e,1e936474,63eb47d6,eacfbd67,2e3448d7,fac889c,c9499396,c2de66b7,cddc064,186b6df6,3a6a831a,6672c34b), -S(56f12bda,d8b630c7,5ee497a4,93d48907,63eb1bd7,93d03fee,a19ff997,f42f5464,4d1a3990,7c650896,4fa7ed4,e815379,8e2adf10,80ba7246,3b4e3536,1e34c3fd), -S(e350608b,35cc41f,9fda92f9,34d16e58,c53244df,1446b03c,2e782a53,2926c9c4,b20d72bf,506c2bc0,b35e022c,c6e2bbfc,f34c71bc,a4b44a2f,317741e8,bffc1dc9), -S(5a7bd940,cc23b3e6,614c92db,a08bbc7b,63dffd6f,11117b2f,80c2fe2f,849de903,502e5557,8fcc9495,411c7d18,9979f7fe,8f4f587e,53991dfa,4ade527a,43cfcecb), -S(99ef5580,b219aa84,4cd407f7,d949c07,f7452587,bab97ac1,faf0b143,7351be63,512adebd,49f4f2aa,a26dfb8f,e5c483ba,6ed5b4ea,5d4ecb88,bb165a3e,2494faf7), -S(99c0c468,a95e76f0,37988aa4,b2ca903a,64a95b17,19f119f8,e12aadb6,5438b9ca,fdcaec6d,c390c33f,31b4074d,7e5a81fd,f2b9f8cd,b5f14957,533bd406,fc68ce33), -S(a9f80643,5f1442bb,8a14f402,6ff6ad43,4d84e34f,cd499aa,adecb2d5,125f1829,533e1697,3a3b7b4e,1e82a4e4,115f8be9,b811e787,61fb10dd,6908e0a7,aee4a7e0), -S(8ed6f9a6,2ea10768,4f90825a,e81d486e,92a9a890,78d144ed,53f54cb7,3568baaa,d99f33c3,b7311023,c4266c5d,adae7ce5,a6409fba,d3767f3d,669aacd8,230d8568), -S(84dff52e,25665e13,102e23c8,698e8990,e5d63e86,330703bb,54242843,8fc9a46f,b1bc70eb,f8ff0905,e2ba529f,1af149ea,536fceec,2a5621ab,bcf89756,ab0f69cb), -S(1bc3844d,78f82cb6,ada3b0d8,86b4f89d,1a4344ba,431070a3,3f3dbc77,2c523410,94580bbe,a198dc00,2b226e48,7a745090,ec603b3f,aa6e5847,8a8832b8,3b0fb096), -S(436e0b9e,aa94e6e,b20f58c4,678ba5fb,5e1d79ca,a7bf4179,3b91c962,325979e5,1615e98e,ce7056c0,428e55ad,f4353400,4ee4e158,347ac5f0,715b0f7f,86c17047), -S(45f8a062,4d3ba9dc,d577dee2,f5387f25,3eb3b53c,31fc6e97,836bffc6,f85b9357,b7a628b9,b9068247,d8415fcb,c5f6e6c0,e72dd75f,cb1abb62,c947cd06,5ef22ed), -S(b86ae36a,bb489583,84e95ee6,8c46c0bd,8f0110e9,98e34595,1f6e6b59,fef4e2d6,2e3ef338,ebe96f24,ac112d8c,a6803f9c,338179e8,c54420c2,981d0159,27d983ec), -S(247b2b62,79dc1d09,6085fa0a,390bc09f,2caf6d90,24f953a7,54aaa29e,a418574a,4d3fc5ab,9b3912ae,f67ff98c,2e641ba9,bc23aa8c,f60ae6d9,cd41ec93,7c4a834a), -S(737bc72c,964ee56c,822f1e31,9ad6f9f6,57785748,55689eff,492c7587,a98deae9,2aa7dfa,d4f105b8,690a507,8fe81eba,2736c301,6ea4fe62,71e47d50,18e4e01e), -S(d2ecf284,fe7663a3,810ed1da,c8533d5b,a647004a,3e22683f,78dcf0f2,1db4c5c8,2fc3895d,beca5b8e,17a2e3dc,3346b957,3eaf4457,ab0a140a,6d119304,9349df04), -S(3cac275f,98f2ef42,b0f78a1a,52218150,a18fe23d,b1361151,a3dc7477,fec811ea,a426ed39,41b7ef3e,48b0e267,fc1cbe50,4b1e5671,f4dec906,a2659792,2ccb6259), -S(f74a08a4,6fdbfa99,843c24a2,f9e5fec5,b941c29,43a25cf,131deb7f,1c3303ff,6fb92df,aafdc8ee,cd7c3416,fc89fb5a,458c2c97,84f71698,c512981d,a8edfb2a), -S(91d44932,56fd4608,48f04de7,25b3fc8c,656a38d6,f8e319f7,1ecf513,146eefcc,cf058db7,69aabd80,12ea780e,10aed66f,4bd5e356,1b0d359d,167ebb3,2830edd8), -S(d194e53c,1a2a2c80,f7bb24be,b372d751,118da62e,9901d94b,66cfd289,19387bc6,aeeb2818,d00b7307,79fc14d5,31a3d803,5e5642d3,b7335543,13c8fda4,c940b387), -S(ec18acf5,a9624f91,1273482a,b03ec7a3,345ccc2e,282a6fc1,cbf89a2a,45e798b7,ca9f64ec,caa12673,a2901fe3,684ac70f,501b4d63,601fccfb,4cb08e53,86671cfe), -S(488bc882,77874baa,6fc9edab,ee101b5e,1d082a4e,d49da47a,af5e6650,90e0566c,9487231c,3e6681ff,bbf953da,54ba603c,89a00340,c4e50c51,545a5c6d,d51b98b8), -S(25d4374a,7f1eb525,825253ef,a3ff3747,e4555f36,9fec50af,21716ae6,8a11d34,cf475aea,53df9a1,13670563,e0ade1b0,d4d90da2,11b87318,315f368c,d53c5e18), -S(5db16271,c0d7e9cb,dab1baa1,4dba4fdd,1716a7b2,8c2e07c8,186899ab,18a6418c,344f8bf6,b722e92b,ed436fcf,41be9a08,327002fc,7b3b57a9,2044800c,a0d1b2a6), -S(402bb93e,8162ae4d,f23f5d72,611eebc9,8d4c00a1,e4d8967a,da1bf524,9ad1547f,f0c0b1f5,aa183000,7a964ed9,12bacd81,9a36b55d,7d2c7c1f,12da6066,a28c1d68), -S(87b76fd2,91fd3508,52544b80,85b07b94,20fc325f,a0ecf42d,9354df82,467d836e,f0a2c79f,4613218a,3b35cbf4,24b5fea1,7d2ee9c7,ab912be7,62270195,8b70c133), -S(e2d73ca3,ffca1eb4,191eb705,c22cfeeb,a7f573f8,463a0cc1,c73bcaf1,3cf6c791,61b861e2,5aa3711a,b92aa74c,814b4df8,37172f43,ea0da2ac,d81ae961,1735fa85), -S(1e59b370,be38e5d6,4f8b6fdf,7c2351af,75ff9d32,1f583d58,bcd0e8be,ee0855fb,d166688f,24b4b33e,b171343a,87bf8828,5cd5d073,a5023bfa,dc542660,70d3cf13), -S(52ef3e6f,5aecda7e,e2a6451a,ec2badeb,235829de,b7cf6e1c,5a6970ae,662e2078,533ca8b5,8d9e2e7c,2a992a22,3f385846,748a1686,34e1fb2a,48d3f133,8512bb08), -S(a4b1cd10,20a321cb,53717818,ad0d39fb,5e9524db,4456e0c8,eab045e5,b2a97be7,979d9ed3,4601d962,3f084e04,9ce4683d,783b912e,6a92c07a,38ae744e,fa7d046f), -S(bb01149c,2352baba,8f3fcca6,a8fdf9da,854d7,7efebf92,6a0d49e,abcfd871,b186fcef,1d368ceb,351d5e35,35d19052,7373a9,36a625c4,c0b3cd21,d4188720), -S(978e8fe7,c4088cb1,27f9e8d7,5dc43453,ed16470f,4f940413,eb800ec1,b315f269,6f7f521b,1493b81e,6f099fb7,22ae2a65,f706a351,2b74338d,b708bfa6,4a34f6e5), -S(7e61704c,77e4a6f6,925a1c48,8965a72f,7bc8e76d,cf316371,13f682,b5fbc0ca,da66aaa2,c39dd05f,7f5803bd,e5bfa0a4,21eb628a,12df0869,6c6614f0,176b15bb), -S(87c537a9,b97dc885,3b7957b8,2cd9ec81,b8b65d58,47a23106,e6df3d5a,cac3fccf,4939698a,6123ae1c,42cc6ff1,fd006fa3,2cb0a5da,a3889721,f04a4a59,e0fd7dde), -S(590b5b95,37a08784,f804111d,6ccd7df1,7bd317ef,aebd7bdc,96f3df4c,aa8ad437,7aaf5053,1c187684,ed8238af,c621e151,dd6e7c6a,2c18bdc8,9914a1f6,cfde5e29), -S(913a2ff7,a9416e56,afde1c6c,6273d7df,150deb4b,f2db3f3a,7ff7fa8c,173ccc09,e865c6d1,33da3db7,2dda798,9a5b860d,671c9de9,d6132784,30b5a552,85a9854f), -S(b01fa220,1ba66785,aaff5f59,347586e,162ccb08,ca58179d,5dccaeb7,636b4db3,d5589b8f,2ba1ef60,23936d96,f2772d4d,cfad1f26,cf124265,6765dc2b,7d9f543a), -S(511fc077,bed929a0,249c65d1,3f59c607,b8bd0279,c3ffa23e,8c6c4ab1,800b6363,74b03bef,b913cf04,f44fe5ed,40ff2ff5,9e85db23,34ba902d,84dad90b,68a72912), -S(d8597fba,dd03e235,defd0d4f,72c054ba,880390aa,c1c356c9,1eee50f7,8ba567b5,86bfd1e7,f1df87e4,be26c892,d2c1a634,1904c414,bf84dc81,d65f701,efe90bc1), -S(34b46527,86464956,6dfcf2e3,5717955e,4529f88d,786ed832,f879bb9b,5f24ad6,916bacd4,52fb69a,e8f20094,8846e706,e3cf466c,a34a7c6,b9a24df1,1d48edac), -S(f68965c5,55a826be,187306c3,8695dbcf,370c5fd9,1a018912,ca143d8f,b9e96c07,2342eb5a,bea7b80c,837a18c7,ed606930,248ba6d4,f5ea3650,9a3aa10b,c0326dbc), -S(80bab356,e346b2b0,511775f4,be1a7bb3,fba9c65f,5cd035e,b9300162,547e75c0,e96dd58a,53a9e313,2c3b494f,2c53bb56,da17f573,8bc90a10,58063906,52c33363), -S(55a3ac1d,88f00e04,ec95215b,68f37594,9e10abb,ebb1928c,6cea668e,62897e7b,31b5984c,4280d3ed,125d2223,57718f54,b8e406d0,bf4feccf,2deba94d,45cfd5bf), -S(7e0e03c3,f82556f5,a85322ad,61cc60b5,d096c684,19c76b77,f328f51c,bc5daa41,36b4f520,f84f8e1,7fc79bec,bc2d4340,e77c5b0e,4fa944b,c0cb2f07,4c5bb1ce), -S(fbe1fd76,8dab92ec,b56819c8,901cb8e8,cabbd809,f61c0f83,70fc5697,7a90b28f,6fdb62b,d011208e,aca8f8bd,68ef539d,a6a5552b,8187327c,19c6f4a5,40b1e750), -S(ef2a9571,ba9090ec,1c50d5e5,d8955609,2f7e7610,625860d3,c0e1f22d,e66e7a0f,5ae0a396,d6cfe9eb,7e3e6923,e7d1d925,851fa4b1,38217320,92191366,a3aa1c27), -S(81652fcb,7a968f46,a38a6b9a,f3f6d831,577fd45,dbe0cd75,ca4ae8d3,c34812dc,bb130db,74334258,e5dff98c,cf8e72b9,95b986f3,7177c98b,ae6f7747,3d869e17), -S(e0daf5e0,a32eb5ea,606b2760,62c8a60c,a4b476ab,b5f2b172,9a15c529,11509e75,8eecb80f,c47d33de,c036c661,e940aa9d,26bc8541,369315b9,b7552487,d32e0f4c), -S(cf0a6b13,f6ea26b3,8927139f,1c5fe769,6f297e00,46e4f529,1c4d5c60,57dc917d,b8c731e7,5d0dda67,63c1cec9,b70cc4a7,e39a7ca3,c1dfe8c8,4a895d03,b3b185ab), -S(a5b5cf9b,35914a4b,6af16c2a,ffb6bc8b,5228ac11,ea91da48,fca654dc,b6b8bcae,e6fa217a,42e72a81,b8f564fd,a5438d3c,5d0ce8f3,71b1d6d7,c577d70e,f0daaae3), -S(d4c1d178,b462e260,c6b7eb43,b71dfa56,899fe5d9,a421da4a,edded57d,4a0010bf,339fe1d4,83f047e2,cf2cc9d3,bcdb8f0a,df9b491c,ac87a512,e901586a,50f35276), -S(3d343aa3,c6bfd408,1b64d616,2523b272,ae207a5e,bec0e530,4e0792ea,3743b150,5dae9987,49073817,cc513c16,382edfe5,749a8dcc,62f4dba1,3e0c88eb,c978abfc), -S(34242394,db9874c7,14664ff2,90cb1be9,c48c1746,d53aeba1,536fae00,7ed83a4d,59203b4,b8b3e0d,9c34790f,f9cd0716,8606cade,9af8ca2f,b77a6fae,d6e10ae), -S(aa8c1b42,7588ce4a,2a0fb437,25a27bd6,6f598323,fd525e88,a3a586e0,d2d64a08,2f1dcc5c,269065c7,a966036e,c281d05,39d4cc40,fe42fc37,667a49e8,850fcc00), -S(699d3ea,9658f9e9,7fc0b69,4927f4a0,bd95dec3,cf104144,8167e4b,50482c74,416ac99,d59c046f,a754a7ba,d37b474b,ae7d2192,f90719e1,39b6af6a,e2b2fc84), -S(1cd6ac9b,93f5b488,5c06c9d7,a44ea260,11c9537f,d75f5abf,e9d7ced6,c14a994e,818a63b3,d367f655,4afc7651,7fc85fdf,3c69b881,242eadb5,8649ce89,f1905e00), -S(297c80bf,24a78c2a,245008bf,40a828a8,575e6362,5c555653,980f8313,6ccfd660,5ccb3479,60c1c639,60da5605,4bfd8d5b,61ee83aa,d815164a,b387dc37,a44b412d), -S(915638c5,f9d1b491,99f6ea3e,c1843d4,33b832cb,fad78dc6,ad55fd10,9eaf31d3,bd097f22,440a0c35,e5648ff7,724fe5,2163edd4,3c1b2fd2,7c49d61c,7194f225), -S(f8274560,da2fd048,5b974537,16844970,d1c0c1e0,ab450703,739aebe1,28a7788,58c71185,2a63aac9,5a080ac1,3d786a6d,75488625,622afdcc,f5344ab2,adea04fd), -S(94b4e84c,61fa07a8,6c35d554,816f2131,3727f614,d641f3e9,8ff74509,fcfd444a,9a30a0fa,30f3a772,747e3a0e,b0d17ad1,c029558b,a5e0478c,160c109,fd43df77), -S(de72f827,3ecfa2ce,67d55302,9f242afb,c3ac130c,4e711a41,545edb3c,dcb90d64,3b64bab4,4141392b,76e492e1,49c166db,272e23b8,dbf3fb13,b17396bf,1c3834b3), -S(6e7b3c5f,4bf9bd45,1c5b25d9,23fb5768,7aa2b1be,dbfa3317,db823b8b,968263fd,5f7c0be4,ba960cad,e120bde3,c8ab685f,e80f96d1,5a012993,d1890b89,563cd7d8), -S(3e4c6252,307c116c,33f5e2db,5690dc4c,57210b58,3b2250e6,ace138a5,24a1b376,e82d521f,4b50a3e7,482ebd30,93f7ed8d,70c6dd1e,6339af4,7ef453cd,ba3a91a), -S(99a27d9c,802a5519,3f9b767c,3d9c04b3,7c6445b8,e49887b2,55bf325c,118bd175,2cba1615,5809eb23,8e8a35f8,7d80c011,2b0b1587,1e56c567,26dbe6c6,d9a477a1), -S(24b5cc41,130a9fc0,d694c99c,a00edba7,2c8d2a94,7db35421,6ac18ee9,6a88e99b,d409cef3,7e0fda7f,27478fa0,651ac750,bab44341,98d60fb0,50db541d,f416c488), -S(903e8ceb,229db84f,803346f6,9db1b473,4d375dad,b29ee771,c194c1c9,4f068066,405c25cb,2ce89007,bac620bd,1e7bb959,c61fb5f5,cb60bec2,15a978c2,91c63aad), -S(77702bf1,2ddf612,5d3803c7,19be7b60,c4dfc0a,54bfb54b,c58d2595,230e92f,dfd2bbd0,8cb1b67,f26bc57d,2b9bfaa4,7a03872,2011c58b,619794b4,c0bf5eb9), -S(27aee8e5,3f4ba917,29f463a0,888834ec,e83a022,bc9862fa,fc5ecfe1,d082fb41,1be8786f,2ef69516,e18131be,28cfb9b2,ec0ff57,6dc75c84,5f2a7080,94b40bfa), -S(ef967d14,d819d4e5,5324496e,868c3167,b94393ab,e3382466,44fd2b59,efccaabd,98858ad2,fe5db334,740a3bf5,fec4bad1,96d39e5a,f09209e8,95e086f5,8a252975), -S(a2228f83,18c5fc47,1536bbb8,9baf820c,8b2b48bb,8ffbd4d5,56ae162d,bb80a78e,79e06c54,ae0030f3,a6275aa9,8897e7e2,637ed005,c6aadb63,33575232,b54b2bff), -S(5ef437b0,d9a17584,6bb1e711,7b7fa86b,504385fd,307bcaa7,ab558ab3,d2bc5707,5aeb2e4f,83a73719,e1268a48,6a578d84,3104f0c6,86749b59,7c4b3fee,8ae5b586), -S(35be1b54,47f8a2a,512deda4,31958c11,9b187997,66eed6d9,d30040e4,363274dd,6539313a,1d5328c7,bb389c47,98c08c05,f9412c1b,31c08509,3af720cf,6c604288), -S(4e548261,89c3c699,eeee1560,b9876e4e,5e0c8677,f849a9f,e2355d2d,aff7aff0,49bbccfa,2a7078db,d032fd27,98a701c1,c8947c0c,fecfc1a1,38dfa387,4ab436c8), -S(37d9ca55,6ce9a853,b79fc831,69b6778a,43737dff,f5eda67e,eba8f267,867018c,9a9ca2dc,2512c397,a16780f2,25686b51,7c40d90d,d97a8077,91be382e,86378d10), -S(ad37553e,383b985,a4054cc8,a909af65,5daa7957,c380be16,aed94ab6,407ad12e,98e09fca,76eca761,9e3905c8,ef688726,feb7891b,3695d06b,5af5aa3f,f92dac3a), -S(55b0a9fd,7dee7ff9,84cadfd2,fafa3f5e,30cc6fd3,72597902,c8cb9163,55e2a0d5,97da1eeb,96599624,39eec4f0,7fe182a2,cfef4a9e,55a21b1d,64a43a8a,8edbfbed), -S(c79778d6,64e3f159,5c9ab43e,3930b722,f734079c,eb131b50,badaa53,337669e0,1dc01b47,e9908908,d318e947,8cec0a8c,37f7427c,bef205f7,9000617c,ea33c723), -S(ce6964a0,b5fa0b4a,67385884,12d6ed28,75da7d26,dccaac81,7f3aad1d,4a9500c4,faad869b,e4e0262f,fd67cc01,a0523f98,d15d9cbb,7bf7e8f3,fce7e20,26b7f765), -S(70f8af3c,f7fea8de,e62a3ec4,770828f0,52f819ca,e031c9c9,a0706d0d,b4d5751a,b4c4a600,6e4f831e,c4bd750d,62a52d0d,57399b71,ccb71f6d,c00287b1,67a1dfd2), -S(11f0d683,9f28915e,24d941e3,7cca8754,bab9a8f4,96807679,89300b02,8e79a041,1adad681,9d726c2e,2bec5f69,75ad8a4f,c7209872,35ea7486,2ff38333,2335a647), -S(36a0d630,625c455,5c8b711f,a28e2d0a,4ea34f6b,c81ac8a2,6861d58f,ac3bc9c0,89c1e59a,fab4fd9e,3245ba79,876404f,b4cdc7a6,2a9a90a,f307a8b3,17453467), -S(791e10ba,970b964e,db48c4c,fe698317,fcb64bf3,db8418e4,86c45e6a,fb0e1819,e9ee5073,73d105c6,b7012ee0,ba60b9f5,89d98773,f0bcea03,14d6f707,7746669f), -S(cfb370,cb6de70c,58c40464,c20c1cdb,9850be9f,ad9a4af4,2bbeb6b9,f173725,3f5bef6c,814390a6,c99037da,eb7fa919,7e9c806,50efc919,6650a42f,ae425619), -S(1d5b7762,bfc3fe49,bcbc3176,158f186c,f909c04a,31480b17,2451acd2,8024321d,ad60b8cf,215cdfb6,62a29985,c9f185c2,19936929,b9cc5911,4cf5329c,44ba080b), -S(304bcf43,342c9d7f,fa8e05c,66cd140a,57c4f58,d223a1e2,6b93a374,7c73882d,e250d896,acc87906,b79d9ca9,63246ce1,9ddd44fc,4e834643,f2d592ae,219f9767), -S(60bc17e6,9cebe27b,b504d28a,b657064,3bafd4b4,2d82e3a5,77dc8c5f,4a05c4ce,e45ae47f,6088f05e,f6709166,9f608598,ecca924d,ae7ad37c,1852009f,e23912a1), -S(cfa64de9,ee4a849a,de71b1b4,340b8d18,1341d00f,e86bca01,3d62d800,3e20454d,2e72bcaa,1967c37f,a8f8ec78,b82b5f6d,3c7d0136,28bca50f,c884825a,6c967e92), -S(400e67b0,bbefc4f0,7aeaee57,1c495584,de4e7832,377bf171,ee3e38a2,69e53d73,762d4b13,f91d4e40,ba0a3fbe,3c085922,3386add9,b8b1c432,88052b9e,cdb8fa3b), -S(fd3ebc1,e1c751dc,7f897ec1,f0ae0817,22136109,11010904,6c105497,47602cde,43699e3,74af29c9,692fed1b,acfe00c4,f2d91908,eb7cc181,7c270c76,453343ae), -S(60a18f0,740f1caa,ea056b17,9808ddc4,aedac1f8,482bfeb6,a97516e5,d84c0a30,6efbcdd8,114ddc58,cfc193c7,f11ce4f0,931b3f56,4290253e,a5289d25,7e7d1350), -S(c08a77f2,b9bfe746,ef89631e,1bbe07b8,5007d1eb,bb18547,6d7f8f49,4283e1c5,6a94da87,4c350d0b,cc23ac89,9d342752,97421c77,d7b7293d,669cace8,78121770), -S(247f8ba7,b8cbaf03,2358985d,955b4ae5,673622fb,ce1b68c,877db077,d91fa63,a180777e,3b8b7d6f,733d0565,b038b345,d598a9eb,1d592949,8463940e,99f7d74b), -S(18b7101d,a65cface,68d7ecea,5b926eaf,79722f9d,5962a86d,e1eed6be,ca08e4fc,60b7377d,eb39da03,f5bad331,f41586bc,6e3bfff9,f7c9eb7f,aae6f7df,8869f7da), -S(4f6bc39b,33d45e5,325116d6,f8eeb341,d15a3f40,57b64775,932f9b11,a92e1959,1cab1c18,422dc38a,e1a8d4d4,ecc84748,4c47d862,42ee4dfd,28624a72,bf693433), -S(45ce69b1,cdd90a2c,a14a2f87,b12d1f8a,7425935e,2f2ecd5e,6f25b087,acc4ff2b,3f850036,ead34b81,3eeffba6,c3b9dc77,8675152d,f569bc28,d4e74539,896f4b34), -S(8ef39f34,27339934,a1b969f5,b203d187,2d3c467b,1a25ca0b,d59b385f,d78d0cde,926604a6,8f82a4e7,a7e5507c,e1f1730d,c43f9a10,bb15bc15,9d8b940a,7403a5b5), -S(cd83545b,fd621045,245390b0,938c12ed,d530949f,6ebf0e5e,90ca8617,637d2cdb,ec79aec2,77d9b2a6,1721b499,ecde68f1,44faf32a,7984550f,54fe9208,517a0dc9), -S(95482d05,3fd19bfd,20a218d,82442cca,89d2f1fd,883300fe,9898e7af,3e1e7c3f,233aad3d,c798660,1aaa61ce,ecfdc48e,9b3e09d0,76a14945,eaec9d67,60713743), -S(f96fbc5f,eef4ffcc,d5c8ce74,a390858c,24cdb060,529974f6,fb7a7afc,759d7684,d41bbd7f,54c6ba72,aa64996,dc8237a1,27d767f8,ae4ada04,26879426,6343d663), -S(c31f5733,a92bc02f,28aa1abe,6dbc932,96ef1980,a8b876b4,941aa05f,3e4415ca,cbb9afbc,166505de,b160f3a3,fbc99c6,8b9aa548,ba80b83b,e70700ab,611d6bed), -S(e710e709,b2d1abaa,ea81e54d,4c913029,61d058d3,4aaa329d,bf673da7,6cc50f87,e6078cc9,c093a8c4,804ade7e,a2bd8f74,78b93dfe,47cadcdb,18be11b,dd450acc), -S(3209825e,8e6a7a03,cbb96e9a,cec60e29,fb3d2113,310a5f27,69c789d6,fd2d0ea4,4a1b86bd,fa71c5ee,fb640c0d,2fdf6941,42790350,a48b7189,41cded36,e6627117), -S(d26aa999,c82be0b4,25268242,c969c812,7160c34,8d61060d,2cd95fda,4ad91572,193c9343,5ad89189,37df995,5b8ea66a,5f81fd49,aa463d63,bea7e793,d7867078), -S(f505f201,a5f0a8b5,420db5be,304e3824,5552efc,d7736f27,a70d63e0,846f7a05,affbf297,4fd36a6d,45cd403d,e620fd5c,24ee5094,82f03dbd,4ae8d1e2,8047e07), -S(e81d7da0,665574cc,11b5c7b7,c7d49ea0,e12e5a31,d8d4059d,e589c87f,8ca189de,cd36628e,f84c929f,bd057c9e,9c429e0a,28562415,7a1f718c,5f6d9c6b,2402a25f), -S(d183676d,573926af,6b409350,fcec841a,9d7450fb,2c122dee,dc7f061,8ee870f,4401a6cc,1b298b4b,b7069ca0,70452571,1406bdfb,8d991e0c,a252461c,155a37dc), -S(7d8eb701,a4555db0,e28755cd,b99ec00b,188a5fd5,aba9fd63,b0fe59a2,e5f69621,26dfe0ea,387948f4,320a99b1,79cbab72,e0e7b4d,dd91023e,3ada4706,b1e14de1), -S(62b18c1e,6b41494d,242c807f,aea4cb90,6c369829,bd480aa1,51d42ad6,f2ab6e16,806a683c,ca4ba62c,d0d7210a,2a642a97,11a2c336,2cbbdd40,a14c49dd,7445157c), -S(3beffdc1,3d43053,e4975be1,2212ef06,756e420b,28c1da19,7f719140,40754d83,19f74783,30213117,c1cdb3fb,c500423,14c36c4,bb0b6073,504e29d3,2a7a81e2), -S(883c1fc,6c1e9ab1,f8728eb6,7e3c820b,bce57c8e,78920acd,88c56b69,8e21b57b,a6ee80db,2f153833,f397e1e9,f7d0bd3,b68e3a9f,a83fc262,88a3460,241f30ff), -S(cb54c3f1,d3007e9c,a6f4c7de,7cd6e728,22ed6627,3d64251d,23df0352,ca7f3f56,aee4eed6,3bde44e9,132e8405,c088e412,c8dd4856,9be5a980,adf9969,261282c), -S(40b26863,67d38ed4,ec41c0f0,b8393698,969c98e,e3233fbb,b2c9fee6,14fc52b2,9f3c3a8,44703528,e8a3d025,d536832f,f17e0988,4e90a75b,82705e61,c5b4f811), -S(90431e86,74d9685e,4c91e51a,a897fd1,b5aee499,7a8c7405,508d77a7,d0d742ca,b35bc817,b63059ca,8c21e0b6,f3c198b5,ad7f19d3,7711d02f,4695712b,e8706df5), -S(5ad701b,3bc26c4f,cdcd7882,71d259d8,1d134c0c,53063b21,c740d7d9,9c235474,615f2956,b5056865,3103ab4f,d53a1e00,49bce03,db115d5e,8dd36c11,1615f997), -S(75a3782c,51dbe62a,f9da5199,17e3a59e,b04511d9,f11b7312,7dd35b8e,6da95cd2,38061610,c0052d14,bfc4ef8,62d92a5,d59bca62,9fb7a240,299ab954,8ae21484), -S(28e60b08,2edec9a6,1fdabde1,b65c2e0a,333b5b2f,2c8cb97a,fc20ccf9,13792765,c96cac7f,4efb4633,8d63ddd5,33968f6,d09f074f,28e3c57e,dc868e7b,df4105b6), -S(7dc515d7,f7f20959,7e52b182,97b5933b,2ef9ef30,38e18236,39f6ac5d,214762e8,37738e78,9222d0d,5d7e7979,19b0ce29,81b7be24,abd4e0f0,8b989500,a348218c), -S(a8ad8d74,cf467d29,a97690b0,a1c539c9,604e5bb,77d4f719,fe1b7507,d51215d9,4180c361,21659aa3,fa84ca98,8676b3c9,23639184,ee991576,3ab9878b,558fba54), -S(6a71e2e7,99f1c56c,e38052c5,767ecb1f,85c2abb0,55832994,18417a12,9bae566e,481b3cce,208f33c6,6d4181e5,7648061a,86246ccd,31f92eaa,6200591c,1662b7cd), -S(78d0ae79,7a94ae5c,b338574c,1bb635bb,3207b491,fa42e6fb,7c861eba,ddc195dd,1d9e9cff,32ebca9f,d707544f,ead5363f,15a9af8c,e11d8036,49c6fd8f,cca067d), -S(1feb4e2c,357837d3,8ed62d33,4cba95c3,54ab6bf7,2d9f1007,b7419ecd,6bffb072,8e096dfe,15e187e3,92c4a26,2b94d5cb,63fc4cdf,f14e1b76,33d40946,ab074a45), -S(e9a3ce53,cb11bdd0,6c0be1e0,848b94e7,ef68d881,88069893,2facab4b,d19b2344,878838a3,d85a38a5,60a45847,20d8ea0a,34cfe7c1,6b65f35a,60b766f,d77d5fae), -S(2043c86c,4c96437f,f96ce0fe,ab5f428f,76966c30,4dbe6637,397d6b35,730e73d6,82eae267,3e2fc564,c128723a,b74feabf,905218a6,6567ea0a,4cfa74ec,5ee7d22d), -S(d02b8896,63ada221,3e6b458,7bbaec0a,2b1cd8b3,40a815e,fd9f3e36,c782727,c5c4cd5a,4bbcf08b,e1b8620e,24930490,c9f0d61f,66ef0c2a,937e2077,b178f8c4), -S(345b51da,c452419b,6cc320ae,8222c72b,12073fc5,a77ea07f,fffc10d8,61482094,5a0406fd,42916840,8fe4c276,bae94cb,710f6cbb,994da133,932c9d7,cc73242d), -S(275d0e66,da342f04,c9cbd00,18219dee,1a42f9fa,418d0a55,3f98b88d,ef845ce3,3fc25f10,74ad90e0,4ff09d42,204eda1e,a63fa50c,152cea14,d322ae5c,2c4f6dd0), -S(64709e5b,8c4eeeef,9b92177a,b4a04de5,f0150612,c84657ab,855d0145,ecb3aaf,c3b0e1c,56a5a00d,868f2a1e,35a40b0a,9d6b55d8,2df87d15,95b1890b,8b9a3a94), -S(64bb29f9,5e7f48fc,d436891,8d527785,2ba8a6bc,f2e1df43,f7dc4123,ae2b3be1,1f4a8fec,eba87217,3cf8bba3,bd19598a,ea1c8998,945f5b32,f1f52d00,8ed1355b), -S(6f401b0,2e10c301,27dcfc91,2e3a3396,93e8d2,f392507c,338dc113,d019e520,d9a59488,ea1e613a,99bfe1d9,dbd36a1c,3b65ff90,fe8983ce,9665ccbe,1108073), -S(3af33a8b,63b062d5,30b7ed95,c9d279c3,7be8e95e,6e173411,9d354814,b361abcc,4a5f16b0,b6ac8371,b2674adb,933a7f62,d22c6133,1ccab67,e6abbff8,66124fae), -S(a3feef6a,34754c7c,d888e898,bfe5080d,e3669502,d5ec3fbd,ecfb2dfb,8853fe54,a3e7e218,6d88e82,f600be21,5ea5bb93,44a6e10c,464e5f7f,e1ea24a0,3eafdcfe), -S(2e6f36d8,910a303f,c4c93cf,660c31a7,ae7b2ef6,c2ab5cb,940f9623,e2de83ec,3ca98ac7,a03b0b11,1104bc99,d693d068,7350c4bf,f911c183,1848bdd5,bf35e66e), -S(5d7cbc21,3016b19b,2dde662b,a677902f,cfdcb91e,25dd62ea,583b6375,1cdb5aee,871c5aa0,d44c404f,b42badbe,a9b99a43,29db7694,47b93d92,bf5dfdb2,648f4677), -S(383c7ab9,6e772e7e,47b01559,ee3bd4ce,9b86b38,a6f57968,64e45eb7,112fa1fd,254fea35,3ab6bfa5,2018668d,9f3cf2ba,bdb4aa59,28bd6a07,852c4b4a,b9bbda6c), -S(96aafbb4,1d6c96d8,72a6a577,13b25b75,814966c,ec1f0162,31b74dd1,46322ce3,bdf9a817,4c367d1c,51d4be31,70cdee51,a937445e,f19c1c10,52da1f67,e9e9561e), -S(4700205b,e431bf70,6728bf7d,16172589,7d104107,5153a9d8,7796bc96,49d479a8,4117c528,9d404239,97f67970,65d3a9dc,6b3f8c13,1008489e,6b23a631,6f86551c), -S(f81281d6,7377a69b,5ee7c680,744ea61a,668eb128,dc404955,f541b0c,e414b37d,e54bd7b6,783b6888,4bc72551,1e97c5eb,ccef5049,a28fa13a,a15232da,eed7e23e), -S(d898d15c,276b3b92,77f39c23,93f60540,6a7e201,443cce6f,d873d8a1,44eb5a,5785dd47,80f67f3a,7efab06c,bbb1044f,98d4425b,b0f1cc99,3b6b4b2a,a5504d4f), -S(56297c68,51dff96c,6122ae9a,1cdd2ce4,b1aef6ed,884e5998,28c77de5,eeef72d6,4f2494f6,5ebbf2ea,acf70249,f543c97b,add6f6ba,3b152b22,2b371a83,2f8664e3), -S(1adf1f2c,a5f3c153,ce8a6dfc,c1a5a21b,d98b99e2,135b6e8b,494c6ba3,2703822f,13fc7044,cf6c75be,ed84aa6,bb1fe11a,9f36c562,5a152c6d,81b373c0,42bb99a3), -S(f42c77d3,b6b36250,bf4f535f,27c00c8d,61b5ed76,d4928138,cc0e672a,7c72851c,3700f507,c90c93c,6fa6648b,40df90e9,b3292356,4a9bd471,4cc310f,e48da924), -S(17aee799,938d30d3,7edb6b8c,19d4d0ad,86ecdc34,c4b7d504,9d2b3b9,3e10cbf9,2527fb75,a787f794,a5f06a55,c3b33f7b,c575948a,c5454bdc,c14c598f,34459647), -S(55acc75,4a188608,46ffc6d,a6e3e2e1,18cad61d,e508d333,784fc716,555c98e2,982a4306,65448652,14f42c31,18e3214e,3981529c,422a0c76,d30d45d4,777aa87c), -S(d06c7e99,dbaf0943,6a6790be,e7487614,95ace755,448580d2,7614a30f,9bb7b5f,a6958136,41f3025d,de7ffc89,689b385b,b3c6ab83,6b1f21a,28e492f,de7a6fa5), -S(905423fa,3f9bd590,1a502d2c,7d4ac0d,2f728dac,3199db44,b35362eb,c964c8b6,1c33ef01,ffd75d94,bdd523f0,a41d629d,bb5ccf7c,9305d309,b3ab0842,16cc81ed), -S(8e799bdc,f32e5256,218dfaf8,5d08b6e4,d083975e,5ff2059f,c5b57966,3dc8cbad,60d46f36,c0e04600,bee76037,3af3196b,78b0957d,7cda51db,f1ff0c8e,fe6454ad), -S(653174f,8da924ee,322a18cc,8dc1e89,2ebfd90,dd1ddb95,6cf0646b,1e87ffb5,ace4b278,27361b77,59031384,57d0df70,9756272e,2f9af74f,55651c40,db5c4cf5), -S(77569132,e25d0051,b81f7692,d46faa9a,640e7d67,30cbb6b8,60078810,5267336c,15b2a80f,d78fd28c,d65d1e4e,4e81ef8c,37c8ae46,e66ea794,b60a0e87,f8203d53), -S(ec162da5,7ea2e308,183ce06e,d2fbff2b,3ec6e70f,e9d8ee2e,a4861160,205e506e,597cd367,d22409f5,b5737cd2,f1878b7d,c5d73603,3470839f,daf2d0a2,1b1a6424), -S(dd4a71b1,70f06062,b476aa37,aa025299,3d6d5020,a30f56df,6f31bf64,5633c6cd,ee4544c7,866617b1,584ce6bb,78627918,7222b0be,77d7ec4b,21e842e9,32c8ed30), -S(39ea945b,1d56a29,bab310a1,194f2e20,e13af9ba,5e37cd5e,d24c7203,9f4805fb,b29aebd6,9849c35,9dad83fb,56774bd8,3628f423,b724efea,80f778a8,370240bc), -S(bc774075,cd344d6d,a2f00112,3201bad3,bc52199c,b099441e,1d2beffd,16c13ae6,9e2d4f9f,2e019b0c,d3a8f248,31780f74,16569a42,58ac8f07,9945e179,c087959e), -S(de53be6a,6ee4fda9,ff2f399b,ae8b36b,b8331c83,c76756d2,3ef734da,57c60246,335c66f3,7472e014,3831d92c,bbbbc826,9046105d,64bde79e,108e09d6,b3f6f23c), -S(6cea6faa,a27557d9,d4561e57,ea755ee3,3d9f6905,36f91ed6,da93267a,fe758b88,e187e21f,4b67e4ff,7a285d97,1d42080,12638b5,ff88d4f2,ffd5cafb,6860a928), -S(fb5f6a80,5875c22,f2b4dac3,9c0a6f05,849fe524,586860c0,c3f9ca19,8091045c,6bbc77a1,f95ffef4,2105ed15,1ba96fa9,688e9e,cbdeaef6,81394b61,a4cf8f1b), -S(79a6afb,7ab3b569,e913cf30,72ec03ba,82c4aa4f,6f90be32,354286cf,52350b8a,32bbd09c,7e512933,eae14a47,fb940fd4,c60c3cc,c27b26b4,4588b278,6eaed993), -S(bacd7215,27863177,9a1878bd,800dfc59,95041824,3bbd492f,98ece53c,454f8613,f6ccba02,47279a13,371077d9,9d8e5e19,6e0c8f28,ee4ff9c5,21f2e928,c8a8dc1e), -S(15820a62,6c489416,14856974,18ebfae6,a7148dfa,895caa28,691bc056,c0e6bd52,14de4c03,8ebb058c,51b82407,1c58cac6,1bf4d105,e2f1bd77,419aa4dd,168d57bf), -S(9bf21f25,14f78ce3,5bf4ee31,334882ea,74106a98,bc5f1a56,d7de831d,8fc007ad,66962819,7a38b3d7,9af6dea6,e4d0f9a5,c03cc43,20742d2,83cb6573,7972622a), -S(b4c70aee,a8a836bd,cb3ff409,d0ef44a1,ee4bbc17,e93d233d,f4fbb081,3883c0db,48f35a4f,c9a9deb9,a454cef0,c0a2fe75,fa23ddb1,d1a2ec6e,2f16aa92,59bad8b4), -S(56d682aa,9381f1ae,4f356230,1f2f6bd7,e39f3e1a,1ec7eaf8,4894bdd9,78489b47,6c95eb11,4fc24964,b9bbe344,bdc32627,ccf1e6b2,b7ce8ba,e466c728,d348efbf), -S(7c7a9846,11fbd84a,9962cdea,1aea4ef,3572d15a,99b1f3dd,7676974e,f797b377,c1372815,d6ace43d,139a57b1,d37937a6,2f0b56f8,bb24b48e,a42aeed0,1715c7fc), -S(a89c7e,16838239,fdb87872,6c107176,7befb82f,ecb9e14,5768bab4,b823e2fa,957df64f,eba5b191,b6ef724c,18a1c874,75728177,682311ec,d709cf65,5ed37dc3), -S(7fac1495,4974d3d7,ac54034a,b497ff66,3f6cb327,506cb906,b0fd3028,f85d3dbc,a5c140ad,9a1bfaf1,ea578aa1,b14ca9fd,49473ad6,32300652,1f7e434a,dc45c4d1), -S(1e3032ae,8406cbda,e7bde21f,44a6ed5e,feb5787c,18c1ed16,1892c24,45294cf,a73be032,b2e98fa2,5fe054b5,d6d30081,b6b331b1,80124e8d,d85e2fa4,c69666ea), -S(abe408a9,5079597,bb9ab65c,852a985d,65391aa,7de247cd,76b44a02,67691d7d,1df3e191,219619ac,79bd7808,b5166a62,29babd11,e287989,65e15651,8472e8ba), -S(45ace807,55779736,65e5235,1133622,9bb6d606,6b5f09f0,76f5f984,51322f4,da7668a8,b0906440,ab68c7dc,41602d25,4bc05a78,f5a4320b,1775331c,537f3d87), -S(2ddf9c36,4dd4a1cc,c3582ed1,e44c0b21,1644c44,525f9641,c726afb5,af481780,cc3f4d02,36cdea64,cb350d0b,9c44d223,ebed2cb3,a66f44df,5e296ab6,41b61679), -S(41818580,a97d4a79,f6952aa7,db37d288,a40bf8e2,5328201c,284130f1,216868dc,4d6212b,47944485,c4e2c4ef,b556b856,2de81a46,89f0401b,2d7ac123,fc83913a), -S(905ac526,b7aa8986,1b2cd233,16455338,fb0310b1,adabeea3,a8e66fb0,5d2b7c50,f166e203,33ce73bc,df2ae289,9aab8004,568f3af6,381f0914,1d980155,7674d7aa), -S(89b95280,7022c368,d05f2fd3,10a13a24,1436909a,6695c999,f448b2ea,2be1c642,8d450758,5f2ff980,3a74f447,8a403ac,60c4c28d,54a77556,89748c58,f1efd1fd), -S(d4ab0d06,df52b5d8,9cbf1c74,9d25ac32,9abdc525,1d260933,490a45a8,bd5b0eb9,f5991ea3,6906dbda,efd4c6ad,6cd36380,9b978396,765c5ffd,f538091b,b25bf652), -S(aa3327dc,8c9232f0,48c14e27,fd235a6,58db506e,7de5e2bf,33edde07,38109ed,9dbaebe5,644b9728,23539091,56551b3c,540d9c85,3fda5bde,725fb89,d6bba192), -S(2d4b4ef0,3699faa3,a519a0a,72ea3ba1,d2f43f0a,c22a13e9,3fef213f,48b1773d,e6720da0,40eb745e,f99124f6,dce35709,2048462c,5623ccd9,f58fb739,e2314fcd), -S(fdb1cc8f,966c7bc6,8d264c56,8066a106,b102c741,11e40514,a2521dc5,5ecd5035,541b7302,a6e38776,30b178b4,b692ae76,3d59b5c5,cf5e5bfe,6427de67,c271dc27), -S(9a711c07,1b47a858,230c5111,5622f83,44808f0c,ed08c7ba,95170a83,1139b5ac,3fc4720d,1e63f39f,f4170950,78a268d,b7f9d911,3cd8bbec,6e65696f,e7e3e44f), -S(aabbe7fc,608871d5,48530bcc,44006a66,319d002a,4d0b49a2,d9c6ca4b,ab9d39a0,2ab2892b,bee509ed,8f221a9a,4f9be9fc,d9d3a2d3,3d7b54ad,383064aa,b2eb9465), -S(238bf052,fa44eb80,3ad4b6e,264942b6,da3ef420,a6c2f113,b2ce2020,9341d0e2,db6d37a1,47552f6b,8f6ec7ba,7554d4b1,49ff8372,2ed461ac,6d5d5a33,90afb0fc), -S(b276da77,f35f5a18,30ac7277,230b70de,1359c3da,c8e68155,6862a37a,6bea9fcf,8b2f05ca,cda2bc01,898d45a2,b9b20bc9,380d3beb,c5f0b346,96d4f4fd,8958a1dc), -S(5a7141a0,afda71c6,a3e8eda1,83409a64,e48fafdd,1965c00f,f711f7bb,ba1625c0,34d782c5,18ffbf0d,c6f9b0e0,b8403cf3,14cb817d,3e84a7f8,63589aca,cb44dbb4), -S(d186323c,b93ab6a4,b435154c,8c5d094d,51a8aa5d,586db604,d1fddce0,f35fe864,65c383fc,ac4a0450,1d483bba,62a1ee4f,247aaffc,7f7c790,eb4fce7b,782ebd32), -S(908bc35,6d29a3f5,1684bc27,72bfcc5c,552ef35c,a2fe9ece,f08111ec,8c368e7c,93fd8d48,6ad5cdde,c7ea498c,ba825468,caed6c4e,ac1c46bc,43411f3d,de9091b7), -S(21e05a2c,6ae8e1da,d9e4d553,3841c89,2d24f91a,aa201b95,f5f3a25d,d07231f9,d8cda13a,c6f7c54b,abcf3096,997e59a9,617b806a,1d805a5b,9d5d8621,d37a2505), -S(224de404,5c6b241b,4b705523,777dc0e0,dfde304f,c6be8077,cd831d0e,c738e33,bf8c695d,5ef0b37,52c84199,d7ebcfa8,d4988d32,f64a79d1,f0863ada,b6f84804), -S(3fbed77f,3851705f,55eac28c,f3921f23,c67a44a6,3d2dfd01,89d78835,d6106a6e,2139e1c6,4d48a58e,24306471,6bdd7098,c7644018,966a2b02,236b64a8,e628b532), -S(5adb241c,b09f712a,b5520909,53114781,388a6f2b,66218069,d6f5c758,1e4edb2a,9932237d,1be0cb9,2d18dfcc,6ccced53,e6cfee60,d897b6c9,b40c3ee,2b5cc9ec), -S(a4396528,ec7f9a,cd8550a7,7245eca6,117c4e8c,c50a51b3,28063d68,a744d7f0,efb8924d,7f921890,71b1366e,e8d0b620,af274d45,56f2d992,ac709d71,9f5252d3), -S(e36dc303,56a9e037,c9ececb0,764aa755,e1493e23,5ddea3ac,44ed4caa,4fea7bc7,338d5c5b,f5a84dad,5e865696,2ed14c15,70d4eb8b,89fa60a9,973921aa,dfd44353), -S(a6c6c231,238ab32f,361743f4,5d337eab,4a529a42,dc45f1c0,670fcbd8,a0dc22ae,4a3433e5,b415460e,4816b9c6,c1db0657,58aa6279,ad4f47c2,a5f07219,c50d00d6), -S(df09e277,b56e0f7c,2e93d8e4,d47778a8,3aa32c99,b0ac74c9,d64ffe8f,5e44b900,b77cd700,b6027f96,9c80a4e5,a2435750,35ed890e,30fdd9af,b41abe4d,81de4e94), -S(803abc31,138b3d57,9a18a580,bf0520e5,d9328812,14f5587,e49371e3,fe03b02f,a270bed5,2ef7cd2d,4d5cdec5,9d92c980,6e700c33,a487b4e3,f507332,99b54aaf), -S(ad15ba0b,c5cdcb53,6b55cb2f,171d1db0,712ff30d,b10d05f8,bce4d70d,22bc0bc1,fe7faa5e,1699e6d0,1e31be29,b5770756,fa6485f2,f3077f82,33789582,bb5949e), -S(85cdfde5,65959eaa,d025b6a0,1616b7ee,8f710833,187243dd,1103a0ee,65031993,facaf5d7,31fb65cb,f10dbf78,70ca3fc6,68a0581a,4eb73326,15d03f4b,87b53204)}, -{S(9705d56f,f75c7d2c,bacc47a4,a6cf8b10,300c688c,fdbd1b1,528f41b9,652d49fa,c53f7f11,896f2edb,fc957dd7,2cc90856,c5df9d86,43e42489,70182843,84201b98), -S(69db829,eba841e5,c2a1d54a,7f8857d4,4e898caa,fc8d990,eba45c75,9986958b,6b5589ec,635f24b1,4892d895,c56cadae,635de22d,de7b5b09,43e1c4a0,d83f0120), -S(4a8da056,c550978c,725da71f,6cf59df0,e13e3d86,b2255f10,827060bb,9af50961,abc04394,216df6bb,1052db88,e23237a8,13985857,a8048c7a,51787b4,ee7913e0), -S(775d4538,834d66c0,d41a5627,f2fbec9d,a5ec1e12,dea8572,7a32413a,5cbc3612,2c423943,5281901c,6e6665e9,d98655a4,91477e73,fbb3874e,7793a3b5,4b2ccaae), -S(b9eb2bff,b24696e9,36393471,a13ea71e,7ad68377,e78b9eb6,cb40d9f2,7da4632d,c54bb96a,383df77e,a0d77c53,ae2fcbaf,ccf53c73,99e4ee2,faeb338e,8cb40e8f), -S(a8aeb77d,ddeac4b2,71efb2a9,4f44dc31,9f32a0b9,7a1d0e67,8b4bde2c,a3a59233,8fde1a77,e2c76aa1,b5ba70da,dd37af0d,d98115b7,f17d26ff,ed936a7b,5803374a), -S(16f1cb1f,1e8bb14f,b475b130,ff1d0ad3,167b9249,efb9fe20,b31ab365,cb92fc60,9cfb2bed,8c1eb7db,6bc1b7b5,baa88916,b8f68fbb,d23be873,3c54c038,3ad0ac4b), -S(64563829,eaaaa500,c57bee41,f356b8c2,fe7c89a6,93ac0fc7,35044ded,5ae6292a,7298e685,c9bf4faf,bbd527f2,7620ae5c,2c3a342a,4c8d919a,72afcbbc,8b53a50c), -S(614092fe,2588e655,484871f8,3479d350,319b21dd,511e93bf,db81f898,7b2f3137,d10cb0e5,1201122e,fbcb3788,133fc545,7b0a4569,b44ac629,31421019,909adfbf), -S(e0b693d6,60f49c41,d3dbe7fc,51fba3a7,744a062a,46b57b8b,36504e9a,1585f5ea,21cb0611,a5014796,a744a507,2a4ebb2e,41dac48,87bd660f,e1f14a39,819e8c5a), -S(f3ee19e6,d27afdfe,a932fac,72f25828,a6f52c1d,671dd85d,3db0426d,74b8439a,d7c32438,6b62fe7b,fe894468,aff8262c,38bd0eed,4374c9f4,618d16bd,e2925874), -S(fcdb259,b019b7c0,ad0b2e93,f07a89d9,e26f121a,7974944f,85dabfbe,ebac9359,883cb06f,fbe5a647,60711b8f,d99783e0,4f59cee9,31d5a3f2,2cf1d692,894fe4b1), -S(bcad7844,a44ec239,dd113ada,7acf73e8,6271c920,72afb585,60b0f002,a09a539d,428f8d0d,529add2,73ff3728,83f92160,940e71f9,c0a06da2,3084363b,a2586edf), -S(8d54b2e0,f4083478,d6a2ea0a,1416ea8c,fe176621,30e2bb28,fb733656,9ae4ca98,c6d6ba83,fd780d91,ecc8016f,841fbb62,1726fda6,5840f183,7ad17bc6,33106a3f), -S(c9513674,d582a1e4,d91f6ef0,55920a50,1fc230f5,e5bfcf42,8c1b15df,d7f3a8e9,d01c55eb,4d685119,8026badd,3425d4a8,f56e7ba2,6c306b32,5686e279,81aa5cb9), -S(51268b15,a1d43b33,b95e92e3,cfdc7740,679cbae8,ff6a36e6,1da3a34,c8eba7ca,19699ee6,98d95b66,95e21f40,64421d25,a95aa7b9,9eb7ff0a,69331e34,c24952ba), -S(7b46c85d,6364fed5,87230ce0,9e932aca,ca356858,1ecdfa8e,f9b236e,1ee7b671,edda0f22,6808b01f,2bb5df80,2c9b613d,469eda9,e90be70e,4657342e,67519cde), -S(bff9cc3,b68413cb,9f9eae8d,f84adfc4,563069e6,28ff023d,6ee3cfda,8f97a935,651a2d85,cc10831f,f1571320,500415b7,24f232e3,30f47261,8d482924,40259e9e), -S(b5370f4e,f8b3af3f,3e936c34,e7c8cd89,21d4ecc3,7e5a5c0,a205fd37,9abc0aa8,6e889dff,6350f4ec,c3a413ed,694c1ae3,367d463f,be212a76,bc2a5a4a,b59bb09f), -S(72623c52,8e665a8,80c31e78,88b5777e,6b53f02a,6ede4aae,f2ed3bc1,ed351d42,4e2c6c63,c762652b,43383c13,806162dd,1992bbdf,88a3c714,a5f29522,a0db689b), -S(446e4144,8f66c9b,8eb06f5b,e8fec592,9abeacb7,befae28a,cae5091b,798d4f0f,62da012a,fc3d4eb3,4207db5a,8579c581,6a8b1543,b201e1f2,90b413bc,a57f7306), -S(428248b6,49cd424e,12b81504,46443a3a,b6e921cd,79e9344e,4613c653,7d0fc039,864dfa6a,fb191af,91286054,ba7f09fd,75e3d661,c91f939,ef834325,aa26703f), -S(c252c5c4,13e2a430,18ffeb55,355644a0,15e04cec,31424a41,9533af9a,eac0b688,c37efc23,26a2d965,9563b7cb,cf0953f8,cb3ec5ee,3c7ef263,3a6389ad,eb00fbac), -S(b5feaf98,f617055e,b976f63d,55901b93,7e63662c,5b6453a5,79a0c905,c951c037,5372b044,fca66887,566df1d0,6fe0aa12,d8405f84,529db971,a6422820,e6ce7f08), -S(c628a5d,72550157,365031d4,fe16f6f7,94636130,94447c07,e767ec63,8d62986b,539fb7a2,9bd686c8,9e98a1fa,ba95a493,2650b98e,f92198c4,534e58aa,39de796d), -S(f1d0b5f0,d6e30201,2bb50ede,eaf78813,f0a72315,6ef086a4,415e2d97,44acfa73,cd8accc8,fc951f05,5409599a,6da7e5e7,beee325f,2a7466f9,9be63efd,f6d9416d), -S(1d46b065,ac7fd9ea,5771363,dd2ca1a4,cadaf6e7,8e93a037,87aec58,af30f179,f3518f13,c9aa688e,7770d0a,d4dd505e,a22b4430,402ec3a,664fdf89,e9b6e752), -S(2bc0409a,b43950c3,16588fb6,51db2509,a66b074e,6df5d35e,a2ad0fa2,1dc32dbe,2a6df1c9,97bdd5bb,c831d308,d292a30e,68e1dc03,c16ef2a3,183ea616,b16a2891), -S(388a72ca,cfb9856d,174f0937,dc6d721f,63f915a4,6c2fb4f1,1b0cb296,8390109d,2f70bdaf,ebff44d5,b7f6ec79,48184e57,63831421,5dc35d40,48e5400b,dbc84d5b), -S(5404f49a,61865863,859fd7d4,2f008480,e93d8c50,3654525c,38c09ed3,66f95640,71626266,fd861532,a73eba6b,69c6fc4e,2c727ba4,b10e6274,821f3b71,fbd3ab2d), -S(eda6db04,9e8ec72e,c224ebf8,417f2123,8a50b2c5,b149d4f6,2a9bd2d6,78a0f67b,b016fd67,fb3f3fbd,7e53c210,94795570,7ff177e6,38f5a8db,74847496,5618858a), -S(3b71b31e,eef08efc,571669dd,c4deee31,e72f898f,5c83766b,8e58db66,e0c6b4a0,8dc3e307,4780ee6,b8122e3b,d6137998,1c80b72f,66f9f3fc,46bcd11b,a78b821e), -S(1ab86db3,750a687c,39c7a672,c115c29b,1f8f4ba8,586b9957,6b6b1894,7858d52,f60a122,80e05d3c,cd0cfd97,e1029cb5,728ff2d2,df077af,13645402,51412618), -S(eaa96c50,98e79e7f,27b3887b,39a6f74c,983eb44a,9b9fb7f8,e36f4582,596061a,4da962ab,c183ec56,5e37b1ee,3f75c531,3be12425,df54b4be,e4510b45,a84969db), -S(b3b4b315,6609efaa,7964743b,c6789f67,8e40b123,c336f64a,51bb322b,79a6e569,30d6e2e8,4b2cf3cf,e44b86a3,6f3655a,4e1b8e5,442084c0,454f5fde,c5cfa180), -S(1dbf8ef4,174e8259,ccb03ff2,bbacced,d04b30e2,301a4627,77669f9d,4e02f006,6292dfd9,f5df7ab7,31103e38,da6b59cf,4ea57664,887e8804,b61492ea,add33edd), -S(74a9e0ca,b7f1168d,d1ddd81d,fd00e731,7acb92e7,a81ad625,6f655fbc,561dcb05,aea7175a,f97dbff,a0ffcef7,1c89a8cf,d101b3c0,6f424d9e,bced721f,19578d7c), -S(17d35d3,507f39c8,b7429cd0,9c04fa49,efb0d47c,a0c1a0e7,6a303c85,ac5d35f0,88a8998b,603095ff,1771d3e6,d7d69ce8,268c8f6f,20df114d,88cf83c4,e148c4a3), -S(890a566,fb2b0ac7,1a269b9f,90a20877,3611a6c4,ded7874,ecb8482a,f758b0ec,6cd1086d,8ad35581,bf49b063,b1818b20,8e2cb340,17a9c0c8,1a197450,e8d7fd8c), -S(13d1b6bc,13d5b669,6a6a423a,906476dd,d3a671cc,ebd5e119,a8cbf6db,622ecbb7,1099ec23,c79d6dcf,3d2380b,eba653f4,a3fb4bd5,bfe22e4e,abd2e57f,3953fc85), -S(775298a0,c8968fc4,6c7c7e7f,571a784,13ad7766,a9409a6b,6ce02a2b,3e033934,2c3640fa,17aba57d,e2dfa700,ec4ae691,28579db9,91ba8670,a5d8f0ec,b9009c86), -S(ccdbc86b,a89a8496,35c20279,223ff5ec,8a545acb,58b04b53,eb2aea74,ef56ccad,9d229bdc,2b1731a5,730c8f75,5edca111,c52cece1,a65949f0,f51525c6,2f4e6abc), -S(704800e9,c4e03a4d,9aa9e41d,8619508c,9d17766b,217a3d3f,cc5efca0,67594157,7da8e92c,22174290,d08c222c,db33b345,c45388bc,da9434d0,99514d59,2660c24b), -S(3b958586,e7bac33,711be679,30158ea2,38bd6801,f087ae0f,e694e482,a4654c06,93e08192,d074e631,6f7681bb,49b9398a,cda6fbed,c42d372b,2bf3bff4,66ec70dc), -S(1ef945be,6fab11ec,4b48a57d,d2c3ec3a,5eefe46d,afc58284,a005e02f,6d5a8dc,1ffb979c,66ab8493,8a12fc83,52eaf5ed,431c3d14,d6e472cd,503bb1d4,1180c069), -S(72ba6f,627d78a6,c265ffcb,2c8a1e3e,c716f52f,4dcda188,4ab23325,b3bdb1eb,7cf1eef7,aca4f18d,1b1324d1,ae6bcf24,3c870fe7,5a977c6a,c6872ef,c1602afb), -S(2fc567f4,3df8fed0,1eed527f,8b4338d6,92143c20,13b963fd,343aaa4a,ae3e971,c3375e3d,e52b9c17,647e36f0,b4a60031,5837b2e9,c61d039b,1e934ef4,b9cb8864), -S(6c80f08c,30b3b243,1c3a4b1d,b2cdcae,505c671a,11dab05a,4ecfd68a,e5cbdec3,46dc33f8,8b54e177,88358d5f,bfc4c834,4e376338,8cbe10aa,22ae5062,5d3ed7da), -S(587724ef,65997e21,e38bfc75,80707319,c3065fd3,9dfb9cf6,fcb3de84,d28a0f3a,4993a8cd,7f22b55a,88818c49,8eb18807,a93d1246,f0f1efa5,6ce0efe5,68366dd9), -S(f82fa826,8a43213b,5d871f8c,fdb6a6d1,e706ad8f,2b8930a2,c495bb90,39d1d5a1,78749a3d,b47e256b,9ab3ed40,9b9ba1f,741ddaa5,431f4f22,896ebdee,8ddb5d98), -S(18177602,341d74bf,9ae572c7,d60febee,fe37fe20,80c89722,434b9ad4,3c935dd1,aed1c747,a87e00eb,2fd8ca9a,b860ebff,f6ff6b6a,9a2dd505,534b28cf,1f37f7e6), -S(842785a0,11028ad7,4704fd7d,15e9284a,cee1272d,936c1300,d8598623,de359971,d507ec1d,cfe03f65,61a7b192,6c14e4cc,dec54fb8,4587a9a0,cafafa5e,81b35f77), -S(c22076f3,441370ae,c874a32d,297b54c6,f284efb3,95741124,21428332,140763ce,109248e7,857ca454,cd9fc292,731d800e,8a29d13,e557224,bdc47992,717306c4), -S(14c75d2,c7f48020,7f6c7b1a,ef4be041,d2c13f4e,48a9d9a7,b4809f2f,a20ebc67,267d7fa5,be716683,2f48fe5,f782b719,c707edb4,4e2eb6e9,3217e6d9,adb78647), -S(ebbf722c,67339545,ab15b2c5,f6c517e2,e32b319,a5c526d8,656ab4eb,4a72486b,2c56f524,3d33c2d7,7c989453,3108ae44,f8b5d86c,9082fee3,c99236c0,258e42ff), -S(9313e212,4ad5658c,9a50fd28,70af7f26,9661fefa,41b0b5bb,25b8cc05,9b8a2892,92d4a8ea,73210fbd,a730c8ad,50a19e7b,11f65025,a2fb2915,7af992e7,b9d449ed), -S(5549d2ac,f2a7b23a,908d1529,696530a1,41ffc39f,323cae7,374666c4,12d9fc5a,87a51da1,f8766aae,f1161369,67259d,6137b607,b579a215,59e9e3f3,3a4368b7), -S(dcc897ed,9f994741,1e15bef6,8eae2771,27ee8d5f,b2ef8ecb,f47e057f,801c7b1f,5bc17162,f6470848,a4b222cd,357a4e63,c3a15ce0,5fecfb1b,19290b7d,6af6bdfa), -S(a9ead801,344ca82f,738dc5af,85534bad,d320aa7e,2af4420d,b4479cb7,d9d747e0,1e3f6e3b,d065bdc0,99630291,9f2e408,361c0f,76ad5c7f,4ce3f220,a69fb30), -S(4e7e2308,67db8bae,df576eab,ea65f2ee,23efb749,e0047ec5,370b0db3,2897997,6f59c99a,15fc73e8,e393805c,d04a1254,5b8292e6,e8cc8cdd,cc426b16,90b9643d), -S(6d52baca,67e37e9d,cd68597e,f2ec6b83,27abd9cd,c5088043,f420168,726d7c8a,8e721f7c,7d77b0ee,17f2bcf9,b5b1b9b,da9545fb,1f4d4c7c,d544f070,2af986ef), -S(2b4bab06,bebed117,b09c6304,18185408,23b27f24,72223ab1,9dfa9d41,25271d00,c8e41ed1,6e4812e8,c32b8c9,4ec4c4a4,f3f00c7e,2a5bfe2d,27b6ea9e,82329cc), -S(21b85eb6,104564aa,c8b070ca,52b993af,4260e911,4cec2a4b,92041c05,f420285e,712a8ae5,e03bfcac,f6d39f31,ae20c22f,c702b364,35fbcdb8,6a14b1be,7622ebcf), -S(b95236b8,fe6becfb,98249114,a26e910b,62bd5286,e10a0dff,dd145b5f,ee2dd84e,3f0b83ca,e4549f4d,4512b410,57757c4b,7a3b115c,32819af7,6c31d204,c029fc21), -S(7b2b3f20,5debfddf,17bd4922,188c6bb9,a1dfdae5,910803c7,24a6cb4,d5f827e4,4e60c6c4,c1932812,457f7bce,98b8b77c,66512966,9149860d,726b3f08,4beaa2a4), -S(b2333534,312b443e,3d5a5559,67da3b7c,caca2947,2aab9281,d389e10e,2071cc71,5bb0be9b,d27c0b27,b2a2a68,d0767f2e,7ef79a4b,4dffd183,2163d7fa,9cf98ba9), -S(20067cc5,1be142a2,b6f5f30b,18fb52db,a675bf8b,669b1fcb,d297f73e,93920522,a80c956a,f0206a2c,74b11133,82fcf2ef,883114a7,a72012b8,d7dacd7b,ef696999), -S(d092a75,8080d695,2464009f,672a00ba,f49d884d,744a749b,fd884228,8670f2bd,da092b71,78d8a373,fe5dbb6b,2822c9e3,901b356b,714044a8,6b70bc5b,e5018f9b), -S(91f482c9,2e9c481e,79b596ac,e716270a,ee9e9cd0,3d502c9a,96a6e8ee,114d6887,af9bf0d1,ccb2bc3,3d8d3c4c,20346223,19104e3,53ccaa29,4de71967,634e0b08), -S(51bff42d,76705ed2,334de997,dc6d916d,86274f42,494a86f1,e57ec18e,538d195,2ac758d,cfb59a56,e483d361,d7a5e3ec,de0a640b,f94ac8,cb9c4a19,9fe423c9), -S(285483a7,8b621501,b294bd80,3469a136,2ffce135,a526574a,38d29d66,c69733e6,c5f3d286,f82fd0fe,f799902c,76421359,921280d7,72a91c42,33379711,e55a1e15), -S(848dde1c,490b4a3f,2aeaa7e3,97cd2840,23539cdb,a3a79752,601e5868,a29d7110,182c5fa8,574c673f,91302647,2f9fda27,dee3f57d,19c10e04,e84ea4,f532902a), -S(bed1c6d6,82d48d91,3b6ece9c,c71cc51b,418d6f5f,f2f5fc78,f4d27bfe,8eea513e,7f278fee,8696dbb3,fc762602,dcbe1a5b,653b8738,e93ecafd,8c23a90c,d82aa45c), -S(46d3d211,67a906f2,64f7ea9d,231cf44d,f523afce,8b99c3c0,b5f88ce0,f19fad02,7da52bc,905f1f2b,78c798f4,4ff85e90,c4b7ca2,4d2ab28b,cfee6cc8,373676e9), -S(7fcc6146,3554506e,931212e3,fb68719,914943c4,a067c3c9,a0952225,c5f39fc4,ac90244,c5d5446,20b17f6a,75cf6dba,6a05895,e1f3a097,85fd6ba6,a440ec68), -S(a3cd5ea0,b43c25e1,c45aeae7,1d05fab,e9009262,8b544d6c,364abd1b,a4c0b9a3,312ab3bb,fbd8cdab,1c7d01b1,53baab40,517eae29,b8ccb28f,27278a3f,7bdf0b85), -S(c446daba,1825a802,1d62796b,1ef604eb,d905db5f,9874eecf,7be2ef0b,1cd2e9fa,1562aed0,d869425d,3adfb280,a959fbcc,195f632f,f6d8695f,f8eb3381,f7f274b1), -S(77c9a086,1095246e,b59ec6b9,5af0c435,a64ac0f0,a238fa70,6c5aaaf1,3d9e32d0,8a89b6d,442a911f,66d1c966,997331a3,db74fdc4,a1305ec9,e13f2c1c,4f1524e7), -S(19e2aaa4,fef00f4f,64ec5b45,d8cf58f0,37ffecbe,f305ad18,eca01edf,33e62cd0,2d636e48,ab56e09,12b922a,d567164e,93f6185f,4b3b5b54,73dd3b62,5a1bf359), -S(5e6a3b49,60264ebd,1b98d889,5722f263,471343d0,a18f540,141b6d17,f5d0ac3c,8f91deaf,390e1d5e,dc5c329b,b8a067a0,e5f497c2,39fbb4ac,3de3c3d6,ac61f35a), -S(6d90b780,b75219c0,5e5f30cb,61f5c9a0,44c446e6,8bfa56f3,f80d54dd,6c06aa91,6e02731a,dcd7f45a,d52a3550,f6b37f32,4a913c2f,6e48f264,480e3248,a06eeea6), -S(e4358de0,e3e65fa2,25d164dd,cadd7ef,cda7a801,86d11fd6,92222d90,24131cdc,8621625f,69c4cb56,67f92d53,74bf8746,aac1d17e,a9401978,89aa4db9,677c2320), -S(6088bfbc,79b7fe62,df884d2b,ff605794,9659ed63,3d9b7543,ffa88cf6,db81063a,ff27059d,811db138,a061d6fd,e4c289d1,54d7c28d,1a13bac0,10004c83,9146cd44), -S(89aad23e,2b364a3f,6f4e218b,2a519c35,51b58eff,fc0b264c,549e2d41,f1552464,1f1e9915,1a56f61c,e48f3a75,4fe02fb,2cc591e5,8e7289fe,39c88345,3c868b10), -S(c354a06b,468e1503,803d69d5,919a68ee,9e60509b,7d85b543,dc06a004,215525ef,e6656a2,bd6c2569,aed8d779,e061842d,3a65f9ca,a46cf5cb,11a870c5,3411e09f), -S(960513c9,bf25992e,265e09c8,4749b4fc,d3dd1b9d,8de5ba17,88099526,2e2fce90,f2cee526,e2f19b4f,b089e3e5,aa4f3d4,dcd5be51,67afb83b,4471a220,f961fe26), -S(915bfb4b,e41aef95,f4b84b87,5f4b0f11,89397160,c8b0abc3,5c976a08,29c7b534,e1238986,b3b6ea5e,528fc6fc,ce95be98,a0490c37,e2964739,6294a245,5580607f), -S(54a414f1,cb9bec65,f1e8f09a,f12d91de,8615f47c,370a3a18,78beeee6,8297e07a,9d9accac,fbf02cf3,a99c5d58,9e9cbc3e,45e9080f,1d345fdb,93ba4306,c6972ae2), -S(4495cbdf,4f71fc3d,bbaccefb,1eec5f13,acdffd13,9a0e9a5,cb798086,a8a46b2e,1100fcf5,8f571f89,4b625179,31a33fa9,eb2683b8,9d6f9ae8,748d6615,7e40f6fd), -S(737740a4,35247754,b4264e73,7f7c4572,94bb0b0d,102d535d,86995ea1,68b7aac7,601553b9,eb20b8d6,8a0b9562,139d75e3,d3003a4,12837753,29c3696c,42f02f63), -S(e0dfd6fd,1e6def44,55afe74e,dfa69eb1,310ea3b2,6d55a13,73cc0118,7ca720c4,e6d63ccb,96084257,8b764a05,15ab78a2,a5afc188,a8f7a4e1,52adfd3a,e56c6bd7), -S(b4ccf2f2,4a114f61,cb24bbcb,f300a643,3190effd,4930afac,fb2bd4e2,1cffbcc0,3d9fda60,7a752c7e,4316f355,fd0fba2f,1f38bf3d,e9a78bf5,5ebe58ee,e7d13a0c), -S(9efadc19,dc6bea69,e0b4a59,e0bb9e35,a1d4906c,4d612da6,f32f7f33,c96345be,19e891e7,b714e7ac,32f801a,bdc2904e,df8882c5,dbe25ad0,f414fc95,da4915bc), -S(3a4058b1,cfc8bd88,499ddc79,796f07ef,a59bcd4b,bcd37137,2d76f95e,bc177c95,d3024cba,358ffffa,aa3a95f6,cac1dfa7,1d5d4f59,91598a33,f02f3141,81acbee5), -S(30ac9730,53bfc762,7f7bb8e4,a97ce1f4,3918418,e3ad8f1b,edca9bd8,dd7f6ab6,495b6849,a4d4d9e7,8ffc49c8,976b5f9f,a631e1d1,95fce967,416659cf,f91c6147), -S(248a974b,35f025e6,1a462050,38a0a856,d136b68a,2ef09691,69332629,a35cf2e9,b25a8e72,efb765f2,66794992,9b3ae32d,f148021e,63aae20a,d4450e3c,6b5fb5b5), -S(107899a5,11fa2b90,fbe5889c,fef115f,f0c9cac7,62f82cf,12487318,63169a2,ea1c4278,811fbe5a,6f011375,35b584d1,a85d3236,c66d52a5,845a6ffb,3706f8cd), -S(91905b3,e5602f5e,6a780acb,4a33f7d5,4d87b239,dc9f19e4,99560d22,b062e897,caadc62b,71d3fcc8,d9d5e410,7a11fb75,832693af,46ae99e4,d8f7d140,900b82a2), -S(e103d0f1,1e7bfd74,821dd503,53b08f2b,3c56338,f4750fdc,76b4bbac,f7ab2404,eb65ee56,1dbd1e1f,d5437b7,b86b1502,3bf423ee,f75e7620,aa6558c8,a039f741), -S(f35e2c54,f2e8f2e3,fdd18dbb,e0244de4,5b9fe772,7c00727a,5f12d7b1,def1c45c,a01aaabe,85682057,b649ed03,e9786133,e5d22cee,4e5c56a8,31bb310d,fc03cf78), -S(5cda0c4b,ae3e3ab,8aeaf59b,ce9b57bc,da0d8cc1,b638cb8c,aab26347,e8188bb,d992c965,4e8a3d6a,4838c9db,64fa1114,e88986ad,da948ddf,52ca17f6,f600c219), -S(cecf5b7,1a36fd7e,2990dd73,9fd150e9,e6183368,436b9702,f9dfa05d,a88220a1,34bec823,e6cf7184,f837e738,3c4b5edb,3ab3f027,d3034639,b038efee,5dafc8d0), -S(5761d842,db207d20,42e3df0f,d95f13b,8f09210b,c7c8521f,4c33ce69,5473c28c,31c68feb,48e1eb87,afa40cd0,a4e55c9d,862c914b,714a290,4dbefb01,d59e4dcc), -S(d4b5e716,5ed18b35,61994dc0,e2af0ca6,3d34d053,d89d211f,4157434c,dae8b10b,137db71,89d25a86,cdcbc931,ad30c5f3,27c368e0,6beb1335,746cf6d7,bbecb07b), -S(6e9a9ebb,9cdd9729,f3bd261a,ee9ccc5,3d55a9a3,fb79d370,489ebac5,9951df97,32db39cc,a1a862db,172670eb,132f79cf,dfeb7022,ebe19b87,3d9781f1,1691f4a9), -S(ab4f56f1,941e7a55,7f7090f0,ba8b10d0,13db8e61,f702ec07,c4b99b2a,a54e12d0,c1a1fc11,51f23ef9,521ab291,cff740fa,42e00fd7,1ed3012c,86e72709,9374c637), -S(6f9165f7,e1f44fc1,1f7bfe76,7e8f7f77,3d25caec,17cc7357,d0b99ff2,1258134c,350f1c38,50c74078,3dc7a5bf,3b590cc6,45063e44,f46dfae5,b1c961d5,822b5840), -S(ba866c2f,67d4b6f0,8317a5ee,32519cd0,93c17fc6,6421a156,a4056eca,dceacec3,93fa72ce,612e210a,42f81d5a,f3c16d26,36895eb5,4e2d8d98,e6d3589f,d6ec72da), -S(35834355,a9445a8,40cd6b00,72e6a3be,54d80301,7da65bbe,cd1bef4,6788ed6e,92097690,e15e333b,55aaf635,62676402,cff85231,885060a2,2a29f263,667e6b5e), -S(50864d50,6835ed6f,86b25b45,11db0367,d88de358,62046623,573e35fc,6524b4f4,e970bd97,a9692202,376f485f,5548a980,188650dc,91ea1351,8cded8ed,7724508a), -S(ccaeb079,8fc41009,fce22bc3,3f191412,4be3fc03,cf9031ea,84f1a017,b9d5b3e3,b0ca53ef,45ed8340,f448edae,2ff784c5,c0b3bf3e,ff93cba0,8c2ebfa,eaf64df3), -S(46f30e66,cb54b89f,17063c32,dd1543e7,e73d4a08,758560a6,e62e7329,63076c0d,b84bafbe,69b45a62,498dd9ed,d202506b,9be830d1,6d6fecd5,69fb8f96,6a6a3042), -S(265cd9de,e006d582,45a04fc8,82f0ba5,b7fc91c3,6535e748,514ec587,c7f80327,7199f872,7a6d937b,6347d351,2b0050ac,a8e37652,3d922cf,f60c4b4a,846a0f57), -S(31cf7fd4,4e30a151,5e8a06e7,347416ce,104338af,3cc8deb2,ebde204e,de6fad28,5e1a97a0,bb0d965c,ece3be90,b971fcb2,a5d52ddc,5f19cd1c,9db15671,e5101d4a), -S(61110e5e,f84ac25f,85154139,d8d6c850,9ec024e5,5f796b69,f69e7bf6,3c41ce05,b67f5359,bcdfc138,963568c0,b386996d,82b77005,563cf104,2736856d,e548abf3), -S(539655be,97322448,a93f3760,9e67a02,ae39b00c,ce1bd156,cf9e78fd,65788661,105f9f23,4f075bd2,dbc1b74e,3e81dead,125792de,6025efe5,7463588e,eb5a7015), -S(e899c784,7f0b1e06,d4dcdcd8,1d978af0,aa00395b,af7e82f,a25c1534,1281b81f,f37e6134,1687ee5,942992f3,138238eb,1b2f13d0,7353f69,905c0b02,f629f436), -S(ae2d2d8a,be3313d3,33ff5efd,3d31b73d,799b1684,47478e38,7821ebff,8d722ab8,680721ee,9acdb2a,bf38c78a,910cf9a9,3beb66ff,d086c982,639ef987,3c234ac9), -S(b9e7abb3,9eeb4754,5d79bc29,97187c99,c41eb1ec,7fd6eda4,33eabdb,d60a5470,638a8f7a,b02eba6d,84d23582,46180a2d,864be6e5,a6abd36e,b2609ca0,3d0e0ee4), -S(2b20a9bd,a7a6730e,95454586,a6778672,6bc18e60,9a765fc8,c54cfe75,ea0a5a06,2e442fab,623d335a,e9c2a2d7,f89349cb,cd2af4e0,218841c6,d5e0bb9,22d0e382), -S(72fc3a7e,46d9a6be,f381e977,7253e8e5,f9db3afd,46648e8f,33b65080,ddd2d199,85cdc38e,d45cf08d,c23ea251,cf8a8c49,6ee654da,ed173c93,ee380d30,2a0f29bc), -S(db069c4d,3b0faba,af16a827,74452e57,72aa87f4,ff3b97ba,cf17c75b,349e4d86,b794f792,85fa96f8,a7037f7d,ca851a52,7a83afca,26965e73,6408ecc4,1247c3e6), -S(7cf3ebd5,aa1b2065,7d7d0ff6,a34a72e5,60436327,afd1f548,ef45eb4c,46b01b82,51de8d27,2ac224a5,2e5c2645,1a9863a1,8c9f8c03,43663023,d7621a9,21f1d855), -S(73b0a3f3,233b1fa0,30fc1062,69453fa2,2120b0f,e6f91d1d,c637e0d8,6573ac63,e04e33b0,b118fd12,30a816ba,a5ad9265,90ff186d,7187a7a8,cb740e29,8de71787), -S(32769d34,ca2c15e0,6e520b40,6a8cafb2,1f541f25,130dee67,7f4bc606,d3480db5,59ee4d85,31b67173,a8c1aafb,83ba9ac7,2f72dc7a,238e1630,5a3ad39e,d508334e), -S(bce22865,2f6cb032,82f50e4f,c834216b,59a6e9c3,e787cc81,fe8391fc,3f2b7101,d5ec8a38,93820cfa,85daf98c,281c1059,51986ac5,5f4ec530,925db0e8,c98661d5), -S(6911f551,e3522b85,93a1160b,356a5254,968a45aa,cb9fb870,37e3cb28,7674ea84,d26573f4,f3a58064,83d6d814,553f8dfe,e1d3b413,66062b42,ecb1f4be,56c39839), -S(171de86c,6dbcd466,2cc5a0a6,967dea53,46411198,a8fad3c6,a21761a0,5f3303df,4c6652c3,ed4e1b35,119473d5,96ce0350,19ac08,acfcc66b,8664c86,21288b0f), -S(8afa0269,be8300fe,592b612b,19758692,bed5d98,6374838c,126981a0,60a8af40,6f93d092,f4d82898,7d3aaa28,d8764c8f,937902c6,a2fa6380,91d4e6c4,d07d8eb8), -S(9c6f623b,1feb0699,59b129d9,aea3349a,13b92c41,ff7cae56,3f39adc3,474a3721,c6033ad1,f7045dc2,76f1937d,31d01a83,cee9a2c2,e6e8e0cc,c130c852,76a76b78), -S(5c88e5,bc110d8,ab0e77b1,e1592dcd,d576774e,4efc3499,5d05dd43,fdc8a22a,33edaf3a,e34fc2ae,b2d1743,c5be7c31,7ca09368,8226b5b6,c98be55a,18c162f1), -S(244116d6,b514bc40,7e5f5ead,624efe69,dcd1997d,881a6490,d2db3517,5cd57fd6,e9194bf2,e27251ea,60f4761a,5114d205,c4d2c13a,c9fe5887,61098e90,beb5b353), -S(db49b35a,9dd72d8c,8d0f0424,20c769f5,955658ee,7eff4ced,9dd7d31b,c0252dda,222806de,3c908a10,c71528f4,132e59b5,d14480e2,391a8aeb,8a6f7de6,1c3bc66e), -S(e208bc35,609acd41,72adc7f7,94ba78a7,9103d213,78c1ef29,7dddabbd,d782598d,f8b4fe8,6f6f1fb2,3c4dc711,8991a334,7314a3d0,1428fabb,6167bd64,dbb31e6a), -S(2da52754,60fb82c2,d39a242b,fcbf3433,be971662,acf9c5be,923859e6,443f3d61,6270758b,6974d5c7,3e5139f0,35d1e218,aed29c9c,bf17b6e6,b8ac6708,b09c69d7), -S(3df8292c,e26a8c51,3e5af6f0,4bf7323d,de655d97,dc00ae71,eb8e1488,bddc3132,98b07c95,c45573a7,97481882,b2f91bcb,6aee1d75,21377640,b6a52721,9d420750), -S(a2a22d6c,e949e74f,813c68fa,587c00ed,3c044c2,42456a6a,70b83f30,d8bf954a,6f4c0800,efe49001,9770f0cd,ddced4bc,d9a3994f,a1721cc7,df0576cb,e289b9a4), -S(8a240ca0,aa79c339,b274df12,b5d739f9,97a84246,b330c28c,fb148c8f,dbe40559,e8aabf1,7ab14974,899689c1,113e002d,2a410d3,b06cc5c1,d0fe5eb4,1bc480a5), -S(fd61d479,d57d73b,1085b312,2c5026a6,588e64f9,f642148b,589de7bd,418a3b45,e0e660e0,642739ac,f2127785,dd23475d,e83dbe72,2915b732,cd19dde8,38b240f), -S(b9cf694,82581706,6565e261,e9c231e,4e95ee01,4a8eb744,12472b86,d5b2861d,969b8e83,a3c2b9d,a4f496bc,b4f7cd78,a7e418b4,c793676c,7e1a8c,fa6bd33d), -S(91ee433b,c5c7e9e9,becb58f2,bd659171,2131260d,8a26d65e,b3fe33b8,442fc3aa,86215e62,1cd6542f,32c9ac7c,930282f1,de0cf7bb,6f6f46d7,a29ffa28,22127b70), -S(1cda7a25,3e8caf86,bc67a7ce,7fe66799,e4ece2c5,64622557,f3b402e,e4b6a6a7,28e11403,94b46fac,df5950f2,9f44a66c,e0c0fdd6,942f1856,db17019a,40cc7623), -S(52471c90,2508a47a,718f3abe,285b8be0,e9e1e243,35e27673,35a25746,2c864fcb,94d8cf1f,5c08836e,7dbd2373,860d78d0,c17960d1,5babf5e9,fe85838c,1923673d), -S(dffa4f8e,137745c5,d11b8330,59ba9fd3,3d09c9b3,bab12c64,dda46a2a,63ba3b33,982d5daa,f0bf5143,e59e5c2b,54051c11,f8e42e30,adac79fb,6cd19446,e56ef372), -S(7d5d28b8,88d15a4,3721de73,d1e3be0d,677b6153,58a3664e,63bcfd04,c85bd47e,9f987506,34bf602d,fc02ae9,9332b494,9f4d1f21,84a96f70,b7c51051,5546556e), -S(8e65236a,47ce5e43,671364a,2e99c5ac,4375f3a2,9110560c,fcb4895e,637be7b4,d4800683,8beea2a4,9b220e38,345e0719,b91f2315,caa6bf8,1ce59b58,c0ec0b79), -S(e8f250d3,f4365f7,696a9b58,b09aba7b,e884be51,86c5f1a6,d513b9c7,bb3c6718,7548cb27,8710e668,27aa9940,6caaf865,e7b723bd,e21b6ebb,855b8150,cba0bddb), -S(87cef4ca,dd9dc07e,a82c0f5e,943e5ea,42b2a9c2,8ed24e46,5604a85c,a98e08a5,736974c8,9718b1b7,95fab8c0,9cb4a3fc,1dc9c73f,cbf0eac,848a4421,7cdbe789), -S(48485885,4cd24d10,aa546441,e132dcba,b433b740,b9eaca38,cb80eaaf,bef064a9,91a91c0f,87523cdd,c6fdfae8,d16145ab,a2c67a44,e7e9655f,417531a8,9e44f693), -S(6f7180a9,be73fe3b,3c88817a,154ecf8f,3102fc3e,a1dddf97,4eefa00,224d7149,e1ecb8a0,bcd0f4f4,8e039dfb,8974b552,4456c764,f4e668e3,9640c3da,4cf24931), -S(d2f859c8,29ff75b5,cd951da5,2fcf0794,251293a0,7e8f0bbd,925216c2,4441fe05,c5edfca0,805026dc,32644722,70f22291,f65b60f2,5f93648b,f4163ad6,d12b704a), -S(38454e28,6e44de11,7f44b4e6,27ad0b15,d555c6f4,f8450624,d5b717f4,88c5f47,916bf1c4,eb9c5159,3e52e3a0,e1414e97,652997c1,fb9fdb03,f34e96d,4c8cfe1e), -S(b039e580,64f64b6c,dfcca8a5,1c93b169,8aa14b60,a2bb6ac7,d098987d,6b72b5dd,17cc6940,313d054e,34ababa7,99fbb1f,a518df36,b2896039,adfdee62,dd5f65ed), -S(5633c240,8a81d35c,61d6d5fe,3f678,220109a7,97716250,aea118a0,52939b04,3997de40,6495a96,ee3e655,3a69b04c,b11730a,709f1077,a5ac9916,85c0ded6), -S(a4f3f220,a7e2c9f4,bbf541d9,8ea71661,e142bb2b,76b4b7d7,af989652,2d2cc79f,40064f02,5dd4bbd7,9bf80bd0,f697dd6b,26ca8ea4,d04252df,ce5888b6,5622e669), -S(94568051,acf08d5f,e36691a3,14b44373,f46065d5,af48e08f,f34adc34,d3d7c15b,59672baa,3698714d,2983e23,1e7d985e,acc15cec,1dff4ef2,dbede100,972d2e16), -S(a4ddf835,3421309e,a41570f3,cbb0002f,5fe81975,35dab4ae,179a7f0b,dd24472c,ce127d08,cac2622,56f116a4,c993f504,b6df5833,731d04a8,1c0f0154,c4126078), -S(259799cb,4a4a4238,5bc3806e,17f19a56,844ba9de,8e303d2c,1cc0ee3a,a7831da3,aeffe3bf,b15297b3,4919cf90,cc808308,ec41c63d,f4af573e,b1d46675,20aff2b2), -S(d65f0bc,b0065fa6,4b13abe0,b621b2d7,b08cca48,2eed0267,8b131fc0,e1967dcd,eacecf44,defa0ba3,3bb5e8f3,9ed0bd15,5ab9aa57,81a22307,ea0633aa,64f98f23), -S(94ae2db9,1ea43b15,fcb2acac,93cfafe7,36874373,efa30c31,98f10b3,b94a1b93,8df119e3,d4872a0f,3b40d3dc,fbb894a7,59f5719f,b81f875f,71ab5b7e,f8cf7db0), -S(126fff6e,9e1c65cd,d7e8aff0,6a20c00e,cdad4440,64ffa43,675a0df1,f7c0ab35,b4eb051b,e05cc632,ac1e23bb,23814d1c,91caab71,6b214dfd,41f6f44c,bfe2dd72), -S(3c8081a4,4183a093,45397a2f,c895877,79139c29,ec6dcf0e,d24016a8,e9d3b210,45a3dfb0,9ff805eb,f7533bcc,1022e0b,8c69b658,88a0393b,66ad3151,b0c3bd57), -S(210f6bb1,25fee215,9a04d068,c87093d8,303ea3f9,1f8f20a4,69dcffac,39295f72,d96e5591,4b2f9eb3,20b9e17c,f3e9a9db,9f284be0,3575b192,3e8d561a,bb5e4d5f), -S(54e9e6d5,df0555b,3a29f1a4,33623e38,5edf8a41,d19fc0b7,c82f151,f14a73fe,ba04d63d,36b3d5c0,3ac704fe,7d15d939,918b8311,1f83bc55,4cd56c33,ea709936), -S(1e65329b,765365a8,6a111355,eb0308f7,c1702263,f8ad9e35,46bb285a,2fe6bfd6,e265bf55,5e975aa9,f2d8b9c5,420c33eb,1a05eb58,ff40da46,2760971a,d044b654), -S(4380d3fa,48cc932b,4f5453a6,24dd7dc3,b4071e7b,eb1a1295,ad8e64a,aa7b40b3,6da29a3a,30cb7bfa,26bbd0ea,cd84c98,c4091683,be9e9742,8dca4fff,5c2a6393), -S(c3990744,d6f84a2f,490a9e8d,feac8534,4b1d4524,1a573d53,9718b6f1,c1bac2fd,2387052b,2161f56e,fb3efa32,13bbe3ec,97e2c78,24c648d6,913bd9b6,c8feb342), -S(d7e1c842,25966972,5de9fb3c,25ec9fb6,4ad1ed23,566e2930,292507b3,e099dc34,5e1cc09,97290936,184c22f9,747e043c,dfb86fde,142dc129,77502a2c,4ad3fbef), -S(f14fa91c,140d3de,5936b6b1,5e4a1bab,8aa22013,ceb72503,27f608e9,2e048f8d,8f429f64,7396fc1c,fb5c33cf,e982cb9e,a762735e,7e595335,19b2e302,a976f0cb), -S(c7837842,5ff42ae5,fbaf9186,81440523,3286f91,5e170133,d81ef705,e80c4f4c,84ade3df,47e23a3d,9f16de8,f61c7d1b,b0428619,8ca74b68,78947cb7,4a5faf43), -S(f39bfca0,beac1ee1,2e98624f,32830908,609e7c64,37175322,1650e813,3874b0c9,19e4fcce,fbc53b63,a3a6baa1,252b7331,fe5365f4,86300711,f6c438cd,4da8aab6), -S(703da707,37e1c78d,1a6dea54,6e896d59,984b1ac8,188fb720,ad837273,86a2c188,e8b3547a,23877467,75c9bcb6,1ed4b4d8,9ee22da2,1052bfc3,aaefceab,698f3322), -S(ba5f3f79,b3d5be05,a3d85b78,16738253,7fbb206d,841f8871,b9f578d2,2c17126d,40acdb1f,c139be,8a1350e8,3d52ae1c,449b3874,71794282,d5ba72a7,5aee5a78), -S(af43cb78,d080053b,7fa4cb34,4d70be1d,57f2acb5,e6718bce,abcff626,c8a44d4,ecb553f,1aa18a31,e8ba2306,22898b2d,fee8d6e5,2dfe6ca1,2ecb5f73,71a5987c), -S(3a3cbce,2b4e40e7,f2c32398,9dd6d35b,74f666e8,48d73e8f,b5810439,f0e1749,f29b185,7c7c98e0,696795dc,f243b662,835c6d00,9a7e55d8,612f6841,d3b891de), -S(81c28d3f,6cb88bfc,dab4f911,98e1184c,d0455bbd,998e8ef6,e98cef0c,fbfe101b,5fb09335,f0527b23,555db9,e5079979,13b75422,d75b5059,198341c8,542c53c9), -S(e9e5ce5b,3c613100,5c4e57de,6133cab4,d65d953d,a4536926,fbcbfdce,1ca56fcf,f9016f,bf8ed329,4a1a5fd0,cd66bbac,e0cd87bc,e51adc95,628b1a8a,25ac1f4), -S(bb45dc5f,e2265ec7,60353992,45f51c8b,72b642ec,219396b5,5ab0edbb,f890c4c,b375975c,c8107cbd,1f5068ab,c3f2f62,f1e9b76f,befef470,be29d5d5,a615408a), -S(38356fe5,4d91f656,79bf2558,36290b9b,b0840b9a,fccbc6a9,163c164a,3e4c7f30,17101271,b3881a72,24373054,39bbda94,6ff03805,abcc35e7,d960a46b,54122ae6), -S(fe6f885a,2996a35d,2886e6ff,e1d0945f,515f5853,c0b9e922,ea82c4e8,db2b2385,2310d0b3,6846cb50,bc3159eb,37cc6b8,47645b07,207ec23a,c75b26e4,fcc0f96c), -S(f84f2cc6,f645b44f,b4cfa5bf,2840caac,c6f512d4,4b0aca89,987bcf07,af8089e1,dd3ed3fa,5ea7f359,8c2b2030,92ede474,b2f594a9,61d7fd6f,8348813d,bdb97f9f), -S(8f2921e1,dae78a3a,4557d895,50de9bff,7641749b,c963764f,e12bb329,2ac092a,9c7f813,20fbf8a4,b4f08b57,58b02cf9,1472612f,113f1be7,fdcccdc5,2336058d), -S(28dd6677,d6085587,46523eef,46aa90fa,496f04c,94e8aa00,2636212a,913eabe3,3f6da403,cfcac4ae,f2bac7ee,9788590e,5cf58a6b,8de534bc,a2dfe892,44309e34), -S(307b5b7b,d959def4,9d3518b1,a53cffa6,f1d87c73,157a0713,b3276821,30face1,b32135db,5ef40508,184b19f8,d3f150b9,8eaa6c4c,edefbfba,ff300b2,86177d70), -S(caa54ba5,ec29788,c53ae86,c58b8436,dd9a62a,cd41797d,1cfba1ce,2c70f251,71ba3e8d,9025e404,aca75114,3b74e0eb,4ef2fe4c,179c1146,e774b432,1e51d7b5), -S(2c2d5637,4a4d6333,83f5051,c6beef25,884f41c8,c5474107,e8f19532,580c8e63,897e1870,4a3767aa,3ce72f7d,dd4bbc7,b8a77594,469cfba9,f3a366a,807ba256), -S(7aa31729,dd90cc03,e40e41b3,5682ed5f,1ac4addb,3287c2df,b4061369,18065e02,e5662d23,55a0c036,73b120a4,fa430d93,fa1a6b34,c371e464,3e40432b,44aecf85), -S(2f882827,4abc0c90,27b6b76b,f60523cc,fade023e,42148f2e,5e237c20,e5da840b,d402a02,3dedbaae,ce4d003e,95daf219,cf47b98f,ad547a92,fe77090b,b9772ae3), -S(a4243ce6,15596c36,ea766263,4142a9ea,817676d8,a9f6c7c2,2e6ab9b9,a74a2fa0,6a2f60,20ec81bf,3d32c353,49f29fa0,db06e8fc,d4058dbd,5214aa0b,8ddbc595), -S(8b7b7e38,a9b704f1,3dc12d15,1f46a3d4,950abd52,cbdc79cd,693e00ad,b7556934,2cc742ce,60e35db4,fb432d93,299e5fcb,f7647856,d8ae4e8e,2bbfa6fd,a60a6a84), -S(da61f7c,31e2ae17,39b188cb,59c9132e,e7120f34,b49a846,66538a2b,f338911e,c8d93b53,d102dd0e,20da925c,e6f63c04,4239fa5a,2d04df8a,9fe68f23,6d03b6d4), -S(38925464,b72e70e0,361c0420,ac92348e,3d208b63,37e55b31,6ce554de,afc2fe09,c96c91f3,c452504c,fa868726,7985c532,181fd1ef,82344a45,4392a4fa,8e534c82), -S(ddc0043,46b27c54,d6a927a9,a053195,335c476,bc602490,96b1c62e,e06b6cef,be6ced65,445cda54,2cef4ff9,2f85289f,bc6c5007,362a4cad,5df4ec03,b450e7bd), -S(5c82a52d,84832270,3cc7506f,fc457b46,8aa8d5e7,1c55a4e0,2dc1971a,a298ee6e,49839199,fe6d88d7,3a75b59,d06a2fb8,a0dae45d,29c35cac,161866c2,caff5021), -S(b9793612,74eca1cb,e5a41462,aec446a1,d70cfe40,61925ce2,558980f,c1d9d435,c59da470,8771c732,d7c94291,8dd76768,ceabdc74,4fb49700,6305b591,2cac9d50), -S(be9ef1b,591477fa,7e3b3f2d,a0c9cb1f,37dbc3ea,f4529f69,2f455f57,fe3a026e,9617409a,97621fa9,b8f8d926,ffc895bc,eb60d2b7,37708bca,99258077,e9d5999c), -S(397f89f4,ea848a85,860efd86,5ef395e6,26e9657a,2cf04097,7af1e8c0,f75e6953,baa93eee,2bfc5d47,e096d20e,c31a2a07,ea369c85,66dd8402,80dccafc,86e991e1), -S(ee263d15,e4437d90,9f1960f6,504663d6,410a12e6,3f70bb86,de33e148,2ba907d3,2512cbc,bc9cbd9e,f0037e87,d51e6fa7,9d96c748,69b702e1,aef8614,859604bd), -S(3c93ad7a,85d2c4f9,1e03bae8,1d9ab6f1,d706779a,41387c9f,4b24ae1e,c8b7497b,ad1aaa38,5db82667,984d53f,88cb0564,6140f339,3b936f3,6d39099e,fca9aa36), -S(fcf7a309,e1362a1c,6659c2a8,e504ca6,8815e320,9ee6a8e7,96c4f173,f1769216,970368e2,15005e71,7cb31c4a,b0963246,796656c6,be28022b,e458fc9d,424bea47), -S(7237b824,1ea29c9,5f7d216d,e15a1c67,9f4f546f,6f79e306,14e2b2dc,226b9402,597f98f4,8ac7e00f,db3ffd2f,88e3e16,57417a6a,25c18b20,c2bef0c7,fb49e6c0), -S(1198ec44,7691883f,5045634,c4475b75,95c2ef24,29e7124c,2ac93bf0,2c0de7cb,ff51c40e,d65465fc,4688436f,7f5d873f,d8be9b50,87dadf04,54b64ff6,e9f8f789), -S(bc5d666a,7d29ca8,21112968,8395a4aa,2fcf4f94,a8437d22,6ccf2501,5ff713a5,6e7ad8e7,b74c48f3,45e71e1c,605bf4cb,808862d1,aa292686,4723b14f,c8169c22), -S(1e05f444,c110aafd,e3c828b,97db2721,d9ae0270,456aafbe,3a2c5579,ea3a2154,3e432d3c,baeb8056,105b67c0,c0e1551b,eeb617f7,c8ea4ac6,4cd29f27,c77b534f), -S(2d7ece5d,4ee96a96,91a5812d,7bf888c8,6f0992a2,51ecd061,b583965a,895c94f7,9a9d0b4b,da5d4500,49ac087b,a30bc507,aba5baf8,f98ede76,debf59f9,be1390e2), -S(3b717ec2,ffb0f062,55cc8241,f972709c,6c3507ea,8e11beee,d5e267e3,2fb576ba,5176f106,23d062e,ec697f2f,c7090352,4fd6700,95baf419,d0251030,101cc915), -S(304652cc,3fffd5c,c86daa47,ba797d5,14d7f3bc,11f5fb04,83b7c217,794a7156,c0767215,17b5f18,f92e6995,f35fc65a,434aba1d,f48a2977,62d1a04a,a587d479), -S(2c9f0acf,c4f3b56f,4a0c6262,1fac78f5,1a486173,dd6bf323,d66bfc48,13ea753f,b12aea95,b7543ce0,40291db2,1ba73dd1,2f0be788,38a81d9e,8e00e0dd,7400ab05), -S(bd236103,9f096e04,770bcd3c,3a10d5fd,66ef7fa4,a6c869b,52146314,90ae5dec,d28b95e4,6774745b,23ad0dfb,dd4766d9,8a2f770e,446a5c16,3277499b,e21b6511), -S(e97ff1d7,4ac00778,97caa1d0,a640ffdf,3bac580c,beda2fbd,23f25f3a,e9a26f5c,f093150d,95ea1a72,3a54e382,8c919940,3c296d5e,fd2ab41b,25cbfdb0,9aff5ee6), -S(f8ae0f13,a6beb793,46450b3f,53f36ce2,8c81fa18,56bbedf8,87e9723,9e15026,3988af1a,f632948,8e7bcc78,5cdc1ae4,a572141a,6cd15429,e6b1b40f,5b44e529), -S(6a944e92,c051b864,d4d26bb7,594f4ace,43951291,44b6d255,5667cc08,86dc515,13a75d28,c910c56a,a5dd2e75,9893d4a7,d86f0efb,dcf715b0,28c45277,50745660), -S(fdcc9b7c,4cc46a5c,8b114e05,c1f44bda,ad11957f,f05a0544,7fd49ce2,7c6ebb5b,72b243f0,1c142e35,f19653ad,a3d8012a,67f0501,a155a644,67629b26,58943381), -S(841e3eb7,17767093,19efc620,4b1dbf4a,d339564d,7ae6ff8c,647a9c27,93e9a5c6,1e5d0b55,7e50e0d5,9abecec5,de33570,d2a57d8b,a2c2d4a2,e90c0ac4,d4edca19), -S(fecf1c0a,32317cf8,469f181c,5bd52ae8,50913793,53569b28,c0c90c0c,dfc7b248,c61056df,56ac8e15,1077dc68,bd0a4819,c19ccecc,552dd14a,bfd6a457,516ce448), -S(82efa605,ac4e5e4d,1b68bb8c,b3f8d24e,47af1820,a7600345,757a36dc,2b241c52,171f1693,a2a0c1df,531d3d2b,5da06241,651482b2,3eaba4fe,c5d0500e,868db6a), -S(5ca04a7,afee22b4,c250d0b2,98691a5e,6b6805a6,b44da5b3,6b8a100,4fcdced3,7bf3a990,465166b4,e8d19ede,f41d7ec0,c7ad86a8,2ac57853,fdc731bf,15a3df09), -S(db455b79,de85315b,ed8ee65e,d8b5d659,5df2d2ed,9eb6e9cf,ab939fe7,93105df1,d821dce7,395db88a,98624ed6,44705a39,e2e53e6a,ff3b7405,3e8b9e18,4e1efa5f), -S(f0033201,aa7e6293,de70665,38eb3133,d2a6b56,5e73ace7,81fc98ed,ee458fb1,612fe4,d18f43a1,12988418,42d875b3,2c9525fa,154b859b,8258f904,d69c5d08), -S(77172496,3722d684,2039d1b9,92eea093,4c0fab8e,4be3389d,7d5eef1c,c31fd291,af3b1ad6,499c3224,aa47c6da,26064bd1,a2357acd,db722182,19350cbe,b84ed1d7), -S(7f27ed8a,c56722a0,730ca755,f23bbe11,ac868be5,e5571f70,5b11df40,28771532,adc25cec,11fe3569,7c8618ea,85005c05,b0fc73c2,db51d6a6,fb55c4d7,6ab9094a), -S(919105a,5d0f13b9,d0c6618e,21257efc,587858b5,6b6b4477,849f43dc,ed12bc0,54c7da67,731e00d1,316a0461,3debdef1,623feefd,784702e,eb42b995,4da27472), -S(e04d08e8,ab086e2e,155ac0b8,408c0163,e2db4afd,57703ec6,8a14c43b,3ddeee1b,742a114b,87e041df,93d15822,80a41360,86b9294b,20efeaf2,4d6b44b6,68a891ff), -S(82c95d88,5715b88b,5c583b9a,467a5c83,4b066ad9,3dde97be,866eb8f7,fa23452b,dd594973,f5cc5595,55d31870,fd9dd65d,c2b79733,c9db8c44,987314a4,d6ca0bed), -S(634fbc51,4efde752,b8726840,82372231,6166a17,ed706b00,1ca80ada,e4c43d8c,61cc9b14,11cc8e1,3f6a5243,64b04221,ece416c8,f5f381aa,8c3ff977,2c20042), -S(d85436a0,1c84e01a,c71ec9d6,93fae5b6,21764db2,1a8604cd,c7b37b21,452348eb,d4f9e6d8,5e65d57c,8bef1acf,a844d20f,1055c756,9690a10d,a230f5f0,8e0f9f8c), -S(200772b5,67197246,2ca9c5c0,e042d0b7,6990a34a,506494f4,f66265fa,4458459f,15e7e0b4,23c66afb,92411156,5e40b8e1,47c97bb0,28bbbabe,8e1a83cc,49b96e23), -S(8d8e235a,8c425a9f,d3556276,2b3c5404,ee0d8e2d,2e41c785,a05f34e6,1ce50acf,74032ab2,8e67f7c1,71bad531,fb1fefd5,d4aad08a,f44543ec,3e731dde,6d2877b1), -S(a5936747,fd423569,cb233184,77b992eb,d2d996bd,b47908a9,59d1a556,bbd51804,4cd3cbc8,ee2e795f,fcf5fb64,4deecb2b,45d6aca0,d70bb33,83f7d16a,d52ad109), -S(486156c4,8f785096,ddffbfc1,fb1d358e,2fa7600e,4decc327,e8b31014,21b75001,dbbef974,6482e537,225f5459,f3f7f62c,b0229307,72c1f251,75ae3a20,f6410527), -S(be858e3b,217489fb,1401b203,fb268592,ca1ff022,4d6fa329,78de85d3,b8a49324,f0bff99,e982b3e3,be3a45ed,f96f19,38d98b51,5b899d16,3abe2e53,bb67e331), -S(641e9c7c,cf17bc7a,45bd5298,af2829ac,b0d78a28,7c03f056,982e14ba,807ad7a7,c4bfc1b2,e338f2bf,7c9afc27,63ad340f,b5b27787,fba888a4,b8c4cd86,cf745fb1), -S(e8566e5a,1e855981,c6e275aa,3199dca3,3ddbb528,482ef60b,2e87c9cf,544cdcf6,94adf4a6,1643a235,9ac421ce,c5aa5ccb,779d4a9c,62bc01f8,93643405,4329b8bb), -S(f826dbe,15974b59,f4c45c11,584ce96f,56494195,4ae5972c,876a5358,82c5ca5a,79babdd,ab8c5a53,4f527ef1,459ae3bf,990f9bbb,a0d1dee9,d6ce6c53,330b9a96), -S(ed712f5b,a2d886d1,5e7bfb43,9c57bc1d,c2f9adb3,9bcdb62a,29c05d2b,1b483a07,36830fc8,b64cded9,719e6552,2ac7c6fb,3d6dee60,dfe6ad8e,30c5588,e4a3d876), -S(bd372233,901475d5,a6a2e1b,e11240a7,bf866bf4,cdecea09,541c718e,202991f8,4a24709c,cc93a928,9706125a,8922c828,fc309dd1,533e702b,fbe0fe7b,218f5c65), -S(f196cfc9,50001e76,1e6453eb,3afb64dc,46c793c6,58304f0f,ca3fa342,66da40e,274b3da1,eb8ac4d9,aac325c5,187b1507,ea4e24b6,1a74c2f7,84e9218d,d4c6f68), -S(d0b4c5ad,98eaed0e,6011c072,a2de350a,5c24da34,5a60980c,fd1c73d8,3d1ea674,9cadcf76,7371d792,6b818ee1,b4be2c53,5cc1d760,bfb7c47d,dbd846c0,c2568449), -S(41051a05,8771b3e7,a8fd33af,1838b679,b13c480d,ecc065a2,a3386d9b,25c822cc,ccbf9cf1,df8ebe76,159ded17,2268f71e,c3f44e4b,2d5a2efd,5d4ff9b1,7f41f8be), -S(1d8f44db,4d7f28b7,8b911ca4,9f622337,414fb0b8,81b75ea1,e93a757e,36cfa0df,e486e0d4,83987655,8d4671d,537b47ca,f734157f,6843118,ec5a3293,839fb77a), -S(71fbe897,6c6e30db,b71530be,42cc3fd1,80d60acd,fb3533c2,c0f2720e,e1a9bd43,84560b27,383d8db1,5558a2a4,a8107878,4c62325f,60ba0669,69573488,262efa7f), -S(7f42e7a9,cc3960d4,98e05160,95477ca9,a23cfb84,675f1b0e,c38e01e6,86daa99,ab0c4acc,6ae1fad3,82eeab7a,e7d1450,6db254e9,6abc9a9,d8c55c9f,7e09621d), -S(8a9c65d6,5c400f53,db6a3f86,ece6e185,1295df9c,19a55e34,348d5de1,c6242448,87d177f8,12769257,ca0f6e42,e1db9067,2387b8fb,f0462051,59a55d8c,79377af1), -S(d7b721e5,332820f1,c8f16624,4e3ea5f0,b63117ca,983ae4ee,9017d44b,ab18b5ff,b2b5b7c5,9b0fe6fb,386e185e,44cb43db,76e005f2,a5cc57f5,4690841b,7de26d19), -S(fc81762,38dbbc4b,3969fa08,31c22a19,bd163b3,4327452e,467b91ab,940622a3,b5f38676,ba86221,b0a02c03,6819df58,f2dec21c,51f456eb,7213289,6f7a54bf), -S(54e5db5d,2f87f24b,6e62ba97,6d941198,8584b337,ed801172,82080190,821d2418,ffa698d6,3e953ebf,b755c0c5,15976246,b5ecfa0e,397051ad,136f88fe,81987e14), -S(b18d7cc2,4023df48,776ad32,b64b234,1ae42cf,74b19038,6f3de4f2,bb029bf6,a12abedd,ead9d502,eb28a8ea,d65b2a19,29ddd548,1a7fb93d,e8d43b94,bfdc8547), -S(22df5ec9,d2acaa17,473e0ea7,2ca2eb49,9622677b,6abc063d,1bbb3648,7bd3294b,4d98a1e7,8dbfa279,227a6090,b61a5831,a6eeec3,519710c7,85679d5,61b48a6b), -S(6ca320d1,fd3750b6,5606108f,43585ab5,fa3663d9,65428a40,28c17eb1,95790eb5,b346253d,d2912350,86ffaf0b,bf7af93e,3b4f44a9,fb820a53,286067d4,98019e87), -S(9df9049a,7cf65986,5c88b93b,3688e9f0,53eacd78,561d97bf,58358952,f1318a9b,984b2aad,3891f7f8,df36b785,b56f4967,1f572f11,2d87023e,6003b3f5,fb80f3db), -S(6e96057d,9827d88a,5ae84c28,c1aa2158,af62d298,2cc26c05,30d48d2e,d879aa0b,92cf1366,8b9784d4,25c16b50,afdaadf7,e7c114b7,783050c8,7715d6f5,1d273a36), -S(5719e0f4,60efeb2b,78eab426,ce8a0623,3f092d2c,97d9edf9,3d22d403,a07fb86e,5c27677b,63486c8d,3f2454eb,30d5d511,bee44e6a,5bebca46,8e1e7b38,61c69a12), -S(87e1fdf2,c83a698a,9fa294a5,252894c5,4f84b148,178a28f0,42870a24,e7ce1175,654db1d7,c34e78a6,e9120a54,6b9df354,b7d385fe,13a3522c,72adbd4e,660f2cf5), -S(9c915f39,cee954f2,3d534662,f2d381de,834a1fb5,13739902,6c1b6b97,53050fad,8b068e52,e6821405,8974c43d,8902a00b,d2aa49cc,f0c4adfa,fe631e09,ce658112), -S(d77ce2dc,6b94603d,c2093771,ee39e720,93150705,56ee100b,a4a2738d,b6d22ada,81bc70f5,96f31096,a2054807,aad9e9e,63260eb6,9d524289,71675300,8d71bfbd), -S(ef509ae6,9fa82146,ac152c96,d76313de,c1857882,a71e8955,270497e7,33a3af9d,a614aaee,6fa558ea,fe7d8d3d,4090192b,c8a7b70c,d4dbd766,a965d684,544e5bbe)}, -{S(5b27aec1,c644f0a9,ba7f6486,9a960ea6,28343ab,da3feab2,4a2d6add,754866a2,3d1f365c,2aee6c1e,ab2f1879,429b6275,5d1bac85,2998ef25,8a914bfc,ca280b43), -S(51509477,fb7660cb,b15636f7,a53b1e42,6066823,690af014,b227d14e,e428efc9,f43b885b,4db6e28d,d93b9feb,f035014e,8600b6f6,ad6fbf13,6eafd789,2fdae717), -S(484b85f0,516bcba3,ee08f829,97496e55,b3856c94,25682c80,837a8d65,16096083,8649305e,2f245dc5,d4a9082f,a29f9421,fb20ad34,2754d8a7,8ed0e3c3,ae933ac), -S(8fd997a6,792e739f,83666c5e,25bbbb47,ada14d89,d3386cae,2084dcc9,f546ad7c,f85d46e1,1eb472b7,3c4c3731,bdc3620e,c2991b29,599871e5,e215af28,9ef08cdb), -S(5fbed326,3a7332e3,104dab58,c47932c8,a3f262fb,14fa35bb,a5021344,e965871d,225d98be,876cb5df,db578da0,c25be784,5ca1f5aa,7ec273a1,7b9b3ad4,5998202d), -S(d3ac3c1f,84be4b7,1e47da62,ca159e02,5cbf45c3,a40b34b,c3f3b28b,b0bbf1d,b2b94603,f6769cda,f9a766a6,31d7f48,e194f51f,2250347a,34719c55,beb30e17), -S(6233110,a8f6b13b,fa99dc25,b912344d,1cac4cab,f25318e8,c7d1884c,9985a468,dd458304,e3782dee,71ac4c33,c4e45e3d,79dbff13,437f9b99,ffa991bd,778e0707), -S(3cdd0f3a,b2b52a8,65ad9d4d,d65e089c,e2a66772,a20d5dad,9768fd5,6ca5efe7,ee940af9,90ead7a1,a7916eb0,44470103,b73c39da,23288072,1ff245fb,93b021b2), -S(9aa9bf7c,d8b58d8,411fde00,84e05511,6f11dabf,a699a1c5,614eeb3e,4af41bae,71d72932,7f05269,a99de5d,cee09c4e,dcdd3b76,a4465d21,ceac33e4,3741ef6a), -S(aec139f4,4598b687,c14d01ab,250160ca,abf5d9e0,1cd69959,2ed2e988,22345aa6,d8307e0f,9018ded8,d883339d,7ebe1fa,8ad39889,d0853c89,4743e704,d5afa618), -S(7f99f6ff,4d46e361,8e55f46a,ed55b95f,3203ee16,848893de,c33c5756,1184611,bdb6721f,987283ec,873e80ed,450d8c5d,9e7e2a02,ae56fc45,9e69d3c2,d2016c69), -S(8d850e4a,e682f751,22cadc1d,ea01a22b,377ed983,c833a4b6,e5945fca,4d227b2f,94c22c5c,3864879d,e4b861d5,e9e33523,e5f848b4,fbbb8d3,4aa21a,85066e3c), -S(194b8c89,7231a783,ea9a835e,ca4b6744,f0d0fdc7,232ddd43,237fb622,14c869f,db961536,179e4275,5b9bb682,95d1c75e,b2b7a19d,d5084960,7d9622d9,cdf46937), -S(760ad01d,c8e83c2f,ee63caad,9a86f648,f6b72424,4aa158d9,66b05647,eb6cebb9,9d08a9fa,1d21e580,d34c9fc9,10b8c294,522379fd,c61fb056,895261bc,cc827a3d), -S(c2186e23,813e84c6,222138b0,1ab17c55,d47af51d,8e4239bc,1600fd66,d971cbc2,200a33c8,7f9e6d4,1d5d602e,6002089c,6246345,107e8b5d,5abcd35e,7203ac68), -S(4ef2336e,857336cc,dcf3c9a9,48685847,1f639021,bad06218,8a66e4a5,dbadd35f,67f8d186,e79780d2,b063e723,eef5531a,d95a653b,4289e98b,d4df52be,1b40e8e5), -S(16d03f6b,c21a2a55,bb0467e0,fb8668da,de88ccc8,cbdf562e,39c992e0,4cb66545,82a7c24f,b5dbbbd6,4ce566e1,94834d22,7127ab7d,ebce6fcf,60ce1482,4ffadacd), -S(edb76db2,a1d454cf,e8b9761d,951fbefe,49054fd7,fbc7e800,5051ae27,5b41e8e2,343aba4,56c46bef,17a254e4,df28e783,cb6b09cb,f40b062d,22a04aca,701b66d0), -S(b505feef,7c6f5219,7cd9b159,5db0e30e,f1f3be2,7e65001e,df1a9f4d,ed86af06,fbd1a957,d0a4e43a,652c2555,312ace49,92e2647d,5167c18d,86410bca,87705e18), -S(50e755f5,f14333c4,13be7594,34be8d74,3691156c,12a46ef2,c730839d,3871f097,a2925d1f,263c9c2b,32c4fe8f,4cb2b7bb,8cb6cff8,3f0ff900,213afd01,e5d7f01c), -S(6fb573f1,529a88c7,9f278108,82d9c8df,2a02ee28,84168ea,7ac41219,23d7a96b,e34f7cb1,e4c93ccc,8e7ec63d,4cd5c198,efba1a26,fbd24ca,2f09d378,30bf2589), -S(3cd35cf0,c96e32f7,2023447a,f9ada5f3,8082543e,12bbbebc,947fc3ee,215ec98c,24ae2376,10990d87,f4d9257d,45857e86,de05f6ea,b06c889d,c44d948c,dd5c4b84), -S(6b853761,e19278c8,11a01f0,499779fb,a2daec9d,a5ece88d,b25ee726,21f42eff,fceae86a,242bcc35,885a83fe,ca3807e4,13f46408,8d46f68b,860ae389,c3f6aae6), -S(d32d3024,34b1cddb,ab02db35,4144d96d,845028b7,c8b5b45,adeb3ad,84eba58e,762cc6a2,78b94842,7a7fac39,de201c91,c92f25b6,b472456e,67407ad4,9b977b45), -S(64275dbd,a2ecc977,3026dde9,f1a098d0,63986d88,8e958430,23ebae9c,82218f6a,e27c46c8,41829e88,2276ab9,e146635c,953db6e4,f1295efa,3111b0c9,40695056), -S(1becd08a,a4aa040b,51fe7380,396a18d4,1fac0c66,91093cd5,d74a31a3,2b2e3a9e,abc07812,ee13caa5,b040cf7f,ff4637ab,a9e69db6,7834efa3,2f864858,ab138989), -S(f9976dde,8c971e73,fbcd5ef7,50947027,711d5a7c,bb273871,cc293cc7,f4a1f732,408ca6e7,ceb96781,f0b2f4a0,af58f2e8,52ad5438,3399ddc6,e9a65144,282aebe9), -S(fa71702c,91ef2cca,d80796,ef0c6246,9ef32e16,8f5c9ddc,9fc7241d,f3ebd2d9,94491856,fd63fe93,7ae6e95b,b35bc6c7,85732cd7,7305a83c,65ff9ed4,42f5e11b), -S(b5ee5d7f,60398c08,f66d568d,1ce39d82,5c64c7d7,c65c030f,3e35e86e,c87b0036,d2c62b4a,71f9c662,9914ac79,7f34203c,eea50a58,ca8ed06d,582755b,380ec185), -S(7aa05776,3de6393f,a4b36ecf,5aca8f74,6e5e68ef,152065c,820a2207,80452ca4,58d54e32,840a40d0,b2a8a175,4138a62c,f054aad8,85e97731,9fb3fd6f,d9729bfe), -S(74b062cc,f09ac530,e607089a,8efb5a06,656dec8c,e1d1dc01,370e43eb,39594b1a,6d93d5e8,eb3244d8,8457e0ff,66cacb14,d38e286e,f42aa6c,3236b2ea,883e9f64), -S(dd56f2ee,f4dbedf8,ba5efcdb,c569ed21,4aeb7f0c,e3aed757,e72c91ea,9dae7642,c8a30e73,efb151de,d38785f3,2f5a9030,4e62becb,b0c470b7,1f049dff,7b75c9a), -S(a05bc315,ed5ccf78,34d888a5,788263e8,573a4321,7b0480fb,960e0a3b,e7575d0,9b8568a3,1b1b8f6,ad507db8,b6016280,28f43990,1c9e9f94,14ded563,6d06a78d), -S(c19022f0,5c316bd8,e5c50a4c,1a0a6808,b7a1a696,8ccec214,da81e039,53baafd2,110b1cbf,5a01e8f7,95d0b996,a3e6c2aa,3645ffeb,59a77473,e51c4810,665a415a), -S(feca2015,14edddc9,8aba216b,cc37722f,f6c60202,d16c6925,422582f,dfb241f5,61c06c06,d0e50e98,2d9ea3d9,44079084,e37b5c9f,9aaffbaf,c89d73d0,20dfdcc9), -S(d3d271c9,2b843b36,a24f1928,efd4f197,c90f176a,70539f,e290b150,24a4bd89,9179320d,bd5577e2,d7e58d67,131e47c9,118e78bb,18690f7a,74e9b38c,99cdf6e8), -S(2d12ae62,3f4b552d,4b7cdcd6,8f16c9e2,58d83cdc,b5fe567b,a5216cd0,6e94a2fe,469fca9f,8d15b969,8687e33f,4a6cb20d,aa8aee7a,a2911802,f6f26f1d,fb22d63), -S(55c31675,9974d7ea,57b0c133,b6e1f1b4,9ecf0c15,feaf74f6,b63d6d8,ff525a92,de38ca29,5f85b65c,4b56dbf8,22edea40,19f61207,f16b6364,6943d43b,4a959f14), -S(739facb8,74194ac1,e60a2206,10a82629,4f1bea44,ccb08f67,33fb30dd,79706bca,dd77cfb3,641a3786,109dcd08,700edada,8701732b,819f41f,14a55104,9ef8f38d), -S(9768a20,2ecc0ba5,8524d10a,c6d2c18e,611a1215,401a8ca6,571828cb,ae5759bf,5d35c2bd,2e7019e1,6e6bed11,15a16d72,dd4c5ce2,fd848434,4d8bd392,c4a680ff), -S(2161e7b9,858db630,a1bdb50a,6b13a6b9,829c302a,a836f0e0,d89f5a35,70065067,c565cffb,915ff76,7bab8f73,aba21a7a,9168274,d52681b5,301f76ae,a9b6daf4), -S(2a9fced1,fe2b258c,6de7b534,212419e0,c6c1cd6a,50257dc8,79f954d4,c351d7a7,887f8024,d75a1f72,e61807f0,d8c310a3,5df7829f,714433e2,214f9180,ae552e9d), -S(769d9e4e,8a1967a9,1df6e8b7,cf282ab8,7f9e773c,5dcb94ae,8af7b125,6254b879,53537a42,ffa46e16,63821069,f5bbc62c,d7a0206a,7407aa8,154c82f,dc390650), -S(6fe3bbae,441f902e,7ea02e32,44e3ecfc,6c45ca71,9bdd5e4f,23f7fb3f,540d45ed,d0cb3379,c858c9e4,6115517a,c65d3452,16dc744c,60a6f1c5,7cbaa8cc,f4462123), -S(6226690b,d8d94bb7,168670ce,8b4d18e7,a35f0fef,ab50c816,195f0b4,37fa16e1,cc8f53f,9d16582a,fd2be5b1,8db42faf,e8d83ce5,481a88a0,9c54ed2b,7023c3ba), -S(1e5d9adc,dfb56218,1d10999b,336412b7,d8fcb37e,dc5d20ab,8f8cc789,55e8a72e,221d5b4c,58ee5fc4,8cd34b1a,cc9fe795,2d890d35,4047746e,405d83cf,392184dc), -S(9e978fa2,ce0875b4,ff79d6bb,4f56a9c6,10d646db,c81cdb06,5430f9e8,4198b707,9608823,828dc9e1,2835e261,1026ea34,c9b4583,46ed41b6,4bbf8441,fd621e35), -S(ef6ed3e0,587229f5,aca0534b,f632fb13,f4067712,9d41350f,2e92bc1b,cc1d6f8a,c9852e66,260fa65b,13ba714a,2629177c,80030b2d,867f4e98,83e60ceb,402e5ad1), -S(3c104b7b,79c14740,46a032e4,8ac22ed0,1a8b8812,3fd1b457,977ecf3b,b82e2720,809d1774,22521dfa,f05dd418,e5783577,d542d683,8904cfe3,35d8215f,1ee63b6b), -S(5fcf6b6f,de14e372,11d15178,fe37c914,bb9802f0,e67cd3f6,3fe72688,e9fd2dfe,4e468677,2032e358,25c89a7d,28fa840f,ef33bfee,7622421a,f2393182,ffd8123f), -S(d3f81471,d6d530de,7b8fb0c6,125c1b0,596e4430,dd89a22d,94a516e3,3c1cdaca,31da0106,ebbd0289,c68bf092,381054ff,718a8bb2,aa65a9d,47a0ef45,acdb8e7d), -S(c1d365d1,98ff150,ba208d1d,486de98f,1cb9e23b,4e83c58e,40d15f77,9b12688,7c11b3b7,5b8dfb0c,ddf97f80,e3ee4655,1242897e,2152048a,cf4910f3,2b819a3e), -S(c935f87c,752efe3f,d1208536,2c49321e,ad521ffd,b11fea5c,24e1ed72,cea77a28,1cd31bc4,46b90688,266b9f3c,74426c89,ae4c442c,4184c3d6,206deb3c,a92d1fe5), -S(2a88eb26,49349f3e,7fd6a43,78a8fdeb,86df60b4,dea3416,1c811a59,44a98040,e7fed2fc,a145255f,a06e13bf,9bbfb1be,6e15e330,9fd624ad,9b352c8f,1caff852), -S(313ff59d,1dceac83,4c70fc63,f1f32df6,ceb4253f,8327ee35,ce4ac575,9ec2821e,d0ca06e1,30d083eb,8a7501a1,dc80398,e67a133c,973121cb,377e31d8,fc4bfa14), -S(ebb8d7d3,81dffa3c,8ad10bba,aada6598,98ba7694,7662bfaa,e5acbfb4,36e6931,f01e6b28,fe03ffb9,42ebd387,a29c2896,32bfb526,58a7abb,34c10bb5,24cacf8), -S(208055ea,a3c94762,5e9cdbe6,91584b6a,a060d127,63f9a305,ca360baa,9d601a7a,ff382321,b7f3b513,1551c441,f6a8365,13d16c74,f3b74345,a5100ed4,de88e00), -S(1579f653,1ae0ef0f,b9da909d,959b82a7,1e158400,b5d34f5c,8d66667f,cc6e5c92,50f898cb,60c9630b,507bf817,fbfb7d3a,29d3772c,74e7a7d6,19bf4198,7a09136f), -S(4b40b410,56a43404,559ec18a,1bb18544,ad8896a0,c8182f51,b9bd0b7a,ca178f51,a9f22e06,79e43402,d6397eed,285db77b,15ff1073,6a367a95,3a439961,8cca3fac), -S(67673db1,2edf2be8,c0d330f,b26a04bc,bd0e6714,5c7b0984,11a59719,e845be8e,c34f45ec,ae724308,2245e950,f62b0c2,2b6e1b1a,eaf5d8d1,b503d9fd,e09e8cca), -S(8c1ec49b,81d8e41c,3bffb5f3,7765bad8,474f647c,833318f7,b6227608,a1f8a9ef,fbdcb1a4,a418b7b,5398835f,8f68de59,c7430754,87f52c50,a968c40c,35f3149e), -S(d823fe57,c0934eb,a2f15d1e,b445418e,e5092ffd,b3241d94,3748dd70,9e4d0733,b20ce02c,69b038e4,a5e37858,8dd0dcc2,f2433141,a2fbe473,e56d860b,379fe4), -S(d16cd142,a198d5b3,e2e855c3,b1b900ba,12d0e241,c914377c,1c880cbe,c3e9a10e,e0fc81d8,9d32e421,70161026,97e51be3,91a984be,739b23fc,6e3d6649,109ca782), -S(34353521,1fba36f,58fb6f55,aa0ccd4f,4052ccd5,8edccb05,164e82bf,111b0af9,4a9ce50d,2d0bbb0c,66a74a00,c91d5f7c,92b416b3,f0bca8b1,38e5f456,fc48f6fa), -S(254b9165,d4afe2c5,eb4360ef,2240fcf8,f8f4ce78,8237bc4e,c8edd63d,92a8b4fe,3c7267a9,5df9d1d5,96208351,1739729b,25d07ec0,53f30233,acbf1f88,b9cd1f7b), -S(a993528f,cb239c1d,eb824cfc,41ea09ef,72cbec61,ebcaf0c,4ea7890e,3aae0f3f,78b41a68,6f832e10,576820f3,552b181a,ef3b133a,fd5dca99,c7fd7b7b,247336c6), -S(dc431b9b,2d0002c5,d46079ce,463fb29d,6fca380c,4edf8188,34c354cf,7f123f13,32ff1932,2de938f9,9be1fbd3,3c553510,8c1dc5d7,caff8dd8,c4db6218,54b9bba9), -S(bcbc08dc,4ce90c27,54b9a79,ffec9320,3c78b60e,adb3f750,2cecfe12,d475773e,fb691bf6,8394b040,d2049147,6ee7ec8c,6d69baf7,a2ebdb5a,3b455088,3285e468), -S(20ab53a0,d5a26bab,ff0700c8,945e2487,fef10dc1,1c523b2a,14dfa8e9,fa6d68bf,c6ec861d,dfe29d4d,1a23d3d0,99802f20,ade886d1,257f669c,3315ab5d,effef915), -S(c58dcb0a,8700faf3,55a26e39,58c61617,3c2d5c07,824041da,71dc5d0b,6bc351b2,78ba4b31,5d716184,9bf53d1e,94a6ec8a,2268538a,58ce2f17,fa1ab6eb,beb9810d), -S(3d665b4c,831577a8,c536598a,3cfdb3b,85e1f45d,566a0b9c,a6852ae4,171be6b9,e6a349a1,36827310,e362adc7,cde91f6d,e6330122,592d1dcf,a7917d1f,8948fece), -S(6f8d4774,efe7b37b,d26f5849,22b78273,cc5ad16d,80f0f4da,8c54e167,33c5c7ec,b63ff2af,2fed919f,256de972,bda71f9e,e4a5256a,22782a0b,c06a7a48,57876d44), -S(97daf45c,8666f208,ee72dcad,c4658613,b8466605,be2e83db,69104973,5516b1df,e33deab,5ee28d64,b818e2fb,6acbe9c1,cf060142,210235b0,dbd9514a,ddb57402), -S(c712fcea,95039f2e,a87762fb,5e5fcba3,dbf7ff6e,658bb64,71a4f890,88e6106e,174f28a4,9b38ff36,1c28941c,b89c1d62,4606c269,6619d157,f05be89a,ca550fd7), -S(f42d3ea6,d791c681,ef6c16ce,9ab763dc,df7e1f54,42512b3e,f9ef8904,f6f30927,abb04412,3f2f1329,17cb8a01,26d21fee,59606715,6a3735cd,4cf2969f,a506eee0), -S(a77b7262,61365881,c1aeb570,12555deb,6fe98240,cfebf712,386fca2e,efe460e3,3200fd50,9500ff2c,df4bc618,f43e705c,b5000762,dc3bfd57,4ac66722,edc06daf), -S(82af11e3,34b229e,16877594,b9f7f157,8cf51255,c7521ebe,ebab9a81,a2b1bf76,3182824d,7afc4ee4,2e5b3965,65f07bdd,b47d0f3e,39685096,e96bf5de,4c00f47e), -S(b015e32e,802b997b,4c8db911,4cd0a3f7,8fe91699,a9d3c344,f03c77ad,508bb842,28aae64f,70b35de9,992216dc,ca1cd63c,d41179e9,b7ebee7b,964031c5,3cc56a00), -S(580ae367,e9118f01,858d82d8,20ed6c9e,923f3d,be934b3c,d0860fcd,1fdaa714,94a96e04,8b7d8b49,fd12bc04,d6a0f7b4,a0bd671a,dde14d92,9d8eda25,ef3ce73d), -S(b24a5ed9,65ed6463,b30b0be4,ee048957,2c62524a,50937daf,e863dc0e,4ea3484d,ed8897b2,3354ddae,149620fd,a3f7e17e,c8a5b46c,fd0d955e,7326ab1,2c7542c3), -S(5f9b9a03,2b21c8e1,31e13c2c,8019db2e,524a85f6,3ae03014,d27bca62,971b938a,3f954d07,f7ef5c7e,e4b288d8,3722e458,d38d5950,b38ee4b8,35ddb017,68a1680e), -S(61d23399,c8750a26,ff4220ff,c3a7564f,f6df92a2,fc133ee6,c9228ac7,56a77b8e,a3ea3176,80b9fe5c,25c74f3a,5cd0f4e1,73f9a47b,f13c6757,3ad9584f,81c0d0fc), -S(39129baa,19373bf1,db83360e,c1cf46f6,cf6041f,7aecbdbd,c0cd8155,4047f4b,e524c633,cad2a058,3826b241,a0f9f90f,1c29aaa8,7fe9043f,61f243b7,35966525), -S(9f4eb067,ba8943b2,7d9c90de,e3e3f570,9d470e03,4400b49c,8863852b,e42d2d82,7decbcb,df928f29,2359c31,5c4e9d1f,7c81daeb,4153b6e9,835fb10d,cff87699), -S(c3c41675,59499453,4ebfe29,32fc3a8c,fb0bd4b8,f58fcdc6,111e68a1,2931d68,9a6e07d6,271039b8,e3198823,589508c4,353888e5,46e8a759,873fca67,a687aadf), -S(389932dd,1bdb022b,aff12e7d,96ad188e,f2a38d,e07db076,d4ff0292,878a581e,591e7dea,d8378307,82c9df98,3eee4623,d736bf1c,7cada52f,9e9775c0,9b2c0e7f), -S(6a24296b,4ed7585b,b6e1a7cf,a6bae760,bd87c580,c5136641,ae890ba6,c6aca188,d389a8dd,df70e094,32a77278,89142e7d,7a1ed1dd,63e56961,14d4b9a4,fdf7d48e), -S(a3adc560,82a6a35b,76013450,a511c437,29000a3f,4df1cd21,d5a37aff,25236ffb,9e298b2d,73533849,d981556e,c4ccd2df,2cf8a84d,49fb32da,414725d2,e8bc8172), -S(b1761d8,b63ede1d,92aa5d47,9de387c5,10085632,dcec781d,44b1cad6,ff59a49a,16e10005,9f5b54eb,fde33551,d68eb053,a91a17a8,65703a4b,a0e4fcd0,ee35927a), -S(da2439b6,9512ddbb,8a3bdf44,c3dba4ee,1047594d,f274a33f,db442c6f,3313cb9,23a2b190,cd307fd,354474c4,95e6b0c2,df104478,e337e7d4,9acf1204,666f16bb), -S(5247030d,514afa45,41d07a69,e5670aff,71d42ca8,d6258e5,298efd35,2ea5912e,76a36497,2edb4c57,e29d6de,9990e7d5,f542c84c,764831fa,86ef5ab1,938e27af), -S(8d2dd8c8,80fd50f,94fa6552,3270fe1a,61c92810,3aa1fc44,d2db7955,765e9f6a,1a99666d,2f76e63a,ed386a7c,25a6e66d,cf3552f8,5979cbfb,355a91cc,ddee161e), -S(f964ec9b,b42fff6a,87d268fb,b6f58bce,c53bbe95,5780f6d2,765c682e,3b29ee6a,f1b5d480,1aea1445,177b7e30,7ec2ebdd,4615fefc,59b22312,1ef80277,45790fb5), -S(388ac82f,677422aa,c6576748,59fe634a,c9768335,b9f6402,dc089b40,186b8898,5a93f486,77033639,b9c0861a,c82e6326,e7a20e73,9fb651f7,ca99c3b6,b56e0e9), -S(e67c3d3b,760b9bd2,10cd6ed8,d261c0a9,3a24395b,5bff814f,18d1b1ef,efc5e322,370323bf,db8d6a31,8066dcf,439c9447,72c8a049,9df2486f,426a1a4f,297b3c47), -S(e3cf3c48,39595c97,a6efef6,98e75220,4d6ae09c,d4e7c231,24e16902,a175b95,91e50db9,f3a1a3c5,634fc2,6dcf9010,6fc27d4b,aa24e659,fd247c5f,93c83593), -S(b16d475c,c60b5286,2bd250b6,f4ca284c,69e30698,96eb3633,18ef6b7d,3928cddc,ef3fe367,312a3e06,b992f862,8e5b0c75,5b6f6ff8,fd62cf8d,a0353a52,1e6558), -S(758a7aa2,9433f0e8,ddcb6e85,70ffddee,2c487f7a,7800e6ee,7eaea634,c8c3b7a5,cbc5ebe,9bb4f480,2d50f99d,746065fa,7c484a84,30643962,50508ed0,a75ddc49), -S(3c2b2b05,10564b7b,7f53dcc,406d4329,e0faae16,6259edf9,ef26d1ca,308f0352,19f44e13,cd4e6107,2983cd91,81f942a0,f4cf0f4,8a10426b,c3f30dcb,8693af36), -S(ff644ef5,ec4f91c1,33ea443f,d783573e,debc003,7f74cac5,af866a37,302cae5a,50eaed81,332176c4,20e63c38,9ad9faf0,75e45a26,8119342c,b635231,1778e3ca), -S(2ccf4da9,9aa616c1,900f566,89d356a5,1396526,d488b635,f10c368,ae066c2d,46da8b3f,ef5c7994,9f94721a,2656b55c,6946d493,49a03aa5,fdf90c0f,4a152ed5), -S(5cf33ec4,cf6f3af0,18e94ca3,2d31845c,f1c4764b,2ccf3992,48467c4,b3f11924,a5cf6368,c5b617bf,6c69c7f9,fb0c769f,285720e1,432fe54b,def57fcf,8fa25b1f), -S(5ba03c13,93b9a100,928e6e3d,a0cdeb2c,8be4d653,93a233a9,b7811e4c,d242da22,15f9029,4890222,960a70e6,8046c2c5,de15de6b,8ada4243,64357c39,b11cedad), -S(ff9cb0f2,62e3a7b1,d5ebe749,112c8b02,4c766789,c2973446,ca2b8884,e5eb1035,f5194ead,3d090604,86d7f0cb,f72fb540,273eebd2,7c94a199,6f9f35a0,3834886), -S(b747105a,da190d97,48094f54,ef60d1d0,30e3f57b,f32d5477,5c6929c2,975a3978,18f9265f,b2cf77ca,f5aa62a1,8e82933a,2cdad96b,2866b5ed,c18196e6,97e9565c), -S(48c6d033,45abe61d,aca1dd55,8d782685,d05bf49f,2897fd37,ac112e98,1feb0ca9,853a71eb,1a1dc7f5,78adf995,a254e545,a1effac6,7afafa22,cd2c6be5,d9915b42), -S(27d839e0,b29aac17,b84a7654,b2e60cc4,6b8d02ed,8079a525,cd0463a7,f21cfd2b,9974f97b,504bcbeb,d8d3f3d1,1db05229,69a72357,2de8ed56,ef877402,8a435c55), -S(8fc52f0,3dc76184,195d95ef,baca3ced,9aa1b3e2,5f36c75d,65e67d4a,28337ad3,6e024d2a,ef78ac8a,d59450cc,de13c8a5,2d23eeeb,13d11cd9,7b4a9fdd,be716a69), -S(afcfe9a7,44837fea,d3140ce3,4e281510,5fa23b8d,1f497440,8d6ac3c7,70b46c6a,253c825c,8bc94bbf,3dd2a33f,f6eebd7e,203a34,69858d9a,6b48638,5ca557d), -S(e4a30e5e,16db32a1,83532b32,d466e985,d664be39,bae1dd8e,2e34ea05,d8575028,58bb5c1d,95922c2b,62aafb36,6bf22c8b,35d8947f,a082c4e,ce9d8ea9,cf24eda5), -S(76ee906e,b69e9ea9,667d4582,99c6c47d,c0868bda,ad8622d9,b8a85a9c,be6faca,88f10eae,25307ed8,e519abac,a00f721c,8d08e1da,344bdd62,5f6077d3,4295f4ae), -S(bd58f596,ba832cb4,2e3d7445,428f79c1,59da797b,317cc471,88188f3c,715d3cd4,8bbd7cd1,a511e88c,d7a904f1,6db60414,d4555337,1f72435d,cde9b5d8,715d169b), -S(8d450276,b722186d,2e93ed73,3e45fd3c,660225a7,eea0d90d,bb6b7370,1b2dd80c,271816bf,4c5676a,86efe5c3,5ddcc606,804f4cf8,15d19937,16733964,e00d552e), -S(7dad1a19,4b46b8de,f3d16ee2,6fb3d1b2,a9d9c026,c5923bb3,f4f88bfb,736c2b7a,ebd7b4fb,6afc3648,746823c4,d179687d,6d1b41a7,fbb597af,f028844f,b6377681), -S(de25311c,898c652a,40fa3c4c,6022d195,e4f5d336,5f8781e2,2b0bd1db,5c733c73,194b36a1,1d99a3c5,4e7c5e7e,31846b12,4229ea92,74737a57,22056cc2,56f3723a), -S(cb204893,6466f088,32470071,1afa626a,a8289325,913f28d2,f1e17ef2,8fabe7ff,c60b4373,bc81fd85,b871c930,827b6833,cfeb6708,c40c1942,676cd766,ddd7b390), -S(6ab3128f,9735753e,341ac4df,9e4daadd,aa5034e4,831b9681,15634e41,da047af5,ddccce3,47c9c588,88169f04,78859080,27c821e0,1400212d,4e40ebb0,999c9464), -S(c4b853bb,81d90026,c6463268,6440bc6c,42cb7afc,513a748c,dbf09039,82e98774,6ab31853,982a0b98,48173818,215f13bb,940248db,26eaa964,8300dda4,1482850f), -S(4a489c6e,cd52b4dd,33956733,977fa0d6,25e4f721,d5389076,91a4a251,e1c65902,7f7d73aa,23f31098,c5522a38,1172fa16,a10b4e26,9457c09d,15c14954,bcc794f), -S(d58a8e44,50f0ad1c,298d3add,5ae874a9,5734c031,3d2f27c5,5966c468,d8b0bd3c,7bcd6ddf,d7759f7b,3523852a,704862bf,4994f6ed,4a85c430,e9696d8d,365fda41), -S(fcb440d8,6d7441f7,52b1aa2f,28d4d5ea,ec2fab70,a7739b7d,af6678d5,837425e3,ac13b9d6,a0022a93,67d81f8d,f7824b73,11a98184,30c5bf50,89f21a61,4b1d3686), -S(3cb6a8f9,b1f8058a,dd2f9076,19a3fa97,8f13089f,fd0e41bc,8ca94760,9dfa9762,4968d4a1,8674164,74d98e8d,7110df5c,8c1ce11,903bb98e,4fac0a4d,1082edd4), -S(2e719fb6,2c09e74c,46fbd39,abdc8e06,69e38992,4424a985,60aa405e,99ef47b4,bfccaa88,e1105982,de52f422,15c5cfe3,a82b7c4a,b5e0edee,46ae657a,46bc6d30), -S(809d777f,f7e7d3a,d02f4c83,fab4e618,15a1c29e,caeb6d4d,8573889e,33035a5b,4d04a535,67a1a24f,f04f4e8e,259ebef9,cac4e89b,31cd8135,2f7037aa,da84c69b), -S(6538984a,31b67a2,2bd11be0,2daa7449,2abe195a,86c08fe9,d1465e99,e08a407e,10610211,327949c1,f8e4b459,831e8fcb,2b7b4db7,c53dba33,acfcd510,aa22e935), -S(e67dac32,6ff78b27,eb24b489,85d1ab53,60441d3b,62258756,74741a67,c0b37d33,48065a5e,21dd1e4b,b5c3a085,16f00aaf,a57e98aa,9c714663,63d168bd,90b72337), -S(6fee80f8,cd36865e,f4548366,70f9e40f,3ebb2754,aed3f5cf,1d73faa5,e7e7c72c,d3d52778,2d4675b0,16addc86,445378c8,5fe38f75,3e3bbdb2,d8a73e12,461a5d1a), -S(9940330,2dbfb6cd,45a98327,e00fc86d,171b39bb,811a0af7,bf0916c8,b04fd369,2a5bb90d,126b586c,6cebfa67,7518d008,b2348e11,362a5636,8e0b1d0f,8046aee9), -S(43224e6f,292a71e0,3e1b3168,4a30fa0c,a681fe1,283dabaa,f5629633,5dfa242f,b6caef5f,77e5598b,b8a477e8,66cffba2,30927e28,d8e55b3f,fe71fab6,90c6f567), -S(804e1a5b,8e16bb85,f041f46b,a0fa8ca6,a65fa2b3,48432e66,ec10eafc,1737ce1c,2b77d1c,b1acd0d,878013d5,465779e3,a55713bf,2be71990,7471962d,e07857f4), -S(f52a94fd,6bb9d519,3692059d,868901a6,33743257,3ec200f9,61b6d964,d090f849,33512a99,94327132,501a0fbb,166ea870,f7bf1ed1,657d3080,f4d7ee1d,acc85128), -S(6febda44,3ab8d9a8,756333af,86ce177f,32d782a6,114a7464,4b1fd081,9a436087,65fb2b1c,8df03ea4,2e72c6bc,82e2a39c,57f7912f,8f513fc7,bf97a45c,4f9e1fa4), -S(da0532a6,176166de,9350ae75,7ee99a5e,9502f292,f842e94d,74d35230,518876a4,b3ff19c7,f141a7b4,f24dde01,a82f988d,8178555c,38e0816f,e1da20fc,d724f510), -S(1db46fae,ef1d0a54,9217028c,1fcf73f5,6bd573fd,6c4b1730,f3cb99bf,2e163ba5,496640fb,ab04b388,3a35ef75,5d2a0ae2,17522488,a567d7f1,7bd951b5,98ee7456), -S(e14ae4c,2f1483e5,a580d3c3,6ff82525,a6df21eb,ac91aa5d,39391e5b,650b5436,d54ba5f3,2db765ab,b8f6e464,5320cba,c029c13c,2edec227,d57d3cb2,b8b6faec), -S(a382424e,a89563df,e7157fd7,b438c992,604a49bf,1462f590,b84591f,88ef7e01,b8a510c1,4bb0f355,6d432ddf,859d87f7,9f4c4448,522bdd86,a4e99328,2ad6f960), -S(266c1844,3daaa40f,821c1ae7,7da98daf,aab29b79,36ada9dd,238c5fd2,73b45614,e3f38773,27910ef8,d5cec282,9b7d8b29,83a184da,870ab8bf,4f43e6dd,4f0cabc6), -S(e7b29b98,b1cea663,3e686d67,19778d3f,f6af2d87,e93bd576,10c95232,e8ed5d29,ecf316db,b2a445fa,2ec84705,b453314d,48e16de7,6310b78d,a19f8a45,36f27bd1), -S(d36a3000,869795e0,9eaf616b,6e131204,d341db61,7a18ef66,e133a59a,acc47bb2,24b6bc32,487bed32,9d9bc27d,b08ab6e8,114bb6ea,e813d80a,c3dc7add,9ded3979), -S(c9783ed7,85dca51d,55e55a39,4c4e9b91,9c4d4c3f,ea461afc,51eef4bd,3a351cdd,e8e62138,4b4aa109,6d269fc2,a364a3be,e4584bd5,c551435,3dcdedb0,9037bbb8), -S(764eda83,aa90cd1d,9cb96785,e4df2614,aba504bc,33403866,b6f13b38,521bbf79,9d1fc736,72bd368a,cf6f9d32,489a81ee,782ef74,964c44b5,6dc4bd2a,ad4363e6), -S(f757e8d5,aae09922,278d2301,77f1c80b,5466f76a,f9f8d106,f0814d0d,b152484f,83ef8bdb,17c78a8e,1a4c54d5,d356170c,79ad312,6d62ef94,94c1b683,1798adfd), -S(a180a3ef,400e4918,9cd8b3,e12b3907,5b268be8,4c83956e,9e08c6e8,230b7fdd,ebd5b8c,75f1ecb9,cf2c8ff6,e863447f,7c821219,8944686f,b1b758bd,ef9e84f3), -S(5ed707bb,96ac41d8,8d85db26,fef84af6,d5f7d8d1,a680a0c4,8f23a1fa,89e37dd0,bf45cf6b,d0bb550e,590dca49,fe2b158d,e91c2835,3c75f49,98c1c446,8ad03e8c), -S(f8dc28cb,f149265f,6b6499fc,baa6ecaf,78300a37,2dcae813,59cd0d8a,e00cc52,179468ee,d7fa52ac,372cbf1c,c5974532,de4198ec,10e75f95,43461ce,fff87415), -S(8ad564f9,5abb28a4,5c807ce3,1b487918,f6f963c5,ac0cf977,c5fb7957,2954d080,acf894e0,35653758,fbbcb5a5,63d5c196,60d29b3f,315a784a,29168df2,98c8053c), -S(14503a2e,83fe0cfb,bdca0382,e872da3,bd7b6d6e,96e02415,258a8989,55a18e5,8955e448,67226b0c,c529f16a,35a5297e,dee0fae5,228ad6c1,257a0204,93334896), -S(86a30681,82b8006c,282bed7e,9b4654b3,ebf5c4ea,90c92311,a56a876b,3d78d183,1213bad,e418b68b,46ee5494,a7dfb32f,d74218ca,594686d6,f5b8b6a,26a4c3b7), -S(8b226ca2,c060c2aa,13e581fc,9ca8e471,bf8d1c4e,228f9de0,2015465,43b7c70d,4c264984,52085c7b,e549c4ad,fee6e710,9cc7b9ad,b94e0ad7,f7798930,917d1509), -S(ebd1c317,db586e4a,3792ecf4,4b2e45f0,ac727360,2848667d,19efedf6,c4c942b8,7c252d24,d2639fd2,2c0a7ce2,fb277157,f421e3b3,4d1e0f6f,ffe31410,213d06c3), -S(1420c547,78d72aa2,1f54a5c5,83f82c02,b5f3f64e,cdd16250,3741f4d2,c01d0b67,ab4ad7be,d53adc3b,158b7cd6,7cdffade,beaf126,f17b8c32,62d62ffd,764bc686), -S(e9728ee2,3744dc09,1e798ed0,786d7ec5,a31cd5f0,d2e019ae,3f52b8c2,42973d9c,9f0edbe8,edd17b87,3403b94b,b9e8fb8,62cc4463,52944322,8531a365,107c8861), -S(c2c41287,cdef251c,518c1820,ae86f38c,ac816984,b14f3fa0,4060a425,699cb291,ba991c3a,2d04b449,5dc04fb,6bf6b820,a4c62a01,f76dd8d1,4897ebbb,cb40825b), -S(6a63edda,8380737b,365e58fb,3a0fe1c5,816a8c05,f24b33f0,ba0c4473,45a0ba51,54ff065a,cd9c9ce2,876b5066,4f56599c,f22fd280,ae8fbc2c,92c38eac,c0c0fc1e), -S(63ad7964,e9af4b60,78319699,f8846900,e41a159f,c5d1b924,bbef3fb3,cdb2d098,bcc3e4d,2c17926a,d70f43cb,31c4a2a9,1a89a8d,3b79a8b0,1ec9d9c1,49b606c3), -S(c9e80434,cac460e9,bc245b8b,6cf501ff,3d64bb7a,a4ea5dca,c8932dbd,609e8354,87b2ee6e,a42e02a,9fac38bb,c013391,b9af1965,dbce484,c5a3bc02,86fa6172), -S(c547f029,6388b9de,f6502985,2ebee9fb,f9e4b8b7,f7a320e6,c7576d9e,e30ba1e9,a014b375,7c859ac2,29527273,78886397,56324353,25906a28,ca6e737e,acce884f), -S(a21349a2,a171bced,4034c1bc,f79150ff,84830ee9,95bac1b2,b1bedc13,c95f0d31,ea32dcce,6af2b400,4cb4213a,a67f3448,2b09672b,546e578b,28adc6b0,ce022db3), -S(4457ae67,185fce79,deff71cc,f73de43d,23a9f4b6,f374f637,c8a99b6d,2d582d7a,1278a7cc,6f1a5a6d,58824021,af2657e0,87ece4ab,fc5dab51,f85312aa,f6468fb4), -S(4c6743de,9af3d665,a0192f80,bd015fd0,d16fd42d,8d026175,df9cb80a,84e0fcb2,86cfa514,7d0a88b3,6a0b976b,eb5530dc,fea2cd7d,b6fb0409,bf1bad24,33bd6aa7), -S(6d591172,8f3f1fa1,3fdf09cd,7045404,d150e597,64704152,1ba15b64,a8782af1,fd22b976,4e7007d9,ddcd3b89,9f060e45,c59e4a9,470f4d87,153581b0,11b7d2b2), -S(1aae2b60,88895bf9,d199f120,506faa23,85c63220,81047e48,1dd7d0ae,6a6f128e,c3e73fe9,db489a15,87ed17c9,88d29145,848bac85,134857a5,7f2233fe,b558f030), -S(8a42240a,ffad26ea,8125ba65,2ba897c0,69eb1e7f,e821451,4521519,817c3fb7,927c6b3c,9b35482c,55199381,b4997821,70be3f27,3a1ea14b,97dcb193,901787ee), -S(a4b366e7,8dfcd7b2,3f997552,663afb38,3de01400,2798e0d6,b20ce8fd,43a78cf3,b6c6dc21,b22334bb,69f6db03,4860840e,da5c23ab,d3206be4,cfa3ad3b,b1a41c4b), -S(44b8576e,7a2cf334,d5e9db51,86605975,36504ee2,3c138e9c,86fa9589,91a8a08b,79e1e4c8,2a61e956,1bd8076f,5fa8d029,d5150348,ced9a145,95b9a1f1,82a05d54), -S(88efb8a7,eb91f4ea,6b97a97a,30bf21f3,94326140,ec60eeca,23adafc1,fb11ae22,c540c164,542181ed,38036b5c,417a6b22,819c4818,73da6882,c394d87d,21011fe), -S(3d939a17,76686fce,f2e544c1,2406e89a,aa7256d4,8415e59e,f00e3599,1b630682,cb784214,6c633d16,4f3e47e5,d7fca1fd,bb46e76d,d94b7588,d21d6ab1,f6e1ae97), -S(6cc31f3e,3e5e3dc1,ff2008d0,27ae58a9,a73857e0,26d1d304,3aee9f90,664aa53,15923b66,8ba62960,f2938e29,9c230e02,fee1f3b9,936c4658,36f685ed,e0863073), -S(c8c42052,4a7837e1,57e5b15f,85c4768e,883148b9,bc490f12,27a2ffaa,9e5219ca,99f0b3e0,6c2c6bdf,6a105e14,5745e7fa,328bd209,720157eb,c665321e,c99c708), -S(fe57812f,c8650a76,6c34f0dc,468f008c,71db839,331038ae,accbca1a,30d1ab9d,27f732e8,23ca34a4,dec45aad,7c2a4cd3,43ba0cba,f2bfb75c,6ed6deac,2e524249), -S(451482a6,1cd89411,e533ffb,d5e3326,d1d6d7e6,caa31fe5,7531f892,5333a253,c03602bf,83bdd5e0,edea9cb7,328d8315,d568f3f2,be8ef1c1,7172c940,768ba474), -S(e3aed935,8a98ade3,1206182a,66254c6e,4215efda,e5f75f0c,d72923d7,2d6caa73,f357e418,4cb28038,cf3d4abd,c9cae8e5,90a6da68,a984c169,242d2725,cf5b7829), -S(26f048ff,87b2f0be,2559e62e,9e66aeac,222901b9,59bf20f1,df872ac5,b3172107,49fc51e,712b390d,9fd38df5,2023112c,85f2f29,5521bc,4ba8334d,7a133a0e), -S(f77e22bd,5403193c,4532800f,2db0a283,d0c000f2,18a09b89,d8d10175,184089ea,7a8f9b5f,6e94cea8,dc8c4276,a7aebc47,8c2d296,4c37e3a5,5db10ec1,10c2d385), -S(2aa4ea08,d6580fe,2c0fd0b9,cb266837,7b6bf2e5,853adc74,bc58804f,b8735e4c,81c26240,7984cf2a,8ffedaa0,dcd359ae,9772773c,534b9075,9ef97d49,755bbddf), -S(93de5e98,8e136037,37cf4d1a,284125cf,2b2cded5,261b7b2b,9759f7a6,62aa5f53,5d2f3168,2a9c0f64,caa483f2,1a84d28f,3004dcd9,5d3344c3,e67b28b5,61e74d59), -S(90f86beb,d1c5534b,105b7618,606bae2a,b0fbdb6,d4fa3f4d,f78f12e1,fbb81ae4,c887f5ca,fe5a0803,9e9d16cf,e5f61c12,678586cd,fbc7f65b,ab01b60c,be5dc191), -S(e0a415c0,68e137c3,b5d3228e,d9d22d8b,b343fcd3,916f2e06,f2499528,1cdd5948,140cdfac,a0276f79,adfb826f,4c9b4a6c,f619034c,a7a3d0bc,9d948abd,32320e80), -S(e9f6cc7f,e29f218f,be6aee63,32f731e0,5ab28caf,254939dd,46e3fbe2,5fb6948d,7c91feac,7fb402d7,8f71be8d,98dee704,c1a0a4cb,43c319a9,9b78e555,62349a39), -S(136657f8,f5006a7e,89bdb5e6,e9a7e477,f78a29f5,ea5ab67d,c948a9af,680afdcd,b8570d97,c025fa85,6e1c95c7,a70db126,f2588430,cc01da2c,81fa49a,1e388b4c), -S(2a11afe3,c4e73600,5a0be836,60f7c99e,6cb0acd2,b6a0745e,69d4c1ee,605cbaa6,a28072d2,50bec98,ded00976,d905fab5,91aee0f1,997386f2,c798b102,46bde95e), -S(d7ceade,fc762de0,36ae242b,588ddd80,ad002019,aa885514,b98545e4,30ebe453,20e318b9,67c2f786,c53f63db,8686acee,84bbb7c8,3435b9bc,e6c664c9,8832fb37), -S(505fb394,d184e5c8,d9a826d5,55ba9525,7ffc00df,3c0ede33,7153bc89,86e1a925,c30ce615,771a2219,40d3987e,52af5c30,8fe45b41,d5078eb3,821fcb8c,9ef722c6), -S(330418e8,93f9360a,40656da8,883d1fc4,89441e5d,5a533c1b,23480695,8e67ecb,2103e7a2,e02ef7a4,c245b479,f6778cf7,e6419d4,41bba641,6f6c18ea,8bbd2459), -S(1467a11c,31ff8b94,2270cd53,54297b4d,e22aaa6d,3aae02b9,51e7f998,e0345eab,9d3e32fd,bce7daff,10685a08,afbaa791,bc0ebc38,d7095045,1b227db0,74a18cf1), -S(d58c9888,fbb41521,ded03c08,fd61032f,c403eecb,1c810032,e5eed64,a93c878,cefe41e4,8431eb2b,6c6e9877,fb83ac78,dffc5147,3c1e5929,28539567,a08871a8), -S(16169695,7d2625ed,b6aa9bc3,9f7dc514,e6c5e60a,39114c34,b960874f,c8c66c82,fff007a0,918a75ed,5bbbe234,dffda70a,7e17006f,1e4afec6,140b9a3,b762969a), -S(7c58b323,1bdca93a,a19b84e0,4312a347,5addc621,91c66fa5,a4bf97a4,b8b5552d,b1aa2ae7,cbd6f1ce,12b33408,513930c5,6335758e,f28f2a8c,c239f727,55ff37f3), -S(7c40af3d,d3e774cb,7c56e809,23b9fa92,f0cafb2b,f1eecb22,9c204cfc,58ef311,4dc0ca37,90e023e2,83b8878,bbca65c4,28b7e89a,76bb0b63,e92e9d20,3dde7cae), -S(a862b5d4,978928c0,49a466de,94176192,f1a57ab7,a849e548,ac12fb9e,369c916e,ca9126cf,7c1176ef,e6fbceaf,26760dcf,b1c24a28,96a3e3e5,a0051d60,ddcb4ecb), -S(17b54d00,5d185207,b4d8966c,62d3c535,c94c6140,166374b2,958b27d3,ae202765,37399472,b28ecddc,7e54d0f8,d80448ba,a0ac56b5,df9b1cd1,6cf44139,4ed92816), -S(40d75436,113043be,31bdee82,2ecc3a69,bbd157d7,72ec9b73,a4a3c96c,da28a6f6,835aa9ea,ab4c1ddb,35fa50e0,e26891d8,2b7e01e2,a237f4c8,c66c413e,faa7e140), -S(32b82a0a,5c267263,3e021c81,ddc1341,7a69e8b9,7b814dab,d529e38,424bb064,ecb8c97b,aeed6bd5,c8b922f3,1b4634b6,fa5393af,aa5e4ee2,c84d4aa1,651b4935), -S(ea460efc,85f7644b,bc9729a6,ce55296a,4277f0cf,3032775c,ff7fb96,da4c56e0,e8637568,b09fae6b,40a89f55,6f0cd0dc,a710fce4,b37329c6,57cdb05b,71b5b513), -S(cb5fcb0c,942a860b,6cbdbcf0,1b8498d8,68c8b9ab,bb224b79,4b8fc38a,9fedf311,3248669e,9fbf75d0,f64d466d,e42fa01b,deffdce2,99b45c1d,c7d8154c,fba41a5c), -S(79432c0,23a213cd,44c29e2e,f7ec5bad,1b4888ec,6673a84a,40a398b2,33aba92a,67cc9316,c2347676,b64e88ed,18fe3ff8,5c9e35b3,cf78d5aa,79c757bc,74d445c2), -S(9dce010c,4ce908c7,d0d79509,27b8803a,d695e8b1,67671865,2f97e264,3a7b683d,49419fca,ede145fd,7cdc7f8b,65dc7b95,11a72fef,2264fb79,1c8d40d5,a39171bc), -S(43b8b5bb,9b56581c,ce92eacf,29fa66ed,f76037d4,3656e4a6,bc0b7f1a,cc42803c,c83017d3,30b17369,70fc16e3,cf5c85f3,199d2d8f,a7179a06,1940bcb2,65313dce), -S(b0c8eb7e,c0fb39fc,b6f3c18b,ef96cae6,b9a23f00,751a4d6a,3a2f5f40,75e544,d66399c,d48302d3,2dfb5d26,9219eb3f,d81412be,c523df58,77e5227b,d65463f0), -S(b981ee1e,4f26ee24,63e81f77,f16dc05b,646e1fdf,d2a075f6,aa422e77,b3577cad,8a582c30,4d062936,baed15a8,9c39ebd8,2d5645d1,c0fdbd6a,d48c587,7626c612), -S(d04c88d9,8ff5570f,6fa37dd9,432966e4,bb524a58,d3ad8cc9,21d0ca06,8fa80889,dfb4007e,4f3ca38,304373a2,931dc322,7469d8f,9683e7c1,dbe59c2a,a17713fe), -S(d00d8053,68667056,55eca05e,53fa60f0,cd778e40,647154a3,c106a3e,5b8a90f,74785ee9,87323562,b815f4d,f9316a91,e489186d,7b1ef978,7ee398ad,51d8f94), -S(87dac80f,34b74bdd,6b2047a1,ebc132bb,c83fded,82405d4b,691d25f8,3e4226c3,da7e507c,2b135b69,501319c4,77ed0b20,731b56be,3dbfb386,4e0f4867,f03b120a), -S(95249c91,bdb94571,7b03d8cd,86bfcd36,3d51c012,38593cdf,243407c1,9322f8f4,a139a970,bff6a5ec,3d9876e5,6dc11286,56c98b90,ed6fa58f,157d7476,deb6bc50), -S(eaa86b89,f5a4befa,1caf1828,bcda7c32,792b468e,9e7530e5,13f1518c,3014cd5c,329bf9c5,6e431d21,a4cee5d2,beb4584,e7aa01d0,5935d7a8,44ee79ff,85f582c2), -S(b2ede9a8,6f324bce,3f62448c,a401d636,9a6ef8ca,89a48a9e,f9fa3bd,9138cd74,d942f74e,89ea55f8,a2642deb,652bf827,79252c83,b91782ed,6b3244a,439139dd), -S(c03fbf90,797b672e,24d06d02,fd70ce22,778309b8,96053128,70f48b97,aff20585,c5d44056,b4fca7af,4b7b16b5,fee76438,f2a271c4,655df4c0,8de3f634,4cac13f), -S(6da64321,c0642b04,ea7eadc2,a7739b20,7af8f1d2,fa99d26e,8e924241,4eba2a25,a08c3484,bf46e429,d7ced694,41412b1e,e2258109,b8c17dba,3370cd37,b8a77546), -S(9269c7c1,4ce5d777,dab467fe,3376662e,6f266272,5e2695f1,fa375b9b,1a1c2c4d,4dccb6b2,ecaf9f7a,fa3fe17b,e2a4054d,bcaa6e33,25b32070,24d5e324,ba1ba6b0), -S(a0933917,a532ed22,7a575482,c1090486,71a6cf38,1c6d825f,98f1938b,d3837992,c079790a,56f5e530,52760bff,8c76df6e,ceba6071,3e90dbc3,88b3527d,64aeaf9), -S(bf2cda66,ceb98433,d3e54e48,cfc15b2b,92c94031,ca9810d9,cbf2562d,c61d7017,2d31e7f0,ebe2068b,c16e81dc,bf1caa0c,6ddf3b52,13849e91,a2bc1bc7,4fecc72c), -S(d1bbcb50,4b9d78ca,ef980ea0,d2b6e8fd,7abc0d8b,3c9227c6,eeee3cb,956d6be,a1292ee9,ae1c3057,c45ea7ce,68cdf9d3,c19a6889,e58b321e,e9858dff,f4d324d8), -S(3cc406f,a049f410,2a752ba9,30f83d98,81110a45,db5fc387,c2d43a44,de33bfde,1bc1a076,f06dc2b5,ec1bc062,c9c480c2,39eb5418,4006e94e,623d2bc6,cb00ac91), -S(5fb9744c,a35cf11c,e11392c3,92bf0a98,5082ac15,5b265fd3,4cd61ad8,55532230,8bd17d0d,c7cbe859,4ff79a3a,15ded6a2,81bb065b,a78726a3,d3819ff8,58dbe34e), -S(27509ed6,ff7bfb6d,31ff0333,a994f531,abed34fc,de8ecf75,642351f6,b259cf3,bf2f0e5e,913d926d,cdca7918,57afbae2,309a4206,b408bc9f,d75b3abb,174d14bb), -S(a619b048,626b9e12,86535c8c,b5fdd8e4,1a64e834,1a8d27e5,d4179569,5fbf70dd,9f79dd50,8e50dec7,fafb80fe,99889701,54f382e2,c2b24d74,6d6d82e9,97049dad), -S(1f8ea1f8,4bd83b5e,56a8e6db,67b5416e,1052a6ba,cdd161b,420d7b46,7070ce02,69b2865e,bd3cb91b,548a4aaa,81d74310,88bb6c18,2d914697,39322037,12760963), -S(fd33ff10,574f02d2,e9c52bf,9a70b430,50917f88,a8eeaa9c,938c5f40,dcd1868a,25fd0d1d,80a21136,c8ac4a8c,4f369b57,d6221a67,3aefd4ce,be30d19c,9334c47e), -S(75799364,7cc47d16,55dda6b2,a269f061,f575ec91,e05af43a,f7e219f4,4b5d2380,d58645ed,d803ca11,f12fb489,9ffbf03d,daf82c98,2b6529f7,28e476d2,22fecea6), -S(fa0717af,d0f83028,3e8e22c1,c240d540,b81b761c,a1daba1,b45ba00,9246985a,ed48a3d0,cab1c4d1,59ef8f0d,e64a2442,c02acdea,43b5b16f,42a75a7c,68b787f3), -S(164fa71c,51623816,52949c27,33c668e5,2a5e3812,a3532452,a6ef44ce,28f49da2,11ecd95c,3dbd9463,4867af2c,290cc555,ef22832f,d7040873,35fba559,e4f010a7), -S(a213fae7,5dd15057,4b6205dc,fe03a2e8,cecbc7ea,1aab088a,fe20e8a3,b46a9a5,c135078d,f26d341,a767acf1,c7b449a9,4ccbd00,23459452,4f5b8f50,9b841042), -S(515d702,8406f03,6e5acef2,1445abbb,daf7ecff,5a31a664,a24396d2,f5d12b0a,db966859,4449028b,f3e6f53f,5bc250f1,51ef3df1,59e26c0f,9f4a346e,d60f3876), -S(3c41f639,e7705929,425ba8c4,2b2f77b6,6a461c81,3bb4e8e3,341eca66,a1344175,f57f10d2,46735f9,f6b741cb,4fc57242,7e5504c2,f6259b13,5745c5f3,a1b8bde9), -S(b8bb579a,f9826958,8e288e37,3be73f8e,7b573e1b,b7f5c1ae,3ad27474,1e9f19bb,5c51d169,607ae4a2,5e9fa70a,f67e6df1,89f1d7d4,705c2854,9e4d731c,f5f97278), -S(fe3701d7,1ecc1c21,3bed8ea2,94447981,75577963,2f8dfa1a,3cee1c47,858da678,8b69946e,8b7226c4,ccb1c5cd,8b416504,98fb7a06,ff8d27f0,da3de97b,74dc06c3), -S(9e7880b8,5a2dc9f0,143407b7,304b60ee,8dbc2b44,4f751fbc,f1b4d25a,da219985,595e4ea1,2e495f97,f61d9220,4f8d06f4,1a78a3,5b6014f6,e82ed051,2697ce7c), -S(b0d1246e,50c2dccf,7cc9746a,afa49227,62487f19,aa6835f1,1379a6e,f3c0f6a3,1dd6e8ef,973d8dc1,fa440594,a70b989a,80728e32,17fa0250,b7c1de39,b1174b45), -S(355aaa35,f5699e0d,e8fa3d4b,d361123d,5b8bf5f0,c74a149d,7cc024e8,2998f7fb,f905e0d5,b3abd09b,5f9b8c36,25f2597c,3430da0f,3439b16a,ada46421,4b678d55), -S(6eef7ac0,ee4da5d4,c8bb3e45,ebc67395,592f313,1d1ba424,1f909ede,818d6364,b0e832d3,92ea4728,7a35d4ec,861a43cf,6733ccb1,bdda8c9e,dd5ee835,92671a5e), -S(7fbbf8ce,f3e99b11,8def70c4,aff57b17,79e4e341,750f7b76,e44245de,8d90ed7d,3032f38b,6570cdd,e39cd075,e4acf1e5,815a065e,f2a84a7a,8f23fb20,6a0c99e2), -S(a9d4c727,a682f85c,b992544e,4e910ac2,beae12af,4fd74ca9,583ff9c8,c06644b1,794e13d1,fa08b167,433be416,c73d7f5c,c21413d9,a3d1393b,84e7e470,a6918686), -S(332dd1b8,ab8e5b66,5c614e8c,807a9015,56612396,adab5c4e,e8ad5856,9c44b1da,d4b39084,5fc9c364,21dd644,c323b5f5,f5d45b39,2885065,dc6667c1,2cbf6b12), -S(ba843971,6fd06d83,e4ad8774,4a82ca41,32954db8,b2bfbdcd,4935f6da,3df7ace,78facd39,b9739785,dab82b40,7dda50e2,db5d4b78,b9e57fcf,8c240b20,5aedb9c1), -S(ac7129c3,3aecb4ed,e60d0ce6,2e2cb73c,798cbbc9,58ef50a5,5bdcd2fd,d167b648,7376ed23,196f4c1d,cf8b5104,5e2c808f,a7bcf43e,2fb9f85a,ac2b3929,4d704edd), -S(17408c0a,8946aa45,387f043c,874deced,6a15eb37,7bcdbcfa,b7ec087a,80516034,cc942afd,78203ab9,77583109,a499b71e,18566987,48c2ee70,ee8a1c8e,60af5c31), -S(4f0df589,d69887f1,ae4e72af,61c083ec,8ab634b1,7b82d533,2d587a22,6f8eca30,e734fe8,926d6662,50cebfcb,50d48e42,593350b3,f2456e77,b6ff5dcc,9e3f3b6d), -S(b0d20898,74f0e672,92856890,51749d54,dc4ad1de,f6d12d3,243830ca,f8da2848,2e790c5a,79ebb86e,fd5a068f,864a7266,fe6d12e9,ec664f02,162ea3ae,e004a808), -S(39d07f28,30d2f3e8,29ab5672,db6888c0,fd224c68,57f3d0c1,aba89da,3f7ca96b,590a0812,e58609d2,e28ae3e2,9305da12,f46b8b0,70c07b2d,a644a956,12f6eba5), -S(20762b89,7ef06eec,ffce19ee,918ba264,4e93a2e3,9f46163a,99a0b218,a94171ac,e1e15917,3e3d5e4d,89cebf5d,6269b14e,784a0d72,e617fb1d,cf7bda13,33bbf989), -S(d2f0ccfe,813772cd,f3b75442,bc16e554,4edde28d,b6c64729,16764483,7b104626,c6efce8c,c63919f4,65a6778f,4b397573,4c4a93b9,43a40ea3,f44d4cef,78ce5199), -S(19520039,cb11eaba,ec1ef6e,676202bf,d5bc4bf8,4e40ed2b,2daa2a4a,2e07095c,fea234e7,3b01e2f6,d03768f4,a534c93e,c6e3cd50,457f27cd,7b6998df,b6e4cd7b), -S(3787750c,f3d73be9,52209ea2,38558541,8b6e79b0,fe1a303b,ef82fd6d,b2c9bf94,b91b2fbc,a09d6fe,b19dae3d,49416fc4,a7c1134e,22982bf1,4aa0678e,c5cdc030), -S(13abbdc1,a65ebbc2,2988a796,bb369866,4211dfce,d3a04d6a,6730d5db,6087b34f,9e4c4a2,b691acc0,b034b690,5488bff6,5397a267,13ed67f2,1374db17,fa8e8b21), -S(602a458e,1cd32ffc,d35ce5cc,c5d7b597,7e20c0cf,66a936df,4eeab00a,b7b31918,167ce780,91340b37,dbb5ab8c,e6fd602f,534149f8,4d67b16d,29724802,a8aeec61), -S(71082819,584ef5,2a690803,d24fde15,148e193f,35534d48,f7a1932b,d3f69928,9b2cb12f,668f96aa,824e3f94,79ee706b,c09723a5,4a588cca,22ed898c,c9aa219f), -S(6349c108,312beebe,145d750c,1ef2721,d536c507,4f0123db,9777e920,c72fc1f5,131f675e,95b5c1fd,856cff13,57a494cb,46e19a26,b9218b67,c6cd2823,c9e877b3), -S(892b764f,e954b331,7c5f8564,b67e7255,1287a06b,32bb476b,f616fcc6,ba329331,b0a0a00f,91d0d637,258aacec,9bd0ac32,e10ff4a2,dbdab74a,a15bcac3,d3fe55ba), -S(c2f38edd,371ef544,a1443296,afeb6a93,6705e89e,fb23a13c,3dc6b619,ea7516cc,6ba10142,71ab78f3,1603a39,dee7ae62,7ee034be,ab1fa0bf,61e18e7e,df40fa9f), -S(bea4f01a,7c61d100,da78c48b,e6277e38,6ec6c265,89a2274a,fd2e1792,b5f74618,d27126b9,9b074a95,690cff35,cbf949b1,8cf0c449,d76f2511,59f1a217,293ceb44), -S(7bdabeea,d320217b,d5e2e84b,eb28b664,e9632606,28a0f281,ec4f2edb,3f3b4bb,49c45d86,f06c42b,4e6e2664,3c4613e9,411103bb,b7abd818,1ab8a0ca,b9ea116), -S(a913e0ec,5e360f89,9c611be6,144a16b7,ff3d03cf,28851ecf,67ab457,53ec31f,9bc12b6a,8595914,333fa4ef,3096cd6,71ee444b,7bd6da65,67d91ff2,d1f278b9), -S(ec6ab00b,e272be1c,f0d359f1,a7fa0f13,55a151a6,d03a05a3,6fee5019,6275846,42d200db,e0edcf3,634055e4,d66cd689,b197f872,d91bf660,e797518f,f4c2ad), -S(a6142783,bdafb512,62b2359b,11286fe1,f15d7464,47f4f507,318800dc,c55ef428,cefd1ba0,4c19a732,aa498eac,9734197c,889cc973,6fd0800d,a051cac2,b0e4bdd2), -S(5f8fea38,cb38f90f,342d7daa,95912083,7340591,c4b98ac7,c9c8cccd,1f2ce457,54c0d093,45974a7b,268f152b,d96541ad,80561ec5,264af970,9ddcf7c,80bd5a55), -S(7b222e07,2d7cc37f,a3d73009,31ae8a3d,cc264153,6c538457,c153ebb6,d84ef26d,9dbae136,e560e343,af858aa4,20e077d9,f4e19cc1,c4f709d7,7875b44,780b90bd)}, -{S(53512a21,4a659914,82cc157f,da02880f,7c4ff9e6,47a93136,c1e55725,9ce7132f,3ccac75b,13cc40fa,5ab2e017,80f55f2e,b8e6a7e7,22b2e6b1,13a28316,b3c99d3), -S(da8a162,a47944c9,9880ddd,c2bf133e,4ec5d836,54609c06,68dbd68d,63784b58,a94bfb99,53fb0921,7b659c08,fecf83a,92b7ed8d,8138c8b1,45f9198a,f7df758d), -S(6eb60bb9,26ae0a8a,3f23d58c,e7dc6b23,f5c17366,2467ed14,61be451a,7513f97b,14225da1,8bb8ae78,8478014,6dc68934,8e4d60e8,41a46ce2,71fedc19,c512d6a0), -S(b03b0869,1b3495c1,5d06c55f,54f1d324,b353d848,31d5c43c,4d524d3a,52b485dd,d7a61b34,9f42ad82,7145f010,e00fbfb4,2e20140c,a0d420ee,11069b25,12147e1c), -S(8eb61e15,83ab8058,a3603895,7709ff11,85eb6bdc,14043909,1b1754f0,506c9bc4,c7ddb27,4c723f0,620fe2ff,2eb11365,1e19c551,32925a05,1b2a297c,9dde4a91), -S(e09474b1,3a1975c6,147f69ac,abe0941a,333ad7e,59495b9d,20747e3c,92f65d8e,98b01b17,b57f285e,b0b9b0c,52f8f390,cf2afd9c,7e90a024,c8758ff5,11008725), -S(20679abb,aa71c3b1,e4ae9454,dbb55cc9,fba632f2,548cc28a,e7f65ef3,c52335f7,158b4f49,53ef5e70,b1c1b847,1f7530c5,39a9e251,98ecab8b,d178b7fd,6b51d391), -S(51e2c9dd,b8da0e35,ac6b6325,4daeeff9,cfb2cfb4,94ea2ca2,46e9ba28,4b86ff33,309b9033,a723ed89,9ffecc25,2fc3c44a,d4bfa991,9c968ab6,664f53d0,4c9d3757), -S(b8760392,98ced8b4,2f1e9a81,2980e5b6,2e2ac1e4,2d6e8525,4bb7046f,68077fdb,310711c9,2b821f61,66854bde,4988708a,67e6c0f0,dd392b77,2435a50b,47d9277a), -S(ae072fd0,c88a0514,a1db9641,50022cf6,c186d645,57be5748,7f8a1029,7cf32f6d,862e7709,f135acb2,2d3f2239,f1d33af8,288f7434,191f84f,f6a0bef6,c5544cb1), -S(3390c74a,fe49647a,8c55fbe6,6b7eef3d,11462c16,8f4a4fe1,447fa5ad,3899ab0,ad8390b9,b98fb90f,b8885691,380229bc,24295d8,995c7810,5a7929b2,d0979027), -S(dd7625a7,10121e02,527bcff1,80f5ea43,efe1c39b,50c20176,6d172c4a,1dc58501,4f6b4942,ac8b6d5,849f2301,9f5112e1,c250b7c3,4f603e99,80ca8743,8d7c8f70), -S(ba116ac6,d0c9cfd9,16e059ee,d94ec9f0,b726e16e,851d771,340eb6fe,4bba54fb,aabc01d3,e65fe86a,4206570f,14571b10,5e226e3c,7d603b54,c1266f0e,258ca5de), -S(dc7ce33b,19c27352,a277797d,a5b70697,6e875638,e5315232,ccc814b9,a2ebd97a,5e4a0969,91396fa6,6d1d81ca,de2d54e4,f0e4e835,ef95f74d,3f21f234,d5f5cd62), -S(200a15dc,6f7b0885,bc49b66a,dcd41acf,b084059d,f55971d5,90173b46,e0755ba7,e68be603,f2c09661,af4e8ef8,b36ac49,270b97cd,f37260fe,9c27fba4,ebc3d828), -S(4969c231,3887e01d,c2837bce,68667593,beab92d3,6f7b0bab,c8368c6e,7ba31d5a,75a8e9b1,5ab4c54,a88a8678,12b93d0e,81887adb,3653518e,81d5124c,4503ffdb), -S(6f04a5cd,5913ac08,dfbe8f6c,57ce496b,dc05930e,56245464,6685ac62,85c3abd8,19fe0060,42a12c30,b7db3cf2,cf3e7a01,abd09063,6c84e285,2a045d4,301a8954), -S(41d07a8f,26009140,e5e338e,7b3e136c,b8b51e01,dd80d441,de584af5,74412fee,a77aeda5,4ea2b2cc,853e3b6d,c128c15a,6e758ff9,d22a8a38,3e28605c,8000113d), -S(dc52e1dc,e07a94e2,e1b7f59e,18e25e0e,eee2ea86,3f127649,a818e786,cc0f3269,c26c196b,a42c4a7c,331af677,e3ef1f63,8133dd2a,bcdc3c37,218b594,6547b3cd), -S(e5c26f1b,311566,152138e9,33ff4834,c17e6ce8,62c84c66,4068dd93,5fcf72da,2f293b72,9c67a27a,6cb096ee,53726ce9,fa88ffde,f8c657c6,af27d995,c4df36ac), -S(44b04185,5f6f4c6f,e6e6ca5,d71dbe95,2e1706fe,f9db95b0,9b073566,c235d50f,18f4285,cf142a82,bd26a508,2bb6b319,eecf0ead,a12f3d20,800de5d7,94d3858), -S(2c4644c2,4ca3b395,655beb0c,32d610e2,f9477a30,7757b0d3,dca3f87,4b7580b4,6c726213,c7864e17,3ff2ed6d,861ef4ce,6b83882c,1c319b9f,6ab76765,26f5f7c), -S(e3b2e18a,24306e18,c4cc6b9f,f42fda12,ea84329c,dacf0484,331bceb2,639f8ced,8a11b73e,4de49f5,6b00a3c8,2b366df6,afab3320,ed732254,c1deac3f,e2d4e601), -S(de42b164,ce28acaf,ac6440e0,274882f,158c1e31,2f080371,5f4ee6f7,6bf6f03c,385de0b5,c533196e,b3d3d0fd,fdd4d0f3,d173566b,7d5f1f6d,5c6c3735,7a98249), -S(3d018969,a03f0134,5b26adb6,31d7abcd,e6399f56,c532d486,bce5b501,98e4b68e,e8dc92f7,6a007d98,f6a548e5,3da24c30,d85b4008,2e7b923e,35a5f18e,93d772f9), -S(c77978c6,4caccd00,27b31a61,769a06ca,636f8603,49fec444,4821952d,9a2fa7d,869c3fc8,1f722012,750d9f96,349ee0bf,e08044c4,f8af04e0,80a03caa,84331df7), -S(f68d647c,e49e9660,efc740d7,1394b8e1,699764a2,9679660a,67566ffa,ead3d9a6,1d64d46e,1ffbb7ba,912b5659,656ce860,cb897a78,21958d3b,ef0185da,fee27c61), -S(dcf7708b,a5c5e05a,4d65200b,77b5ec5a,f08ba85a,46a76bca,dc1cb444,fef50aba,80c88800,d22637cc,6082bdf5,6774efe8,31095951,172909d3,4a400798,c34db159), -S(3dcc7aa8,90604a5d,bb22a5d6,91a42080,ff5844c,5c756fcf,86a2b0cb,becae,4b1721cb,e93246d2,9913fec7,16673f3b,8a02e3ac,dd258db1,d2a22bf0,4412bbce), -S(961f4700,f8c7db80,a5157a76,181c9420,9950735a,e1805e85,7b204f6b,e9b7d33a,85d980ef,b7a33331,4fe0c3e9,1ad61569,69ca8902,6951ce84,cf26c0b9,7d67ae21), -S(54d1da7b,87d57e72,1a6fb923,7b7be29e,db200b81,dd891b9b,9183e3f9,d61da16c,c7467f66,9010912f,e5dd6bd6,ea97451e,3a95d89d,2abcd2ca,ff0a3a9,b90ffa0b), -S(1072acc9,b5fb92fc,41b3fada,7d5a4434,13c73a1,734ffd33,94df394f,ffbff1ae,87594f8,f1f834e4,24756584,40664f8c,418ad3e,7a250e6e,863baa8f,a37e44ab), -S(ae4d4dbd,e751b25f,ea37ee64,bc8db97,ded52741,72f97b8d,64149db0,b8fafa33,d19761c0,b0370155,817e2022,8bf31e5e,3bd0f021,3f4b23e,881b6d5c,733fcd54), -S(328c26e,cb0f4648,4ab9dc2,c33d35a2,d0ead36e,8d1778bc,2771cf6b,55486c2d,63137d2f,a34981fe,f2e12dd5,5825b824,43f052f4,96211a46,995f0001,e6fe8322), -S(ae60aade,4c91ca13,d847353c,61ca90b3,205aafb1,c5c2f2b3,305c81a3,e4c7fd3f,913184ae,93837553,2916117e,34e04698,96b052c4,a93763a0,5f8d7153,2201f1e2), -S(a608ba7f,cac3c42a,20a61800,4d317248,e5fb7e69,b230cf53,567a4114,5d7cabe6,273eaec7,75b37b48,bb6f6ac5,695e8887,f8bde091,1884684b,e64b111c,f767ba1a), -S(ca5033f2,97194ff5,b850ce4f,77f303ac,6188e43a,848fa8cc,b1423289,da634671,34bde31,85e18a14,c0701ae3,4941de08,7e55cf6b,acbfd7bb,9a68fb53,62656790), -S(9fe36400,aa701955,6fb4bc0d,3740bc9f,363dcab7,2eccb27c,35a5d1f2,30f047de,2f841d40,bc786920,af86c55e,61c17d46,84b31096,72dea08e,3c04caa5,82ef33a3), -S(380fb487,1f841eb2,69c93474,4e737089,ddca3014,d9c8f760,40f39b7d,1e9271f9,c7c9944,cfa05673,85d49f7c,7051a04d,dd2d7bcc,36f0469c,8904dcd1,354dfd5f), -S(dfc4a0c,73ff4237,2716889d,e05c88bb,74462b15,2b02b692,6b41af3c,d52bfab1,31809a46,1eb7dcbc,8766031c,d8e02fdc,c882c7ee,a1e2f7e1,5342bb44,53b859bc), -S(561af1ed,8ddbf862,5f1553f0,31e1cdfa,34b8f095,6bbb8ed0,365ad1f0,5c3b589a,965b8e9,c6926a32,edbd7251,251a8a05,e83e40f7,7ae3163a,4a6044b6,20e39620), -S(d0a17522,1cdaf650,ed93f289,ff3d2199,e8fb3f81,7dfdfa95,f7685715,75a6e058,81f7478b,83dcff41,ec9c0cd6,c1515e02,d7eb550,282f37ed,168e6229,ce5c5d56), -S(3f42f09,cd5db26b,df31bc12,a82b6517,aeabeaf3,8c4a316d,27594a03,ecf3de3c,c0494e41,89ece4d9,d08a3c53,ea2bce3a,a65ac759,eaaf07aa,c1a809be,7482ef9e), -S(b7142a5b,239386c4,35fed19e,46fad0d6,2b4974c,f9a7c582,fc45af40,a34ca699,17db42dc,624a1d07,83b3bd69,fb6a8a05,e4175134,9a3d9561,1d4a74d4,28f42a12), -S(c3e483,cd0b21da,31845a93,b75b60b4,800b5e59,43a9708a,251d0135,91d54cae,8e67983e,1469d74d,c61be1f3,f606adcc,a02c5556,a1f06fe4,2f6dce0f,c4c5236d), -S(49d0ae34,23572f85,595efe03,963d6032,5bdd79e1,7a538a54,e43706b4,cf4453a0,fc1505b7,e4e126ba,2a0dfc66,d8bc8616,27918a9b,df985045,9df4bd6,2e0d2fba), -S(9f8373d2,f0053731,f0e1cb2b,1ab08fbe,8ea1a930,87908d7d,5dc06491,7afb4719,f22bf0cc,9b1b995,ce01a96b,1f73f6af,bf92ddf4,ca57e29f,80cbe5ac,a8604ef4), -S(f760b681,1374bc96,102e537b,8b187cc6,989602ec,118efca4,5391a344,eb82ba03,4592a7ac,655cc29,72e26d63,9a99eef5,ace2ecaf,ab414772,de2f8227,87c4d750), -S(4f465aea,bbb79ea8,60c87a8d,541f9c01,afa48dc6,765c24ec,b6a49901,307c80d2,adaa88cb,e882a86a,2d7c2ddb,d5eb2385,faffe9a,ff52481c,dfd6b1dd,f72eb3f7), -S(4f3dacce,862428f7,ab62b4fc,e20d1f12,19183207,64c2a51d,a80fcf1f,f86ed5de,97f8326c,21558e18,d4b7376c,1c14822f,d53c68d3,394dbfac,80a583e3,c668bad1), -S(f1905b3,d04cb49d,3db59404,4037ef71,e42f4311,d59b3160,b917e355,75ca9e3f,c8c005b5,5f49132d,fb2d316a,b0214872,dbf36f7b,f2c876e,6397ac87,ce6b1f3d), -S(8ee0a2bc,f853a469,27efaa1e,3356f1b4,61796e7d,7496cc87,8daa3f8d,11e46fb1,67b6599a,d8037160,f298c595,dd0a5a40,dddac020,d8c8c99e,c846cb81,13c13232), -S(a8f55dec,3872a5c8,c3d7272,6dc06f7e,5c7bff2b,9a8354ac,a184f0e7,8024a4e7,a27ffb57,47c61b33,fe555376,5e2148ca,76fba57e,fef4dcc0,3777dea0,3b2ffaf7), -S(e4cc6907,4387a6a,2e94ef7c,97daa582,9c2f84a3,9b71e76a,c0ef146c,a3209cc4,297b82a3,115c3eb1,eb75677a,bcca1e55,9d2caa0,31e1554e,abb697b3,90218e2b), -S(e3c2e255,57edab4b,64295050,94470b06,e380e503,cd55b106,52cf9fc1,d56c45d1,6621db25,53c70d69,f96facce,bbfd4ea8,32262010,35983521,360bbbb9,43110b8f), -S(8a27f3d0,b4c0ba60,b2875b70,33d386a2,e93e2263,a7f8ccf7,85a0a2f3,6488092e,9525a706,c37af8f1,5ec496b9,ecac74a2,e96ef02e,9c30abf1,2279bb5d,100a2ce9), -S(94f34fb0,2d416fb,4819e24f,165617c5,8929c2b5,a0d00bd,e8c3e71,7ef188ef,c5cf6f02,c0bd9e80,15a436e5,eb837289,66bf2b68,64a5ab82,88564fc5,166ac90f), -S(2a1e9e10,2e0ec944,bbb7c570,2ec1d655,525bc965,85dddf63,e4b4fc6d,ba65943f,64099714,f1c157cd,90393aa2,893703c1,ecacd1c1,87c30518,dcb05be1,d7eac677), -S(cfadcd6e,b147c4d5,3502b628,ceaf389,73ff3aa6,b46a304e,ab7a4608,8a7fbcb1,21cb905,2c53efa7,ffc62ba5,7ea8b29c,4eae5801,2ac40525,6f095363,ae169da9), -S(5f7ab5d1,86b95bce,a294528c,91bee6d1,c4dd6b9b,7f393f7d,db09a3d9,5d268189,9ba6285a,5ece8f7e,5cb8f8aa,4aa83910,3a2ff288,2864aa10,cd6f96a,297392c8), -S(38f751fa,d2993ca6,c3712a16,6981cb52,168492c7,2676c7b2,94463647,5510d2a0,ee57807b,89b36b02,d1452079,6438428b,7fa4b2c4,d4f52070,2f00ea00,33b7c957), -S(7c5283d8,c775232b,b03608ca,3707a2e7,5fffbfbb,1aef19fc,5823d8ca,2c5ee31a,6f645f62,29c3b646,c2b6b5f3,c2755ae,75a5a0d0,a6b732c6,38e946bd,637f7ce2), -S(d78a18d9,ed411883,568b398d,56426fb2,41bb3e0a,4bea3503,18314611,b297d090,fec8298d,79aff51b,ccb9f9fc,ed37639e,aded3174,4d0d934a,b19c0945,8b538559), -S(291affe5,8fabbd34,f011da48,53e100d3,a6638761,fc66874f,4760f7ba,769c9e7e,79c609f8,7ff45288,943bf869,4ec6d4e8,66c77f36,92d9e328,a85b1db9,92bec6af), -S(8cddced6,c63b74c3,608fe52d,aaae8c2b,15be6e3,e2eaa564,ab77d22c,f6e2eb32,dc05e6e8,e917755d,3e54ea2c,21d74781,6e6ab14c,8ad778d9,b7809ab,aeb12d79), -S(67716149,58e24e55,e786ae7d,64174609,5edd9dc4,c70ee3bc,d6764bb9,10253c2c,274f078e,7852a04b,fc766272,1c8290ae,95a7b036,45b20ad,9376504b,92642b16), -S(54bca4a8,96c5abdb,c8170b62,bc7479c4,dd33f4f3,75f709db,eccde832,73d452a3,7b1f1e00,b7f117a0,92196f02,1e499e,5b0a5f12,e4361596,5fd253eb,4891110e), -S(68df83,b0c12c86,a7ddd748,cd687bce,13ca941a,83b2a172,676971d8,566dc3a8,81fbb9d4,49ff2bb,851ade7b,18a5449e,83b2a02a,4be387fe,77eabdf5,964935f), -S(245ac706,b6009bc7,34782325,c176f05d,d5cecda1,9a0183b1,d546cb4e,55f975a1,72718f65,fbffadf6,dc9ebab6,515e7866,af3bf119,739207e,415d4ef0,f1d902a2), -S(548bb01c,70b6cb4b,d5e21e8f,dcbbdc13,76601235,9b1ae88f,2d615bfb,73ace38f,67aba9c0,d0532fa5,c71134f9,e80fa73,f47ad308,e27b6a2,3a3620de,f7e109a8), -S(548d71c6,c5dec0cb,a98c55f,720493d8,f16c14c7,97245548,5249ae86,cfeafc81,9c811c7d,5f7b67d6,728cadf8,aa0c3f39,54130c9f,81a3af38,24e556e9,40212668), -S(aaf4621c,4679308c,93fb34b3,d882aee,f7bed71c,23e5bb36,644b69d9,23ba66d8,bd4c368d,e9bdf4f,9788125d,9db04c58,aed4de1f,ecbbc52,2ef49b39,e0d8f54a), -S(bd0a071b,396afe8a,51a790fa,f11c5db4,2fb2dba6,a38b4f90,f7df7d86,f3fd0bb0,3dee630,46d723a2,1299893a,9f5b0371,e9d30aa4,d24ca28,aa9b1fe2,2636e05f), -S(57ad7d5f,7f45090e,4ffdb906,17ddb128,df3210bf,e10509da,dd71b00b,aa135e5f,58ba58c,b22308a4,d7d7c1fd,5f3935dc,69a5996a,d5825bb4,2fa73034,ad1957f4), -S(308c94cf,c0234e10,5c147a0d,155818bb,d6f534f5,3c02ceb8,14fe03fb,1e0c2c2d,90860fef,f41da4d4,b457e267,3585b997,2fc2465d,de0749d0,dbc3b8d5,251629cd), -S(ed769107,95f5a585,9fa26429,7e51b183,ed30cd21,ce489c48,6268ff01,9d500407,395ae9ea,b309c345,a6aed39b,f2fa5b62,a85801b2,74242b41,433735a6,41a3375f), -S(e4ca72c4,2e3d099d,f48a2154,b7f7ecb8,53ec83e3,4a25c1dd,f7fe224e,50dd6a9d,5c67482e,fd84dc6e,96e3b258,758ef03,a9b72b1c,e210ee6b,b6125143,f2a14f8f), -S(e0cebeb7,32a3881,66a10ad9,e4099f23,3b1ab63f,f214916,a2b24c77,de8c5d2f,6b15c084,c58da2ca,c074f02a,7dcf05ee,8b836bd2,bd7811f2,53df8995,6de6b3b8), -S(da35f459,40db892c,9fe6d0df,98f18323,cac75843,d5362cdd,1706cf59,329faf4a,59ac2e36,d811cce,3f9596f8,c7376f89,5c13bd99,1e7377bf,b9742aa3,7ff78bbd), -S(e1b0a76d,b4bd9e71,ce6bb854,670d2d6b,a6e8f792,bc303d36,bf3a9b97,46ad7833,1561faf7,6a4f6e4f,506ffb62,dc55deb5,6cfadfcc,9e4b14d3,fc5f9dc3,a5c8b801), -S(7a51bcef,7b352661,a73ba2c0,27c2fd57,2d77c45,ea8fcfa7,c39cf9e4,e95d7e36,dfd9a155,29682f33,cbe45ecf,4c0438db,e11a6fa4,51017b94,a33a4f14,5db35a2a), -S(b51f1635,6a08d923,dc87b99d,94399f2,41cf62a9,62eed5e8,de8b9a65,53d139c2,e48542ba,633cf153,43b97d28,157f19f,374a8b1,c154abe0,1624d5b1,17387b41), -S(62be0f15,6e567bf2,452b941b,2ff646b8,97708993,8c054273,7ec99683,d07c22f1,63c8e8ba,3941e7a0,f90ca26c,2fbf9341,df5db636,c113566f,a8bd1193,411de1ad), -S(78012331,5815683b,59ac7d62,54055360,4d4a73e6,453b405,b7364664,5dc78282,a02a235d,68bc552f,6627e23d,d01c2dcf,3752b513,a5e3d925,f9e43a17,4c947ad8), -S(19d975dd,16aacc11,a25b6d36,580dcace,3cb19e55,f4a0c9f5,b221a847,c8d64d2a,621bcee6,c7662473,ac82570d,7f888020,18ce7b83,7b635b3f,d44ecae2,d0633f12), -S(ea6d786e,dd234888,561afd6,a57d9d38,2a07450b,8bf787ff,b5763d3c,f9f7e5cf,ec4d538c,de2077de,a8c68b96,69bcfd9,700e2e3b,ef671a3e,38bd9d50,c785ed7a), -S(edfdbc79,dda15c6b,b74fe3d0,711d933c,8d466dcf,b0a51334,48e9025e,85c0e669,e503a18e,e2ce2fa2,3512c4b9,c7e70dc,ff70cc6d,e6f78e1,74fc64e5,dfd4a2e4), -S(d79bbe99,7c2ed85f,1f687ce8,b761caef,9629d374,ff3a1c5c,2e62aa55,848ba917,c87c80fb,db44be0,466cc253,5fee352,b52b65cc,c9ce620c,eeb0e09b,30dc49a5), -S(9a3c43a0,230fb046,ece16ba3,29999f45,ffbfd674,a1034025,8ed4b71a,d76dbaca,84ebd352,b26289f3,d0f0827c,fbc95da4,79baa21d,6a98c85f,1a54e773,d06dfb9a), -S(bba0583a,9915f4a4,5a015244,29bb3362,6d36cec9,f6d6e966,3d0d0e93,ab296a5f,f2f880d5,8b29cc71,23b7212d,a0068bc7,17ed8651,b262d8a2,67f2b959,4726eb79), -S(bfc82f8d,50227d6f,bd7be2fb,fa481d35,9b2399ee,ad216a36,5ee7a0e6,25843e83,43c7cc25,f3c527e7,a42e15f0,d73dcded,987ead91,4dca8a71,f6e45269,e0132aff), -S(e5a790dc,5c6399ba,43519268,e22fa9ef,1d93073b,e4b5a07e,d8c7ff25,c8674a1c,2dbe7dd6,c60650b8,91baa13e,7580afb1,c68c213b,cdbcb32c,b7d2f7a8,88f76a47), -S(c48038af,f4b316cc,928b2b94,decd9975,dae28b6a,46dc0d9c,808a5f17,3b251f23,8f1af5ae,31eae121,b5c53e8b,59766137,7e064f33,107784e,751c0bba,43cadd4a), -S(a0663a89,a8770439,4322ae5a,f2d6132a,e6882f72,7a30c7d6,c774d34a,50947e8f,6b3e8a03,6f099441,1b598704,55a2ae52,894a4aac,b49717da,4ac053ac,4a152d9b), -S(776c11b,2c5b2766,ec2d3376,63672bf1,933e6bb1,70d96423,484cc0e,f75fa07d,7ad71572,7d6552ea,62188868,8ed43013,53846bd3,da2e772c,e5e7752d,ade5505f), -S(6cfbc277,48c72aad,d60b2a5f,b04160f3,45fe3f2b,ce005f66,4a25e444,87ef44e5,96d309b,11b41b41,e851fd16,c4c751b2,be08a35e,d912bc21,8673ee4d,44d535b), -S(6cde4b89,ae0d961d,3faf8024,b64fad52,9bef7e4f,9f7792f6,ae242f6,7f559915,d86bb9b0,de0a82ad,ede30426,98526356,5d7ba22d,6be061d1,f31e479b,3590e3d8), -S(c2eb111a,62da4ddf,72cea94b,a85d2777,1ed639c,6c511c65,cd15dce1,6d4ed6ee,ccb342f5,3248ed9,b4e9c8a3,edc75d,cd519754,ec0e82cc,970a0190,40100231), -S(199dbd18,e72e70eb,7c16d374,c32e4f21,6f6f1015,96b91690,a846edeb,83366c79,3daa0e0d,33059817,dec9591c,a3981891,7a10a344,1d5d5be9,2ce4d81e,1e24ca3f), -S(7b175876,b6cecc08,324f0564,244b7912,59a04060,d63d9bb7,b1f9952,39b7cfcc,426a29de,e407029e,80872b20,3309b9d3,e99e9099,3892162f,385f7576,d9aef02), -S(8c182626,ba2b47e8,8415413,4c131ec5,d0464001,9ddc60f,7136ac5a,cb7f7f70,3eb5783c,c185c51,12afd02,16ccb429,d35ae768,3ff5f3ec,7de3fca0,b24369cd), -S(c21bf9c0,31fc1e5a,a18bcabd,fd278fe,ac280c08,d1edf19b,9dab3ffd,de8a6d5,9832eb2a,26d38233,f057708f,4465772,baeab661,c0b958ec,95e0e02b,94bfc543), -S(28003d74,2da7249d,67abb09f,36ef29bd,3eec106,5c02926e,eef4198,a17ea4b,f7a23dc7,779c9bce,64ee2bd2,eca6fea3,78cbda92,40c6cc9f,cef560e4,9b4dfeed), -S(de29158f,43169b19,4de65951,1c905015,2b0990cc,d24e73dd,a9b0fbeb,660749a7,2a39a6ab,42b79a7,f243a8f6,112333a5,8451866a,280dfe7a,ccf156b6,8f1f6f2a), -S(5c8c9c5e,8066e79a,38e3450f,59f2e504,2a65db6f,44233598,4bf0e4dc,37550e62,d33b710f,8d84ee3a,b8481efe,7cc4099e,8a47d64e,bc0433d4,f966fb05,7e4d68c2), -S(33853003,86c14fe8,1ae5ea18,1cd3ac20,87ed14d,6014bf9e,cc8b386d,dcd10541,db06c040,7ffee11c,5dca0af2,1856426a,97f3831a,850d4107,12b314ee,42ca1129), -S(43506cf0,bcb58366,a3faaf0a,fc8ca79d,3022cd0c,7b17ba3e,a7ea2e24,8332670b,4869e72,44c0fe15,39a93b9e,c1c16e59,880394cb,3cdda9fd,d545d4d5,968d86bf), -S(d13850f0,fa4e1a3b,12397c37,8b2f6654,46247ff1,d270538e,fa4d77c8,ae27b2df,91588b2c,c27f879f,ddd8a8ca,22165952,38224cab,e3090655,cb02b045,e869ac34), -S(995b5075,c2e57ac5,3bf1d8c,8b9a4900,207c9dfe,b0dcf3c9,86662c2c,9ac162c4,c75e3e71,3c7887e,1a47a400,dcba8a5d,4fc7841c,7f76f0d,e150bd28,ec3b14d0), -S(6af47ea0,6e2e8217,62482960,10afad10,b48d75e5,ee95f04d,66dce112,592cd7a5,2d6b4963,ee90bd6,21ec5220,6416178b,5d7b0853,7fe8cba5,ed06a25b,1078752f), -S(fa6a5eb9,780c0714,6f5abc1e,52bf1113,bd512198,95233975,4d58673a,64db761e,e57e10c3,d00af8ed,f4d601aa,e236e17e,91ec638c,d01c0c5,aba1d243,b95c89e1), -S(6d4b83ac,e44638b0,1a729bda,479705ee,e4194525,182dc1cf,f3002fdc,1ca3aada,1f57193,38c38891,fc6a0b52,c49c6bfa,c5de856,72c9ac41,3b137834,ae7ce48b), -S(6ea5d9b4,d638bdc7,22e03664,fb63d6b2,368a9bc5,eb6f68c6,61f79579,d89d9de0,c0c306a5,6073a961,c7e85e0f,3221bf96,b09f8ade,da8ef6cb,8289c8e,54540af8), -S(1a2f35c0,349c0cd5,1e4c9fa8,b8ffe4fd,8c595994,2d172dda,bb8bd8d2,d22628d2,55357f7a,cd9a9694,f2fb8a31,46546a4d,ae705945,766f8565,d8dee125,a9735003), -S(34f6720,2a17f704,80565d92,d5d268f1,95cc0873,efbb0a45,62ee87b0,bada9e07,fb3bb7f7,f878b28a,2fdd81ce,71465d96,e3dc32a2,1dea4715,61f464fd,29b19cbd), -S(93cb896e,64d0c453,3d82977a,872ae1be,1f1bd6c1,d4404ea,f7688496,2a214a86,f3028814,8f07a191,4e908ef3,66d447e7,1100fbc9,4ad1e4d5,bdd01540,135ce7f9), -S(1d5bda0d,c6378439,d30df39,5516e605,7c8b5f6b,fdda8582,ccefec6e,3d68bafb,45e2182b,a2377a32,df9b590e,943920ba,482db2e1,443c4269,37a6fcd7,14555175), -S(4d0c346d,7c4c5730,4125f376,9ecbca25,33a737e0,d5c4a85c,357a8f4b,792c02e2,4dfdb5b4,b04c0188,e8b1593f,a9d82ff9,ea4c8314,50231cfd,f5d0edb5,6f7679e1), -S(808f8958,d263ad70,bdd91b0f,76f352b5,c5c280a0,90ad41ab,28d60bda,69b52052,cf8dc4f9,eaa81931,f29a4e04,a0929d3b,c710f43a,845d6b8f,c8c9af81,7fc66d77), -S(6dfb47f6,e33f8073,9251982f,7fde21be,1bfdb916,41a8fbd0,1a36a2a8,6b10a3b7,447bb5a5,e1895243,d33d3883,e8210f3d,b412df54,adc9e35f,313a8006,141efe99), -S(8894aa46,b158f826,12ad4455,35ec03bf,c2625d61,58de4278,2848a919,65fe5e,3d280519,aef54f53,81a73760,6c4ace08,e48e87a2,71beadb,cb17314a,5a0e4b85), -S(bef6abd2,a6a2d391,a045c2db,24456a53,3dbda4bd,4e39c3b5,afb1e845,9cc6efa3,b329a528,f05589f,375c188d,83a3b7f2,89a40276,7482dd2a,4c5b07d9,df7543d9), -S(2588cbc7,171a57b5,afbc6685,6546fcee,6f1bba26,7cf73a8e,1eee643a,290c8b7a,2b6872f7,a85118de,ebfbb42e,21bdbdef,73426417,f2cf9a66,e430892e,c189f192), -S(e1362758,cbced085,6d7ef7c,9fd4023a,6aaff6a8,46be23e5,fb7e143a,e50d2fa4,1d4b750a,e8fd53d5,bab60889,36db9fd6,1c05bed6,87abc705,5882a4d4,45754599), -S(f1bfab09,821e2d48,b8849002,5222762,b703615c,e89300b,3774a966,c5bb2dd7,5cc77e20,b0ccdb36,c48687e4,bfe5e264,50dbc5e8,df38b1c8,322777cd,1396d309), -S(f3c5dcc0,778156a4,ed1fb225,bf1617b,cd56a4d1,4d91ab0b,a135b900,ff5cbe74,297e4146,42d565da,17933bea,4bae64,188843cf,9ba103e2,c33e533,15ca5ff4), -S(b8c26559,6fe544a2,e34bedd1,88a82771,8e48f880,ef1a9e00,d4cb7ece,84f79c23,9fe1b2b9,f3e3f392,8ff8b8d4,a72670c,dd9979f2,883f44de,f74dc6b5,be093390), -S(780b8246,11dffdaa,2ba0f9b6,154305b0,6a536c10,923fb056,ee6939c3,c456f6ff,802f9ed4,f6e395c8,b783b21a,d5b7e58d,6d3e17d0,b73c3607,39d21ace,7f05004b), -S(ff5d8fb9,f80b0d2b,9135052d,97cd1bed,de7c0622,f0c7c9d4,7add4578,62570cb2,9cde8f57,d9f72bae,e90a6e0,89911674,bfb126ad,933439df,c9c1498c,eb38aa6e), -S(9b05a751,91f7b248,f3eeaa5,2fed8be1,b1da6e9b,12313382,3bf46a8b,220bebe3,17c9939a,92db1886,e178faac,633fc1af,4249149,3b8e1c02,51c78d78,5c5ed5f2), -S(ce661b0c,12d51507,d8a066d0,5f43680f,909407c6,9b0de379,875ba50c,c8aefad8,ec469d8b,c9095247,53f92cb6,415445ee,7fb4a67e,d28d3019,6e1e1d06,d585237a), -S(20916590,d0a22ae8,3bcf92fc,91b93643,188d2289,12eca21d,5cefdb6d,a46654b4,2d7bf778,66ef1253,92854ac3,7846a5c6,3feb6b14,ba1b36a1,3b77ac3c,8670e871), -S(ee7c4337,24aab6a0,fa304ac,50501cd1,a540309d,99a63c56,6b20165f,1283cfca,9e3f97ca,ea42cc45,51283884,b19c2d11,50c420e0,745ce88,8ae82918,4db7c50c), -S(a23a466,57083750,56b5712c,2891b543,150c474d,2d02b9a1,8d72603f,b695ca09,f5b2c285,b4f341b2,966e71ce,d1e5c64c,e05e8058,ff2b4a2b,616e6f5c,40f5516a), -S(21193f,20328f14,cb0d47e8,6bccbd5b,e1a2fca9,fb1294de,6cca05ac,f5697768,16147a71,cb2d0f18,38f1e80b,f395a13a,9c630167,caac326d,aa890139,ce162042), -S(89db6f1b,d405c8d,b29673c4,2dad2574,ebec14ee,9cd6ad0f,1ac55f42,eff5067b,20c82a6f,ad90c731,420cdbe4,47e57450,d544006e,16ed9088,e5a77089,4911b3ea), -S(1162e4a3,4f3a6d,6b360059,258a1a4b,2a316064,b2e0aa56,3acf1a5f,812a9682,2433cddb,650c9234,aa4d6d85,f8442d83,1a9fb48a,9e92e62b,aac0ba2b,c90d1807), -S(6c439ed1,e0dcaa04,a87d4bd8,6898fbfe,80fd130a,c4721fd2,8707ca68,d1a99104,b221ecd9,2da68080,ec98c4da,be4c615,e2091f90,4031f875,db1e27fe,4dc852f2), -S(ba5b6e84,f225ce20,7cccccc7,6646f78a,3da1942a,55792678,18e70aec,b651daf3,9c50d8e4,f3e0386,72bed48c,985787ed,62c4aed9,1f32b1e7,482801b2,be4e09bb), -S(deb90434,437d5b7d,32228c47,e3e384ba,4424010c,20689aec,99809623,22cc3527,54ae32de,29288f59,e78e0fe0,b690b148,d60487b6,971e6c01,7561f49e,3b5855b7), -S(19120ae8,baaa0394,8db3e91c,973ce918,e3b80039,15b8df5c,564f8b7,ee7d4485,c260a8e6,e3abca0e,8b84a937,a9f5e19a,160d7178,d40906cb,4b2221f0,d6b9b84c), -S(d3f5dabe,754636a0,741b81a4,5abfcd5b,90b8acd6,94e58419,df0dfe57,e2e45c8a,f58f03b9,5c18b14c,859786e9,24ae9ed3,8d6c800c,57793e64,fc4a711b,71829149), -S(84b37eff,d81d892a,df94d68b,2776ae21,47c56d3a,c9ce48b1,a5057830,eea659c2,b54b242f,7e438a9,ed18b0fe,cc8a4552,dd9351a8,f763a5eb,6a217669,444a96ea), -S(32127236,3f659d58,2e0871a3,5aeeb25a,ab7acb6e,90c1feb4,dff53f4,a3eaf0a,cf01c0f0,8bb8ca11,dc6b019d,dddbbfe,ed3d40d7,2d06116b,62618179,fa8d32ff), -S(1e07bece,17458a93,98c489a8,aa0acb83,21743558,f009aaf7,1be7034d,c6263023,b0b063f0,c11ecbf,f055cd8d,6e43d009,a7519613,44498adc,3f7c87a,441ec9be), -S(d77e610f,8a969baf,fdacde3e,44abcb7c,27207311,c037e516,5a96f17d,a656ac7,645ef0e5,2e4f0786,5a7cac65,54066137,fd8536a1,2a4aa0bd,8f535254,72e731cf), -S(fa630fde,2aeebd4,7ac7caf9,3c6b4523,cecc5f4f,5a26d0d9,a11d6b11,19816c14,acebe389,85a9dac6,f3d80e0a,a4271c8e,c81aa049,d9eeb36a,e89fc522,55ace7d3), -S(e3e53a9f,a0d0286a,f56f1418,20ba1c38,1697e298,49fe82ab,4ae5109b,2bb2ac32,f0eb1f22,e432dc55,98844676,1fcdddce,de875b5d,f7d8cef8,109e389b,8720819c), -S(1372173c,a0754968,db48bb68,87d1c81b,47686f89,c6859fd8,3d608fa,8a767367,31ab8ad8,be50a9bd,99a738f0,345ba781,a2d39e94,1ad9ef81,4d4ed33b,bad08cc0), -S(5a82c886,754bfec9,69fbf970,2d87183c,4c6ecec1,53e50d49,d4a3e1ff,341b9b3a,b8abb03b,63e4bdcc,a58b3717,7f349fa7,4c87afa4,79ecc3ef,7e15352b,6d59d61d), -S(aba39636,9a7a032d,8cda05eb,588a04e,e0b3e75b,dea52776,16af7bc,14423f4,63bc3d87,8f419a78,440099d0,e26f7e73,8597982e,4708604c,e8eaedc8,2c54a34c), -S(1db97bee,460e7aef,f3132d52,48ecf43b,911efec5,1051efda,9a231ca3,a366bb86,8a297bee,fa67a334,97cfd06,211c0e0e,b876e570,e255f415,c37bfec4,bdcc129), -S(d115ae92,b28c2144,a62c6272,50cf5b62,7641533a,e5c2aadc,cafaa9fb,7f180c0f,b7bda4eb,63064115,fe29dec9,4af5f9f3,12a354e8,24827fe5,d33e0737,ac3a8657), -S(15234a63,9b7e216f,7d035d46,7146b90,2812f449,cd7fc332,ac8d773d,b042eb65,8c0d946,a55f5703,1c9ee375,b7e146d3,b1325114,72527aff,d4a6d36b,e96bf6a), -S(25290f2a,b404b4a1,19bf8895,c0c31357,1b9cac69,7d25c6aa,303cfd38,f375b190,f7b23d34,2ac85b40,9729f41e,6977d70a,394c037e,8b43c148,e8d7ad5f,1cd35a0f), -S(6a75480,e949ab33,dec0849d,80e4e458,e8a3da3f,bc7f0c10,521d752f,5fcfac3d,8ed6efb0,3dab1dfd,fb3d7c1a,90419b59,b4ed6a09,b76a1234,ec8f1890,ada92a06), -S(37060ba6,e749f01b,99de96,ca96ee67,ba0c6765,6c1d10c4,8952aae8,80350ed2,7b5eaca1,b6ececc8,87dfc4c5,79cfa9bf,c9e72bf3,a6bcf79a,3877caa3,553a420c), -S(e3bab26c,6646c20,279cd320,76c75574,4177fe6f,77de9821,36ec5162,5d13f5f9,3377bfe2,55a7c6e2,24ca5ab2,e36d535,75bc4333,75bff71a,8ebc1257,5f7fb0e5), -S(ddad1dba,85a9b343,bc53d5e5,956b8b7e,11331b3e,8a572679,4b275930,b9f31e07,412686c2,1acfe9f5,3ddf0e5a,f5ff827f,c3c912d4,7a4a4d55,37a9a5fa,29bdc4ed), -S(6cb6f196,a0deb885,568b7595,c3cd5198,d8755e78,9f194a53,ffb863a6,4858968d,56918ec5,2263ef0a,e34da425,69277e1,be8b7c97,880081e9,1532216e,c3798e87), -S(f5dc85a2,d7c3da94,833d7254,aa8c4a7b,6b105193,eac25377,d20ff6ba,26a608cb,a311c934,58419e7,823207c1,8d1cec01,dab3a2a3,248d1be5,e36d5b1,b076054d), -S(d8d0a942,57fc6e64,975a62b0,4620f382,c8946d2b,3a14397c,6f7465a2,1021645b,7d0c9f12,291e0493,87202b90,cbeb3d52,328a002,3b79b3cf,6c22e1c2,bbf4474f), -S(a9bf9157,b48c2e92,537bc4a6,43d03a4c,a0276831,a00ae6c7,b31a6d44,ebdce70e,34444099,98aa2495,e7d0ce03,fb265ac4,76ed8c84,ae87812e,b52ed5de,d482c1af), -S(e88b3754,d452d447,67b7765e,9bcc318e,2426e82,6f038685,e696b9d1,e2fc509,609f6fce,4e37102b,dc9def2f,77551726,a43d2b7,8d81a672,7997a94b,a6824723), -S(3f5ce314,ec4060ce,9d6ffcbe,bc6fe525,c9f5b80f,7f64b92e,242a4768,5002f619,bbcc8269,297e4467,950bdbbc,e0eba72d,815822fd,6679f5aa,122b5b1c,f1ab4571), -S(fccd783c,c1b4a564,cf93810,adebcc17,c2417f3f,d9358d59,ac32c13d,98c30305,65388d09,5f8d7c6a,1c0a40f6,16748b7e,30708444,acc9f90e,b644727d,b1984852), -S(6e372625,ca297c57,192852da,61b97651,1b0a6306,9bc63bd3,bbc17fa3,2c03765b,3216c5cd,2edfbc3e,1e2da24a,64c3de41,1229bad2,e44b4548,86b4766d,db184885), -S(364b023a,893779f,d8dc892,189f7565,b6642766,439d3e4,f9a27111,e001e191,74ceda0f,32a56290,8d9649ea,56c3bdbe,9a4c0bd3,dab2b99c,f9067a62,d34a9b6c), -S(99374e3d,dea10db6,b493a0c2,3c2cceda,8ecb2b41,6364136e,2f8acbd,51d01791,f9d261f6,733d7826,af2502f7,8fadd97b,c3644559,a1d18162,388c8eb7,b372ae53), -S(f1e858b0,2f8bab0b,12711388,70310289,9f40b11d,ba24c309,89e237c2,e5ae6aa8,3538eca7,9ae4f5cc,da8085c7,b53ddf55,adbc1b51,8d4ce4bf,9f00e22e,b7afa426), -S(96424847,ba09f93,37b83bc4,f5b5a4d,a79bbd37,41258d1f,95dafe86,f3b8751a,af2e7579,e2c1cb46,5a8a5d53,473f7d37,398d33c2,6c51f5b5,954fc1eb,bafc5ffa), -S(2f57a7c1,de175570,8ea98914,787ed66e,246a24bc,2ee81fc8,81ebc6a8,838f8e50,dddb2d2e,6254b5e0,e090ac4c,f758879,1c51b32c,f70361d7,f898258a,a7853c48), -S(4762735f,ba8aea2b,9eebe42a,b1eadf24,1cbfb083,163f8f8b,104257cc,360d308,b03f799b,2b504ad1,e98ca6c9,fc27a851,63fbc620,9de110ba,cbcfe7c7,783a0860), -S(6390203c,6c219a18,e6390e45,e8cef444,ca6de696,4ae43a44,e0700dc6,a735a125,a9e6e44,5a3aced8,f072c0a0,1f5d1d54,8f6059b2,880edaa,fb42fe8b,cd4787b1), -S(2986e39c,d19ad213,b171b4ef,c24bac25,50a6fafd,7907f9bc,440af15a,35926a3c,ac5cab3,b35f667d,e4d2d7a3,48010cdf,bfe0e6ef,67287bc9,ec39daab,395a1e52), -S(67337f65,973e6144,e4f10db4,d8e29ec4,46a03304,b6a949bb,cbac7ffc,ffb4ac7e,66589e70,64003376,8043360c,977e35da,41e22f6c,3c3299a8,e0642b4a,55c1b99d), -S(3f9f9f1d,e2775ba8,96debdb,a7cbe0d6,5d2058c2,4a54eb7,c021c226,96aefaf4,776f68c3,292e0ef0,ec737629,d15c8410,7e40dc7c,fe846936,3f2cb18,b4e772e4), -S(c42e2e02,20f965e5,3b40eda,a3d7b450,24b943e4,2067b40c,4662f6d8,1cdcedd4,89ae9af5,95837e93,6f419b4,7e8e0e3c,a768bda9,a6a5aac,801b30d,b34e0bd0), -S(89f638a1,7ad9e13a,378cd116,38a7ca27,181b7d83,6d8423de,a2ac857,9a1cb5c8,83397996,e70f91d8,5a72747a,9c2dcdb,fe895967,1e2001e0,b8ec5acb,67f4d008), -S(677a6390,82642fb8,dbafefb,7cda5bda,294e6f45,73312359,f6cf6551,ba0f2013,c3d208f6,e7c0dbf,f35ea183,9cce662,df4c0c79,d9ca62da,942a7601,f90c5d5a), -S(e5f2952e,36002cff,3787b459,f2b566d9,aded6da,b00b31ca,88c05bb1,789c56c0,6e635a5c,a6bfe707,f8111c0a,8853caa3,52ae42d5,2835ad76,7e6b0b34,de24d626), -S(e9d7e208,e3550536,e827e2db,1b5e33dd,6e3f520f,eca9c121,38ce6c79,cf9bc2cf,b2c90c54,90ef649b,51508c18,f9e2a87d,c95e7446,7434d9fe,cf362304,6c75a548), -S(76a0047c,a21f1cdf,f1934c3,73ab3c14,801f3342,e96dc8b3,d9c9f9ed,8ed32b33,28c5e795,f0cc967d,36a06b75,51338d8c,1967a2ea,47468a93,a79927a8,b93f22fa), -S(6e25a2c7,1c4d0918,45156c41,a6158082,44141684,a148b2aa,a0a29116,4ce9f7a6,b47a5db,c22779dc,f8368917,ab2ad290,f0ca9387,738a2cf8,f6fd00f7,f7120c22), -S(5dccf366,b6a32767,f0e9f544,315d56,754780b8,ffe31bd0,4cbd4082,8df79dad,3ca94a06,188ffb75,81f6db19,4a40b3f7,c827828d,5339c9f2,1f0bd167,2de0f8eb), -S(4f082d78,87db1b89,744007cc,14743578,634c144f,c199dc5e,6b024570,595aa74a,c982c1c8,8a724114,e164361e,12cc6810,7639a530,97392b24,f11e89f9,e3c63525), -S(73dedc7c,8cd2b6d4,de56e4ac,9fd8e7ee,77f314f4,11d66953,2da150cb,896025c6,5805bc18,3267c258,8a7a5820,1e5c8f59,f05e8384,a380486,af07c89c,1b1a318a), -S(8ac4c219,fa1cb64f,625b7b6f,c1278cd1,2958c9c6,4cbc964d,127bdb2a,e472b43c,7dff6939,5f076e57,6882d7e2,d0fcb544,1e301834,cb5085e6,6000cb23,cb621cae), -S(72388fba,92feb394,fc6e6cf7,a849752c,41665040,54271441,c7a9cdae,facdba6a,cb846fcc,e7518e85,54d90f1c,286b889b,31bc2910,4915f30a,b36bd43b,e2234e8c), -S(4b11582,3f8b93a8,5907a139,5d4ef6f1,2a34576d,bb021c66,9ec26ed5,150e5fcf,ae353938,3897397f,15daf2c2,736c3929,93a1d05d,45268cea,3cd62ef0,a340f5c6), -S(b4b2effe,f45073e1,57b3beb9,59a177ee,89dc672f,c14cf312,fae3449,60064d00,bdfc076f,17d0523b,a83d21bf,e0f78623,ca0e777,eb78415d,965c4f6d,d1476472), -S(8143ce9f,a7b5b232,3d3d6337,8892531d,12e3152e,e14ff290,1790300e,99434113,9b6c8eed,b575ba3f,94029d9a,5e7eb6b5,1952b760,2550e10,babec290,b0fcf0a1), -S(83c04e84,9fd179d0,d6add7c2,6ee808e2,a75262eb,51301dfc,a15e6a16,4e698c51,a4c05e15,156790e,802f7670,2d10dc49,239f8d1e,fc9d612d,c7e8aa85,20b789a1), -S(7f5b9f0,57d3b50c,c39e81e,150a741a,488c0bd1,2ca18fe5,cf871b6f,22832554,8246a447,5609e61a,a474db4a,c9f526f1,197cdc40,86c7ecb0,edd7ecce,2539aae7), -S(e27a13f6,a1b82bba,ae5d0212,e0fa90a3,a6885ca4,684f91e6,dfc8343c,14841979,c9164ce9,a53ef56b,b5805464,7becc9bd,64a49103,70487438,87152f38,237ad8b8), -S(4ba91b4d,e63fb74e,9c06885,340dec13,8f6013c8,f58abb7,5ef0a748,bc323cff,6595582f,fdf487f4,feb2eed0,206bd640,7f1a24fc,3cdb0fd3,bcab0d30,739efdb5), -S(37a80af0,650f33e6,360fac3,19b28e3b,817bad51,bedf9193,c745a45e,93f378fe,5edff10,fd0229ac,3ee2794f,155c7f12,b50a08c6,7b5e6d43,8931af1a,a039f892), -S(65587572,6c9a2bfe,9c2faa59,474247c,6955cf20,1bcf6c3e,513e7b54,2b5dba5f,8cbfa42f,ee790c4b,ea965128,14063b46,25131ec3,72028680,3fe69ae,2e896389), -S(a289ebad,8d4a93eb,f7cad50f,1477246f,1345a3db,7699c9f3,9a7d94c5,1433f957,41ab3d30,9b10aed2,32fb4d6,ebd906ba,50e94f34,9e4e6ddb,a65ba374,d4bb6f82), -S(d70d75b4,93a9b2b0,9af912d9,50336091,3e8278da,e73f188e,9d7f5f5,b159aa8e,fd76cbca,4edacf41,f568b81d,8f854fec,439a0ddb,caa0ede2,5f7986b9,a6ce746e), -S(97c66bff,6c03339d,9b688460,58e4bf90,12273be2,32b1f5d2,89a426d3,72024ebc,3db99430,4cb5571d,7c5ff64e,76a90913,8ba307a5,ee8aafb6,6bc884a7,590d0e7c), -S(b88b642,5b8aee75,ce0643d4,3e2a168d,2b1178c8,a9d3e5a,ce2aa55,1130f8bf,cb954eca,4898b75d,db5f9c4f,68f8d9b8,6fb7352c,112e222d,4e5ea298,6a47df3b), -S(41fdc70a,bca5624a,cfe93282,1550ed70,d31133f1,83692b29,c8013601,afe6d0e3,608a7ed2,d675b20e,6a9cbb69,7df4a79a,f70a570f,a2676830,39b69c27,a984fdc0), -S(3f2304f1,b643cdfe,630e184b,854895aa,c2a03f61,59c70ed4,a9837fc0,c0869434,df5e1d6d,11333420,be9df6b6,5eced485,ff0e4d5d,3ed79ec3,788e15be,dba57b56), -S(7da74b0,687c9c5f,d063f1cf,44b2c644,d51b2e17,49a3f8b2,b98b0d4a,7ab43258,2537394c,a042c341,b5faa3b0,35f5f19c,fc2ec9a,f6f34c52,34980336,1d89fc99), -S(88487901,eaf30bb9,27ed414,1a9112be,dbc46be0,52f43a1f,e910f23b,52073fac,6bb951c2,b7f30e71,9ee77955,50189ee3,9972adb7,fdb7a8f9,f335c8ba,51aaf659), -S(ad5c1c1c,ec3033d3,9f3d1ced,41f2e369,de9883ba,3f78e7b2,5dd658bc,42aeecfd,90001dd,b99673e2,37405bbb,f4d4321a,496f4350,660bb9d8,d5613846,e4e6fe6f), -S(bd8dc061,3da485f3,43335bf3,88a57a50,429d436f,a74a83e9,8d9d93a4,868a38af,173d962a,fa7cf6ea,65c8755d,870e4eca,1ef9ba70,97d9bf6a,be26b575,1fccef16), -S(900c9c35,ac4e9132,4f60b380,c7e80b88,f33c9d7e,242a248f,6425f010,63d99af9,5a6e22ae,dade8294,169c4645,a4bd0e73,ee212154,47a4f06e,6a662a0a,a7b88cb4), -S(e9384af4,a6f649c2,720601aa,7c5e62ba,2c60537b,1fd2c416,b2985601,1d18165,61295342,ed716c76,c4d35706,95a69bd,65fd9a2b,832ac562,59686967,1833b0cc), -S(b053211e,e18fe64c,aba2f7fa,9d8b8d5,e79e11f5,8188a811,12b2f9bb,e61ca72d,440ce2cb,27a783b7,defa2d0c,a0334f84,7d623960,ec5007b8,56f8c7cd,932a89cc), -S(6e4ec6d2,3a333b66,56977023,2e7ca03a,5fe1475a,d82bb93d,a1aa6489,997a65a2,306fbe38,9ef70003,2d69ff0c,8d483ca2,c321fde0,5e7bb1eb,8414015b,c1ec8527), -S(546aaf63,1b68768a,cb4240cd,917afaab,60aab408,17e7d5e4,74525ebb,2638eecd,ab3e9be0,841c2b05,5b85516d,a7d89a82,9264d773,c3d6f92e,4a01a7dc,e157d02b), -S(312287b0,260355aa,7b5ca09c,aa8773b8,27c1d703,eaefe0e0,99097e6,4f6cabf2,eb73ca95,f36a0d11,45ea347f,dac667f6,c32e7ddb,aa2ea5ce,e5f5443b,9de2b90), -S(95453155,af512fa0,8c745c6,d125b76a,d0c76c3c,fa21e64,ee9109b9,bda25b04,958266b7,5200f00c,bbe904ba,80294860,bdf8ab4b,43ea7df1,72badd31,55fa414a), -S(c0846d82,c4e06acf,9208af16,3c854637,242a7751,bcbd2f7c,f0c48cf8,b690bddd,3701a7e6,7161f8a8,8a3c8af6,337a7c63,864c1b08,6cc96321,a1748cf3,f51026c4), -S(d2f24301,44d98d6c,a873294b,26a0f0b,e1fa3e20,96e98fd2,c2fc59fa,3744a432,c8bec973,52fd66be,ddc74ddd,83117873,3ebdbf65,1115fd23,58344938,4f56b194), -S(1fd84c4e,abd5a38,847dc661,158677ba,1c53ca44,4a45fde2,b9f333e9,c5345dfa,59402870,3c5aff7,a508eea7,a419cc32,d2c72742,4e3f71aa,b54ebb37,c4c18afa), -S(441c5505,ccac21ea,630d129d,538cb631,6a315281,d7b5165f,c8e837df,6de93828,9c035747,37779fca,92991de4,e4d771dd,a683c2d,97d15c3b,941fbcb3,7936670b), -S(f48aff13,ccb0f2b9,29e760bd,fee45815,bc1b5962,93bdd09d,ca16feb9,e83553fa,a543a386,5a9762ad,90c4c270,743db1af,6a5764a0,ab75415f,3c8be28c,8d90890d), -S(2758e9f4,7bc46ffa,19a0d74a,1a9faafe,effb2c71,5f271d52,6071c340,78228f69,1acdef34,44060612,367591d8,38256b45,1cb883a6,d749d80d,12edef00,ade9290a), -S(af1d3280,417af143,129fd94,cb216f9b,d73beac7,c09a9d31,e7db9023,f568c3e8,27fac1d7,6f33eb8d,7766cacf,ff91936f,2c540a0a,a0e60c9,a6942fa4,2329ea66), -S(299f64ab,28071d25,4614d985,380918d6,944174db,1c9d815b,bd334e80,b961aa0f,80ac4e19,47b1d355,ab9a85e3,e8c009bb,f6ee09a,9f99c599,4a81369,607ed3c8), -S(b45cbdcf,14222123,d45d9f19,bc92236c,6ed90909,91081804,e0bf57a5,e0c724eb,1330030a,d6b49e4,5106118,1c9ae21d,606591c0,e326c5e6,ce09ef4a,37f1d15e), -S(be8f11b1,c27d3ccc,40224467,c26ec9d9,f7c60038,deb6b296,2d3ee415,11292062,1db86cf8,130bdeea,debf75e1,8bdf0d7,83357050,b7c4079d,1eacecdb,19b7c34e), -S(9274a7c5,af18755a,ecf84a48,9a0c81f2,9debcc09,9e875e76,fa3572fe,9dafe482,539bd087,e98d5d23,49ba9422,a99f4f3d,4241441a,59347c9f,57526ba2,358bdc98), -S(8455cf49,a3e4806a,46747459,ea510a3c,5ddcd79e,1c062750,6478e38f,1577f3d,dd941fca,cb4c717e,3523a7d5,6206cbd4,3e4e2993,36f7698e,605b97b,4d927b5), -S(8a4ae542,f82437db,801fc18f,ee57f9c6,d355d55d,29cbfef3,a498845d,5acca7b2,fce5096b,712cf054,bea762b3,521ac601,946d193a,cb229791,9409145f,753b84f9), -S(1de9a879,fa9677,69fc9f3e,d0ac8bff,327d284,97278947,7672a972,bdb192f1,ae095175,6c8dd516,b1bf6734,ff4f6b11,4dc0b94,3d01659b,4525347c,3be62b30), -S(764826a8,88303d4a,45db3a44,7fe13a8a,555f0973,da32ab3f,79c0b504,81ca23fe,14b29537,dc0e8a79,d2a64d1f,d8eb96a3,9d624216,deb614e5,2102b7d3,45dd9f1), -S(19470720,24d9f677,652300a,da20e5ff,39814a7d,daa7a363,ad3100da,7ca8cd3e,c7d36a40,62edfcbd,243b7c02,f0313494,4db0d7d5,6097018,23e17244,3a49b4f2), -S(346e886,d5a228ae,5b894ba1,fd25465d,47baa88d,f2c48000,9db7562f,e75f5e26,f2b61353,c4b6aff7,52318707,99e0e262,8c7d1da0,6b510f7c,bb995ba6,e1048f), -S(4aab5528,f4423b9,9485dacc,66de7f6e,94c34b6d,623e9ed8,538b2d4b,97f74fcf,a9ffb993,3a816aef,69fcd7d5,78930e65,d05afb67,55370005,4913d30d,3f2f5759), -S(3265157a,52941c75,a280bfd8,780e1ac3,62f1f5d8,20e62ca7,ed7d8b86,1440642,1dcf93c,525ec12b,97d1a700,f09f37f7,2d57a4a2,adc359ea,b1a514ac,a8862e9e), -S(74970421,4aa5ba55,2d0ea93a,b57d7788,5bbfa9db,2c074169,345a6c08,5053029d,88ce8b1d,77f1ee5a,63967f86,a8b77cd5,c5785f18,73566125,7c99358c,9f78ba1f), -S(6060ee1c,bdd369bc,a0e75dcf,36bedb15,a6c168c6,a65e4d9f,f065bf7e,c4afa889,eedda38,3a9aab25,689ce477,75273558,f2757adc,4a4d78a9,b693a1a9,f57a6e90), -S(6c5ad52a,ccd3dd47,427ed711,538e5517,7aef476c,e9a3856e,c5ea6b23,60b5cb41,70e69676,421bcd4a,e23f252,a4d2201d,ab77846d,9fa00303,60f39880,6a252b8b), -S(59b3bdd4,e63f22e9,7bb57319,c5dcef38,573c40d0,4dda14f0,cf799479,abfd0d70,be998425,f4f56645,2eccbb83,e4ffa58b,1144d70e,f9a28249,5bdee74a,6904c15), -S(d2d11068,deff8644,b07d75e5,6eb440c8,1da830cd,427d4b2f,558150e,83fdf333,41f882d5,5b07cfd8,9212f717,77b3a846,ca57ea11,c40d480,16db8e11,f3faac3), -S(3a87cca1,e244a5d1,b237d776,a170f5b5,5efbf254,dc1a67cf,f9578af4,6f9d784,47b25110,42be177f,bdc07222,9bae8b89,8e6b2638,6fdf236f,93148d78,31f71fba), -S(82f63ea4,34aa60b6,fb16196a,c2979486,12a12e50,c5ecda17,8e0f6317,d858d026,22a4e99d,e5d95329,bd8662b7,82c32ae8,eb0b494d,6dc1d395,daa7fb23,97c5caa2), -S(bbdaac46,6d3bd845,fe67a5fa,3ee5ed3f,cd2e762b,e35220b,e9fda52a,51795bbc,eaeb68f0,4ffce7d9,257236f7,f266bd5a,a85833d9,f4a06eeb,766bd426,b403b515), -S(d3c4d162,862026ab,9263571f,4df35e1,c0789887,99bffad0,2b677a63,4d20a367,cc6b3c0c,c1cfaa4c,ebaba6b5,57b914a3,f23618aa,f7282448,2f3d6ff9,966bc6ef), -S(558d059c,52a0b251,462be6a3,d8e0020,f5c0d6e6,44407dfd,62828a29,8eac4f3b,bf82d395,2e5a6d58,6108ee1a,f7bfdbcd,b4450f4b,30c72aeb,6109ed01,7c338a7b), -S(880bf94f,48db9565,cca7e8d7,b646ab31,e9be0736,727c4266,ec68ae38,c0a04196,8cc3decc,aa0fbd8,36aa86b5,ca245e74,8e22e8f3,1b34fa8a,5a1de2e3,32d10218), -S(5bcf6861,946ca2f6,258abc7a,9db72de4,20170290,ca0c6765,9bf93286,5d806dd0,ffdf39b7,1a08f3a4,1be73acb,d9ee2924,af21c53,22b9ff48,94408928,3cf22d59), -S(53f70440,f6c09489,edaf304e,c064466b,2bd9ed5b,e9affe95,a8cb22db,d842abd6,a7e74cf4,55af4dff,3b3bef74,902daa5f,da664d20,be94863c,63cad3be,30b13ab3), -S(d6c95017,439fcd33,9d122e80,a36ce813,f8eb4312,2db80ae6,e4b09c5f,277237ea,b9ce6112,53a6a066,7fd411cc,a1584cf,b1f05348,240b9b5d,f73aa3f2,637073c), -S(7d78776a,46072c1a,15c23544,f013d058,a3485a49,83a1593e,aa8c2c25,351c0bf1,7caf8c7f,c802918d,602be0d8,48eea77c,58c9d65,15a7f9c4,8df5e3d7,ebc941ec), -S(30586c43,54218314,3881348b,e81076f1,e8d3b527,8bbfae38,229ab1a6,6b9a49c9,d3e968c0,f94cf4e8,85b22bac,45cff2d2,e2fab151,36b2a2b3,fc2949c,1f9698f8), -S(93b3fc28,34ea8639,8a15fa40,2ff48069,3bbd0710,c560915f,e66b798,2e402625,e9382fb8,5dc35590,27b78b8d,13730cff,c2b4dcda,64d27dfa,105fd5dd,b307436c), -S(27375095,c1ae101c,11f6fe18,cb926f38,175d90a6,9e394884,4fe5331d,e466ec87,6aa32240,9ad70cf6,1b8ce6ac,6c518959,accef648,37839a07,8d18aac5,51ada043), -S(b4ec8bdf,f517180b,5c87fd51,e5ecea5e,5ea6d107,525fab0b,6b80a0a8,d462345b,76950c00,5a2a7e57,888082fa,631ba270,af02a5c7,73e57869,f3295ff,74b18bf2), -S(efbb3723,c386d2d2,bf0806e6,c42bf0d2,4bf94b7,b10d0dbd,d4ebbe06,d0a22d21,af0d1096,4781bae7,c7438228,b2525fed,962bedb0,b741cacd,9a7027ab,6a3b29a7), -S(2b6ebf5b,24e78685,65aaf770,ba36142,51bbfb72,f49af29f,c55dff7d,a55674c2,396a0cd1,886fcda3,172fca09,807c929e,afe8b5b6,38d63b05,6baffaa0,743ed723), -S(8229420,323c9f9b,d88bdf0a,ac9035,fd33c3f4,b1411cf9,28a248e9,bd71f95b,e8566565,2dfa438e,289d021,4a1531a5,632b1369,24c01cca,6897842c,1dea3995)}, -{S(534e9d8,bea140bb,4970b516,c42f2677,dc413f42,9b7c56de,e261f60d,ec68f9d8,e55aff90,1098b0a9,ea377acd,b62dc479,da109514,2654107a,28c68e9f,73b1cba), -S(c3d305e3,8e23eef1,707ff287,74f82631,ffcf3814,ceac1e41,52d932a1,67c24c51,10234701,f8a8bc0e,66bd6d38,d3924b0e,b57bc295,2d2c190,e6ccb935,2baf8778), -S(1f3f8c12,8d216272,ccbe44e9,43e82acb,d91ad650,72bd8ecf,adcfb1c4,38c44272,e5c4b103,a42d6238,39886157,43bcf8ac,ae397188,1abd5299,d8152ee5,674bb58f), -S(84f33b31,be4a83e8,6ead05ce,df1c9eca,57c60eaa,fa917c7f,56f75572,902d360f,854aadec,13bb6307,70855f06,a77ded40,5be99eaa,93a06b08,dc0fd7f7,525613b3), -S(9b4e0dc6,aed24421,2160f3d2,a0ad4ea2,8c9193e1,e442f632,a956b03,7f9b4db5,4d3d4970,9c0a7244,5e0b9537,2510902e,6fcf18d3,be72cb9d,c3c8a252,cbb593b9), -S(5eeed41,8a5e9d4,fc0be136,b5799c78,bf819dc7,32280d6a,43f10f39,e17cf8da,7615a870,c5cfeb70,1ab28456,a912dd6c,c2b87fe9,8aedc101,bf3beff1,89edd2e8), -S(413932e7,c2e1fe6c,dc1e8330,3c60e361,dcaa1fbf,88e3f329,96a77df,f39b594b,6891ea57,c7572d9a,b134ec3b,bbb65547,3e6932db,1d34a142,26b806f0,afc2cacf), -S(f73a8ee3,b7345479,19a49698,af05acec,1771cfa4,91d3bdcb,81cd997c,b63ce64a,37047e7b,e5742560,9e1640c6,5e89b560,138a00c8,e11700af,3061c185,4bf8a2f1), -S(5edb35c6,c68b4956,2cb6a0cb,3e75990b,7106668a,fbb71f37,2b167e49,5f535b9c,deedc3a8,56a5ee53,60e34c44,e7169af5,7a86438,b982c966,48e37b64,683bfc0f), -S(71eb89c3,8f391043,3c7c1b8f,a3689201,ea234d5d,b82a78ad,2deaff4f,c2bcf53b,350f58f8,1a2a8a76,4c70b16b,6d6f5040,882ec073,1fc9e3e3,f09c2daa,f113d5d), -S(ba4b99b9,71d6e91b,32227a44,be3712f7,93908f54,9ea958db,c1a425be,ed53cb5e,4b985486,76b813f5,df3c84b4,ef8f3279,94c65e14,525357e2,5f82a782,f2e1a041), -S(1975444e,ccabe01b,dabf3542,f3bd4651,94515698,c2b03f16,fb56559a,8d5c66f9,88287b5e,140a9558,2e65ea24,613cd20a,e2811e72,3fb8b12c,dc7c5fda,c5e0f50b), -S(e1ef5109,f37af125,d6f01cde,7b90dd77,cda704d5,121e436d,8ee8bf15,e2e4d4c3,458d2e4d,c8cd77fc,10b26fa4,c19f202b,d66fa6c8,e2fd2e4d,56299e7b,5fc9063f), -S(983839a2,7b582450,5aba0977,80dcdc26,cab2250d,d895a876,b17a4a82,3faedf63,e236159b,9c330576,cfb674de,a1bec238,3018b697,b8e41cb6,1992c5d1,bf49c588), -S(3f4997c6,b1efec78,fc198097,af19e301,16efe029,3cf4ac86,dda22ff2,78394c8f,e92d795f,d14cd101,eb15c75a,41c854ba,267d0557,47c81536,e887f97d,b67e3be8), -S(1095049a,b90e7946,c24bc411,892f911c,6b72d0fc,12af1186,ec43dc7,bec41a6b,85cfc876,55842640,8f24e382,a4e91ee4,7411a3d3,f4a257a2,6419b495,68363dbe), -S(567729a7,12f183b,e7ea601,68aaaead,594a778a,e9b936d8,a397a78d,f53ff5a1,cee7716c,68bb61b4,586d03e4,95f7bf0e,7c215870,e9f1dc0b,1f08111f,d855ee4), -S(ccfcb55,f8da139e,ba60480,ca57d942,5fe16cc0,902ba610,fe8fd2cc,cbcdc016,4e4d8abf,8517b55b,8f6c0dad,3adc94e6,8d995917,de33d623,432cdfd8,188ba22a), -S(869ad71d,22fb7aa7,7b5b65e2,c7b85a45,34185b07,a70a7a5f,fdc963e9,6de4c2ed,3bf234ab,30c8244f,d7a6671f,cff79848,ac53e1ff,fe104aa3,387824c1,f6a3659b), -S(5288d151,6d72c379,e14361e9,41835760,73e67c92,6919ad4b,a69e29c6,43d416e0,2f010e43,ecffa3ae,3d8200b7,e6f35ea5,31cd3db5,c5079b33,1ec1611d,1881f8e1), -S(b771768e,9e7bdb3d,76ae8a00,c4258be1,db77c45f,92318dac,777e9ff1,7ad71320,b068224,7f3fbb45,8e7deef6,7b52710a,5c6c38c7,5a94c154,9e503d81,72da0fe8), -S(7444e64,88164e8e,575729e7,88dc3197,b32d04d7,403f9565,611ed212,a708b98d,ea2a9cd7,49c5a3f9,f2d509e9,5a69745,a5ff933e,1c87c141,ac5112c8,b70a4667), -S(6e995fdd,ba6e0954,cbf84ac1,1d0990c7,ec5fa3ea,6b6f070b,2a68844e,ecea4ca0,743017fc,340132db,cb1d73ef,d1bf5bb7,95b8a0ab,8b898af0,3b2f36c0,b5b7d921), -S(b60c9741,38e10b6,e879b4ac,8de83494,7e345e8,cb5a4320,9a5bf1cf,286f0f85,469d652a,c9cf7d15,268daacd,4630da47,d74ae560,6ecc49c6,9ce00afa,df51d990), -S(70f4f8a5,42de7bc8,48555b84,6c058d1,eed230b8,6864a079,fb91f662,ed27f6c6,21323c29,bd6321cd,e946dfdf,d705894a,5025e2aa,abe9a0db,5efd1223,db2b2457), -S(b23f838b,3aea4309,7b1fdfcd,bad0a3e6,225ad4fb,a01ad0c8,49985f90,8a7120f1,7569db8f,46491a9d,b6566f95,92e126e3,6fa681b7,d0653b53,c45e2cd4,57c3bc4b), -S(9e447e8c,5d040a11,4964ac92,d91eadd4,80597e42,5181be50,5027019,df6ab481,c58a3c86,7fa55ad9,46e0f3f2,729a389,b8da3706,81c895be,5697090b,310e8834), -S(6f98b221,30ae2b8b,4f5852e7,d7e6ef2,1241ff92,ffb63148,4c8265b7,6d863f2a,c4f8bec3,3f9b7f66,a9827e8c,216489c1,c93506d4,42938861,4658e7bf,239a6419), -S(ecfcb0e8,f66c9de8,4d4f93af,e890e083,1b785a19,7b7994f8,c6d5ff4,63532df3,4d1d6d29,429e7c92,4f91a6a3,43b8e805,748b420c,b5536186,9c709033,87696ced), -S(baf48656,8401761d,2994b7bd,44d886ca,9a1dcf85,14f1796c,5b39326d,8f9d5690,ad60d65b,28f193f1,5a120a7b,9bc692f0,100e6189,d26703ee,1a941cf8,bbfe0e2f), -S(574e43be,ee264130,8e0e8d5b,dbf3f28b,3027c865,e13184d2,d2e1256f,4c56a401,e664d4d4,ecbae2fc,45cb7963,e9722bb0,8e72ce14,82f97e69,3388090e,602bc9c5), -S(b289585c,25bf9b38,9d89b7f,5b98dc76,a8e7ca73,f753aa26,f5d6ee10,27e3c41d,7cd41d56,6a17bf53,444f8ff2,3ef7d117,4459b1d8,1bfb1534,cbe7828c,e717ec68), -S(61ad4ac1,7baf7294,a482354a,1aefeba5,882b1353,b898bbe3,815103ed,14eb0411,d09a31a0,2defec0c,fa80ec5a,d4412b4a,fee6ae94,559db5ad,1bd7a349,142b352), -S(adc1d894,31f83ab7,a6ee5ac9,49b0b3b,62a28c80,c5737387,47136161,494e967,bbc7affa,2fe3a76,96cf69b8,e0c95b38,5f836d89,638ea2e5,8347db7b,dc316d4d), -S(345384f4,491801d7,11dfaae9,f7fcc4c2,adcae518,a993d0b3,f43b0e47,5d440b5b,bdd2e3ca,a0826774,e5e40693,c531cd7b,49514b2b,fec5b39c,9d995106,dfbfb5b), -S(e2fff030,ca48a7cb,6d587044,fdd94a9,d81f5605,57750b77,7435ef6f,f4af95e5,847990ab,1fa110a9,ff895c51,20d9a300,c805b343,3b1fd578,a62815be,77cad922), -S(b0342b00,a1bb6391,7154ea18,f3ab0649,45051137,1004c15,2a6eed35,adea23b2,1cbc4c91,888f52d,efbb6551,bbac455,ade7d78f,9e507516,ce0fc70e,d67e2515), -S(948901c3,3f670c89,e4393400,14bf7e4c,e59955c1,959929b4,ee74b3e3,112ad9a3,2a39d44c,93906444,48294f82,bbea8bc,b431d2a3,48435b88,5eeab283,ce9c49ff), -S(a7f64583,3fd0a62,367d4675,b94a5a49,f9fdf94d,c6597ea8,164a00ca,7a3d5315,b4fd7015,75ab42e3,9d51622b,c5639f5,9b67fc4c,a4f2f62a,7b6bc3b8,fc037d3c), -S(50147d69,fa4c421,25b1b7d6,74cca767,11db050b,fd2efb0f,d2f05036,796f446b,5445ac4e,674244d3,532f046e,127692f0,71057a33,b7b40f73,b897e8fa,213e2ce), -S(ff1db721,3b669b14,1f92a729,de0952a,86da626,97fb91a4,908441bb,117cfd00,62e7eb6a,3060afae,2084883a,662f780,ba42efda,13c1509b,13123789,364aab01), -S(29ca39b0,ca50e1d9,c718e00c,7176c506,c2eae92a,157cb0c7,1fc50790,7278b727,61bb5ca6,85823de7,fba69cc,1cf9a21e,eadffbeb,15267ada,a8def3c9,a54de3a7), -S(62cd6a0e,a50250da,650615fb,de2e19a0,6d0b74d7,316d7445,79f2be9d,f4023545,bd75298b,c2a3ce99,7e7eaf8,fedd90e9,9dcff8fa,e345ec42,c85e5ecf,61ee1654), -S(4aa8cbe6,57418299,e63f85c2,38d077b3,a1162f88,7d9430c6,1ec2fea7,ada0a758,6e360a94,7b07c27,9fd97867,e2ddd59e,3e77308b,169383e1,a7174188,fe507bf2), -S(6640eff0,e4a7b619,1f66b3c0,ae5e0b7d,92e2955e,23ee7beb,8ebf2e39,65ae591f,b4634bcc,7ef0e6f8,5dfc3694,27a0fa2b,a0e9c0e9,caa03a4c,fd90b50f,72feacb2), -S(d899ae0f,b22f7740,73013f98,9386e5ba,da6077e9,dc49feb5,ecb195a,bc6969c7,2dcb982b,e71ec202,472b4c77,d725c59c,ef6a5725,606d8226,30482554,16eb8287), -S(c9691967,9032dc88,a4580ca,b338fa3d,812ddfd6,7067917b,a2a1289b,5330c6a6,47a8d9ad,608a3bb5,9eabd2f1,8ec9bf89,4c3cabb5,97ff03f0,93a89d8c,a6b4fc82), -S(a4d25f7,3af5311f,26435b3a,31455ec,ee7a3b6,d6c7e850,14875a23,a7ad35c9,bfb5b89,af0362f7,f7f20fd8,a442c285,6f4d330d,247dc6a0,f8434a6,6c5a6d79), -S(edec5d54,3804127b,a814f23,3aa3be2e,e5e46a6b,ec12d2b6,9ed7648f,c30ac1cb,d6009320,5fbdae39,38d1f797,a5184457,7b645345,c36f1d80,705e3c82,f97bfd78), -S(257170ba,c36336aa,2591c583,48455370,9192432,10eca66a,79001a4c,8f340577,13a0acff,184799ef,a7211d79,41340b6c,ad8732a3,d57745cb,383bdf42,ff8e39ed), -S(f5ae8c79,b6a65f05,dc014993,7f60b25a,6def44ac,30275e9a,d787ba73,fc5305e,5634e58f,b5603ba8,bdcabe67,7f757371,c377c1b1,3f67366f,c36027e0,d953d2c2), -S(86c0376,2172c6d9,f53a9370,ca9d1ce1,79a2bb2e,c48211ce,d06732ac,80c9402f,964b4829,a76d7654,91e6a165,504b2302,5efaab99,b4cfc14c,2e84a801,fd220d6), -S(3d481453,e00c8714,4c6048ae,e5e44267,1a601b5e,fa6430fb,54203ae4,c6fd070e,69bda5df,ce150a83,d861f309,349b3397,32620170,d2d9c259,5507c7dd,591f0dc5), -S(8a8ef7e1,733c3e75,c3b39fd,7cac0656,6af1bd74,a240fcb3,b52979c8,2a56e2d6,846956b2,da6760b1,852cc3e4,d0eb39a1,7fd79c78,73dc1c65,9afb53b7,b25db246), -S(ec2eb41,21923a7b,4449d61d,9e9a996a,75469c05,e86a4911,16c15206,97d741e5,488c3501,9fccb8c8,33b09546,9c27eae8,66a133ab,991a24bf,c00691b3,9e1d5be1), -S(a8c08ac3,b959476d,8e58e8da,72323b81,33f55721,318c664c,ff5eb491,7aa19562,83bf5e5f,d76c877a,f10cb1d0,8b92d9e0,3a8f7db0,2c571449,ce3f5ea7,adb3d9c8), -S(eef63253,739af912,b7cacbdb,3e190add,f2931c2d,e0997fbc,5ce02cbc,56a53e75,14c4d6d4,5143b60a,f0a75249,42582d70,fdc17027,e13a2460,84523417,9a5cddf8), -S(65dc0be9,e7028f3a,c15e5e2b,1d27d339,d12a3a40,eee78b5e,4942975c,f65a781f,d635b3a7,97b5ac7b,c072fe35,9a7ffdb8,b1aecb13,fe933b3d,cb627b47,abb2e652), -S(e0cd5d6f,81a70576,2c65193c,c0a2eda2,aa5ba2b9,c9fbca52,5148a4c8,2f2c746a,5ced8640,19c48e1b,8f1f97da,ea66cb96,fc71ef84,36b87a53,e2b5a841,1d474cd0), -S(66d2d27f,eca16c6c,f8a68712,85f4dc01,92fd503e,6fd39cbe,89007d76,20a966d4,56551c4,ba79a293,fbad2b84,4dd1f5a7,a6c8a688,656a79d6,764b9b0f,df4f45b), -S(36d496cb,2749b975,9f4474c6,a4dc0283,e19a2e29,1c488623,210ba1db,1154ebe,a46cd868,c01b05f3,3508961c,61f0a83c,3ea06996,829aef29,37a93c7e,8840514c), -S(4f53c3f2,5a858506,e11681f0,dbfffded,b6bfbc8c,63ed6d09,3028a55c,c19683a5,2a31675e,7e0f8382,625bec94,83bae5cd,76602e36,1dac153,45209b10,78fdcffe), -S(9c6719c4,2f375d6a,c2891fab,c71bfa16,a40ef26d,b0ce93e1,46634221,da12d8a1,38c92598,10c67724,14f83d45,db2a5506,a993e277,f20a8430,97ba286,b2be9afc), -S(115eae71,89f32e1c,28f86c62,abb7cc2c,5fcfb927,6b3d7655,8f7f1a47,8c9ce0b8,229377d0,9b80dd76,4fab10f9,7cb8c1ad,5f0c89b4,47ac663c,780fdf6a,71a0acf7), -S(4f06c1f,ca76fc9b,d58fdd6f,12d0c64c,df9ef87f,fa579b3c,fe7f8819,aa68595b,12292991,95f91eb,18105a0d,b576fd33,1eba5e9b,f6944557,e9a54d9c,c7ac9437), -S(1f18b838,ecfb11b9,34a37132,6d765ad8,b4a1f11a,6ad51d67,3e7d5bc6,8823e742,fe6d5003,e851cbbb,1d575d39,d48ba2d2,de8858c5,95e2e73b,26127e61,fea194cc), -S(905708d9,b066738a,252116d3,451b2330,5ad84a12,92199acf,1bc0eb86,b7209109,7b3cb65f,6f34a189,584ce179,4112007c,71b2d6f7,9667880d,684768e0,9d706d0f), -S(bccf7efa,808ee0b0,f19080f3,cb4c0fa1,2dc46c87,2a7ee71a,1c1a171e,b9f03962,66b9d38a,5582ad7e,8ed7b0c5,2d4e5aa4,a14fe624,a51d02cf,7553f7be,fd2f9ffa), -S(fb6505d7,2fa3e83c,26d7cc0e,e8e8e160,1c46ff4f,299b06ba,7b5250f2,a20a4ca3,75935eb7,e923dffc,c3b0bf80,4861a3e0,a721266a,1395f424,16f26d27,9a582ca5), -S(208d0bb2,1fee812c,e93934a6,c5571d1a,a8d8b6eb,3ad58357,90661718,86a4c103,7ab4af2a,e062e5c3,9f83467e,31d95f4a,c1e0d0aa,d77e2128,a8916233,97379bce), -S(8ff01550,87e8359c,f5081e09,71b5b80a,e482507a,217114a5,8115577d,ffbbd5a8,47c83838,5bee81ae,6738ccce,e1149821,e433b9e0,e11cc919,3bd180d1,97a07519), -S(dd938972,59966349,9edba2e0,1932c7c7,883c99b1,11f3dd2b,f6b079,770f7cd0,c485988b,373de68c,9a07d8d2,3d8380d9,ce28f9dc,9dcd3abb,99705aec,c87f0ea2), -S(247f0d44,50e75f8a,724bc9b0,821e7e62,cfcc6983,860b1997,c73b7b90,515cbb1f,6b861e4f,2f5e0cf,38d91847,f5d159b2,25b43236,2e67771f,da2dcb2c,d79644e2), -S(2deabce2,d1d31515,86894e19,1a5af1c2,7fde9b45,455910d9,598adc57,e46c8823,77016b04,643d44f8,6f279dfa,1a86f3ba,428493e4,89b16462,62e018ff,d70efd8e), -S(97bcfcd8,dfd8f0c8,e7c09773,746ca7c9,de813c3f,14f6e39e,4e597559,adfd7ad0,5f948bc1,84d2ed00,ca4d3be6,6972c568,916e7120,cedb84b8,29f35cd5,dba65e35), -S(d2a6e659,e88b061a,e26bb48f,10e4f1ea,30da5df7,2e9cbe4f,451fb413,c0eb9c00,d6c0e56f,cb2d383c,dc77b93,2c41566e,acd21f2a,93537f4b,683d2f72,547d9779), -S(8a3069f0,b374dda7,b7c1e34f,80ade1b1,b439e517,595a5c88,8e3ab8b2,b2541e36,b13ecf0d,729b7cbf,aeb2ea9,6a80e6ae,32f9d46f,57ce4114,4c24f61c,b0c7183a), -S(6160e9a8,a3c82af9,bfe8468b,5142d7a7,32d00cf8,2ced3a6b,333c188e,ee6c0df9,9c174f47,42f0d46d,aa03966a,e00595af,355c39d6,a7b17ab,637580a4,ab9802be), -S(ff32347c,eb8aed18,ea6c314e,15ba2437,702b9d8e,a775f6f,a1b84b27,83837b2,d09e3f86,e37d1190,9f6ea512,44f9225a,6b8570a0,c90b8511,7a1eab62,f3220a37), -S(170d2456,58ccd0fb,d8c01df2,a84132d8,3eb94d08,d8fb7b53,a929fd4f,38ad26cb,a83ab99b,176dcb0a,e80c5f50,5a454f15,12622c22,e6f7309c,7a827a59,944c4e8a), -S(8acc0889,91014a93,e3649980,b6eb6172,44f56e10,8094b6ae,a7f16e19,1e566e9a,ecfb977e,a900e0a1,f6b8247d,703ebeb1,4524d5d6,95f6e46b,85ec9e52,a5795a85), -S(f80b78d9,22cd9e20,83569df3,ddf58b41,dadcc3d,2a3edb2c,e31cf234,5a31cbf3,fd1ad87b,98a42acf,273a268b,c4f7493a,cc28cb9f,9794c833,153a0947,eaab549b), -S(41b21d40,5602d26c,78028eb1,acb7160,9e53fb02,7215c405,edd90586,1fbc1a8e,55480fb1,3d718aa2,59f4cf19,b7eb7638,2d07c372,c9202c87,b7037993,90f309b8), -S(3d49ee22,22bc61a0,9cabfe95,bd981686,73c2b42b,5d22698,21ec7cd9,6a488ce,2d461269,bfc6dae,48280ed,ae07ca1d,cb8d3e8,a1c9404a,971e416b,d2a5cd2d), -S(7f9812f5,30f80bab,f35a5df3,ac0c4d68,7227fa14,74ff6057,1f8faee4,32cb8c74,805fec79,b3607318,574a9308,831c4db,1fb1cde0,c0094b6f,6e19b924,35e0f118), -S(d5a33585,6c8da16a,6ebe776f,3cd08d7,e32fa2f5,c484a299,6abb9e84,60d0cd6d,fb1e3d96,f95a139a,2c968563,73813e8a,7cfe6ca2,bb97ed22,1e374337,9637668a), -S(a138a71d,854f2f76,5f8d681e,84e91b52,9940c342,8f69184c,d469edd6,43d2ce2d,ddecbce3,a48b0457,66ef7511,b041f6af,f2df22e5,51aa033a,8325faec,bd9ef061), -S(d9a0f20a,ebb51238,14e55212,4b6d723c,1f972951,446d736f,b4d20e5e,a9dc2304,fb63e167,90c817fa,40185611,ea346e18,a12fd1da,fe3266ba,c8c8dc1f,2312797), -S(31b4f50a,d3476189,62a34537,10a1a995,e9e25283,af87725d,e2767e08,4f276324,98b32741,c8e1aa6f,70655814,ba0f34df,7f2ac7d9,40604bb3,4216d8b6,9e03d07a), -S(23105202,c01e6e2,6fc5da32,5d65644c,e067817a,6b54779f,fb9f1faf,57b15a5d,2da13e2b,63b8c792,56a7b49,c44e0014,9f461967,7f2b4709,d158aa38,189f08), -S(2e9bcbd2,8fa1b69f,76193011,9ecd8f38,c88d2c7e,f051780f,cb82d587,8e5fab55,93ac2ec4,33abd509,fa71237e,9ab6a421,4d453bb,9fed86c,2bf9b727,a84de903), -S(7a560f5e,d2952cf3,342a1273,5c627eba,49eaa668,f3ea67d1,9a0bcc92,9b172ed,32d1b9e9,5e1df2de,4155bca0,bc404615,957b16b3,45568590,74a119ec,a24eb984), -S(10d8b5b9,f230099,9b15ed43,17282c23,dba62c42,6725e112,6cdaa3ba,f07564f2,3e5d4465,4ff6faf7,3d3c5a64,bf27251b,de0320c8,b8f5e7c3,f2933225,4f0832d7), -S(924850a5,d61c8491,6ae458ca,491d87ac,ca095e0c,3a37e5d,528785e9,10730e8a,6f115681,341d7598,552d8eb6,7171ddda,40594be8,5da3b9d7,7918d2d8,3316c738), -S(f36a988d,2be42bf9,d39a2b40,c2447f81,6dc2a91d,20edb89e,c8b00c97,c972d837,56ccee9d,619f4b0d,2fc0ec9,ed60ef01,1f10b55,2569dcf4,dd922917,d8912764), -S(7a9b644c,a0b45902,39849b1c,b03687be,75be77e9,b50685b6,1c9d7052,5933ab2e,ac13dd6f,d4f8cfc5,27990d16,cdc88720,4a5a14a7,f15287e2,7b5b4c9b,3ecca461), -S(e9de9ec1,40076c59,afa8264c,e4ee7209,5b88b08e,dcfc120c,9a3e9003,72542abc,284d6201,15f1f94e,54bf097f,b9407695,c62e76f0,f2138bdf,932da8cb,86a13865), -S(aa9ac192,d202973a,2074a2f3,7414ec0b,6ebecbcd,f201a6fc,e43d74e7,8544bac6,95fb5730,f524225e,a7af1ec,8e34a6b,b7300dc3,7df97888,fd0bdfd7,4986e2e5), -S(31b66efb,b2da072b,16d9b35d,5175dd6e,96b8c227,abc0f2a5,94e02f9,e693a20c,e3c18398,aaf7bc6,776f306e,23b1f001,17fdf03a,72474f2f,ed3b0d6b,70cb5baf), -S(7eda3d4e,2257ae72,abe80be1,8edf5496,3a8bea8a,a2be745e,8402734e,97d19d4,ce5e61af,de4301bd,974ea8ed,8239a368,bb8f0b57,1a6bd9fa,c3327594,c4abfad2), -S(297bab00,4b5e8c60,b27fc169,257f1217,48af6f99,65caf54f,67ce172a,e69e2b4f,eee4fd66,57a4aa8e,5eafb1a,e95e466e,976cedfa,b32f8f4d,31a820e0,cc470eef), -S(389f8ab1,2be46a3f,e5d2fd38,9598890d,cbb8d1bf,fd36dc10,8cdf8532,91e477a6,530394ba,2647c712,aecbe545,dec368b,21eaed67,a9d694e2,abfe1e83,1a2ee1ae), -S(36122688,726cf2a1,b2ac26a9,375608c7,2024a751,6543ce67,2393159a,98fdccaf,661b4134,4ed2bc7,c3596a83,b812fdbc,ca95cb74,f7b322a6,ca1b8167,aaf34666), -S(ef5f9544,a9c4148f,6a637ff4,39bff5d0,9bba2824,1d115c37,a5918070,d02f9a8,2111a85b,369cfc85,6db8941d,8af8a357,869712d3,76ac94db,55f3e0e3,e5e8770b), -S(d2c7599,c6bd388d,def00aed,b0cf74b2,b41646ff,5bb690ee,2f72ef10,1f55212b,ad863280,67ab378,1fe9c59a,bc54b06c,9420059c,6fcea9f5,f0bf563d,2f87dc8f), -S(67a35c0b,fb6a1655,23740a0f,23b6a8a6,854c22a4,113a665d,1c35a2ea,c83b72bd,dd5b811b,e4454aa,c7c9adea,b7368235,f3dc2bad,a6b7a2dc,99e86f97,f9d7409b), -S(6b667d3f,158c02f7,32ebedd6,552ef5d1,443df008,2e1b724c,dbaaf43b,efbd2480,c920f76c,c082ad16,d7564ff,9952fca8,3fd4e059,5e11a711,2337cadf,f5f51cb4), -S(c8cd3584,214589f5,62690e9f,71a63e17,64b0e3c8,33f26cda,8388be55,6e336296,c5d0bcd1,7b737bd1,66a2421f,8e1dfa80,64b3ede2,5ddb4ceb,cc8f9335,6ec468cc), -S(8b2f358e,b781cdb7,b8db96ec,7d42b75d,56c494ce,7561daf,b3d0ba8,360c281f,aac9391b,cbce3257,1d01e5c0,82eaf632,65628c28,77e72671,161fc2d7,21425e61), -S(55b0917d,f039f139,bda403ad,7fe1ebd8,912c0434,379ff3a0,da5996b8,bf2b2f7,f592415b,3ec3a143,c9b681b9,cf8c8139,2ed67439,ca67a162,e083cd76,27da169e), -S(c0eeaa0,81a38627,16dc09fb,f8e154bd,6e70e14f,a92168eb,93673780,a8fa76e9,9824a6b1,fd3df6fd,94ef8e7b,b1d9351e,cd3ee62a,e70a1eb9,91b56527,7c695e23), -S(fe75017c,665e766a,13b2b632,cc29e61d,9bd5755d,b9c4f065,e764d658,7204997f,157a23bf,72c25ace,ebee10d5,aca71726,6d6c4cfd,983530b0,3d47e6b4,9027d0fd), -S(bf4458c3,ba27b2c0,cde6911b,6cb61a6f,53642c6e,367f83d8,e294e3c5,2b18e13b,8d34a93e,e7f7ff98,3196cd08,c8344cd9,eaa83481,3f606e8d,9b2f6ef8,bf91ee64), -S(7254ec2a,c6ad1be8,2fd75bca,ebdce771,f4ebca92,eadc0bbf,3c5146db,a8d3760d,6302fe68,4243ed5a,887eb664,46f709c8,e60a6db9,ed062c33,1fc556e6,6f87cd0c), -S(4eae1e2e,b75b8cc5,73688f02,bfd5af22,ca928244,6dc8af5b,9dcf1118,f37ea23a,2a98f93a,613b9b1f,b3725d62,60510ce0,e718d07c,f913fda5,3b4f8b28,ddca064f), -S(b929111b,4b6b6caf,184238e0,82fd9a3e,8b9893c6,ff80a091,8b8e2b22,da6e0d2a,5a207daa,f75abd10,142948a2,cd2e806b,23322e1b,1f52b739,a9c7ab26,2f44e91), -S(6c57b3ba,18fabea3,25dd2711,52e5d857,a2853fdd,5f73db49,cc2e1c25,c98caa91,5a3fed55,397696c2,a0e98573,a30375a3,1b59b343,35c77918,3908ba58,4bb96a76), -S(607ff89f,3c3e3635,a6b83591,546594c2,a20de4b2,e59a01f2,696a9d25,caa0b1ab,47f4a3bc,ec375b6f,2510df4,7ca3d932,524e7c9b,656beb5c,65603c9b,1dbc8a3c), -S(a5f8ae36,a163ee23,d9c2744f,1f32de1,25744a64,f0e21009,445f08a3,9dd8aabf,274fc698,60f62f3,cadab3cd,23086876,31dcc845,43c98f65,b826ba0c,5b27352), -S(bdfc9b7b,ea97cfa7,4e97a822,fb6d8dd9,cdd2784,186f01b2,40db0851,95e1a07f,b02f7e83,56b72dda,81e38cf3,d5cf071b,e3c4c595,118c1cf4,61f01b1d,fb678090), -S(386bc7b,42591be5,41547b61,f0c96e13,6b168ef1,338f0f3c,ca2e59bf,e4f902c8,aaaccc7c,37655f05,1e0bb44e,396b2512,68bb806b,1e1ae4ee,598ab2c0,7b920f17), -S(14b9ba9a,c5eed3ee,9f4365dd,56e703a,2bc35d0d,af288bd8,1b9ceb03,82444a69,53d17e83,d76141e5,81c03eb,367076fe,a831a4c3,3a756cba,e564c851,e71c9a84), -S(e8b86b8e,f0424769,d0a6abd6,f0090030,7e851f7b,11a31012,b404e4e4,c062b1ee,f829b4e,bd2a0a55,253c7fce,73b27cce,9e31acd,fd8345f0,b973143c,25ef7900), -S(ed4cf2fa,b4108d10,c07630e8,333fdeec,af062396,eee23aee,e06365dd,ae880631,8eff37c6,5480bc59,6271ef5b,41743d9f,89a4685d,d497bdc0,8f6a11a3,56d07535), -S(6ccfba61,23d3296e,acc2f6ac,ed746ea3,6c7ce287,6e758fe9,b38603f2,3a1ed8fd,86ad0ff9,ee5d758a,2c2736ce,af4b2d50,a23c60d7,d952409a,9bb0c836,34dcf7c3), -S(4f3dad6f,4f718586,f2ce5239,b7ff5f05,ca384f7,a3171edc,6b11103,55a015b2,20858d8d,ef722f1,3a6e11d0,7d0a1db6,257496c5,e1f64d4,182592e5,f57334db), -S(ebe62fea,9af5d236,30dccf98,cb1eb472,38dc964e,5a145831,fd7b65d7,6b55833a,f828d7a,d18cab39,1af532ed,33cb2ae4,3b677836,b95bc3a5,2807d5a7,7df2eb86), -S(f4608ee8,a9ff5e52,15fd6257,43e58f5,af5ee536,9bf8e5fe,9bb8d371,e40e86bc,44dbb6aa,c7bb3a3b,fdea778a,7a6ce04c,dfe22a5a,c054951,2a52ac0a,499a5962), -S(63be7855,faa99716,cd77c389,5b2eb8d6,ae5d29eb,f64916cc,f7eaec1b,6f81ae30,b1463e0a,44d15252,21670fd8,4a1ed48,24b6effe,f6820787,ebc76cac,68db082d), -S(17306e73,c5487073,30f41a4e,e94370ef,36c07686,c55ce03d,ab6cb6fa,ef1ae2b5,b3f971de,6e09f1a8,7b083dd6,44c5edd2,a67449a4,520dfd5a,6742630a,8fb258f4), -S(81dc632,ba371e74,18cb0986,8a3e11fb,738f7857,9210bc06,cd0f9e73,4c91a064,cac8a551,b5ce80dc,2e5b400a,f10e209d,9b1864a8,ebf554ec,f36056e9,3b99b69f), -S(6ec14358,b2734ab7,3059643b,c60dab0e,d8d46c41,5ca1815b,cc215408,19b71e71,3f6c7c4b,24cd34d0,aa9cec16,cc17e321,76e2c0b3,24bef53e,9b6f3dc6,a4f4d617), -S(dc7cb981,dd03dcbf,66e63e85,158aabeb,db7e2aa2,c4a04db8,e88e8628,28000afc,d187b91b,be3dc2bc,44f29d22,e2a5611,6c9ddd2e,6a946077,deff44df,6109bc4f), -S(8a49a003,8dd13eaf,7223a2d5,50503fb0,ce0f5c2f,a7a03d5d,5ce03517,803899c4,47e6b637,1876be40,dc5b64d4,4bc5fb89,966c49c6,2d4f85b7,c7867ff3,1819f8de), -S(b252b5d3,a75c18d3,79ea1959,67559d02,8b8ab87f,c4c5bcd,842e5de,8e2c406c,eec6b95,c2d5af38,84ca69d4,2134d318,646774cc,4d05f78c,7978e8f0,80072b54), -S(6c30393f,d1f285d0,37f412af,38411133,c1bd1db0,6bef205f,12fa94a,4eb35412,b8c88541,acc9c862,c0186985,cf58419d,1c24905b,1d1abbf9,2b59a381,829fced3), -S(aa8b25e6,583d6898,6ff108a9,a4be30d,5a5149c4,45387abd,e9c1cd74,f3246ccd,1c51efb9,e6225d4f,b7b67bf,1b12de21,718fc945,d18a1679,f5ff6ff9,94d158d4), -S(28b46490,768800c0,4c94fd8d,8ef8c29d,fd66fe24,f379cfeb,a0a9b9e1,53acb33c,7e348f08,308e1ddc,6ffc48f,8e8a137e,785a0aff,fff18285,bc5b7bf3,54ca8253), -S(54b0ae43,66382f3e,83a01082,7e08e596,de37fa5,8c012e90,20a24347,ca1eb5dc,facb37df,f0bc59ba,72260606,d8e94f7e,3f71f600,78f6854f,2fdafffb,cac30332), -S(f8f03b0e,b981e371,a0994d64,6ed73e5e,a36d74e,7a349861,20e25d71,7f43c6b,642c63b8,96d9e995,32dd3403,40f91e0b,35f5d990,f6cbb768,253251e0,d7965737), -S(9c1be533,26c1a43c,f0fc5e13,83627414,89b4df8f,71224d24,6bc07c1b,f22c89d7,4d420abd,af53f191,f1e6622e,bd51e638,9e2cb2b6,a7c51885,f21937e7,3de7e73a), -S(c9b65328,864d0371,86b146d8,fc208126,dac6bea8,31778af6,e944f338,3c72553a,db91182a,b8a8ca07,3e2fae97,41cd81d8,d17c8776,9f2c0492,2b76ee93,c42af5a0), -S(7d945104,a4ebd202,dbd4be75,1cd14d8a,e07700ab,804de7f5,1cf6d254,bbb9489c,77231839,b8d9e627,ef6ed20c,e88146ad,7addbc91,f1522399,da31b84e,7b21a033), -S(2b307a7b,99ad1892,cda61d2a,10c1d972,b5855905,a64309d0,6397732b,c98ab549,8c38783d,51162a87,8e84554f,9b6d106e,e3064b89,3d368341,f96faefe,9a0ceafa), -S(2e7c5d29,c0393ab9,7b93a628,8d6b1da1,d212687,5d45c961,317665f9,9db55ed0,58b9c7f5,19ba5e3b,5d988b51,d50545a8,9a74bf20,1cbf0cb3,64936a06,7c8110e1), -S(accc9c09,4ddabe8f,81433d11,852f2583,85dc0463,9618ea1c,b06fe50,68358940,80ce4a4e,9ae09021,b8945aa9,1e4401f6,aadbdcce,421f6f32,ce7f1317,508cb799), -S(a67ecfd4,3735a152,4908375d,d21bdbf4,824be481,a8ff6201,8145c624,c5cf74db,e993c3f8,5aed69a0,f9b44ffb,80b5156c,33f809c5,e9efef1c,fbeb7b25,c6152911), -S(42f5d252,3d508a01,e7177947,29eee1a,fb7be04c,90539d9e,afe32638,b252e158,7194bfeb,f9ec8e1f,5039d582,ed7d28c1,99d5b07f,bde10b1e,e3b4bb64,148b5119), -S(15bc89ec,5d3b2889,d26e77c1,33eb832f,bded1d29,ce975905,d9355b2f,d99ea1ce,4e0d28ca,7aa69933,6f41e3bc,57a9639,81e2b92d,7b80794d,4787251b,f7fdb0d6), -S(7d68bf90,45c79869,5a8ef33e,f7fc4386,5ac90c37,8d3beebf,6ba3973f,e9d8e507,d14998be,f5bab5fe,fb94ebf6,9c0bf133,a6606b43,f621c861,ca1cbbb3,ae3fccaf), -S(82541ac5,9196f73c,99f9ee01,ef266c5e,908e91b8,b341e052,ae2576eb,17b90025,29eb3c8b,8ef826a5,6565c9ef,c2b2e47b,94e12736,131d1e0d,5b235d0c,169c2934), -S(242399a8,9c5a056e,8073a5ee,45475787,b31ff7e5,3d451f2a,d0437580,a479239a,19d5ce74,8c9a4a09,606e7c0b,6b486098,b743d018,c45e5e5d,8f39a966,fece6ae8), -S(cae84567,8cb2b2a8,de8040d4,3b32e0c6,d42dc902,3db4aa,273d24d7,17a85e7b,edca07ac,15d81467,81185e1c,4829951c,2569fa15,3b7e7ddd,22b58ad6,3b736094), -S(5c3711c7,e676ef0c,f889ce6f,57d9f92c,1cd91023,2b6fa410,75fe70a7,ce4b3db3,9b5e75c4,eef0358e,6732b7ad,56797ce7,82a21fb,d13aede0,d563638e,eaf62eab), -S(bade63a7,a4a443d,26d58900,bec36c28,940f4b32,fce20afc,2adf307c,3ef9d71,3c801bee,78daef8b,5cdcd5c6,bd0e63cd,712c2dc2,8e34cfc9,e01beec,b198d687), -S(cff82bbf,2e6412f8,18af5ae6,f9947aef,5d89eb32,cd8e9961,848f75f9,f9e4aaee,c0624130,346ae6ac,e5e76b6a,a2d836f,bb2f07e3,1467b8b1,76af0345,d8f5a137), -S(b3e4bcf9,f9e80edc,c4249cd4,58794fd3,921ac31f,a5f72c7b,e6f7dbfa,29f5c7d8,c045724b,8630771e,2772cdc2,53b2842e,1ec994eb,52296f3,6e2061b8,b32b9d3a), -S(24c22e2e,55f24320,65e91ef3,503bc571,c5290bab,ff95329e,17644e6b,8ef22386,2f91c5f5,6184c519,6f945739,4f101034,fb5fb146,ea61e009,39641a9e,d8178890), -S(29de67d7,edfddf52,6346fbdb,62e87e58,a0ffe4f4,7ca14a47,426238a5,3a3e2188,69dda846,e0620850,ae6d3fb7,1e6b9f00,814a0a59,ec7e94e5,e412a57d,ea4b02b0), -S(c8377575,d34b474c,de02b73e,5cce9eb0,c80c26c1,a925f090,d6b6804e,accfb653,306f4844,da7b237,38adcfc0,3ae9ac48,206cdc73,7c97eb11,c48c7951,52a9cfc4), -S(bc1c0c6b,b6a169c4,10ad87f4,d1f6b25,3313637,8d766bae,ee9401fd,b6895515,7d794eb0,81d9476d,c4d3cf0b,21b99537,9446a6ad,788f0f94,8acbba71,b20df5b0), -S(8b49586f,e4b4f33a,82ddfa9e,e83b7f94,177c1f39,30707f20,95a3d841,bebe44b1,42fe0fa6,14cc26a0,d2608c6a,31fdb1dd,993aa33f,6d32bdaa,1f9715a7,3e11340a), -S(fc52e593,28af4bb2,ae6abd18,8ce99b49,d8cb823b,7c6418fd,8a5f9757,44ebac16,f130072,79a1eeef,5483bb81,2ceb9090,35fd5df1,b757fbe2,679e2d1d,16d5a5c6), -S(43fcee45,79e58f65,d25edfd,f429d89a,f8e7364e,c0f2358b,83772ac4,27ccf626,907821bb,e43827ab,c210b2f8,c984d6c5,def4ee2,5761a9f7,90049477,874ef309), -S(2634e802,fe58e3a,62b9105e,5e37d8a6,f530831d,d4bba691,a6753df2,1482fba4,5d9b9de8,ab3f68ba,1e681048,c67274d,d1fe0cd,4e639454,a2fac6f9,5cdedca8), -S(56f19f08,a31f7d57,2bd94314,4a22245d,9ce74a11,30920573,9ca68569,76b35dd9,b453c349,678dc948,bdf804a8,4f54373f,c4891fd5,7058f1b,43296f59,b89d1fd2), -S(6f7c37a7,b3b96ea9,daae285,31763ca5,d481c1cf,42237ee7,a1ed6554,68de3aff,eafacefc,292a5d0f,b50cc875,ff7c8ff3,aa1923db,68461f1c,de04bb6f,729715a2), -S(59b44c32,ca7c1a74,ca69dbe0,c47f6199,79b997a0,df691d3a,4c7f3a76,9a543723,3ae06964,698b97de,fc3af051,9f13559e,813e7839,c893a0a9,bad75ea2,bc35e302), -S(e7acd0f0,d0560ce7,2d6cd805,d197fe6d,4948721e,b5e4c40c,c2014e78,9bb5c8cd,c95b5d74,5bb6058d,80ec04da,5135d92d,a447ea0e,9154b1d,93a5a014,ae2faaa8), -S(7ffef78a,e04da609,6754fec1,11fbe130,5fdc80d0,3e7b801c,28e23be0,40cb4e97,579c1fe7,54812978,46f2bf3a,57e1f850,ff4fdee8,8d3949d9,68e81d2b,792b39da), -S(5d068102,af4129c4,49c1e749,91ac0c15,dd2a7e29,fdca33f0,84f228bf,f19f5ec4,75f0179e,d77c3cdd,3cd1ec37,3e2d6d60,5425c215,ff009f26,66b8f7ba,77dc07ba), -S(cb90c398,7f6e05ef,ebee67e4,d9725200,eabd14a7,67c10cca,6fc546c6,ca67996d,c6a9a0cf,d18bdee9,8e054e4d,9df247dc,55ed473d,ed372138,cb21ebce,809d3a96), -S(5faaa0f9,63293ddd,83c2a841,6363cfe9,e102c0df,f4af7e81,c046540b,2fa3d653,66548b52,dd344ca0,2e0352d3,f14578a4,cdfd3a32,b410abee,683d316,61205e51), -S(35fc3454,7f04856f,3fd3ea4c,63c07a0d,bc0e6e2e,37216712,5da6347b,3c53b8ca,a4e3cb12,bc29dca7,800893c2,cddd4482,f3334d53,e215fd91,a01c0f4d,45162cb8), -S(ae1fbe74,e44c15b,263565ff,9f578ed2,39741d8,960e82bf,d8788a95,f744bfdd,d711400b,3b458a9a,75e416fd,c4d0efe4,5ba5666b,9280fb38,3d2bfdd5,83a89a15), -S(76f8768a,5ecf11e6,15671063,999ce164,73286582,c4238ac4,f8ef7e20,d1358f67,da94a126,d55ecf1f,8c899678,cbd7e53d,1171d7f0,6d72ffd3,e166374c,58b4f4d5), -S(f454c1f2,b7b447ab,dd2b0308,472a1e19,c1844e63,40225166,e5ddf571,e8f93d52,5ac5010a,1b03dfd5,baf4bb7a,943f0e16,4aa1df65,5166d021,c9db0ee6,abc3f425), -S(3366b897,99dc33d,a1f900ee,57c2c316,d6c2fc16,f71355ea,219731cc,280c0c7e,dd29b0db,9449e2c,7f80888a,783ef223,bc8cf8ed,be82f1ec,c45bbfa4,b054a77a), -S(2a73966c,9b1aa2ac,7b5b310a,bac40490,253f6cbe,29c5250a,dc57d979,f660741d,77359574,39ae6d7f,157723bd,ab2e1181,209f0f6c,fe5f4d0a,a9b0ebc5,cbed1294), -S(3885f7c6,d80f0060,1d60a213,923e2591,f055ff3c,39425d32,43302b6e,82a0cf2f,d024dd79,fb17c9f1,7db519d8,2dd4012f,f353fe5e,c81025cd,deebcb39,65ed069a), -S(ef33a6e0,f5da4ca,904aad24,5f2ada01,a77a93a9,11935aaa,68bd32b2,a6bf81a1,2ba2099c,3af09778,aeda97b,be4c4311,cd3e1636,f2244580,1a9c8ced,5ac81a52), -S(c8b25a4c,bfefb603,34300d02,585c729d,fccf541f,4942b040,c7b0c442,3f8603a3,480ac47a,674e42b3,a884dc55,be736c23,ca69e81,1af56106,efa66122,78214cf7), -S(6e0f7e4e,e4eacada,cf3862a9,8af74f97,99060f9d,73a9eab3,f3db3a77,20a945c7,4bf3222f,eccfffa5,5afee33e,9d39602e,e0ef3c67,870817a3,a9bb5b31,78469272), -S(32a987ef,6cd9c989,aa1d1fcd,5997169,2db6ba4,f4c8ca08,4b1607f1,697b202c,5c4eb708,50a58a74,5b91143d,ea849068,ab8b1b77,6fd2ec80,eef53d60,2cab45fb), -S(1299c334,60ee62bb,68847930,82ce6c49,bff80a9f,4fe33196,7b09a05,b22aa04,50ec11da,9d7a89c2,68bf0314,7b67803b,824b59c,9d496a5b,8c0d9955,31c8626e), -S(ce9f9a2,55aa6b62,a3184c2,8ea5d204,581fdb7b,1945d9db,2c245e6b,4d0b0d6c,c694fe1f,f93ae622,e5816c37,cf581f3a,4832442,d171b413,f86d4c25,ccbf0cf), -S(ad42db1,1ebf460e,f7954df5,3d7cd6e3,a7eea34,6ea8ca1,2ed4d5ce,83badabd,7c0538e8,a29f66e9,d2b3a235,9b00bc42,6809ceb5,11d476b2,38719673,a70e7b09), -S(fadae65c,500d39f0,377ced91,b0a9c469,3db78832,b31b14bd,78996dde,4b764bfd,a4b8e5b4,e398a8b9,90ddaae4,7247a975,2f2267f0,41a867e,e3b0774e,1a692ca3), -S(14e71e8b,76377b2,52b60ee3,f089d612,402ddf9d,92f2046a,cc7474db,1cf56f69,7121d880,5bea69c8,233dd120,f86b914e,cd080537,649b6cdf,74830f87,73aefc55), -S(b15e94d5,5edb91a1,9883f6c7,5bacc56f,2dd2c1e4,950e267f,c4415968,a75d7730,dbff7f2a,57d7072a,4a076dc8,a2d26233,1eff662a,ce10d24d,e3c8ab57,8251765d), -S(e343c0bd,240de1fa,f1ef780b,4922ddc5,453649c5,7a08e9cf,99f162c0,ffc12e7d,b9b65d5,3861e229,777bbb4e,85ea417f,32354b9b,8796bb47,2f6eb67a,2e3d22b6), -S(c3ce72df,4730b13b,95398abd,fa02c834,c5d20e37,9ebce9bc,b77a777c,f9fc3299,ec87a4e7,71c04584,f6dbacd,10fec1f2,c8bbbf25,9954d596,2309f0de,48ed9573), -S(fb70a931,895d44c0,e31a9dd6,bc2a1cb5,250212e0,5ed1f55f,5c668e3a,8390677,d86125a8,cbc9437c,561ec1cd,95b5190,328588be,6bf7a25a,94271547,1fee6a69), -S(b150b153,be5afb36,f6bf7b27,ec687612,265e3177,2534bc4e,8ac92607,9a3ef16d,571ee1f1,7c499be9,89b86781,229abfbb,db83272b,c7496f17,52719c2d,b0812c40), -S(2e71970b,913e3006,84eccff9,aa4c914a,22c6cff7,3bdeddd5,781f68f6,177adc4d,829fcbf6,1ff72af4,6bfe69ea,d928283d,45db7cae,b1b59252,7dc6496e,22a6ffd0), -S(d361c4dc,3df5e874,cb459096,d319957,398e2a5f,337208b8,6053315b,263ed230,5225f55d,49f2d8b,ffdc241a,b54b5a43,b3856b7a,60cde97c,5e860561,f2da2861), -S(3f30591c,d464af5e,ca79c060,7e6a8ca9,c6a2c2f2,86177290,fda65a82,522566ba,fc41d72b,f20b86e4,6be3c20b,890fe8a3,ceba4805,bfc61c7c,66532693,7de90e22), -S(2f6a706d,f5efe7b2,bf409606,5da98b97,86ceef57,36677935,c08e0b8c,b125db55,99bf95d1,b348b522,a1cbfc73,f2a4e692,1836256a,97bcee77,51ff5091,6fcaf620), -S(c8c72176,255d0e32,ce4d7caf,aa9b7467,ff49ac94,34beb017,9883b22a,4254620d,580ea490,a94a8310,cca59b41,43fd4740,40ed92bf,7eb25bef,a87cf930,a974c943), -S(a5d65fc4,9bf06fa8,6018067b,7ade5ee1,a541bc2c,bee0edc5,6a144f0,6be32808,ed70ce9e,16053764,35c0875,5cbfa6b0,d1fe923a,fc9035c2,1d26fda9,58c36ccd), -S(4a6c4b07,7c6c9dec,d7d6f98d,59eface4,ba2fc654,df7d14a6,57f108e5,d3f91d29,2d2a4b3f,1a9aa787,cb747f7d,961c4cc3,cbd62de2,ceada2e1,a71648ae,feadcea6), -S(97d610e2,8b3771a3,204235eb,faccbe5,29d1a6fd,5003d6d5,4b37cfc2,80550354,a441235b,593f0649,ba50d405,fa597b25,60c2be24,2ff43ff8,3b635327,94e67c51), -S(b9f1688f,4161e507,d8f540f9,4294a967,739231bc,a89c7d8a,c54ee365,1ab65111,363ad626,e5ff0d,7f43aadf,5228fbe9,b60efd2a,336518ae,53a0e36c,206d5d0a), -S(1b748bf2,690e8cd8,e06c5200,5a654bd6,38bc62d6,63ce1194,c4bea3e2,82f2c351,db0ce849,96bdfcea,497bc8ef,dcbd6e89,d0305b1c,4b6dac31,4e480b45,a5a9cbeb), -S(ec9d3d1b,3ac0e4e8,c01c8cbc,5d498201,1f52cb5f,dc7dd0a2,6f447457,aa9da7ab,2934e845,ee13267,b3dfbd3e,5d77cc77,214779ba,51bf7f67,ac3cb131,1000369c), -S(1b28bc0b,ac8ce96a,a3d49611,1f66c77e,b030a49b,e9ee788,d8e395ed,495c037a,ad5e12d2,bdba39cf,5efafe12,f7588e5d,c5f2bc82,c7a0ea88,217307a5,c996378f), -S(6e2929b8,1060c4ce,c6b3f071,40c8b23c,48a87efb,9765f292,13993cb2,9c046638,d68c4ec8,ffac30e0,f2642595,aee701a6,5c254247,a1397726,b0c40a77,1060a8fb), -S(122307d9,313a11c0,e411e78c,d66bd2c4,5aecfad2,3221b558,d124674d,1c66489b,f5713161,cb284025,efa004e3,a70f1374,b1ec2450,78f2252d,6c7da11a,ddb5ae11), -S(81df90ca,92efd148,9383a7d7,c69d4c4b,bcf5b781,e59834df,9ca30da7,cbfa1ed,fbe1932e,421a7a67,30e4a7c9,371ee8cc,a985fd2b,dc1cd465,769ef494,b0c8d6ad), -S(fda38e5b,f685c939,6a2a71da,b66d02b1,a1da8953,c659c880,bd201879,d275a01f,2c729bbe,39467247,601c9b48,80dc7ba6,193f8270,a742ec1,5076da82,65db9bb), -S(45aab7c3,69af7188,9986b609,e16493a7,38a255a5,d4c27a3d,96888275,54bfdce0,4a512b2f,77c0aa0,e5aa021e,2bb63904,aa7c74aa,daf424d5,da8676c,e043fcf0), -S(14b463dd,57d236da,fa835f57,6c4cf514,73180d39,efec4d18,9a9cd1e5,91df4f57,ac3bee1e,d77fb0c4,3cc852e0,90fdebb3,1bd87006,7129210c,9334beeb,896e66b5), -S(5a8fd8db,833621c,e8e21f81,e2f30db8,2a98e6e0,8eddb80d,6a2e63a3,fd7da2bb,6f6c8e76,d846f5bc,b53a88b1,349b95ed,34239991,1e552740,1e58cbb3,bf42c8e9), -S(62b727f8,6bf49290,2600e83b,5a24974e,c35444d9,92c2f083,7bc4dc53,d3ed119,d7daa7a7,b8a0d462,598be5b1,6d36aad0,c07aafe5,600e3955,81c352aa,d6135b21), -S(1cfc0220,cb0f64b7,51fc05a7,897b3840,fb2a1c33,777fedf4,7ebb4c9b,e6059ee,d3a90002,d2f8c20d,1174fcf7,8591ce07,5e2b34f8,83d634f4,7b27d5c4,3680bbfe), -S(89efac24,9b798548,2c3ada7e,c7792632,fe872f4a,b6001e7d,48605b12,cf8cecd,a5d062a0,1e40b4eb,de2e10e6,684d9b6d,2b860f65,9cb6c51,676ee74b,40e5f612), -S(cbddc8ab,e37d0494,cecb4878,cb0bad9d,da00c1e9,c0876437,3405ec56,2318afdf,53ec167f,d0f1123c,3ebb9cac,476c86d5,94762b5c,7a365153,776695a7,169f06a3), -S(d020dfcb,c5e78a1a,36e1f8e6,3530d03a,5b53e1d5,41d05a46,d4e24318,706515d,cc811700,740dfdab,752f818a,cee554e4,d7e142bc,eb5f6e77,9399e160,c7646048), -S(2430846e,6e768e57,d4776cda,448ab651,c876cb6c,aa8fce63,34cfa4b0,826a0e25,9bfdb42c,e711af1f,a0cfeaf5,8264cb52,4d4d9eb7,a9fc1328,4351e209,8818c559), -S(7d3eeede,5d8e3320,80d0dcf6,3a8c6929,4951e765,d881e0af,febaef73,bd9548af,a4b9e695,85b2921f,fd651eee,e320eeff,52df838a,17efeb60,16d5cee6,d4475ca9), -S(4bdedbab,af06488c,28fa5a7d,ebe15b63,759986bc,535b4ccf,66f28e8a,1126803a,e4ad8238,94741e42,c28b330d,16b16d40,d538d081,41f0a5c,92890934,e3c09dc2), -S(65569131,959b4da6,d2b52217,9569e44e,cd7e7ca5,515ffd71,fb4b3444,246f925a,87049181,3adc7c36,9bcb7696,f90485f3,66beaf52,9cd09e04,36d51cb1,6e84514c), -S(7df015c0,7404bd5,518ef8c0,1aa4c5e6,8773800f,fad367c5,5b10254,45e720b,6e936006,2fad0fcd,a52ae9f2,bb7e3f5,ad0ed702,50e474f8,c4e6b62b,93885bf8), -S(90eda060,55bec90f,ae0545c2,30fe67de,99da2fec,f158aff2,ff4c8a1d,419eef9a,c5a0e7fb,f8f5f20d,25f09076,6a8741e0,5e7c49c9,c6408dc1,fc02e84d,79ee165c), -S(b36d9a3c,1a6c46e2,fef6dea2,26b1bc6f,e957849d,d11170d6,25746bed,bd3d2846,3ad18694,f8c0e199,77d0a56c,161a71f2,72d9090d,96a376d4,7d6ee99b,5f3ae29f), -S(7fa2d360,27f7a698,e5e4dece,16f7f78,5878ccbc,dec5f03a,8041805a,609f01ba,2bc2c266,d8d013cc,c215e3cb,8afc5b8f,254b0656,98281044,8f946d65,8870703a), -S(fd314b51,71ddfb60,16f3dc94,859aff4,5b01e7a5,5ebb3c0c,a2ef8262,4c41fd08,28539bd3,657ce721,4f6d88b8,f8f85565,996ec40f,fdce88a6,5820a8f8,4e6271f1), -S(6e37f52b,ab64fbc4,a22cc014,b81151c2,623069a6,6c617fec,f8d32d25,38e23f9b,fe6910bb,2e2e366f,28ef13db,183bfea,924603f9,58847477,ebf816e4,33cbdd34), -S(31ee76c4,de143395,a1d99eb,98e8a579,d88b3450,69ff0b82,8335ad2d,72dda523,155d6f31,9548c9bd,62cc219b,db6f95cd,23295ab0,253e42b2,cbc34fd1,775dc0dd), -S(947c2b1d,604787c3,e30cf04,31fa2b4a,7d823c84,584feb3,5f68545b,639df62d,bc50bcbc,dc6e530c,45892e31,d71f719a,1d515060,ecb123d2,a37eb89d,45fa682a), -S(8a8349c8,46a41e93,fa097893,c4fcbd1c,7c25e3a0,afb17929,72a7a872,570e5abb,fdbfe661,fc2940e4,b8c0fee5,7245915c,7f8c9ba2,1f548bf7,d5c654c,785b94a3), -S(7733640a,13671b1e,eccf3527,3cb9ee8f,d79cd08,ea57eacc,97b39bcd,6ad669b1,7ce5c5d5,abb13079,486bc91a,ececa9d8,d0d1f84f,a5d74e57,e4727db8,833f8c05), -S(a9ec8a22,7c262bfd,f5b00b9f,1acc80fd,4f5d46f3,d24d59d6,7c2cd83,3be94a38,f0d9bb94,ff97aaf8,54b3640e,7926a99,8a731a5f,4800c573,d1279d14,5e4d422c), -S(9837810c,86ca85a5,ffcebe9b,714d4b1e,f5c0ab5b,2650e163,d62fc668,204aa566,bc477f5e,ff56a588,bc68f7dc,42644fea,532d7a25,3f84d17a,9ef7a91d,5f3113bd), -S(9020fe03,9de18af6,61b70206,5b615ee3,de3ea6eb,a8c30d9e,24d4bf13,56db96dd,3a0ac3b5,d1832113,8421bc8a,f978771c,53b98110,6c49afe5,711b4b54,f9fb8567), -S(d769695f,f6f22d11,99224b69,f66aacef,8c6cc911,e43fddf9,481b46d9,97a2ecf1,e8f2a6b5,f05be025,a84fe0a7,23ec54dd,b21c32b4,b4d5cc89,5bdd8e66,d8ecf934), -S(a7668280,48ab1e2b,e843b0db,7a9462ee,3ff0a5d6,f7c12ce9,496b302d,99a23042,42a1296,92217f3f,d7de8cb6,df48b8af,11d8d089,5c93703d,a242c7be,d8033dc3), -S(ba26a7ef,1e0b979e,3541227f,2dec3d6a,7ea6f8b,9e9b46f9,93c02b3e,fe1d9611,b0d283fb,1adccd83,be7122b8,b59e6d4b,589204b3,e96adb4c,a6e19ec0,ef1c142), -S(175ba624,70d63d4f,6a3a030d,a1515677,8e589e8d,80ba62d2,1719a906,68293971,211232fe,97508523,4d0dae11,14831009,229fb25e,51f97182,476558b8,adc218dd), -S(1fdb147b,860c3254,b4ae5513,14839573,da2d0272,be69628f,1b395a03,bc8afca1,b42d0b99,325acf05,a3564d77,55cf9c9b,3208e5ec,24e5ef12,b6180fab,8b3f4a4a), -S(986d3acf,c5cc74db,c844c28e,d91276ee,729a5588,e1f504f,1e6f96e4,a7a21607,7229d56,4a9dd4b4,79f8d8e,17951887,870a4303,53707369,aa8e8d6,deeefce7), -S(39ad0832,b18dbfe,1fde87e7,c5d3b948,75fd76,9941c2bc,d605f3d1,beb94e29,f85bea41,f0c36603,8ea8038f,874d612c,43b928b6,4116550,8878515d,fd74b6c3), -S(3a318109,745a25bb,c6e45068,ed37553f,b2591404,3a7dbfc3,9e67d1e0,24bb2f12,2cd3e0db,d2545332,e4bb3e99,8c338c8b,66fc5061,81c6595c,37804541,8c507a16), -S(617d3fd8,87b99438,6eec49af,4358e73a,bdf52dce,f26ac8a1,52be64f7,e0e8b2ae,a45b906a,45c2207,e4db008,e4fa961e,6c483c24,3c0d7fd6,b11af11,e5f8b444), -S(d1171cb7,e5a3daf4,7b7818a3,2fceb153,58c87d4b,84488cc8,1e930bc8,adc467ea,bc725547,a2d40dd,8d8ed471,1869d711,38118b5f,bd00f0e8,3e1967b4,880da3c), -S(61f610ef,de8aedf,f012a109,5e5ad596,9d06ed54,214e6f33,c69643ac,50df0ca3,405ed3cc,5ae1b566,fcd069f2,e8b67520,74700b94,689eaa7a,3fdacdf6,a798e091), -S(8caab88e,e5fa3cf3,59a8ead3,2d80a4b7,b57453fb,e90a75b5,ea9e4f0e,5ffcb7ca,8b7608f2,c7480114,d8b04bc3,7f089f8f,2075fd9b,5b4a49eb,bd0ab1c1,8ce31a9b), -S(b73ee255,bef7518c,12be7d6d,36314c8,3fcf3c7c,5b0bf2f5,3a1add92,82bf729a,716c6c00,5a82e1f8,1f493753,f4e2527b,99bfd9b9,988b5e94,f7652ffc,6c32b7f9), -S(ca72f63b,ff6ed94e,c1fc4f3,427e90bf,a16ee627,b9112358,1620c156,6f95c1,a554deaf,c8bb3a56,d809c044,49efd477,7d083da5,690ba56d,2a4e2679,71d6b0e3), -S(f861644d,d5693cb4,b4a8256,8a5297a5,595a64b9,5f9744aa,683dd91d,8d58b301,66223ae0,99284fc6,ff5bcbdf,cb0bae0e,cd954610,d4c152b8,b979b08a,c4d4adb4), -S(ffca4bc9,b9a2e17d,250d4357,14c882bb,7e837054,4bee35f8,818e696b,7a7c2c17,4c57c13a,e3d97da4,8644c47e,2cdc4d15,5f6add44,5544a853,f8e46bef,271399de), -S(c36a0163,5935ea3b,f590d4b4,656cbe2c,2e62d8db,ddec2eb9,ab867de,8d9dba5d,d9ed3116,dfe337c1,44025ab8,e607256b,f870c4bf,a885bbc7,3ece4b29,ea6122ac), -S(bfa4fbd2,c9fe8b16,9520ffec,277fdc19,cd53dced,1866d5a9,404cf89f,6141e4da,f76e0423,4fae8abd,892368eb,e48945aa,a3684136,aa5b7a0a,d85d0d07,79af3ce7), -S(fa7be3d7,db544548,45d4bd1d,43c7960,89aa1eb2,4c0f81c0,16645d77,83ed508f,b82cdfcc,4df4b465,4c95530f,d621435e,8679aee0,9918a06,131775be,8cf4e324), -S(818a90d7,5939e32a,af92c601,af9eb717,88443e57,b7759bd,9e7e2be6,238a699a,c951ef89,8127b426,1c7d6224,377fe63a,2706636c,525ee10e,30e11a85,c160b50a), -S(ede3411,d3acaa0b,650aee14,29f910d3,5ffd5684,eaba0280,8971f2f2,330e2880,8a2d5c96,ae4ce2e9,739ff957,c595591a,63a58132,10b86a62,bc4cd164,54b8bc7a)}, -{S(dd7503a2,a3e15e7,39eb9b1f,856d6e33,be4890b2,f40cfea8,1bdf516c,b942731,ca9cd04e,c3789ab4,5088b819,953e08a0,b8adb8b,b2b6f7c8,661a2d3b,83a54c77), -S(b0aafd22,9e0fb326,b5ce8cef,578803c1,da2be933,1f47b343,370c2e22,18bde7d6,570b1e28,a519d9a0,2f9d06b0,6637bd8b,6c7f7e51,5a7c541f,7263e05a,87270081), -S(6d5417c3,2d66d6e6,a2d2c599,366ab000,99cad0b7,55f8f3e5,15afc018,98b9efff,786eee97,bf1a1c9,a57de5f4,94be0a29,663b08ef,5162e971,50dc240e,59d9d489), -S(9c64eb60,9a9469ad,fec8d298,50a08f7d,d4e99710,37c9e7c3,7eab2eab,cbce5b4,60569102,1deb5b10,705231c3,e29dd6e3,b613e6c8,eb313cc,68fd581c,eab98ac3), -S(d219f302,cc6de5c9,8360c088,881465e,22fc572b,8217734c,742231b4,ee487bee,89710994,239f6120,df848623,489173e6,f337c99a,71fbc319,75e768ac,43cdf91d), -S(792810f6,6b9cf54c,ebd8ff1d,159f966a,7da61fb0,34651402,e878e5aa,2b044259,9d2d44c4,b52b24b0,7c3dd127,43fb81f1,e96991f4,53c06839,cd86a2c8,faadfc68), -S(c9913dd5,bef25d08,327d7441,b0793f4e,e3e89b5f,15cdfb3,483f8663,3644d75,e6f5b61c,6beb820c,64beb375,4d80f3f2,6e7aeba1,f4a490d2,e6dda2c,b3131e24), -S(a836402d,582230fc,bc8c944f,18d5391c,3c934e1e,ae1a5f6,2cd6ce3f,b454e6d4,dd8417ac,a9ea2e51,13043d8d,10c8be13,e48a17da,e1d78f84,da4ca58f,d07221c7), -S(46b82270,4a808581,f9dd6d4a,ac7cf765,90dc3308,dd54a6f6,3d4c49d7,f5652310,1e8ffdc8,a786fb63,4a56eecb,ed370af5,9d6300b2,cd05c1b,5bf28d4d,69e64c9f), -S(eb25a657,ff10f29d,4a0b336d,feb63364,774f28ff,8c6eea04,25df2e41,1cc8c49b,6547a11c,9cceffee,5d43a330,69034c93,94777b74,63c1f774,167423c3,2b53bba9), -S(d1548f7d,b928ce6,86e8e71,c0080731,3a1cea63,838c013d,5d52fda0,17af443,b15384ba,3d62a403,920b6936,54c30a87,7cd359a8,2b63f037,64ac24d7,2a8fa367), -S(ddb36d9f,c6c6c026,6c79f2c1,50eebf46,36737eca,d0091321,c1b293b,52837cd7,8e0cf327,fb2f9548,4905200d,1111da22,aec01189,c8db56b4,6680c03f,4d938f29), -S(46737d55,d4b1c924,c58e100c,161206f5,84e01948,22853e82,e641825f,4eb1023f,4374a770,809a9424,12e75c89,75b98345,48e6579c,8b4b1314,29cec398,6b2eb00b), -S(35772697,7312b547,60f2db9f,443d8165,1cb1fc26,dd977dae,3c659685,7330d3f6,813075b9,d73fd95b,78a9e1d8,a9f24595,98b127cb,90c942a0,8b451e71,e40ba38a), -S(17bca82e,46ab960c,193dab14,7eacf706,4326205e,7fe4dd6d,464d359f,6a0f4229,b882798a,dc357f06,4a98dc47,2eb3708e,26cf45ef,48f28c9d,11456658,1e49c7fd), -S(e22d5891,b992aba4,ef31503d,bb64d447,1cbb4013,86f69d10,37770b8,7c04f855,af5fc7cc,3e92b04b,3b61297e,d7c66dd4,47b81728,1f455c43,bbfb69dc,91396744), -S(3960875a,16521b2c,89c87efa,c0ef7a5c,7a1332b5,a84c34f4,4496c57c,d5c9af0f,859ec9e1,f08de5c6,2fad60b7,18533a9,d18cdc9d,91174ef2,c3eb0653,f6c3e5b6), -S(96e92234,e193254f,5629fd37,aef039e1,1457988,7b18ca19,a578bbe,3a23826f,afc02da1,3693bd69,738f991d,9d2e9b96,afb01e67,b05857d2,3054a7a8,85d55f44), -S(f032903e,40e7c8fe,fbf79c7e,a4eec837,6193c3eb,cc919ef4,ec867909,42c8188c,1406b7a3,f9a284aa,c0d48b95,47d0f934,2b6d3c43,4c6b78f5,4b1d9bf2,ff7a14a1), -S(59f8f5e7,1bbd9631,ec5e86ee,e78dc60e,71c74037,db8e32f,4932ea11,9a153973,7b72a4ae,87d78ccd,3758f961,12cd4287,d18e4cee,7abe996,d51f3276,aa28a3c0), -S(8f4c4baf,36df38ed,da5cab7a,90b5d3cd,fb7a6b85,bb000440,35d88928,27b811f4,fab6a3ae,f7d0d7e8,a45367d0,b1c9c4bc,9b6ecd7a,f6739401,8659560c,8d1e6d8f), -S(f19b8fe6,a84b2993,a1af87e4,313208e0,ba301270,3aec1a52,8ea60bb9,eb97333f,d8610a62,ee6014e8,b0eec123,c6b68ae4,62b0be9f,c79788ff,631f7a38,f134a74d), -S(a382dad7,66c4cbe3,336f2a2b,a11044c,31f5de9,6a1fa90d,479baed9,8ea9eac2,9f7b4cb8,c17383dc,ae9e8e71,81cc9f77,6823626a,f8da9b87,e5773edc,9fbb8a67), -S(337af005,48b956ee,58867d93,d230b0f7,313229de,4adcab17,55a24f02,c3c86210,41b3267a,48e288f6,42ed4fa,357a9d84,f77b1e5c,67a6b20,8e8596aa,40ff3cc6), -S(48e35721,f03fcee6,e50f875c,57fda488,75c6b2e,1e0f71b7,da97866a,de121d49,65070589,1a1e0a5e,d2df20c1,bcaf00f3,11b08c8c,a161e1c,7db290f0,a24c1a3b), -S(2db6b295,1a20b609,819d9e52,7d7bbfa8,d47a11a1,33a54de1,49e2994a,ed25d800,d16c6aa7,313723b8,e9c49f8d,66b0e9b2,6ce3ae04,5f1da4f1,355c02c2,4c1685fc), -S(2024d4ea,eb5c75a5,d26263e7,7803fcc,77fbe3bf,ab6106d6,ba134f6a,18e2794d,57bd2c8a,5c3b8289,d4d39930,cf2092a3,2e9b87b8,f8155eeb,65ae9b88,60b92159), -S(3a7aba1b,95085b3,89b07280,219011db,10fad2eb,c003f17f,2576f166,4c0f733f,2263ef94,65065e4b,36ecd1d6,e77fc8ee,2054103a,28434207,e02669eb,df00e444), -S(d476e308,a3456bfb,3ea08fdc,357addb0,3b5f3102,248e63aa,20b8af78,e5e27566,827fb49f,ac326d69,364a3ed5,f87e3e22,297d752a,8c77d399,7c6300d4,3358c19f), -S(b98a3bcb,5ef6e7d9,c7bb8fac,6d5de4d8,c9770950,994dddfd,c0e5567c,bcbfc6aa,c2e6c22e,ec6e855b,890bfd97,b916ae1b,d7f38a9d,51f1ddd7,fb11c44a,5ec058ce), -S(95af1e4d,e478a281,46edbe66,972c1672,815a12f4,eb975fe0,ecf7f988,d03bdf8a,9b5a9c50,c9616d82,98f43a56,62ed85ac,bae447fe,60985627,b6df1ba3,7600fbdb), -S(eaa4b025,2304fdde,1708446,df75b2b3,2ba9754b,ad68af41,515f5228,91a2ca3e,7d04324f,2a522df4,c8686ccf,52086869,8e892ec6,aec91b83,b6e460d3,b0e39d23), -S(113a2818,f9099722,36d3eaaa,14d52f54,27592ab,b924dc45,d6ccf5b4,a02094ef,8fe91af0,62011fa8,cd0f6ede,c5467c8f,d8bc8043,f9760d9d,14c31fe1,1fea3f1), -S(bf5b27b,81d5bc7,ec597a53,accae88b,bed993a9,fcb78a96,d0fdb750,66f90baa,7d7f5fc8,7c6766d9,78a359cc,5a486844,e62003fc,7756ad34,3b5966ae,cd9d7bde), -S(42d53197,4663cd32,c80d71d8,15d3655f,f4e8911e,971a53f,9ba1758e,79fcae1d,87daf2ec,3cbccd53,84bcc89b,9668954,a73283fb,5d5608a8,5746ff2,de26a528), -S(946a933,98ac78bd,a3f92424,f6bb6383,ef7ce19b,2912457d,b26e7654,f25012ff,ca7d7457,b0a52c33,4656671e,c6e68e70,b283df8f,7a033a21,7f013cb8,8259df8c), -S(1c53769,28cabbe6,3b6e52e9,a7577c54,53cf4071,e1050257,6e7f4609,763d1285,95340099,49a53bd6,44045cfe,6c17053b,7cef08e2,6cbc1975,c2fb203f,7810a4b0), -S(c31bab3a,c9cddb5e,91a69aa6,95545d25,5550a6cb,ed8d55d8,faf94523,4edfc242,2786d686,771c3e6f,a04ecb04,cab881fb,bebe70af,1c83f7fa,1fa2922b,2dc62e0), -S(81df0d06,1f3519d3,3e8f7743,8b917498,6ddcb6d8,cdeb5bca,2ba03fc,6d1b2bf5,183ade12,f68baa5a,c702b5d,2ada2794,bd038524,63796f7e,c885b5fa,96dd92b), -S(3825dea5,f42fc36e,37367606,1d8c4589,48aa11a5,12449590,22cf258,acc068d8,b6286350,2fa61c64,9ed1f3f,d64cdf9c,bb882d2e,82723e11,73628333,4c2354e9), -S(9aed85ef,5bd25a21,46007433,b1131528,6510ab0d,7918224a,dcb81585,ebece06,73e1712f,d6b3d56c,53bda6fd,acdee776,aa87f994,71c8cf28,17c05fc6,e5512bf5), -S(3b4c21f6,c0a815f5,80a75488,5b02087c,eee77de2,704b1661,d2c42329,169ae892,997bc30b,1e5ec3eb,df3076bd,d7ff8906,322c229f,fff17b5f,51316dd0,4778f062), -S(bbebedba,d7fe330c,1e50de77,62dafe8b,70cc8cf5,11c44dcb,1cdd55ba,82ed870e,27f2dd33,573ea340,355f9a9c,6cffe63e,44108290,f27fde3e,7c934d52,febe1af0), -S(babf0cd8,58f49844,5902a704,da20c759,881df7a7,27842f98,f3ace994,1937a7e,8b05b19a,62a9b997,4b0a9668,d598c929,c4ec6493,6015fdde,c134720e,fcb32081), -S(a420c65b,33426f3,674a5859,cc16d583,96b3c325,22fd2dbd,3ac9e179,1e5bc48d,695d3557,787ffb5d,8e69293a,afa250f4,6a0bbdbf,7fae0540,94f43885,d92d2544), -S(a31dd94f,9fd72006,abb783f4,c9c8801e,400c4d3c,f4f81906,d853fccf,e3c1cf77,8b49b9b2,8c513ddc,6f31577f,5a576ca9,bcfad648,fe0556fb,30aa3dc8,cf4c9ee4), -S(d4ea9865,929456a9,20c3a461,c3931efc,e73479f2,e63ae5ea,6e1fc227,1bbe518,f214c3f3,844daf1e,8aafcab0,89e1ddaf,6621ab0,975346a1,b04642b0,9a5be061), -S(995c4191,bb5b5831,e32ff6e,6be060d1,339bc41,50af35f8,e69b03c1,3ff55505,a4c0262b,d585aa19,26009953,34f83f21,951dc3c1,a5b9cc12,c7250fd0,c8619259), -S(77ea55e7,8d08e3b2,233db269,37d1259c,ce4acae,5989d056,d4bb4bbf,a7ea1cfa,637a160b,ce9307b5,a21985f6,6bd9c4c1,8f0a0679,3dc6c5d6,d491a2d,ea034f50), -S(f42d8da4,9862d140,30c9e4a0,5349a650,166d7904,97ff4a6e,403908b9,d95293ef,c1df830a,2e091a6c,e65f4443,f7c5d51,86838e07,dd90b0ee,f90b0134,b181b30e), -S(10e6c84a,53be364e,92542b00,2e5303ab,d93507e0,5e3699bf,aa865838,8df504f5,4f191ec3,974d9a23,28443d0b,a6ad8ad3,4a04e06c,608d15cf,d3b50d54,70d2fdb9), -S(2f27eea3,7a95ed63,f1a1c228,4ce37d72,a8e116cd,b5555f10,52307156,818b7162,ffdbcfd6,4b71c526,5c19b6dd,4fe9f0fa,e993bd10,a727384a,84807308,7588fd8a), -S(4ca6d0ee,294e7961,b9716d8,3d9065fd,a362dd0b,1ee95784,3e33c27b,464cbef9,6e37c568,801d5be3,7bc240f5,908229ba,bf7f44d3,26591bdf,58ddb69b,742b417f), -S(17e3a714,cdfa9919,b3a2ab6b,faca1a98,819258de,53877067,84bcbaf0,8e38e807,4422fc06,1df9484,7163efe9,f6a75626,f1cb4db1,dc563dc6,6250850,99a2d1cf), -S(86db66f7,2e0897f7,5a78295,45ed56f7,f94dabd6,c3ca13fd,4b715e78,24778889,116731bf,d85bc78b,277b09f0,5e341374,7ebf0977,587ea430,7e4fb0e4,b3c1d864), -S(5a67a2dd,e738eade,230815c1,cc2e259d,9c0e750b,1d42ee3,c4636368,d2add861,9c5b305c,d9dc561a,ef396711,faa7b196,b149f7fd,48c7f608,13d96ab6,1c23813), -S(bc5e682a,cb10eafc,319401a1,deaa5a8f,97d8b1d0,d65b847f,fa396df6,5f2d3cd9,bff7f649,3404076b,1c978bc,22b56cf,de56a233,414bf112,39ef0c2b,ba8c1c4f), -S(55e25010,b08cc417,3062a4a8,20b00001,fe53546d,bbcd0c86,ca21c3cb,22291201,6ba72697,9becfa8d,53fcb128,f3193f8f,74a99a7d,82aab685,cfa1fbac,8f1d71cd), -S(4b53215d,7c5d43f2,ce8e109d,c98d2f5d,af1ba4f2,7a713d04,22253cbf,c9dd1f4,2e96d,bc79001b,64a12093,67c36c77,dc8cc188,b9f632d1,56bd53a0,462bba31), -S(8d71406c,8eba2f08,efe9a88b,72faee9a,e149c857,d625b710,c443219f,c2e24997,68aad2e1,dad539d9,dcfd641f,be7c1ea9,d4239e2,e881e6af,57260011,bcd0d61d), -S(443ff7d1,5f92816a,7e64e005,f0fed100,efad65eb,cfdd7e81,a6d4df72,a2a91932,3be7e0e8,bfbeeea0,e15f1a4d,cd9b1f7d,85d519a8,1215c2e5,319db187,5d3c5c31), -S(a3081493,6d7359a0,bd8b0adb,78b79ec8,388f783a,f02b2759,318b0178,870ef633,5d89f521,e1029655,432a688,aceb1beb,ba824618,f9eae95e,ee0f56da,21364207), -S(33eb575a,aa3d6ecf,eba5869d,b7eb1340,bde18656,3ff4c32e,bc32793b,4bf50129,296dc28b,b33aa01,684894d4,d2766575,d420b02d,6cb23152,79b370bb,8836181f), -S(4c09fb9d,a61435e7,9e2f9faa,37cad82e,ca906e27,f5d17d,da991e54,e7650e12,1c3e8af,ff50589e,ee448778,8157fa7b,570a9063,d76e6eee,df6b8d98,140c3322), -S(8c0f258c,9162cdcf,9d60168f,bd98b995,8fe2c59b,fe334b76,2b05d397,8ca4cb29,8f04e391,d6abd5b3,1c3de519,2266acfc,c3010617,24a204f3,f209aa49,96ecfc54), -S(e7e0ec2c,d18151bb,7d46c17d,b34b36d9,c38c0e78,4d6c4a53,5661ff13,7de3ea5e,b569bbb6,35f01a5e,c7e3011a,95fcd613,357328b0,f589c77c,a49550cd,63ed698a), -S(33466e36,f172c0c9,41af8635,80f7393a,21111ca9,9962be43,c96aa29c,6418d949,e434328b,8b94157d,72f0329e,7d8497c2,a189a23b,8b663e5c,c6a6431,3d9cb1d2), -S(74546f84,2d5f2f0d,56c6de7c,e25dad70,47664eff,8b53139c,2101b450,ffb7e83e,72ade537,f344465b,349412b8,c5a52396,b811b3c8,64b693c6,995b168a,3d52a146), -S(2a057c20,49eb78fd,6b1e101f,f1ad93ec,237c31d3,b9eb5a61,cfb9707c,10aa3fdf,12f3ed71,9ef62004,29e31f76,50d42a26,3ffec21f,18618ab7,a1978341,34e628f2), -S(6ef7e589,77b46681,18725285,d6a80278,af326e69,37a1a2ea,c38db58,5dfdf391,7b7f2f2a,61a36fa9,92c25c9,de3c375f,1e653426,21657b1a,46e73afe,185293c6), -S(bb07cd89,749683c3,d0d1822f,b2044a0d,89295a1c,489a083a,d4e0d686,5fdda7e2,93217977,cd636dd2,5dc61a32,278701db,488d4b0b,bca43fda,5f616ed1,bc853e67), -S(86a512e6,6aeb62b4,a3f0e3ff,b3ab705d,55da48e8,5c83fcca,8bae1ed2,c7c310,69efee26,59130cad,c307d137,348dc40,5e797bc3,c0e08888,19381382,7c9b70a8), -S(2e98a430,bcbc702e,d038c769,2d0a18a2,9e68ce5a,33297dc4,d0c6b344,55141fc0,ea01fe68,7ef121ec,d612d3c7,95bc2b4e,aa8a79de,a7a6421d,6d0ca841,4364a8c6), -S(1e94d53d,8f2efb80,fd5f36d6,48517bf,a81f5eea,6e6cc95b,125c0f4b,7f6b544a,4c6da236,bdf33222,7cabe303,ebb08be,5d72cc94,ffe09f83,7f89050c,250055cf), -S(8436f6c,1c597134,be20a252,3808f764,a77cc015,92e2c0fd,d99af978,2ef98f0c,5d088601,2a449b15,e7ca98cc,b12c14d5,e56dcc11,21eab5ce,8fd64442,735202a8), -S(dd438a23,a4ba1fa5,8691429d,7a20119f,26b998ad,bb041770,4fbb7603,7fc939e5,c371b95e,1d2db347,89ae43cb,ad439c87,c75d9cad,370dab9e,771ddb8f,f50fee46), -S(a50a202d,dcf0fa6f,270ed4b4,47ee2d09,55aa5ff3,50bde518,b5365807,5e921a1a,13357652,4cc6d018,e3cbae93,d87adf36,15a518ca,9421d847,92b9b6a8,fa45b5e3), -S(7dda8de4,b278bfd5,3b7d4573,1c3df0d3,a32c8459,37dbfd55,6176c034,359b6054,249585e6,a11e174,ba72b6ea,cf02bc58,f53ad9ea,131f22b3,f273a38b,2ea12e71), -S(8c34d5b1,77080808,84081f8c,f36340a6,2526ad47,8402301f,248cab43,c59b510,d3370606,3ac61796,a8b55004,64e458c6,36c6fae0,ac4fc255,b99e03a7,fd39679b), -S(f2af02db,a23f80fb,26dae144,8c01030b,7dd11c7e,e670731b,5a3c8d43,cf70b3eb,3b91daa6,e360244c,ecd16f73,ea6b2ec0,e2bf1af1,1fee0530,7d031861,6df7cd6a), -S(f52e29a5,fc161198,8ab924dd,300a2063,eef50892,c8aab719,989a7c57,c61b5472,c8d317a1,e4bd73e,1520b519,bf5e99b9,537d4014,11554768,ce1c8d59,dfb6485d), -S(ec3bfc26,168616da,7521601b,8213cac6,ff0525f0,bf1e9480,bf74ca36,5043aa50,b85fb266,cdc767a9,9256a2f8,fe3d5f67,13c46dcf,db0e5668,c51e57d9,e40c68c1), -S(2606e785,bb3bb8e0,e9509d6d,d3f13edf,cb945c27,4b170b8e,f0a1049e,c6324d,1eec7f74,981f1afe,b519e261,a9459140,fac8c0f6,798c4bb0,7402b03f,a9f9c4d7), -S(643cc5fe,b10472c1,b7767be3,3d089e97,6e1dae65,766f64b2,13ca7308,fb1a859,4001bf5f,5b1f1152,41c0a5d7,7c402f58,81466079,7217151d,ca52167b,98cfbc6), -S(7af91d3e,31685c25,e4665b8c,60857fb1,a9eebfbc,b119995,bb30886d,49fec506,ef793e78,d32b7dca,50fd2281,76e9deda,fba1ae5c,51012a9a,5e0f11f9,efa36d02), -S(f92595bb,ebf4e875,5a4c090f,cc7479ec,e36df57e,54d02703,77492a59,695dff86,3d693004,acd31ed3,edc6b849,f0276908,3b62f97b,ffe2ce1c,f030bab7,8edf42c), -S(56d8be78,ba1b90f2,f1e2bdc6,98676605,84ef5cf2,42061f99,a372b8af,3bb81492,37346441,7138d5fc,827ed55f,7342e423,b3413d18,a9450670,bd9f7639,e3f7d1cf), -S(5e72a946,f62a82d7,e1a6bdce,d4563e4d,d11ade3,630c48e,e7dde8f,4431cef9,f963609b,37e6e3a7,647bf3bf,370016d8,e6db7c3,18194eac,b8abb926,1f4a6483), -S(915889dd,b578d98d,b96c9d55,e6d10bd2,85448210,19ad5652,5ac888a6,11ebd12c,fc5c61d2,2b2a6235,51af62ea,56e53daa,a4ba1d57,e1124834,e0c3e547,da8a00fb), -S(eb8dbbb4,b11a53ca,4b00a8f0,6bc5d957,9659ed80,df9556e2,99d77d80,1372996c,3f7d9ccf,b1229e71,fd5d3193,4af913d5,e645050a,91095df7,e9703fc7,5552129), -S(11d9d597,213183c3,cb33f43a,36289f32,94fab62,eb073b5d,9ad2b71e,a1a4475f,80f85384,db3424f3,707412a3,6bdf4e67,4adcfc0,4b2e3957,f9ea2e46,416d85c9), -S(4bb5ac37,b29cde8c,a1c39e5d,b3d75401,26617089,c82b5aff,c61f8122,1e5fa6b9,6345048b,ffa2f89a,4e008daf,91784b02,5bddf7ba,3fbd5357,ec1f8c04,f8f9ae5), -S(542f585d,616db634,689e86e0,bfb7b3f6,58fbd6fb,83d0070c,bb13e85e,17e1f793,8858748d,b65083e,9946ba84,3c842492,475e508d,4bf5bb08,6259e5cf,b47757fb), -S(518c6d50,6d72aaa0,ada7bceb,11e1bda,bc0cff3b,2008651,fc50eb54,cf4207fe,c0415146,d6bc2c5f,9f5bc476,a372c8cc,60778f04,b02d580e,64d37a9f,5380d3ab), -S(92931216,496359a8,4a9f2efe,f2032335,1588c283,3f9055d2,d107b81a,7a689f61,3070db07,ccce7e90,a9f20897,fa4c7e27,fb86bb5b,2b0a8a2b,a63e555f,1fade8b5), -S(e9ee9698,eb0f0b82,763be736,798cc34a,4d290a96,db7cf297,7d067d0a,3989d715,ae81b62a,52d7ef27,29fd82d0,1c0ad810,bdfdd46d,d8052126,52b76eea,ac196035), -S(8c8d5876,6f4419ad,5015839a,4c7fb487,dae2c7ae,990a889a,af2d6e88,81a3808a,e5c71696,20452ab,8e38e8ad,8bd8d5a7,e3d1107b,df7d8756,12bddf2b,7f83f05), -S(98f6e4b8,211c9a68,f912dd9b,784ede0a,314a9721,92dd0ea4,540a9e35,ee10b93d,14e8736,c7ea071,8d864e7b,1ba92a0a,101b333f,b33c0978,59151f8e,f39b4341), -S(f76805a3,925534d4,2188dc28,e47ebbf,18a783d1,71dd3b0a,88115ba3,3bde61c9,7a35dab,99b9991e,73e17ebb,47a231e1,66f8363,e27911ea,aa1968b1,c9babb58), -S(302be8a1,aaddbb7,8417d663,ade6d83,160b7107,87193f1e,46d1def6,b6e5a279,cc2a879b,6235c998,a97d50f9,c495dce2,d99448c9,6dc6075,d20746a9,d73943d6), -S(f53ed104,dc5d432e,61057264,4fdad4ee,57b0997,419c4df7,20206a2a,9e14f479,f05e2aaa,14bf3414,ccf324c3,1d8a91ec,eb3296e3,8e2efb1b,8d18ba9e,cee03ad1), -S(bef68e21,4972047,4ada606a,5b8615bb,812bacb3,f2214104,1ed69ab7,4ffc6389,5ddec4ee,3257d388,c1a3f5eb,39440748,480117e4,9787eadf,6d3daad5,7a30c95), -S(4ebeaac2,693c7ba8,bf0f03ba,1455dc46,bcc77b6b,d0a49e24,4a691880,ac38cb4c,f327fd30,55273e42,35f77b8,d081451c,60206100,15da9086,88e9cc82,6e547fa1), -S(51848db0,9cc33ab3,767adac0,11c1b94c,832b85ee,632d6f41,d65d098a,becbc89f,673a636,c3990364,af443053,77a5e59f,fb39049,e4ab37ae,53a1007f,8c064153), -S(bfd27c68,24c034c5,c153628b,ffdbc62f,afe32fc2,caa5d474,fd1a5b9c,d1cf8d5c,30928327,debc1be6,eb58b381,2132154d,5a7faaea,b3a5a522,8d1496f5,fbc4ccd0), -S(deed81fd,719445b7,37fd23b1,f2f98f8c,690ad80f,1c50c719,79d41526,34bd1af8,14ca4015,7c9371e5,8039b307,6ce0142e,79ae3ef9,5686882d,318a61e5,8afacc8c), -S(83e853f6,d88bbb57,f2e29871,7e3d3e0b,bc23f16b,d2ec5488,4cbcd3ed,de170518,14829326,aeca293f,10f54ac4,5110bd37,d6adc578,a8e6b22b,13698e55,70210479), -S(c2a957b3,3c8b0ef7,15b8ac0e,f8781632,63e90354,86e96e7,a398f59b,91e4292c,5cfba0bb,f943c955,54d31994,630f3ee3,599b7192,d869bcf,24c9839f,806c0bab), -S(2cb61575,18b65cec,dc17545,e8dacdb,28f81985,85fae30d,857d37cb,ab0c23a5,9bbc8c4a,5dae47e0,6ae03f04,bcee9600,2c17f719,fed38740,64734ce,3470a600), -S(7b1c1fd6,f4af2484,25cea23e,840ac8a2,ad8839ff,5c8c34af,9d1d72fd,30f80b23,6c51b243,7e523306,abd95216,70d6ced,235e0bfd,3b9e46e,b4e582cb,d1f1b76b), -S(f78fc2b1,6d61cbd3,4687e1a3,ce9e97f1,dae8a483,75b338c7,d595fd05,db40a4ef,dea54b8f,c9b55943,b2931963,a895bbc4,4453cb1c,d1530d41,19e506ee,b0702071), -S(1918eacc,3658dffc,ef195768,c1819559,8c550cc0,33333796,714c7eed,1ce780a2,c0a289a,22ae8b28,87658b8,41a98c47,71f317e8,cc972ad1,155fedb,da9f9fa9), -S(12905e26,7d6a0007,df0d059a,f285061e,d14f756a,27943f28,1cfbf93c,b343e7b,433b1923,cd4367,4b6b9495,42dd097e,7a025026,7dc060c3,ed3a1778,1441ac62), -S(969a637c,eb80c1af,b8cffe95,c6b6fab8,6329ba73,dc7e996d,a0617f90,48a39d37,6e751f3,b60c1ba7,57519dbf,fa7ac98e,6ed094bb,3bd9cb44,f65650fe,6e8b31d7), -S(5933a9a2,b818cf0f,d39633e1,9641697,410bef1f,127bc9be,cd183d1a,f85f44ab,b42ac6b,c2de2526,5e3c1584,31e92065,a97d6e5f,3602185b,1fbc1589,757c86e5), -S(54b58e7d,a63c1993,2a4c092b,c93e4d24,c8abac,76488fd1,9f56dae8,b943017a,ac117398,ad4ef6ce,d0166c50,69804db3,78bc9b84,a9f5f718,b0311beb,f08986fb), -S(77004384,69bbc239,8a70863c,1d7e31e3,b2f1dcff,64beb2a7,c0a083ae,8f4240f5,8a8649e3,7f3ad219,bb164490,529153a2,aab7185d,639040c7,1b5ad628,d3ee107a), -S(768e2c77,32678997,42c6badb,4d87ec8e,34af657a,4f1d6376,d01b456,7f0f9828,56078dbf,1128686a,1a1435a6,3dfb39c8,91c270a,2b230754,4409e9b2,1f2c7a03), -S(b66b24b8,5248a97,a913e1da,6d0d1454,53e0fc61,66ecc62e,2bd39ba0,c3639f27,3037bbb8,e205213a,4bb524dd,49c667f0,408b69f5,428e4caf,1ec811e3,cf5c68b6), -S(1ffc3c5a,d8e38090,ac36e8a7,c44c6ca4,c0a227cd,1192bbac,2804d033,c50534e,f2d8a481,63ab76fc,391ed0ea,de7b02e8,1580058c,8b84886f,f6d7032d,b95b503c), -S(94b3d61,4d0a5e2,9e7e9ee7,1e2ee7ec,87b14085,cf6f9fea,2ed31d31,517511c5,33c88c8b,8204f465,93acdf8b,a837d4d,5a388670,fb24a861,dd4f35b6,b674ed4c), -S(3a94b6b9,b1b8a82a,267f7ac5,9b52bb7c,52b790fd,ee341265,ee1b6e34,e3e7387d,4db0480d,d2b8f2c7,2c60c55c,5e050e2d,f86bbe1c,98b74bc7,f1d3a44c,3b1df370), -S(2b53bbf,2bb1cdf8,44b25bf3,d1931ede,9e5e1450,78dbaf68,7f4e7852,6a6716f7,70be0ac3,170f7490,cabea8a,63a6fd66,3f1ce8fa,efc5343,566f4b1e,2ca08e6), -S(e5183136,cfc8b732,3f926cd7,95dd8766,25a8c155,d5c8c457,53777c9,beb13494,93c62979,e67f9f86,cc0ec570,273f2c7a,876fcb5b,f88022bc,a8666e1,814207ad), -S(c4c07268,a805e384,db81b877,9d1dde0b,9af6e197,b6bf254,db6aec02,94dc5bc7,2127f162,e2cee5dd,96055ff4,a7bcdb57,19a00742,f295007a,b839eb54,eb317566), -S(2a89c94a,8dee1950,3bc5e772,b2ff9608,a57c4ff0,dc6f7c0b,c1d2b76c,26c9610f,10da34f9,eb14e294,8f2a06cd,dc211eed,93c670ea,47592135,dc33faac,bbf8a170), -S(35b035e9,8cc6f96e,d7dc957e,e07c7afb,fc936653,72561568,25e44f5d,fe4ea0e6,4818477d,aeed402c,870fc50,6197a0f1,5c72a378,e42785e6,be38bb21,6d4ce91), -S(f0a3e92d,647c07e5,5a435907,34c0ee65,758e09aa,bc2a81c9,f6d6926,c03a9cd3,18e7a09d,720e65f0,b1b8fdad,66d4322b,99733bfd,f8c5fba5,afa930dd,f441f095), -S(4db3c367,f3ba6727,fa274289,675d2fbd,1ec7ca8a,94d97bd0,46815f04,368407fb,d5e0dc2d,80f3893e,f1871740,dfff1589,ff75940,e163f8eb,115e4b17,dc1cf693), -S(9a0fa624,b0eb8dd2,f50ab259,cdd9b17f,7a6f318,93786640,56a49867,89a5d27,68e82527,18684672,ed4df389,98b830ea,1547ff45,f48cff63,5d291bcb,e80f3cd5), -S(19f72db8,e604db7c,ef2e8478,c04540cd,c3806c1e,eb9e8071,38f0a272,275d451f,3cc5df1b,dd845f6d,a4747261,f8e1f821,c7e6f2d9,d9cf9a90,d3c7edcd,b6fb940d), -S(306fc07b,7e543dac,ac240f8e,7ac82cb3,df70a2ac,1bdebc61,adc65fb3,e696743,f27b90e5,a2a5abf8,19c90983,51521f03,26532b1d,37875466,f87289f7,244a3919), -S(c46e7e67,a036ae7c,b30ae479,d0f87d7e,6cc8297a,3bd4c1ed,c2436e6,b52f532b,723dc476,426eea8d,2179eb11,35599275,2cc391fd,4c25ffb9,a3942356,a56899a8), -S(a950852b,587a01aa,7a1d4688,8ded73c9,cbadc922,e44fce64,61a5aa5e,dde2366e,79a12ef4,18763f51,62ccc65d,86c94012,363cc21a,61d12982,ebcf2ac2,c6337791), -S(8cad422a,4ea9d987,48703d5e,eb95d48f,1f73d893,91c7c239,f96a7155,98bfd153,111116da,fcc7a212,a1e6e0ee,4e824611,a3896543,aee02f46,61bd5ace,2a67c652), -S(3b922988,8c2bd057,785b4013,fd14446b,7261928b,a8907ff0,da433d2e,61302362,4eb99bb4,d152e218,8cf3464a,68fa266,500dec96,5842c2e3,a3dc16d,e6edd74a), -S(36129c09,42906435,56970a6f,ccab5f71,113b82b5,819ed4f8,451ff01d,209a9cc0,b30ebe06,b9b4a4cf,8451d8bd,7d9534de,375a396e,b2d7bc21,67a56f42,6426d3f5), -S(8a0a960a,e3bf57b2,ae76893a,b665856c,e09a6f0e,2748c703,2d951cbb,6ba038ad,e29f3916,4928405d,84dee9fe,973f613a,3c5e1c97,c6e5e814,a927a6ce,60efc2bb), -S(641f4fe,dc351cb1,93a088c6,b6ad8867,442cb913,7f0ded13,4ef0f2c8,d721b887,600a51b0,f80a351b,ce7965e1,eec4c8ea,9feee470,80b920f5,67e4c979,84b48dcc), -S(cca5d72b,8d78990b,267cf3eb,246545e4,d416eac1,600078,2861bf05,c0132b3d,7ea6d271,f01c4250,d07e782c,32f0d6e7,177d7714,e2277282,4968092c,e0444f42), -S(c6ca654b,fe45c9b9,1f3869de,2f96f27e,351a7f1b,4839f7a0,9db2966c,f81f052c,894661b7,2d156df4,2b307506,d990ec47,935b0605,9aa97bd4,26b0df6a,9e3d2183), -S(2a959d49,c5161f7,6ce10ee9,cee3047a,be9c620,569a702a,9827dc66,84f6f35e,918b7a8e,e283539f,cb52fe91,1f5039c2,321a6e8,be0c4449,66bcd7f4,594d1e8b), -S(bfa77e7e,3dd28fd8,a04842e6,6f01a9ad,476ff448,18e4a3ed,ab2a8b6,9ba42ad8,d85cdccd,2f5bbba4,1718b70b,c10cfab7,272377e2,5a578ee9,be991b4d,583cd62d), -S(6cb9b861,de296ad6,363da904,46618eae,fa852ee5,ec1df0a,d0a6955f,7b9c6d97,978d0afc,29cb0cdf,f2ac432d,cde6af4,1aa6bb4e,219a0687,11924142,deae9f1f), -S(83446c25,f0496ada,69354c67,8a1ae34f,154afba8,318be7e4,ec52e5cc,ce9dd139,7d4c3e81,98a8905b,63572a16,5fb7701c,c8f0c53,3a01f47b,532eeced,39cbd620), -S(590279e9,f8a2ccd1,c62b85a9,87b528ea,d746a42a,fa07b358,3c5d6349,ef678b13,75627950,5089c0de,33822465,14565c8a,cd131b14,949626af,15c56e47,bdda7f1f), -S(311d1ac6,4b7b1a8d,7c6ba19a,ee5869b2,2d769098,a6e4ef1e,3837082f,ebab23c2,c0b9714a,e1627902,45649db8,b7eda70e,25cc9905,57397adf,39c2c1ba,bcefc497), -S(f63f9d45,10f232ec,5c1f3831,6e16594e,a82d133d,6dd4c365,1da3f34c,c8197be5,ecbd7232,4e732295,750d8c5c,b0290d04,9c778707,4cab27ab,35aeb978,3c743a7c), -S(b772d2eb,c76f6f99,7722aea0,fb55cd6b,592fc0f,c8b87511,d85226b1,845a517f,6b4b0363,7186cb53,ef0d2dbe,3ec16efb,df0b5de8,dabd4d9e,871f7174,94f80538), -S(4dbc968e,8697c131,7d9bc180,f98a1320,bf69fedd,24d71b35,c1e87c95,13420335,f6ea65ec,44c5e25a,549dad16,ff129abc,153393e0,e76b20e5,c1b1ebc8,9ec169bd), -S(2acfa0fc,a5377dfc,21519105,a5f434f0,914fc259,95bb811f,1d17dea3,2345bac1,682e091a,47b18d6e,7595bd46,28130bf7,faef8df7,e8224e02,3d87ee03,b3be8ff8), -S(d77801d0,eac64c02,cbcb795b,f030ef,37a131ca,f07ef6da,2f3ed0c9,f7c8922,166fed02,aeb1395f,bca109e8,5d599f9a,df684cec,418c7576,a4e67e3e,e1abd7ae), -S(92006fab,e11362be,2c89d0bf,e1250e9d,3c5282ea,38be9206,f35cf913,496c9481,2a5b39bb,755a809c,f76ef97b,7e59f00b,70c94a4a,9dda4bf5,523e3cc7,2ac83832), -S(43af4cc0,66155b9c,fd9decf5,e95ecc50,3c69e99b,b5dde00d,bc859732,f4f7d79,7415eb35,75c9e0e0,c237dfbb,af245290,11f5ae9d,63ced644,f8c5af7a,c3e59c48), -S(c018d581,152fb656,c43eabf5,f4e7aa9,c8c5f722,f5352fc,3dda72d5,dacbf451,f9bc1975,acd5aa76,f2744c85,22a07211,daef05ca,8ab0c200,6196acd8,29fcc9aa), -S(968bba6e,77c83e6f,be7272e4,f6288349,329058e9,c3b197e6,f9b56dbb,8587f2ce,3a841d0d,1066ee35,4fe70855,3bf034ea,4da917ee,87d27a0c,f60f8e99,ca45e065), -S(6481bb71,dce335a6,98972f0a,bef2b4eb,5302893d,175e1f53,9a93dec7,53d8e4eb,94073fa3,98393d5b,ab446695,889f9805,6fd31d8b,c14b5ef8,8669736a,5586d3bc), -S(22d38699,cdd4d0a9,ff6bf179,d611b831,647bbf23,5da1fb6e,ec063070,d5420cde,fd4c6d72,ffcaf8fe,3410a0dd,27497df8,98e02920,272a4daf,8967d547,4fd2cef5), -S(acaf068f,34b0fdc4,b86f606,1f96d172,69f63e48,c739f1e3,46cba1f6,9e4c6164,6f9cae55,559fad61,e20bde43,ae671832,85e83ad7,429f031a,b365cc40,349ee3d6), -S(1d2f237,b91c5642,d3dc3c47,9db9716f,47bb34e5,2bdfb7b4,1640e517,f83778bd,9036f65c,eb367bd7,9018993a,9e01b350,fc903bb0,ada247b3,26761011,bd70e0f9), -S(42bf9891,9c347e33,65990f49,6cb09a3c,654b7a09,29cc483,e9028191,4797b6ee,56ed030d,f2fd51e9,98c63f3c,338892b3,49b2c30e,9ac6b3a9,a0f1c18,16b5bada), -S(b48f90cf,18157b0,de5721e5,c0b1986b,1c16f2cf,1b973578,d8b3a41d,6d18f774,40c392a9,c94e2ef,aa5aa88d,36eddf6d,d01a1e37,60d8e391,4ff19646,94557641), -S(8ec7123e,551695cf,c1668bce,86377900,f79e7311,85c5e39b,9d24bbf2,e6409313,f2f58364,339fd734,910c9b65,be0574c9,2bb9efec,ecde3b50,67850d71,d98adbff), -S(7dd11415,1359f2ae,81d4b18e,5afc6657,788d2bae,5c76728c,d1d25265,a2dc2801,32f37924,4f7389d7,7f23333e,4c4920a5,5658254f,dd7febb1,2c3d9d9b,ba631c09), -S(33556f01,4bd89b67,52e7e1ca,1d5fc7ba,faf6e25b,8a49f57e,51c293e8,6cfc4a8f,5c8467cc,3553a8fa,1e322b04,83a0e3b,fee08772,69582178,668c51ad,f3661454), -S(f92da876,e7df1d95,cc2f820b,47921a26,413cb84d,ea6e05d1,da3c70c0,6f5151aa,907d6a04,dae7f625,409e9d3a,8a92f636,f5496ea6,c15825a0,c9d6d6ad,54068a45), -S(77810caa,1e90962e,31ca5e91,2c310bde,cd010016,1f124b73,81492437,5d24f5e0,205b009e,d933e873,a2e12c0,5ced5536,c9b8918,2776bcbe,b297a955,bbc892be), -S(5740459c,5ba49bee,db0fbd8b,5a5dd0a5,24d47dad,ccdbb28,567ce303,58e70b22,7092b9d5,a3c96984,da084d42,f2bc5f1e,a51cb1e4,b8508c18,6ec7066a,74141f68), -S(b7cea84f,84d3af1a,797d90b1,f7a460d8,de9f4a6a,2f2887ab,8f464123,bf844cf1,22f82480,7b05e21,4b885ffa,e8576fa4,c44a3824,5e256d55,cbb1a5ee,343f577a), -S(5180dbdf,73208c2c,b5e605f0,9f6403d9,ea5bc592,29007598,bad6a913,a80f5493,247992bd,bd823a2e,6ee55330,57d78d36,913654d,c3e089b3,fc042fec,15ee0262), -S(ac413c18,ff3bb767,9070b698,e2108268,9bc59a13,1f011baa,59799d9a,daf43cbc,c2dc42e9,78569e63,ab08b155,1e4c52d6,9f770211,86803f60,dc752573,d536af5a), -S(f7a5bdb,71b339c8,19ddddf6,10ff7be4,6af7dc87,6466473f,a01f314e,67bc52e6,6b572fee,bdeb8cb2,9b72dc1d,5df185b6,c50f5ed2,5e95a61,c1dd4822,72ca2adb), -S(6980f38e,6b164eeb,8eeca173,15c6874e,c35bf6ce,78779e4f,19327df2,b1f57dfe,e19f87b4,4e72b29d,c55a47d8,2b5d9621,f15d51fc,deac84b7,87ac2ddc,40af3935), -S(98adb6fc,879900e8,2ede0825,32da151f,b7a16a5b,8d2b9eb2,4e8dadb3,46ac67d5,a7349dcf,c4786a3c,2686fee6,c8d43a37,b91c1b82,886f853b,fcb6831e,c8404262), -S(c46cfd35,101d86ed,965d16b8,55992ca0,932822a,550a71f,54543922,54b00e36,72c03b83,34d944f5,9c4f553f,c25ff5c7,d887d5dc,4e82f90f,cdce7e41,52977e32), -S(71caf0c8,2402b643,ff0b26f5,7060658f,d29294bb,7695524e,99692495,b69584ad,b11c3736,436c04dc,3f4503e0,27ab7a76,2ccb1bb9,74922f92,8fd63012,e174fa68), -S(cf46226b,243fd1b7,984a38cb,f27a7fd7,e7a35a9a,e972b0cd,4b438c86,c6df89a8,f40d1f01,ed7ca764,11a3e0ff,55d702d6,19a68ff,88d4df9b,3f7d9c3d,b96738fc), -S(d8f271a,a092d515,176b611,25abe9d1,85a15d55,b486818d,b571a5c6,4c51b493,3878f749,5d4d9981,5ba550ef,3dabec35,fba40c5e,d10c4b54,fcf63b23,24b91e97), -S(6d60b710,8fb40460,f893c53a,34c12054,6a02c037,821f2a31,55976104,11657d48,a03c71bb,788b915d,9ac25950,30d8c31,65c0c1c9,ed2abde8,96d3c985,3f14bdd9), -S(924f3ddc,7d5d3764,66b47124,b75361db,8afc0eae,7848e860,debefb75,452ef586,c594e3d2,15f58f5a,255958b1,4936df62,3b68a854,4fba7aeb,58a54905,b19c5f25), -S(a668983,5487c800,a1c34b9e,ce7b2347,1e4f5f5b,3be7b591,3390ebcf,2928308e,626c8044,942f74f7,8d255207,5f9d18ed,8982a341,583f1314,4f53dbba,40c94c0f), -S(7fbd491f,ec466132,c2838c46,a5d6ee7b,9dc0318e,3b3bd3ef,88d3cef0,6465cfed,6cceabee,fa659f6a,c083355f,b14cae2c,53657f1a,3c536b4,193312d4,d4a28e36), -S(85122c42,ebe8457f,be82707,e49e0b1c,be3995a1,2998ccd1,629b84ee,935efa56,1cfe76e1,922e4cbb,1023dd88,2bc03dbe,c0be2cce,9fde0797,92adb2cc,925dad51), -S(3ac4d527,3be6b39e,d6326132,fc212640,450791cc,9eb43b39,a77c750d,8acad644,f1d8d690,c1011f,46f003ed,6f9a3342,ca0e918f,4096fcfd,406644a6,2cca296b), -S(838144ae,70bbc188,a05f03bd,9123b93f,e4bf4485,8e380e2d,5d6723e5,fe955cf3,9d8aa248,2bebcfbc,cbcdf87f,c2342618,74e99bb0,507f472c,e86a1b5c,59307a64), -S(4551b877,fa1d9811,e9fb6afc,acfd873f,7507103f,58ccf82,feeab7af,8e893ee4,ba0da9c1,1fb2719f,9a81e745,fe4ac1a0,221b01dc,7e3eab5f,9552027c,87b2fb30), -S(baebea51,e0fdc8f4,cb3bb20b,cb3f4bf2,b37ce31,121d6b5a,7a3313fd,29fffa44,41a4785,df2c9ad2,99b0d0a4,2032b8d9,2f56835a,7bad7ac3,68370046,52c66446), -S(8c03e4da,5be53c8c,6c6c1dd7,ced8fe99,b88de276,73ec3ee4,f5152a70,d0bbac1b,bef7a8d7,df0651ea,1d328729,b0f85ef6,a22b3d66,64ff04b5,fa1c9dda,2073d25e), -S(8d23846c,34ff8756,bd30eed3,1befcd53,4b171dc7,da0715d6,df3104ac,23104ef9,49ae984b,be3cb83,1c2a18d0,f527df0d,27eae720,922f34a,b270888d,9361b708), -S(362c58de,902d1c62,19da8e4,e8ff33f1,61d7c001,202cb2e0,add6bc30,dedba48c,235a0ee0,909dd6da,d1d8a8b,f5f1720b,d6d7e38a,b2b5bab6,788f1983,a5de3137), -S(f836b56e,2892fe8a,a88aa77b,e345c48a,572d0cc4,87d75ddd,99e3e471,bd0461ad,c4254af,e34e6705,12d3652a,38801946,92a7b170,be6fc60f,555c3835,84ca0611), -S(75374bdc,ddbdd08,2e408d8,4fae0652,bc6d1e48,89a7f0,bd1d2257,d75d4f4f,8b77030b,4ee786c4,2973b7a3,905d207e,46448c36,c7d7db5b,280f5936,eed70ee8), -S(ec299deb,26cfa600,a6385db,f04c5b0d,128231af,6453fe62,29bf32f0,71bd1733,be200050,afb2e277,5f4b5688,8ceb6af9,50f901bb,b9a7dc2c,34f9df46,297cda1c), -S(c2ec7bab,4350cb7a,d45f3c55,701203ad,bc00f9e3,17c2465e,efae7069,fed17a1f,33b1bd74,3375dfd8,f4c69ded,f7232449,4c376132,5afc8e6e,a6b67aaf,b4570355), -S(62a96481,d4d9b559,e9ccd855,2d6307b4,8a5d03bb,7a9e7ec3,de8d193,c33ab2dd,c14bf21f,58c2f112,f399e6e,ada45660,6c80fcb,debd967b,e3e3af90,caa3d1a), -S(6da7531,4b8bf8d7,7d72a367,63696a33,4bf5dd8b,f192e2b2,aa646277,f0d6ee3b,70da7974,1576f5ab,da432280,f269ad51,5369a399,5a7de050,ac7eff5,8b7f96c8), -S(af59c78a,126296c5,f19dba32,b9e414de,dd2f1c34,6d6900d7,3ea52e56,5e9cbdea,35b963b1,94d1071d,7769e4a4,3fee70fe,4a63a0c3,bffa2c12,88ca2a82,a7c38bf8), -S(a86e3627,551f2831,b88021d7,d8cff6cf,50fc07b8,5fbb0889,bab026b6,6fec63be,dd205467,4213f012,d45022fc,75de7c2e,b3c71348,efd536fb,1e5f875e,1ae55c63), -S(2c59179e,d9c22abf,b8856e9b,311abbb9,7ec61cc,7ab145cf,5cac94fa,77d65004,e94a1b85,fc8c3c8,aa86338d,819f7139,96a5b72d,68952a6e,8ae48c47,aef247a9), -S(f406f78c,7be2e678,d8315272,e7d861f5,250a4bf7,354da2f2,dacfa22c,d56e43fc,fe719c86,4d66efb5,16a49af4,a86bf463,6130891c,7fc7da01,4394a319,d66b0493), -S(c89f1828,1d899423,83dc622b,7e6017f4,cc02b55c,5c48c824,5568aa3a,c3c25566,40a58eff,8043e3f5,753f9f54,31f170fc,795ade25,d6200e0e,bed182a7,8012de93), -S(36179740,ea6dd2d2,d2a537a1,c9aebd8f,c9a570cd,6fc25453,1d58866c,83ee051b,80643869,fe206f68,4824330c,18073366,9b2b7e97,51f1282e,3c52fbf9,f4899a90), -S(ab5d8e67,7fc654cb,88458b7c,e43b830d,74b441da,9a1af152,9147dceb,13bb2907,b2ecd95b,bc828f3f,53af76a,b5d60dfe,aa681270,74d8ca61,2558c778,ced8aae6), -S(b1e79103,da12fe0b,51259b9f,3c4b74da,1d8075ac,e1aa912d,ed6da9e8,2bb14706,b726371e,7c872caf,42c049d2,96f998a7,c928d991,535550d,a13af044,bc61a1c3), -S(9792e304,67ce4e2d,77f288fc,34c6b2fd,dde99e31,4f0137b1,f2da1d7c,603f5754,d880bcd2,6a74445d,4ad0bd78,2963cd03,9ba288b3,44711889,2ff00de9,4e966be1), -S(d8180648,f046c427,db5a9912,6d54a1c2,915ffb17,c686704d,38fbe1fd,d60cf774,c4767b5a,fb34dd33,e5de912d,b0619e5,c39fdb89,2c131bf4,97cceaf2,aab6f2af), -S(9aeac423,159b5746,565a65e4,c00c12ad,537385ed,9fcf267a,802e2290,ec19633e,7990008b,db7ff6c6,cf110dfa,96249b74,c5173d7a,f7489d4d,86424749,5ea3c63e), -S(2aaeff31,78bfd5ce,b9aa4af4,71555de6,7b1c2bb6,61bd9aa,8591f15e,8148e97,629620c5,8542d054,86245859,e608b5e4,55c45fdc,32177c19,34eb9b6c,23554f89), -S(bd0451c9,211fbabf,21a6b969,29edcd7c,43f10d34,219c6d16,1c5910d4,ae8b5928,23d4a749,b11a1fad,68a8e65e,5c940315,ff326947,868dd92d,9f6f9221,44a4a642), -S(205c5f6b,88865d9b,b53cf8e9,7e97d781,8e038c60,b8177ffa,9501590,96ce5592,b8848543,287401c7,7229f94c,840e36c2,bb93acb4,eecf9ab1,5bba1b49,97d3745a), -S(a3d24c8,f351ce59,6f2da6c2,def943f9,6ff13d0a,c7efb29d,ca3c39d6,5281b96a,28d5fdb1,a8c1934b,a98508bd,8b17168a,a78cf549,1b3b3636,8164e95f,17e8bef3), -S(468f528e,8f2b12c8,4b90df66,8c401f4e,634b2b9,421d1a1c,1079578e,2739160e,3070d8d1,9cee21ba,510b72dc,b17b7e72,7c0adc0a,baf58150,a24fb409,9f203f03), -S(6a106a2,ad8bf04f,a0ea0c66,179b3a4d,df0eace4,954a40c5,ad3d611a,ff7965d,fe893d8b,20f94be4,ed7b20bb,4feca170,75d2e5c3,61cbf44b,387947b3,8d996a91), -S(e59d055,1f1f0a40,6e94a2ad,c92b1e5e,54b74ffd,8d0af6ba,ad25de6b,97a470a8,b0693f96,9257ca3a,da93a54e,f3c29a62,20cf4c33,a9cc6915,f51e4d50,8ceb7efb), -S(ee7f4a6a,6e37fbfa,f7db77ef,ae9e8745,c5ae64be,338a6b52,e5138ac7,860340dc,c92c0a11,17b2bdc3,d043f6e5,b90f3cbe,412a9a61,79ae3f00,7c397589,69eb1616), -S(d42377d8,5dabf33c,99268106,f86e7939,c87ed35e,affacd68,d211b4ab,70ec2c05,ef130233,589a5fc6,5a23a029,e1857b86,d6cb276a,8f37bb8c,996dce4b,e72bded4), -S(e21015b4,d76f0245,8dffad7d,f67151f0,ff4c4d1b,ad5e13f4,a6e197c7,2e4c31c8,b78e9d47,31a4c0c,3e29e9dd,2173ab2,16a5b8ec,522604ad,43111600,bc3e1733), -S(53c5434,9f0270dd,4c76d116,eb2df817,b66b504,87367767,d4a796b9,e4516f2c,5a4b7adb,66ace9af,59d1286e,3d89b2f,de525b27,6c27c1d2,1d7a38b6,b1b9f1d5), -S(df9917f7,6cf50cd7,2b8b06cc,cba9a47,b7e0f64b,481adcda,a6942a96,2319e81e,171d72e6,cad16682,bea2a90d,72b0aa4d,899e1627,18b96109,4a501515,2b754453), -S(79eccd0e,f2d48da,3ccdf12,91269dc8,21453173,7991bd38,ec3ebb33,56a594df,72371a43,74284937,aa92,6eb5e8c0,6911bf1d,4efb097a,8d78f46,da1a87b7), -S(3a472336,4c182521,81f90fb,66d768c6,a1a46cd,85c86108,3a09696e,922dcb44,bcaefa87,7b8d963f,d6e535f2,db3d189e,4fdd8626,94b0b60f,136b25f8,14e3154d), -S(edc9be56,27acba38,178b0c6f,cb7ce6e1,f6ecada7,a592d6e3,e859a16b,459c6d7d,bee091af,de809fc6,9b819ff7,1691f13f,321dd702,3944432b,a278df70,4ea02eef), -S(9adb48f1,439c1850,1895ae30,649992af,3ce3d085,13c6a92f,5226f3c9,ec09e5ef,3dd78cea,3a3169dd,78afb39c,ff690eba,e9cd5f3c,42d7c583,ef093a57,635a1df6), -S(942953c3,b620e636,63f2bb83,6c2c3a9f,6cf4a931,2587f57d,9489ffb2,38895bf9,415c121,6ed101f2,698cc0f0,9c3ec0a0,c0e8458a,3aaf5879,87ff1b0,89992932), -S(92c539de,88e6d094,e64c4b25,51da4149,19677124,d8d1e53b,4d0a81a8,53501619,c9b5c7e2,dc61d875,4f33243,de28ed78,adea8e56,e193ab0c,d1f5464b,e9003a45), -S(29d33ba1,e9972c80,2f135a4e,add34b21,408be4ee,29d7be7f,c7f8ade,3ed07cfb,847cda60,a3e6627e,5abffd6d,b56502b5,f26df3c4,630f4f76,aa868899,63566e7a), -S(727abd10,6aeb6f80,f1dd6319,4bd4abb2,2db5d8cd,e7676273,cb0b4246,17983d2b,476962db,5de3493c,58dcfa1d,fd206a44,11f590a8,2c7aa7cf,3fb377d8,623c9639), -S(d898349d,89eb2d49,f2865e19,88c3b5e9,f43ba281,6a0ae0d5,b031e186,b23fdfa7,4d3083bd,681a3a1b,988d3bfd,70fd6b13,3a1d2264,feadd852,b2298450,f729c471), -S(88526dd8,a52010d0,fdcd0223,7db54b43,f73b7195,cb3b2081,96257c7e,ced4649,686926f8,6457861b,4eec6999,626115b7,f9e29e0d,74e44027,5df2f583,7b75699c), -S(6b64ec54,3e5c83d0,b36711ec,b0a4b8a9,25fce55e,4923fcd8,6dcb48f5,43bcc107,8a7d84ca,e8431663,3d635a78,9598a22a,532465e6,f86e6eff,108449d,a5b0ddd4), -S(9017d917,e7e80f70,e5fad8f0,3cf0bcf3,b20bd8f7,95c4728d,e259bf0c,933088c0,e2a9c53d,e1278404,60828e57,eb5de14b,eea14cb3,41bd4d6e,4b960ae2,807299b2), -S(2f7b4a5,591268c6,eaf64c76,5a8321dd,2485ee36,bb1b338c,b1473535,658c376d,8f2cce5e,42869466,a3658460,c0ecbb46,5d850b26,85642b52,e01f3b08,544fb94e), -S(316bc4ba,1dec120a,7a10ef1a,aaf40d63,9f404948,ba27f46c,58763508,4809c78,3522dbc9,f861c154,771952da,7dc04ef,5b5100f2,b4355177,b62ace04,a717d056), -S(69c07c8e,2c1facc,7ac6e08d,3b74f1df,cc24751c,ada31142,72d2e313,78d76683,474693bd,649a0877,a3eba75c,910ba3fb,bf8aab97,5fcae30f,cf47a51f,e9a59f24), -S(154e4dbf,787e808d,c19031a2,df25536e,4bc6a71,b03d8f77,5c652812,75a84a30,e79e1a4e,2440cea0,c6c63098,ecfbc52,f5cbec08,39589beb,251af76a,50eac221), -S(61c158a6,b963f853,66598998,908f85f9,bda6ad6c,827702ba,f81922ed,2b675b4e,d63cadd2,c63ef3af,7c8e9695,4ebb28ec,48dd2c86,a69505be,d06ab3ab,c4bb4fed), -S(97dd50fa,eda2da43,aedfcde3,9d55b52,de43af06,13435b7c,6744dcba,81cb9b3f,e99138b,1c86d820,70ff2e82,413b19ae,d83eb23d,636c4380,70116490,bebad75e), -S(b2a43ae1,947e0e8c,e2009813,eae3e500,ce67b1c2,cc19701f,5b6cced2,e775cd57,291593c1,dee03645,4d0b8be2,642cafbb,cb3b7fb,a045e402,2006c702,3532167e), -S(20580468,68663d06,568988f6,17442d5a,6a65762f,cdbe91ab,128ef99,990d722d,ea32d66d,56f1fc93,fd559c0c,e8b200e8,e423d097,26e564f8,8f53b3c5,e8dda8d4), -S(c2b98b13,bbf661c8,f4cae855,158f095a,9b62947,134c5da0,9dd2d377,959ffdba,3d6386f6,915a7e26,c63ee1ee,6970928a,6f0e4e29,cd3ad665,fa4164a5,a8b2cd7c), -S(fc6c98af,7fbf38e,53690a78,34d82a56,170a18f7,a4e702ec,6e918510,2700611d,9ccd38cc,f8aa409c,1a9e0b14,d01bc9ca,69b5ed4d,7f92a177,e42930a0,222cc755), -S(21157d1e,1bca5a3f,2dd0153d,b9af3079,e1e531dc,9eafb9fb,5042af2a,e67d7000,254860bc,97cecac,b4cba1db,79b13fc2,199f037c,aa963d4c,bfa2b9d5,70456cd), -S(316ea33d,dd576b35,e45fc5ea,5e384070,68ca63ed,1149807,68a7c6a0,d6c628f1,dc236dc6,d0ab4c12,63124830,633729a6,9b20a22d,7d395af0,38d6bdc4,34983baf), -S(21b825c5,44a41bc1,9f048a0c,9a532a6c,18df41e3,e7cbf6db,97c871d4,a3cd0039,9d85ccda,c67a4a39,ba10128b,382925d8,6cebbc0d,70354ffe,aaf89ae9,1fec461f), -S(65a4b32c,e116790e,f671e6ef,8ad317fb,efb815bd,fcc1708f,32c0c078,2ed41140,634c9efc,6470a929,8844f082,5a9d34c3,ab14778,7969f095,a1b45f1d,dec806bb), -S(cbdce03,45e01ae7,77ebf819,41123ae8,b4683169,246c5156,6afd6a54,e9eb6844,5414d24f,ecd1a159,70882003,3726c1dd,ad939df2,9a12dee3,224fb9f0,a89f03f2), -S(9c4d4ee8,3a36544,ab38334a,46586864,bc7c301f,710d67fd,226d6e59,a6532374,868f765d,3dd5823e,7e2e6791,21bcd41e,9b89df55,27e191ad,c5016463,ac7c7991), -S(4c890df9,dee96da9,7ad0b768,16a50240,2c9fad7d,5ea13a04,3eebae41,678214f,397de76a,319e758c,199e2343,6990a34e,79b968f9,1139324b,66e5f7f0,114cc9b5), -S(c7f4c3e3,f7ccd93e,2449c653,393ff2f9,c8d362aa,3dd01128,9879c983,f9b49229,d2ef30d0,68321b54,91519698,79d8dafb,8d2c5ad0,9117687e,10c5a57e,ae4df846), -S(e8c810ee,daa58b8e,687fa493,6d833930,e7de9bda,f73f11ca,23734756,d4d05af4,2690ab19,e6c9df94,349600a9,269c76aa,633c4dbc,abf24604,3cebdc83,1e117d03), -S(a3f51d28,ad743812,3cf9a169,d6581d9a,3d41a131,a8109eb9,a38bb3ad,9f66187f,3f87496d,d5f9ec37,2e3d0e79,7c12e7e1,c328658f,49cbf237,a4e36415,76b89e75), -S(ee0baf50,f62282d6,b560d1ff,c18196a1,a038b27,f081da32,1d82f3f1,82c27b17,4e4dee4b,182056b3,dc809d4d,2160a5a2,b6dc8ef0,e933e45b,5bd1375b,c677321b), -S(346b4fc7,535f3a2e,79330614,e0618d0f,c2a44ffe,a684076c,704764b4,8ab3d95a,98a41f22,cbe44fe5,37116f8b,9ee68e3b,48ed63d8,33cb9567,278c520a,e400bbd2), -S(55fc8976,b796bf67,9de4b2bb,aea29d6a,e3cd032f,7611e59d,75b8ffbc,55c32b79,2e5d3a9d,f8b32c5d,bde33229,f2e9c852,702dbd58,31bb1917,2e47685,c395ad1f), -S(4ebe6051,7453c3a8,a7b65c1f,fa7d0b89,c4cd4166,f2b8c670,3a71484a,f62dc563,6fbc68f5,a7b3431a,1dd6ff18,b7f1676e,a42ca708,f56e50b9,8700ed3a,560b3850), -S(14bcdbcd,73f2896,c8b37bc7,e06c195d,17349c69,9be4ce19,3fe4e145,a79e20eb,2bacba55,a4611886,7e3c11c4,4f14bfa4,d5c702ab,b2385584,e07d7b08,42a8ec61)}, -{S(c8116b60,1f8d72c6,24957215,46b844f6,bf6bae0b,7575a77,f1f6c6c2,5524fa2b,b7477ca6,de2004df,34882c65,3a46821b,53372f13,ed822cbf,40c20bd9,ddd1d6bd), -S(f59c22fd,8c5a2e,c990f3a5,e6adcd12,f7cdc433,88ddc16c,aa41b9b2,2fd8dddd,8f63f807,eb1b96ae,ec9a49db,818e1228,b9d9da5e,5b1603b8,f5c65900,782a6c53), -S(effdde86,efffab86,6d1da179,211a52e9,b3ce9fcf,c5c3282a,1a87cbf0,aecc882b,57f4a91b,b88d9746,1d1ea75d,4eb2501,46899ac2,ca707ae7,88f35b3e,9f6f8e36), -S(6a4d17f7,3eb94a48,a369cc8c,4c827003,8967190,3d6ac75c,cac7516c,e78a8da8,51f297a9,23bc21f2,ea576db0,15b49d80,27fb1ea7,597179d6,fc47d749,5621d8d), -S(7af337ee,d52f0c7d,ffd0628f,7866d621,dc867661,7dade077,2655f1e,3c331d6b,9b202463,320d18f9,2db990ec,e41aae7b,112d6390,33418eab,7f86c874,a040e2c), -S(4a9b0428,2687d362,66d8f33,8cbc38f9,8d6e6f8b,bd5dce2,b911d192,2e70a583,c2646913,7c7023ff,abadbcab,4da4b90e,8ea8736a,fecb569e,dd822733,8422d74a), -S(53a776a9,e10f53a8,454795db,bb340cd3,fd0ec50b,51a164bd,549ac834,ede835cf,1b976c44,de266928,49631bc2,950b4d24,f11fce3e,a728674c,8713d3e,35f8c0cd), -S(48ed6e74,c75c7733,1aaef9cf,ce06038b,bb405ffc,160c5711,b98ad6e3,44baf62f,fa56b3e6,b826b847,667ab6c0,ade30415,39d67509,61c0c199,14715bb1,bfb218e9), -S(65db9062,2328f7cb,e9afb758,294e0d63,d0042b6f,7615225,ffbd341b,16c5acd6,1ff10083,e9f66f89,bec1330,dc309813,2d434191,2eaff4ca,b3c20177,7001096b), -S(be836639,aa622020,9ae01ae1,f96f9256,9ab7aca1,2f5a7277,903dd653,18f9dcb8,293ab5e3,c50f117c,71dae650,b16fe28e,bc14eff8,38fac552,6adb3393,e177ffe), -S(5ceb4539,42c966e1,65c0e346,2172bf2,e6e167ba,261d0e61,b67df26a,9857b747,88d78492,95312fa7,ee43ffb1,775282f8,f692a83,c6b4a72c,a1ebb44d,28983f00), -S(216fd6b3,c5358b4e,831327fe,2918d70,ac627bc2,e12ce34a,adcbb23a,c0ed2a8b,d450d01b,83fd1935,f0a7c919,cb91d162,dfd14cdc,3d15661e,a303952f,ed70e684), -S(354a9835,50c72d71,37f8d393,2895f1c3,b2e6bc19,1d9ef2ec,3a2b7dbc,3cd2ef76,e4df044d,4ff91794,3e6d4c59,90095781,5ee0338d,79329ffb,ed74bc19,103fdb6a), -S(4215c5e7,7d2cdd03,25f38b38,8a204013,62114d94,1bc57216,56e57878,b2750502,b4d82696,1aedb8f9,60da2950,cb5b489e,857e30e5,20a8e1b6,84dd4032,d8b6a494), -S(79bb1258,ef4deb1f,4a2baa34,91d9e27a,7b75774c,133b9112,3e5fd848,37a57aa1,d467fc67,dc932c7c,48d69609,f955701a,e6a30205,42a51c2c,10591fd2,134bfd1b), -S(eff02038,49797c99,68c8d63b,14a4d84,f4852504,2ab269b8,182b2207,ba94eff5,79a6fc31,e09c939e,f69a345a,56b90c39,2dd58054,e3f23e9,c16f84dc,ffde8e0b), -S(856e40d0,54323270,3ae30d75,8405401b,72f7ec1e,96cf59ec,1f3b8465,23466dc1,d1200346,5e56370e,96663479,bad5f6f,8fa4713e,79217649,c48eaa8e,4bfaa8b7), -S(f020d944,14008a39,59feeeda,49fc388,d41246d5,39a5bfc8,8f9673f,8b0213a0,e88d23f4,5919f0b0,a037f4ac,aad9de03,3f070c2a,f967fcb6,e251c17,69b62658), -S(ce486f16,39af644a,c70dfdff,6955db6d,ffd6f69f,1dc86c40,a318729d,e6823239,8c0fe4cd,debc1c38,37325664,f8cb0235,b6f32ba3,809dab3b,60c3119c,ded40b4e), -S(2cd69598,f476efc2,4b65aa98,27607a9d,3c643033,3cc78072,7e3047ea,a3a7244d,d287d0a3,6749cc57,bac0159f,1c4d738c,a965dadc,be36bf2d,f3f55372,6ecdbb3b), -S(f7d9e16d,c71c9b21,be93bc6c,b00888ab,974c7568,cc09479,16b09532,7c486850,6e561ec8,7e17d433,22163af,8253b659,15d04fd5,24a941c7,a186ab15,4be2d0a4), -S(e1f1b231,3a8bb5e5,e030d6e9,ec921515,6004a01e,f6d737ca,ae4ee585,80377a7c,bdb81500,9c94dad7,69b8744a,2d19cb59,8335ccaf,d840ddf,8817d4b9,735a8e3d), -S(677543bf,d07c8fce,d24cefd3,bf38bd0a,40079c68,1349bf24,c8fe25b7,26365fb4,3a7bd8d6,c442438e,3a1a53ff,d2a6b9d2,e0b3a565,de374417,189d0dc,888c02ff), -S(b8a18d49,b1d4593b,d103b5a7,dcbe4845,e0ad2644,41d1d60b,ad1e9252,1dcd773e,78ff6195,aaec6cd6,cbbbcb23,a81c6ac1,6bad7a54,7b0ca465,5e1db742,2a0c8edf), -S(b8f4e588,1f4155,b7a4fa26,1e34ac3a,3d776ff3,d5a69c44,6774ed8f,e57201a6,69dd7683,ab9bca83,a64ac013,ba62d2ce,1ac5866c,f9cb046d,84f69b34,168896cb), -S(4520c74e,5c39f18e,47d16c21,51f90013,395f2cdb,c59d7f2e,fa40be99,e843855e,ebc0a6df,bbe76c29,d1f32546,cf7038eb,ab3a5e2,bed16a31,acc587b4,41051093), -S(431f3a79,57636916,5d1e1b7d,dcc1be51,6138a26b,beb1a3e8,5c49f42e,fa6d9c88,6cf98a2b,1f747122,2f6835a2,116b8e94,8dfbe5de,72cd9e7e,7499493b,bc5e590c), -S(a03b812d,fd8291ba,ef0d00c2,25437a90,d8362fd,6c5f1b03,965cb3bb,ae9664a2,b3a8f60,a26d6adb,5e761692,a8cf3738,3dc30e79,6417e4a,23db565,487ed88), -S(2440160d,4b874cac,adf4e1a7,6eb079d9,810be0ee,2a8d6cf,5f9756e4,936608c2,c5823453,f331649e,45a228eb,4b524ea6,89047e70,31ce2894,61f119ae,a865ea7), -S(c62fc4bf,ec4f9113,1f5d3c0d,36807b15,35a52246,225b3959,4fdb8f3d,d8539bbc,a7257908,497a26c1,484c0d25,75052095,a1d71db9,ea5b61f5,e8c4257e,291129e2), -S(1de53f0b,82e708fb,369fbce6,72595b67,5ccc73a6,15797faf,333ad7a,7ab16b,ce3ad57a,99b253a5,ede23b7e,e39c7c8d,e5a1cbaa,8bba04cb,d11d1183,c226bdcc), -S(e7ff8510,10f96b2d,80fefc2e,cb1506,3e29d450,13dc39fa,524dfd38,4e1a5ad0,eb8ec381,58f629b4,79599ab6,346fe86,c1159368,161d275f,e55810d2,84d3d768), -S(e06c81cb,ff536295,a2c025f8,6bfde632,ef52d427,2c4d002d,dba88b4e,82570c1,590c13db,1df2b414,d392d8ed,d8b2a303,3d50460,4f1b921e,1099714,c6e2fd1f), -S(28a5c19e,1a67cc90,f5cb15f8,b969d5ca,503b20fb,e5a52dd1,4304c5ea,4ed6ef5,66b9f844,184c75ab,223c5cb1,8b4ceeaf,490969c9,8cddd8d1,122c6e87,6b2e590b), -S(a7bdb9a,631e67b6,9474ac3e,fffdb6d8,454df8c3,87589e1a,7aa6788c,ba47f72b,99d88a77,61bdfc23,271675fe,5dfb2e70,6a728eca,dc83286c,2f7d0d2d,b14ebb9e), -S(44d3cd82,87cdb65f,90f38467,ee478633,8ba82810,ba9ff195,c55b752,22d27fad,35b7a398,80755784,57b41ad,43bfba60,78d7ee48,7d6cb190,9070c80a,3e1dc4c8), -S(7c42f052,87446002,3b609b2,8ec61849,221a62ef,11e6e3c0,718c1c25,27a03bdd,c57bd1a,a31b2fd0,690e0551,6ff9e744,243e0bf1,91161aad,8e798b39,2484d707), -S(f3555643,f09b3164,6c415bbf,c2031605,eea9abdd,9b76d431,10e61c9c,4afcbda8,2b982eb2,a3cbef3c,d1af4315,178f7c9,236f6dd8,e4bf9ae4,7ee56039,ef9ae98e), -S(dd917a87,6382ee0d,10e22c1e,3bd48a26,4d74cbdd,ca1a062a,8c84cf76,1c59d390,2c958858,2cc386b8,42fc7041,7994e479,f3027693,9011c10c,9aa35f52,335545e3), -S(220dcd6e,447f847d,d0d08170,e9a6a817,38cc5c8a,9e911b0f,1dc4aa8f,946d0cd5,7bc7de64,70ff4484,db2696,4ff06c34,665382d6,91d25bda,95ed8bb7,18c0a558), -S(ea30144c,7ac98f2,90ee04b9,9f5fdbb6,e08cb88a,fc99d635,a3daec8,3393f191,a41b4d67,abe18ac4,79d87a90,63b7f0ca,e5adaca6,cc9471ab,b121cea0,427c620d), -S(32825a95,6bc7e979,b03437a4,efeae923,fba1d408,9ea77ea,9a1dd25a,66f63920,e34d81c,e28759c9,ba0c8b31,e57a0a9d,a45cedc4,9e57addb,b81a3c27,30b5882c), -S(78d197a1,975db98,d2014422,58784a7b,4aeacdc5,f72df33,9aea0a9f,8cec5ab1,1fbeaf4b,8c470387,f2d35e9c,36ada81c,7ec62d23,ec8bfa50,2af1868a,92f9def3), -S(e74f8d82,a67f687f,1ffaf4b7,268ac9d9,dbaf42e7,6c1bce34,9d473521,8a4d1d42,695440b7,a234caf9,1f72cf0f,255d4dae,398f4077,93f40211,bafe60db,bdb804aa), -S(de66c91e,9ddd0fc8,96fa32ed,ac4487bd,2a8fcd51,f4f14c3e,c0cf19f1,532ad5b7,3b1f48ed,30df76af,b0630c27,9914594c,58159b83,42c97763,498c8ba7,deb73aa5), -S(9cdc5f48,299b1090,e0902be6,6fffcf06,ae630650,e5cde3f6,9e719314,d75f2334,5ba9d4e,7dc788ec,ba0b53ac,3a68309f,21971371,e2db812e,566ee46,a61e7fe8), -S(50ce38e3,809cd6c6,601a095e,d5a63594,2cd40f15,f97cb332,fc19d70e,a1214e9a,b7ed76bf,a0e0687c,44b66bbc,ec0fbadc,94fa09de,5b1476d0,6207e256,dca2fd7e), -S(aadaad2b,a6d873e5,a77ed2d9,ce26cb0e,349c7b6f,6847636b,566f47bc,7ef52c69,233b40ba,b4082ff5,c7122143,a45656f5,2989b62e,391bce37,d7aa245b,6c84efe), -S(7b219f5f,8f045219,5959621d,6c161a70,b4ef7a57,cbe7c9f4,fd539af5,71b8e0f2,8efedce8,dff914cd,e050209d,3bb91af8,c8d781ef,a87729a7,c5a6fb6f,8183ab6e), -S(31dda168,6e3ee50e,4e39f01a,68797bc4,7763ff27,5fa4489e,386d9902,c6c328ed,688d2e05,64b66581,cc5b1234,20a6c331,d33019c3,84a63c8a,a6f14be8,5d392201), -S(ea514512,aecfb0f3,94e59d7f,d9d558a8,cf535464,4f2f0963,2e2c6364,b1d57b5f,aa2ed069,dfd3144b,c9aa00d9,5037b099,9c35ba17,d6ee79cf,3e9aa5e9,f5dcca2), -S(bb2f9ac4,107288f5,66be0b4b,7b294e61,ec868a7e,4bb26a04,e4f473c6,9bc8e40a,6fb56eae,bd923ddd,c5028472,aaad2e0d,b0c80465,2e59c87e,45246502,606a0f74), -S(b9401bb,bcaaeab4,9ac42f6e,d36891f1,bddbe0a2,81ec4cf9,8d5f306a,ee9a5,ea40ae75,812da94,9bfcfeef,d22fa5d7,654eef70,34d3393d,6959a59c,2312dfcc), -S(dbf74d05,475cca1b,218bd219,8b24eace,99e0c4ac,56fffe3e,6f8f782f,8f338437,95f6b97c,eed1b3e7,b8de7f15,55f7ac5f,28649660,a458df0b,1806512f,f10dd82b), -S(cbc07e16,64041096,9e78dcb6,585abe6,9ee2dcd3,3febb64c,1f5b8bc9,419023bf,513e2160,56a3dd13,516092bc,fe6a5f4b,3c2b2843,a55ab69f,12f8387e,840a1772), -S(14504eff,814dfaa2,78704245,f0b11c4b,99f0c104,1d103e8f,a221a4f2,d3354164,a61998da,9bbce03b,e1bd153c,c33e85e6,cd2c7b18,a2ff9f6a,4cdba579,593471d4), -S(5b6d95ad,e3defd6,742e2e16,f4ca48e7,118e2ca2,cce878bf,f8b3f2df,fdf4895c,841ad4cf,b538795c,32000893,e0306415,b15edb8f,d83772b1,4de4f2d1,ecb180bd), -S(de084c,e1cf681a,f081212d,7e08f5df,89ec249a,fa419bf3,189339c,8a962f09,7790872e,2b35ded2,78f496a2,8e6c4907,8867c0b7,fd0910b,900c68f4,c11831da), -S(ed4e253f,3e7e781e,86290b2e,56eed44a,47b6f73e,74282d0,b7b54f7c,d75a97de,94a21c29,5850d088,d6cb20e1,9a2a3975,b27db744,4f19d257,cb3c1bef,1a329cb3), -S(3e8f32ec,ea23ba55,cb6d0fd1,41aa2225,9531ec35,bd7f3ec2,7291b798,431e2ee8,1875388b,5a9d4571,66179379,4e7c5046,ebd10c34,9f5df4f1,ed50c11d,952bef32), -S(4d2afcdf,bcdfe440,eb211566,efa59e4b,38385f69,5e7e2063,4c3b4606,32e5a23c,4694e00c,6b55863d,693d68b7,678791b9,f09df4b6,98df84bc,69940429,cbe10a39), -S(84fec62,e92704e6,1013bba3,4dff3876,5e4221ec,f72ae24a,1e80a814,632a5505,b74a1f4,9b9283f9,d6d01827,8bad2cc6,73cad8b1,99a1dc83,bc0ec561,78a2539e), -S(8114debc,44e517e1,1d900358,d0b831a1,38275cb3,371ac707,c4334544,bf076dd3,3bb2baf8,a42a57ce,d6e1942d,8324c795,cb05b978,dad8d20e,6eadf721,9f2b2d74), -S(fcec2f7d,20af0406,370f4aef,b2bd168,592d6a21,d5963127,3f3b836e,d1d881ef,b59d480c,b37372ce,d5ff46f0,5f1700,ea5dc847,1ecd2983,42599bcf,eb696ff0), -S(c000ee62,5a6ae49a,b0226f97,dbef0469,bd02e7fa,a8e3d4e2,b509a6ec,cef15876,b13e0e83,dc9c8f89,6c82ee3d,6cbfa8bb,4beea7af,5210a6ef,1d331180,83946dea), -S(142a5689,bc43523e,6f0c2922,78b7c68b,c588ca37,aa934997,63438dac,f5662669,cfdfe57f,2b80c32,f90af575,195dc71b,b7890d94,c27385f5,1451429e,41de8119), -S(3935bcce,35fe92b8,a2722b4c,5252f5,e6252b49,2ed2b8c4,759fea06,211bae0d,23a96df2,80a4006e,9674b0d0,e44ff5a2,f7073656,3539de18,a87529c0,4640a769), -S(46c985ec,74815b72,97d7052,35990967,1257337e,efb0ed46,93a06124,6bc5d717,952cc49d,f7f79ad7,8c279195,dd24fad9,ad75413a,5ab78869,f1c686ca,52dfe9e3), -S(2770cd58,25287db7,b352380b,b894ca9b,a8ee672,5153b7ea,1f28b254,566d1e27,c29b9df,d3028c3d,b7859d8,30de1490,e1f8abc9,c95994be,13696587,8ffe9b99), -S(8be87133,6feaa5a2,c5c3ce6,8d58159d,75c54e90,12922dd3,da4b534,31bc8153,efeeea2d,440e6127,bc12331,61a18497,68a280c7,6858bcb7,3a5980b6,baa4dd39), -S(675af413,e5bcd4e5,1c522a85,9dc1f3bb,14356298,62117c2f,90107af5,496fb8ae,54678238,ae95415,219b860e,985acd37,9d501ce3,c68b208d,2756cd64,6b357578), -S(5696c5c9,6f8f3b03,f1b3aba3,af85f160,67c309a5,bf4fb8cc,586a1f40,cc4e58a5,f675529f,73ed6987,ba2b1bf5,d202554d,8de9143e,809582f1,4ecfffb8,6a0cf850), -S(2e0f5a9f,5406695a,ba5bac9c,69865f34,ee2cfe1f,5662c055,8d88b422,76d5cbbd,7bb0e1ba,ea55cc81,29b074a1,3380f9be,c67af07a,e91ac96d,c0a46b92,6148fc4a), -S(def49b1a,84ce9199,bfeae925,7a96c403,5dacab0c,80e58a7b,a69609f8,7d3a5214,54c75dcd,2294d953,cd990cb2,a2840c11,813fa97,19178421,18f9774e,de4aefc2), -S(d33f0bbe,51af9602,83b64d36,fa6f8042,fead9d96,138769ed,25b55fe0,6e4b0013,8a9b41d8,32fb7aae,dfe94380,cf2fd2c7,c0e7592f,e3a8c32f,b1cd4aa7,6112227f), -S(6ad93b61,5b5da7dd,8145ea46,7a99fbf8,57529d5f,f25d1aa8,f935163d,4b2911ae,1fc64130,7e4228fc,2354227e,60b67305,9415c19f,d2a084f9,e9caa39b,d2b5cefa), -S(2c886c1c,ba67d840,6e33ef48,6c3e63a7,c3d9610a,67033bc4,f19c0840,784a98aa,79fe3de0,7363b7af,7d3a41ff,5d3aec6f,ef80426f,be455e12,526120f,5b884823), -S(10e59c98,b357ee38,3c306e3b,9c1be538,420881d3,2de1462b,aaace4f9,d84c252e,450e954a,92655710,c3e6279a,94fcb52f,c9aac9f9,2dccb95d,97109030,49cc71b6), -S(32725d0a,dfad10fc,c95db4b0,4ba65569,e88ec325,9cdbf02,5194c69a,3a18722f,d87902ed,f0f1ce28,3bbb3fe8,113f6bb8,9976348c,965094e8,1e24c28c,911d8533), -S(b066a5a6,da035350,33888fdb,87e28292,4ae805fa,45b462da,82ba0622,e6fce040,5337766c,2ef3fe37,42571ab2,286246d5,95ba7087,d3c38332,6490feea,1863a5d2), -S(6ddc1ecc,e8c7cb21,a681be75,a2143ffd,2663b75d,9ede8a15,d0b5189d,8c52f63e,c4da0af6,8eadeae3,ed9b5b61,a73bad5d,1ae8c080,2777441f,cb15910,153284fc), -S(c82cdab,1659a9b8,2ba0414c,bffaea32,eec1b41e,615bb47c,786abfbd,43698d7c,91e026f6,781ecd32,ab59bc5e,2ec3061e,5f6af1fe,bb6e627f,167cbdd7,afca63e7), -S(d932562b,6cfb8034,ea75e656,502ed81d,2b5b80a0,ae85aee1,29f677ce,aa5a282d,ad101b8f,97aadb58,d0b3d8d9,1cd24950,de0a8baf,646e9d9f,734f0f97,5043edad), -S(ec3f50bb,efa0b462,66993e4,233e5e11,f4bf4d56,19aad9c6,37638bfe,d8e45916,d63f29d,3f7b0b6d,b8514712,2343f51a,ff1cf956,e5f49bcb,3a9ea5bd,639dc2a1), -S(b5ff4795,4d6fe3a0,22303189,6eab5c14,bcb6dd3f,497ca561,1e3c9af9,b7e9cd79,16605e0a,5a862ccd,b9349159,13da9d4d,dd537edd,817a0e24,d0d59101,61105b18), -S(b1f153eb,697dde61,36beb382,da8702dd,a51e61c0,963c6d45,338982ef,dee9dc7a,fa1ba411,1823398e,23462cfe,339924d6,b6eec980,729159ef,20f8c8d9,f8143645), -S(42206dfb,8dc8eaac,d0f04c0a,da3a2cd,38c60bc4,6d1fd148,8fe12c04,f15904f4,c44393e6,2969b4b7,ac388f07,8b997de6,d4e08893,dd17699d,9a1cc885,84f3c5dc), -S(56cb266e,152ea2f6,1db917f8,c9b592e,3ddb2643,341da585,c4291d80,d7bfdc62,f7e9f332,8e963d0f,a3d149e9,c4c590d,e835747a,b75df64a,41d919b4,4fb18ba3), -S(5e1d6097,991e9fb5,b099e173,d263199c,cc3e626f,b512e6cd,cece57a4,888e6f9c,a151698a,aebc1dd2,93e29cc6,bad03cc3,2a6785ae,61da1f71,d50240d4,825962af), -S(4acabf0a,8cfa489f,34a622db,9e22536f,2da926e6,97d72756,eff9dd84,72d7b207,5bb50941,836bfafc,7e3f693c,28818a30,825a2b7f,39282d7c,87fc543a,5981d96d), -S(1a9bd6cb,59008470,48b638e5,576d24d2,175afb0e,fdf4c499,fb4aa143,328cd058,36fc0b8f,6605f00a,9822ba7e,c97fffc5,9214a479,eb6c361e,dad89e13,7d23b896), -S(649da46c,ccf59f43,e04c1456,9db1da2b,7506bf36,fd5a1aee,6505d8a2,bb812f5a,251efafe,6319ae16,7d69c617,46e2fb8b,edf77fba,b0ba1fda,1ac30ebd,21c65ac3), -S(66e9a7b6,5682def8,a7a7db04,781614d1,3e176461,b833771b,6001dcb0,f87d316f,ae3d2f9b,442bad03,e27a8d42,fbaf2f9c,294c82dd,fd5b892a,b5aa2a54,df3f9375), -S(d2f13641,6c42c603,82cbb4e0,108a937a,cfbdfbb2,d3195d69,ae3ec647,50fd2e25,e8de2060,b52a7ed8,b1bacdfc,de026f95,a9027727,4a6fc948,76dacfa5,5db7cb35), -S(2737e1e1,5af922ee,fec76921,7064ef52,fe555f93,b01ce4ac,e03d6103,93742abd,f9e08b6c,dba1824,d1cb2efb,d9c5bc22,5a71193d,5626ffbe,9f8bdd1b,48aefbaa), -S(e7a21d74,2203c820,e7da2fac,333c1797,a90b69cf,9b909dce,7b71c052,5c690576,b9888022,82323a5f,8c327eff,d4d10836,23e53b2b,7e0d0c20,cbb48978,f2326034), -S(16acf8f9,854c5d89,5f761823,9a557dd9,320fc976,d2df1012,502437e4,7778efb2,1dd09906,c2c229ca,28e49088,dafc49bb,5033eedb,4cde30d3,8881a2b1,e3368411), -S(74462c7a,64d0ee15,cfc48ab7,874a5f91,c4788e0b,dca9560c,eee55fcc,c2ace309,c9468199,6e11ccc7,ae58428b,310a2057,9f8d686b,a15c2ed0,7f999027,5766eea4), -S(77e35da8,705a03cf,ad891f9a,a2c2e56e,c0c5b88a,38f9ec3f,8dae4c68,cea94ae2,7cde0915,9188be27,54c4a653,ae576321,5a8c442e,6931c5ae,f4657d68,3e30eb61), -S(314c833,d308857e,cc5f6268,406463e7,e2d91a5a,f536647,2382ba41,70c403b2,3ae0facd,f3d955d4,dd4b61e7,ca1f2e7d,92656772,2c08274d,cc98d60c,4ee0bea4), -S(36466998,e5449878,7b27b47b,b8dd54b,617e9132,d6252fb0,1f760e7b,dd242979,7fc61d6d,deefb379,9fa87cf1,aa05da7a,84f750c,e7a37b9f,e30bc4a,4b350915), -S(427338f3,644f6efd,e43b1069,b34517bf,af02bbe0,7638766,76c4cfff,65a01bfd,5d9113ee,13c7917e,ea760105,9476aee6,572f2322,5fcb9ecc,ce4a9cf5,bedefdc3), -S(73afaa20,a2fe0855,c35f1025,aa78f181,fd57928,b3e63d23,8b125432,79327923,d82ab0fa,1f9f08ae,551ed521,b6687a50,b4b4b530,4d5128de,172c77d4,72acf933), -S(dc9ee41b,d5ba5686,319ff6d7,62f1af02,4619b15b,c6dce9c7,3c5392f9,62ecf255,bd5653dd,11485718,68521a7f,68bdbc7a,5f58f46,3e81aad,ed200261,6e95cd33), -S(c32592c1,4a401b52,867fb0f3,6de768ec,11cf13ac,d2eeb1c0,31cc83e0,a500cc21,d9e5f61e,b052b496,b8b59217,75d47cb9,d774c89c,76d76d33,e932c50f,ff156324), -S(356db8da,9f3fe561,a9d21d23,5264fbce,bfc08242,e304e4a2,1b4dd044,7c4288cf,ca4cf6be,9c91b8f6,2d66b101,79246c20,6b99d5e,eec50a42,88d1b7b1,3bb00e3), -S(3ec546f0,fb367683,c4d07c50,c58468df,1a36ba4d,887bd57b,f574cc8f,575f321c,ecd4a716,1c65ccd5,e767df14,53aca971,16376c5,861dbb30,33258bed,fad26f50), -S(b2fa7570,216d4194,64306918,f80d6727,4dde9aee,7b801988,3e6807d0,78722255,919188ee,a4c77dfb,a460af47,72547de3,bf591a96,fae85fa1,696a3d1,dad8dd8f), -S(593ecbac,a3f6e76a,bf97d83c,719922f8,3e17a2e3,a054eb40,e6cbf867,c4fc5d49,7d23ffa1,c168f083,3765170c,7ab2f66a,3d4f8c84,1b9f18fd,f3e92918,51421656), -S(646075c4,181fadd7,937d0b14,75450f09,3f91e170,9644ff32,a71176ab,4b973839,5196abc7,e219433,bbc998d7,57b34f78,93fd3aab,c3be5c3d,20b352b8,5a6c157a), -S(6518d32,d20f4490,a605e95f,2fe826e1,1f4d6295,21cee6b1,d4d505d0,50416849,38bb02b2,2d415ca2,3c95ab41,ee54c4e9,f383e5c2,1dba2dae,a2a24a81,599708ef), -S(9c67d572,bbaa2341,9f704542,95a6160f,39b42ccf,eb46d56c,7781f3f5,69eb155,3fcad5b4,953f933e,3a7ec832,e799794b,38c99476,e85a6a8d,58a20c35,b9777602), -S(3976b774,1e135f5f,2ea4a874,11f9138a,ab02aba9,b4c54a5,9ca2683e,262e09b2,fcd77da9,dd3ddca6,6993d5cf,f997be4b,147eacc1,2bd18c4,a1f18525,fc5fd5a0), -S(508b5272,6918dcea,c92e43c7,b697f2b4,9cbd9d23,1057d116,2d34058,e08b06dd,79d3e174,2bdabd3a,1faf65ba,82477bbb,3631f08b,ab87dfe3,1fc76f2a,a4fa8ec3), -S(bd5c99bf,44d5202f,3b1855df,7dfd11d8,71d7cee4,cfe38e6b,243591cc,ee69cc81,4b15cf0d,cfa1764e,365568b0,630423c0,2f81a041,2c2aec76,7c70d441,bf35a6fd), -S(2011b669,509f7a9b,6987692f,f1ee2a86,1bc8a6c1,f1b2d252,4cf4052b,129e6683,902dfb06,4304a94b,9ae930cb,b2d28c3b,835d3852,93b170ac,b0a8fee7,4ad64a9a), -S(24f22f32,25e5fd67,6ff10f6b,c9e7a829,322329c5,d716af48,ad95a32f,289cce7a,3c39cfac,e2a2eff6,1f034f4f,394ddcf3,31efd98e,3247b3e2,a60c462f,4846c4f7), -S(a845991a,70b6c165,f465ec35,fa698977,ebd6a3de,490f7ec,6a3d82ff,72a8dc76,b8b71cbc,84975cf6,2000b12a,ad56029d,b58e828,f1e37578,73231c52,f03bd158), -S(f75a1682,f24cd7c3,f654f9c8,38bf93b5,f5519a2a,39f7226d,3635f4eb,1e496577,be008fbd,d42449f6,8b571d29,48cda471,ee3a28a9,df4ed840,756d1840,4f917cd), -S(d438d864,6173e175,9962a565,5dfc0545,3e7edf89,22f79aac,78806b51,697cee7d,bf0149a1,33476cf,b6ad8062,94a937d8,6a929ad9,f19a5929,fe648798,6e931ac3), -S(42deb8a4,38b7d9cf,2216533a,22047aa8,3666c4dc,188c1517,b506c42d,add6a9c2,a2d98969,5875a67e,18deaf94,3a73d1cc,798fb025,46949078,ef2063e5,63362ba1), -S(abc5db92,a7ec7944,f4a7c07d,edf53272,2c62e77f,30852f7c,47b34df8,41b1567c,d4917a0,b967ab9e,b05355d3,601e106c,c93d7094,e8e2d452,5731350b,11ee3c2e), -S(203a579a,3298edee,6e5b8f,be8c3a53,825f798f,447fb5e6,c3d0a68b,69dc2600,6bad56e2,c4403cd0,423211fc,38810f40,31696852,af4eb6ae,939fce9a,a2253660), -S(f69ee455,42cc8bd1,490ae8a9,efae8a94,5c5efbc,ba078b11,c79c73,492278f8,2f1ba10c,e93b9f58,a19baf63,46706a9c,78b70faf,dd55d998,c394a8d8,713654c6), -S(838a8e3e,88527ba5,57c80ec,e8818ac5,5cd73ac4,aae26883,bd4b8048,f4fafb29,661859d,6d99d8e8,17bbf643,73726d45,1379744f,4bc93c7f,b228370e,b4d369ae), -S(99d1e947,767fef9f,71ebef00,91d2b7a1,f23481c1,fa3f7d3,4883a18e,59f6f846,673dec94,4b3d82b,358cab99,2a434932,91bad282,e0c9c41e,6dcc4f7d,5737f696), -S(390abce4,4a25d121,301d79a3,dd273897,29145890,c82c712d,760429d2,c7fedf32,e2e868b1,6bb5c3b0,f6305c4d,aa00a536,5e2aac02,71649fc8,b3e309d4,281db193), -S(4e5e2983,59d53274,a2c5ea8e,ae4d9659,bf7b9919,454dfd3d,a86a3705,272e2004,db0b88e9,a3d30e62,696ceac8,1028dbba,144157f8,4073e422,24026681,a7184339), -S(5bc3dcc2,1e1ecbfc,6a14e36e,ed26527b,6f44b03f,c16f146f,23c2d1c4,535c315,d16a5275,99e9b315,6235d74e,957daf90,1ec9f9c7,de9eb7a3,ef6f8138,1b5b29a), -S(8ba374d2,f56e7da7,c6a7b17e,a4234abe,9f6da593,77b13a5a,3f1089d4,cab2f7fa,1e0479fd,8410af5f,3b0bfa63,612146cd,735cc6d3,3e72f982,2b18419c,939d9f5d), -S(6c8747af,cfdedb6a,a45b90c,bad3b269,6bf15c16,202e36dc,5b0488cd,cf954983,75e49114,df83874e,f9ad28d8,3f3bef59,256503e8,f8ae22bb,f7f18f00,94b3b119), -S(3892cbdd,7fb925b2,18e6bca,9c58426c,9a96eb2a,a5f3db54,fb861d0c,323049e5,817622b8,96e224c9,84d265ee,bfd2a996,f6444413,992fd2fa,de91ea39,aec39e4b), -S(8f001a25,19acf72c,f9b3e528,7d060816,3f84b4b4,16d377f,9b70b417,859fb58c,b3c34e61,685378c6,b757b0fc,a961763b,af2e35f7,810ee236,f1d0d7df,92000cf4), -S(4a8ab909,fed31731,50f16b44,785ecba0,af5ceed6,83e1a2b1,6be2a91d,643fa00a,ac88cd4e,26a8754f,d33646af,faff3f74,f04480d6,b988e24c,a5f6a979,25325b5d), -S(49002f29,145514e,f9f81133,284752d6,ca973ef9,daaec307,6f279b3a,6ca9d1a7,3a73249b,318fcad0,65233591,2a07d90,39d1c05d,cd40865b,eb0d3fec,a2bc7c67), -S(1ad5bdc0,2ef4ff42,6d0d079b,3d680e5e,65b0431c,b664eda1,9baec880,6604db88,cb55d682,1e63786a,e496f903,d8b4db91,c22e48e,893347d8,3110ed32,34869d92), -S(316f40f,be3c495b,9256456,1daf8f94,3bc7533f,56d09351,4052be97,fc3f8c1d,eeff684a,8a37200e,ac0f16a6,90c1b69b,c52ef929,8bb1868a,2e9554b5,cd218461), -S(e8408480,72d6ba93,3fec095a,6320008,f28a073d,73625de5,a4fc0f7a,c242f55b,6ba42703,5ac578f0,6ab1e6f3,2b760bf8,b91f89c2,d37faa1d,86fbfda3,e0cf8871), -S(b3c81c6e,d24d910e,a9fded30,a61e2706,829f9e82,87a84755,bad14bf1,36eff3f2,57077559,8581b2e9,254a9c35,5aa6e25c,fe7ff2b2,7c1e0175,38161f6d,6e3da4e1), -S(9b0cc368,c402b063,669e96fa,17dd0c17,bfa19114,966319f5,7b5ffa0f,5c0635fe,c5ecb380,a239b714,99cc147d,8087b453,b01d131c,d49f07e4,60278983,e975614d), -S(bfddfb26,ac59c5f7,f6d9693f,c5498e49,cb1c2b46,452f926e,b120c79d,f49c52b1,8cc30f2c,4bb7897a,1bf13f71,b5618ffb,18adec2b,5710c0f8,d7e915c9,abc918cf), -S(989861b4,ac8b6cbf,56d8442c,d753c833,1830ebb6,369ce4c8,95343abd,2e887fc6,f7a269e9,3ff86bf4,23265f28,d4a392ed,1c8e1383,5792d43,cf4de508,3dbec068), -S(96a6e19d,336af93b,71093fe0,a63836f0,4286b43d,4abba61f,66aaa28b,1732b09,66df4497,c453f01,6425ec93,c6858ae5,300f3757,eabd41cb,da6a05ae,90f8f41e), -S(cc2561c5,1261c57c,8ca2318c,5c5d095e,7de2294d,5776aa74,9870631,34eba9dd,a11a6b85,a79efa99,e72e14e5,c3348d3c,d27af941,305ca3c3,1c48a0d8,ee247cd), -S(9f0b93b7,8666076c,c4f75d50,c67b6e44,96d23b30,b48154f4,f0b11307,fffa174d,256dd20a,f8c0fe19,8ca0cf98,befeb0ce,ca81fcb4,7fc0822c,76bc809c,13eb549d), -S(a7e5f4ce,d6eb2995,a0c1fc5,5a644b16,2ba6ea53,20c7abac,dc36e6c5,15cbd06c,ba65401a,3e1b856,53d98ce2,3596842,287cf1c5,fd249ace,8dedb067,8553e1b3), -S(c4949322,cadf34d,bd82a36e,331145b5,42fb3109,44dca7b0,e0beb9be,8131bf52,912f12e6,5f3fccf0,34e14147,556598a8,550fddbc,9c7f9844,637dfaa6,4d6dbf2d), -S(68040ac4,351a1f3d,ec88abbe,bae3072f,bcfeb944,94ec6610,4793ae21,a8285212,9d5f59cb,316f3a53,3f7eac34,ffa386d1,c555d3a9,49eedf36,b7276e32,e7ac416e), -S(f77daad7,5893592f,978438fe,578e5124,2f98d202,ad07f6f4,1dd4a238,8e3878af,d0f7fa3a,adee3b5b,27f95fb1,4d4e157d,b524c6f9,15c3f5b,7d57fb36,e82dc91e), -S(371fd993,87312364,852234ca,6dcc7d2a,cd58f4b0,c73903f,ba08a0e6,2a81540a,365b2f9b,b4938fae,a9065bf8,5cd88a40,4ee3a651,a8b226fc,e760161e,734fa5e), -S(eab4b429,32320270,ad6e3b6a,5784067b,6439d0fc,d5f0c0ea,579ae702,9d615d29,541f762c,6d825cc,66544ced,5965b077,943e270,ec7a7e20,b1401923,12aabdce), -S(5d8d97a9,fc50bd4a,fd326a61,5492f596,e10a52dd,6dc836d,44128fee,a43f0371,1acaca55,f82d78f9,cb28bc7c,cd9c2409,20066526,3fcb4a3a,f375e44,59c68e10), -S(d37ec7ae,89fd69e1,b9c64095,d5986a7e,b90f6f6a,9daa2638,6138a42d,357c9cc0,ddd875f9,6cf1e99d,fb4478b0,817899cf,1b6cb89f,87fdeb09,c72c539b,9c850e84), -S(7db9b694,ed838749,d320effc,2ed0f86f,1fb0f7dc,e2ce09e0,a5024bb0,d039c6a0,4e74039b,b6018328,bd89a2b3,284ccb70,6d464ead,e9562946,5374744d,222dafcd), -S(b02fdeff,df11614,63c01a8c,1a2c6def,41c5e64a,656e1daf,f8b73443,af060020,39666b4c,14e7c169,3ab2aea8,993f7dff,814df0e6,73c38448,caf88486,ab0307b0), -S(c89a4af,f4141ec4,5a586aa7,53a2937c,e6ad3122,45256466,31336c3e,f401cf2f,b4b2066c,f0c9b0d2,d1cc0ca1,5dac6578,dc7cf9c1,4077dbe6,1a92263c,141e50bd), -S(fd4a625,69fb8443,fe70739,f7c6f9,3794d7ab,5d25c0c2,c099b390,ba733601,741308ef,8600fe30,b912c49e,6b2cbc24,4b84bf30,52e690e7,2f478bd2,12b647d4), -S(f5322b3f,786e45ac,6655c11b,ccda223e,d4689bbf,e5fc6253,e248be82,c0c2ca6a,69f2c31c,96afab78,86220dad,fb9a0c74,c3eb5463,93142221,50369064,1081bf22), -S(f8daf170,7075b29,bdc36d65,a5ed4256,b21cee78,8dc4776a,e3a3c40a,19a2014,7b7fecc9,c302068f,80e73041,5eb31c25,4a38da9b,a72725df,898d4226,ad6585a0), -S(6317fe9b,cdb3eb9e,b7379d82,54253a26,786febff,88b5549c,d4f4614d,40c174a6,8c52a679,a471672,d9e46d44,d69167a1,b962ccc5,38e1a42e,2bf5c731,f94f43a1), -S(5446a1f5,5a7e226d,f1dd2c49,8d49e2cf,19ff8f0a,34c6bc3b,66fc19b,ec036064,826f2d2c,1c347caf,57c90c16,582ebf72,1d02a4ad,52b78254,2f97d10c,d9238e3d), -S(4973367f,ba057d1,9fcda3b0,37d2e672,cc3cb6c3,f2ffd427,c99822c3,b42154dd,8e9b4d0d,9008ef0b,c82764f7,3cc7cac4,331b88b6,740b0590,30327699,82bb0364), -S(3bac5c37,462fc0a6,11d3d47f,b4857256,f4180689,adb7c16f,885841c9,f56694a7,486dec34,2d7525e2,6766d0b7,fa0442ef,3defbb9c,41e4e6d6,5f458191,c5cb79c2), -S(1f0d6603,c942f882,cc8c8f34,98bf9fb2,eefba019,9d95943a,2a209964,bf585b99,869162ab,b05b77d7,337ef0a6,2ff485eb,af6d8182,1e96078c,611ea8c8,338c26dd), -S(2011eaf5,4d8d9b95,787ac7c7,9d8d733a,9846ef9d,ef227091,2f0d3177,599b7f60,d66ecd62,711364c6,c98c95ec,57dca58b,2f972e63,1a759133,c6cb206c,285d12c4), -S(b016df8e,4c7671d3,44e6e84a,64ac5a0d,af2535f3,b614b132,7c9b2daf,724b2dfd,823ba8f2,ba237731,aead8dac,68f0843d,fed9c5ab,8393de12,b0615d5a,908d6d9f), -S(bb9c3029,384c85b7,d9af0869,b5f039be,4a6e792d,1e863357,e1e95ba5,fab61bbf,79fa55bb,47b97456,f0d4d754,5c6a57c4,5824e868,7eae06fd,a07f227e,b49cf76c), -S(e7cb468e,271042bb,3197a88c,bd4a4b53,5581c5bf,455e0ae0,f3f35a90,8311ec41,f0e67e9b,10717789,628cd4da,8eac012d,c7c58083,3ccb18ae,d39bdf1f,b61d0dbc), -S(738b7b48,6ec3d4f2,4fb699e0,a6a9f947,1418eca2,5688da1c,722be81a,78ce60b3,d76aa53c,4129e5ba,88881647,a9e3320a,1751339a,3c10a8c0,b879bd32,e87f104c), -S(31413f55,d4e5c14a,e091c228,74e971a6,1658b881,7dc983df,4ac98264,4b455e82,c86d2a0f,467f93af,b8ef127f,9c818700,cf54f240,e16dd738,c4e90899,d8a5af35), -S(7ddae61,d231a764,794dd836,1779522c,2be61c66,e79f8a28,79914093,8a6e9e39,86aaced5,6ab82f10,5bbffa0c,e73781fe,5494c6b4,35309de1,441077cd,93d7a57b), -S(fd5a44c3,ee4cc565,d2115a3c,16aed5fa,7b005fcd,fff3e537,3d90f226,398c9a04,1dd95003,722e3a31,991dfdd0,495160ff,ea55aab0,7109d060,d414229,c8f5be83), -S(c3a768a3,fd24ac30,4cbbaba3,7cc52ab8,82e3256,b7d54d14,9628ca4a,a8687f43,2a0d6f89,9df7dff5,eacea751,a825ddbe,ecacdc69,5c071093,ad79583a,32de93c), -S(ccca92e,d2ad3249,c5dc5881,8540e2e1,c89c6ac3,9a98401b,f719f008,e8fa5a3d,5fe2b717,302699d,fb7dba86,c368f67d,6a6f3593,d3845906,3621f73e,28dbd1fa), -S(9e5fbca1,7c3a766c,eda0755e,84bc0f9c,1017335d,1ce0f70d,b8b09de1,568ef319,9f8e25d2,8a01b693,864dac0f,ac82453e,41305f50,3c5dae08,42ec41c1,5e7af238), -S(43908294,409a955,9d02f8b5,4084b120,bb980c59,9c9003c6,4ba2760e,c69118ff,343d27f9,5120670b,ff8dc482,66646eea,6ea37813,3ec1fb06,ff5d9756,64327e38), -S(30e3052f,3f97372f,56d505fc,6081ce75,662169a4,a4743cb8,de4e3288,32cf9c3a,d144aa9b,9cc60ab8,436afaee,a6e6b64a,bc0178af,b05c3db6,42c91254,8ecece83), -S(b5b28b37,6e2d4586,c4c3a7c1,d701b28b,50da01ad,c18b91f7,a45daabd,134a1d69,ca0eb341,26746304,bccfae1a,4200420c,41af0558,596123a5,c7edbe9d,3fe04fb4), -S(4eb1aab2,b71aec48,84d626d1,8ee1d90f,77feff11,cf3fb8c8,32ee501e,48c4ae8,1247cb08,580b0c96,ae5e72fc,f7066ca6,e46c5b3e,3b8091ec,8ae5bb30,e5a7cabd), -S(b814e42b,abd14fe6,55cc4641,22d024d3,7cfa9f64,ab59cada,fcbcfc56,f1fa9201,ed8db1d6,2621bf32,23fb81ff,922a0e10,b4ab5cf3,3370aef3,df70ae19,6383b06d), -S(e5ef7b0e,270a0c4a,3f4df516,b516a19a,cb45648a,424a4967,39b9b75e,ac4bc497,7cd38616,dce6fc2f,fbdac49b,59afde1f,397546e4,1fdd2c7d,b8e9efb2,6b1300ea), -S(e0228a88,c62229bb,4fd0d563,5a66ef1b,e499265c,9163d09a,40170969,81f3c2f7,63ec23be,6c858aa,8390d038,665664b0,f085bbd3,d3fd6982,b2150d8,6695e0d5), -S(3abf7af5,f504422e,686aaa6d,86f519a4,ec6d8ad,b1c7db9e,75091545,5885459e,95110201,2b8c0149,dffc0cfa,b1510529,9bfd537c,43c2a1e7,613c4007,7a8be9a7), -S(16c5a86a,57dbdc0d,84320d49,610b637,437d8a27,5bc108a1,702bb27,dfc04e1a,f5387f3a,7596aff2,2a9ead9e,fd87da3c,68bf5efe,b277899c,7ef19394,cc698cb), -S(8350a35,c1fc83f0,3c306984,799d6baa,3a41bed8,45cb2126,ad8025a5,6f1da1ea,3abd0a5c,83976b4d,79f150af,f47a684f,931090d5,61a61a50,a4ebfa7f,d74aa002), -S(58199602,d1ba3202,bffd7311,8679e8ec,7d5dc6f7,f937eb4f,be70b8b,4379bce9,290dd5db,a4091af5,50975e3f,1f0d42e5,d375a26a,5c6768cf,7eade4c0,ed315166), -S(492c0e3c,8442495d,52d4d356,91d03e3d,133d56fa,7371d64e,ccb384af,907fc5da,c7bbfe15,342b1d6,c48cfe7a,595bbab3,d7c4674f,ad9f92f0,30e2d602,4cd10ed8), -S(adc96fa5,f21e4e6,5c5951d6,53379f3a,b2d92ded,ac038d70,ff1e644e,7c7d4de8,750faf48,16e45f4c,697a610c,11dc363d,4846564e,afef6e7a,335d5d,2af0e171), -S(9567b748,4584b4ae,21e6a12f,cc8b5185,e2137c1f,5f30deac,eadd6b55,ecb64964,b9a445c9,3c4d8a7,fb0b4469,45976ee2,cd47ea88,ca3269e,b559e689,84b1a130), -S(e700f079,11611a38,b0ce3273,b420135e,17ec189d,d1574695,d3452530,c8a59f99,e6685c21,6ed61c08,444b51ce,86681796,8814c1af,aa712a32,15e6619c,85bb0bc0), -S(c412823e,31b1f066,9d067de0,d2e2ed09,bda7b53b,6482d8bd,7f352a4e,74e4cabc,8809a001,3f12ebaa,3b01df9d,355c199d,854574fa,374a85fd,6d066377,6957e9e7), -S(50675ee9,1d350fc1,61e189e7,a4cf4955,d987c194,1b01ce9e,1473add2,ede4cde8,2f67926e,7c4baed0,e0a25df1,468c79e6,b07f8bd1,9d460a24,4233f988,45547047), -S(34f8f31e,7a6d98d9,73eb395b,3368b0d3,c566cb2,c2a8379d,bec31c1c,859dbca2,db990a81,fe7a234a,e63b751f,369ef489,aa6929d8,97a3587e,483d19da,dd1b40e2), -S(6bca946d,e15dbd77,9bed6b31,25986a06,50051c2,db72ebe4,81ed24b1,f9cb4d5b,ba942bdf,73219596,9fb8357a,4bbbdc33,c08f1c17,da37e409,50077c6,da41456), -S(3972511a,f367daf8,192f2725,8597c14f,e151bb46,5b8c195e,610a11d6,e51451ae,36f1e442,82786dd2,8f05981d,292c2241,9844deed,5bed41ef,fb0aa2c1,d798541e), -S(756e5104,3011d1c,e992ce99,76c09063,6560e9e3,a85de433,6d9218aa,11796c34,4d714894,96279d96,7ed41034,77fb1c87,db269661,8c452dd,ca0fda9b,e8c31951), -S(e5508c1a,b9e90d6a,237e631e,507bdbdd,ed3672a8,38ee0f7c,72eb4587,b4231e4,24fcc0fd,f5079407,e3c66b02,9e2f37f3,bec5ba72,25487101,b7e68b08,731572e0), -S(d90085d8,d80452b5,cb99dafc,8fa4aa3e,819c6ab9,a407beab,4bc6446,b5225596,e3cbc413,bf74b383,d2f8e92a,9d6062bf,a579fe37,e171734a,e50ac682,da75710c), -S(46470f31,77b6ecd5,34add036,8cf9724e,398963e8,573d3d01,ce3f9d5e,b14f50cf,1a670f11,15b60d70,ac4c2b27,8f7a684a,73446d52,e3c2a8ef,7a84a06,8512f6e), -S(4e92916a,a3787bda,7cc677cd,6f7d26cd,4a6847cb,23d1e3d,beb32de0,51fb89f9,6bdd060e,739e3122,a48e7657,e03ebf35,bc43f4e,3ad864cd,49242d29,fd3537a4), -S(78fec768,fbf2658f,78f21a83,5f9e327a,67d4101b,5ca9fcf0,e69e7421,d69a3045,5de2a6ca,25adc6e6,82333b72,f30557e3,f2f003b8,1dc817e4,be0ea20f,acdb9f59), -S(36327d81,a5a94289,105df5d5,7ed407e8,f14a741e,998f1017,3592811e,f052a126,3325ff53,33c1395,d2548216,4eb153e8,ed94a950,8376cdee,941e3417,f2f0ea46), -S(2e3d6f12,18373ec6,6435d58,92b54576,545668bf,80fe51ed,eee5ca7b,7a5f8806,6f2afbd6,6465fce8,308eb046,1041a23e,f4515687,64f8148d,a377e329,4b6dbce8), -S(96dfe31a,87620ab,647e0c2e,6e9bad96,4ac4ecce,28d299e7,e80f25af,da5885c8,9a1d9194,3507b674,fea7b185,21a2b70d,ac27b4ea,b370b9b3,a0c2ad0c,2bc37628), -S(298711da,2e303ebe,2cc5928f,e437ce90,ba675b2b,b896ee44,920fe3cb,e34ec55,dbe55194,8671be1a,1af18584,5db9fdd4,c4a586e1,98a350e4,c1326d04,5aa3c593), -S(cd603c3e,326a7c25,575b07cb,d86e0a9,d764675a,b3013622,12ffdf5,708ed855,f0d100ce,2690b76d,62858759,8638c992,4736b18,8beb66d1,328ff5b2,4a1fe52b), -S(5a90312c,30a58754,cfc6d248,669d029a,7da84243,9de2b1dc,7731a460,b05b6e21,fc0af827,5890da91,ac2032ef,e82b418a,2ca1c37c,4a19ed0b,8cee0ffe,7386fb37), -S(61ce7b79,1d46fea8,8f4dfb34,474577ad,8ecb02a,ab23153e,c0ece543,5c472e3a,4c5bebe3,2b82502c,8c68ecee,57f29fd,ee7f45dd,fe5bd985,2418c809,6ebabede), -S(df3ffe23,d13b2b4f,4090daf5,a51f343d,17123083,edc4172c,368ca75a,8bfbb16b,9a21d41,39e53dc,836868cf,9c1d0eef,d4660455,7ffbd379,cb7a118e,36273f2), -S(24470f10,b0e5171c,aeaab136,2ea9c1f2,3ff3a4d9,66a1b7c0,5110b734,43a363db,ce557547,69df589b,bd4438b0,14d4f4d,bfb56977,43656c25,83981c78,5803d5a7), -S(67b07bd3,c96164c4,da09d5f0,be038a2e,74ade7dc,cda4e7aa,28699156,36708765,e0183e53,445a2936,a44df51e,c6d42bbf,21369b65,134accf,c0a6ca68,9adc03e), -S(7e3c57f1,43f1157d,f06eb86c,e7a3d625,df513d2c,1187b1ef,2b4a8778,cb9b1192,81aa590e,90de3ee5,3b68d336,c6c77dcd,925742d5,642baf50,f41e6258,ebbdd5b2), -S(784310f1,462cd93a,dae83002,7904934a,2a6682b5,6124c5da,ac037d87,61dab615,5365ac1c,d2f3bffb,f8454ba6,6743cb70,a08781b8,ce95efef,b2b7d60b,fbb7e2e1), -S(ac75ac17,87006c3,e687effb,5822615f,c5608cf6,3ce43ea9,affc8d,e4a9167c,d75aedc7,42240a0a,79f79c91,93c9aee2,9bba3238,a5ac9154,d98d9664,27faa81), -S(943e4dd2,ae1d3f5e,ba7448e8,15d44c3f,ed1b2333,46c6b1b4,b6ff8386,980c6fd3,d08dfc2d,29ebf8d,30fbcd9,e93e4d70,d42e6526,bc2e7842,ce3cebc1,f8105b58), -S(4f750c16,909060e1,f7509604,9030e65,1e6a768e,a3601d3d,f2f0eef8,e18df94,e434f91a,cd77e31b,c9adb0ca,87860de7,6360c0b6,88accd44,715a114c,aac8eb7b), -S(1a609a28,76eb1228,58678cd4,57c3b762,9f0208a3,ba653603,3f887a4f,7df50ee3,99dd674f,864e8662,3ae00cbd,2a484dde,29e9de3d,7ec83f92,ba60f93e,bf316b31), -S(d2fbcb43,5c932861,2d3fcbce,f84ae490,3003b61f,c7927cb6,d7134196,f8858c76,55b6ca82,280880c8,3d66ea27,e8e24ca7,670bee29,1c4fdc11,56bf661c,2f2e0eaa), -S(5c6e8973,c1c98cf6,71d5cef,4acc76b3,b4c5165d,ce162d04,543d4fc5,3d97cf62,9a3271f2,d829451c,8f32652e,c43b717e,a6008478,637b32c6,66a9a40e,2f157c2), -S(be670a91,1930e634,a65aa675,56e342d9,15037a49,845d46d8,ac14a8b7,6024d8ab,4b4418a5,6583d2b5,6a58e324,a7b57eb7,b5111cbf,8c6a39a0,5b22d86e,b51e2dd0), -S(afb47c08,42e4ec13,13fcc64d,98fe73b7,d6bc3a97,c2ac8823,45a82507,e3842e3a,3b448b26,f1e586bc,9425fb77,37a70de7,f559c1fc,97c9fce9,5da20bd3,945648a2), -S(6de4f9b8,29fb7313,d27bc525,c5116408,d03f653d,56244f0b,bce94fc5,2de49039,653e08a0,26d7c2be,dd67b32d,5d031255,5c5e9c5d,b7aa632,c59f971a,85ea0458), -S(91cb27e0,1e60b6b3,6bb7df48,2dd4542e,d36951d8,53971a85,127f414d,67ef279b,5db95774,f7b60f6,70ac3c7a,41bfce24,6aa8816e,4545040,df4bca6a,7173829e), -S(a3e3386e,86c6d952,ad929b79,6cbcc967,2677138f,b051b3c0,53e2b4bd,2d6b7d0a,e7364d0c,b404b835,4f65c0f9,68ae823a,be5c6cdb,a02a72dc,b5ecf7d9,64eca22d), -S(fbf251e5,6b61ed54,467aa548,cf4a4667,258f0334,f6064625,b00d546b,c61f8e10,1a1c0c11,14634786,e9101685,15c0ea29,bf2b2537,529912de,13ef3fbf,3b789722), -S(e0bfa77c,21555000,4b38957e,a287519c,c222b0ef,81f71d76,9c3608aa,7ca6e7a8,fd778438,2ed98141,1254767,d770866,84c3eb94,1fd4a506,81cb05d,311cad5f), -S(6d612d53,3d7cd076,d1494641,af14db85,7db44e5a,c22ff57a,13c198cd,b2cb50dd,62cee347,915640f6,73a23081,f5999fbd,5fccabe9,b84a0409,ee85160c,93fc6dca), -S(393c515b,5d1f771a,e6134c4,c06cda2f,27b01b66,c3976ca6,9879de82,146e0dd5,147e097,83f65b3f,f5e29f6a,12df5fcb,2ae22d9,857f9653,67efc9cf,6210ec7b), -S(bb340fb,c45c7b6,8d3b1863,9ab961d3,b455a803,c7ad6807,62077c08,6fe10bdf,cb210b7b,bd7edac4,fafecb0a,82efa8bc,3b6fbf63,711d24d,2b0969cb,f39ffe44), -S(139ad93,4a0d12a2,83c50f54,99d5cbff,fa746252,6856a5bd,98bb59a,42f6512e,1c2582c6,b1da1d1c,4c8e85a1,77bc212c,ac448eac,564f0ea2,a23f721d,4c153ede), -S(b49f8e1d,ca33f0fc,5713a853,bfdc8e16,edee6fe8,eed7e310,ae0e6d73,e4483c12,2d2d0750,bf422c6,e49b12c,407bb05d,203a44e9,92e0fe5d,af596676,7552bbaf), -S(78099937,bdd416a4,8c9480d6,82a9741d,d57c89f6,a4ab2b8a,8890937e,b3f16713,b3981d6a,8b4f3045,e3d20e74,264b3d78,48b0f9ea,f8d0ebb0,2bc4a2a6,7da3a93c), -S(64cd225e,a4604ff8,b61a8c71,c3f71d7a,62423add,5c851e89,b2430cf,f6300ee4,89f2cb3f,560f0a1,c5e26497,149ffc59,cf4ea956,f20f039e,f2578092,5c2b4a5e), -S(70cd9c8b,7250da54,cc7ec051,43f087ec,c1642e69,b5b74d95,e728a0e2,27f6415c,57ac1d32,dbb0e87d,9a8ea661,87c4bf6f,bb4aa780,18f7611f,c94419e1,6829af3b), -S(a20709e7,d075779e,baa742d7,1e224373,dc7f9692,f56fa9a0,e8d81847,28e23c5c,3f269cb3,28b57b3f,48db2e3d,aebea0fc,c1d456d5,a366052d,2dec91d3,5405a53c), -S(fc3957cf,c85c590d,f2d6e797,c0aeffcd,452ed47b,57213830,20b3f3b1,56149203,65ef1279,884a1a2,bf632178,e23fd9ee,3128a268,bd75b70b,bc03a177,22daae7), -S(e21c288,805a1fbe,8c0df51a,c5360c8f,69c0c10,624aa044,c071ad18,8dca17d4,9fd946d9,8cb67d2f,200fd03f,c3f4fd77,2ee3c24d,6bdc0d89,55e314c4,8151944a), -S(3f6b8f7a,d68d5d6c,fec93aca,7c9716e5,9bbeeedc,dcf2dfc5,713046d1,1617e06f,97112f31,f5e31334,e258e311,bcee3160,3c75f8e,4a67f039,50dfb30,8eff1605), -S(c630444d,7d6a8d6,f396b431,cbad44fa,88f034f0,aef8f6a,ec8e4921,a3373204,2d459073,ecfba3c0,f538dcbf,65a54822,b8d615ef,ced3a394,6d31821a,921cff7e), -S(1b2bab7f,4e833c7e,432d81db,d7b34e2a,e62c3c43,ad1ba0b2,f3cd3d38,88d96f55,e2caec88,ec4d6660,81cd2bd4,fcad109c,fbdce4d2,c0a24aca,d665fb56,e4e143d6), -S(b6a433b3,1f1a70a3,e53775,e5d173f,3d890bb5,b7ceeb9,a62369e2,94705711,95d10503,8959c755,95d8d76,c30861bb,acbda484,9a448481,6f4931cd,34e59d1), -S(b12a9bd6,4b0f0cdf,9568e3bd,a6b7fc7,40f66c00,398ef73f,74dc968a,cce34b7e,ce8dbd0a,9ec6059d,b17f37a0,dd12b6df,6d809b9,47702dbb,a0e30f31,6b10a6f8), -S(f16e345c,70a20726,616ab118,a5a5f252,b0e14377,79208dc3,194ec16,7e8f1922,62657132,12d111cf,bbe9af4b,be8071d4,55eae6a6,d3c5e153,4efda17f,5cd66f42), -S(b4b85e71,f1ee5898,4c660f17,e48ea158,73963356,b8adcfaf,5257459b,77d02399,baf95723,70486c9,567d6258,ee4b403d,70966cbf,4ca6e0dd,b5f8772,1e053f45), -S(b43dc473,1f85b542,4a8252d0,ef1e5681,720405fc,ae4e6406,7d721eca,552d4128,5f9ae2eb,f5f08f78,12181d44,6111ea2c,ab5c66ed,1cebb8c4,2c1e4a50,f3653d), -S(3e657382,cbcbe472,cd8f7e2f,6ed72623,9fc1fde3,15633d5,b3219e70,cda875a7,ad430305,8aeb7ff8,9be1b737,260e1e7a,5d6e8a08,3ad7f5b2,2912b9d4,10ba267e), -S(c30ed331,8f2a76bc,3bf292c9,fd98ba86,3039ec2a,b3acf028,174da3c6,dee3e3dc,54b642f9,3c5ca6fe,987cd9c5,4726d4c8,f59f464c,b847c319,df74ce4e,7da24376), -S(8ca8ad3,7ac218da,1f2c33bf,73a681f0,1c3fc0a9,35bd7540,fbc3f2bf,82e0763,e48ac338,eef9096c,e3d0e679,249c9183,4d0cb3bc,b45fa70e,7aa8356c,8fd3fd53), -S(a75b601a,aeb33b04,d3e201ea,bedbc5d3,35f516f6,3c34fe6d,e7d58a00,a6bcf3c7,b1b814e0,b143a048,75a4c5de,14a74d3a,ddcae6b,b220a806,1a980b18,4a3b49e6), -S(e542c034,9fbd716,d92f0aa3,ab2c7be7,4e81d38,39bbf04c,38f9d933,33e2447d,93f4ddd2,af3134a0,89c3ccf9,34f61ae2,67530a42,12cdbd4,7641f7b4,c21e732b), -S(460de699,4c3b21da,6cb661b2,3cea142f,cee1b50d,efaa3d72,3d55d54c,60bf9258,93de277,b9acd4a6,89bb02e2,b284cf78,4731e219,540c7131,e2636ae4,4183ba80), -S(e5df9251,7e1611d8,5218f013,4f4bb212,9a0a2bb3,b65b2678,45c83bcd,60f29d05,758dda47,b25e31fb,56a8c18c,f91773b2,6bd26548,6925fc0f,a5e34787,a881f731), -S(7bf153ea,7a8cfc9d,e7558c8d,5354f7c6,f8b41e14,7ba7a8ef,4296289c,f134e6a,94367f87,3ea37ec,cf3e1be0,6600f27e,5a4c32ac,1fc4959d,f5f9a6d5,c4e161), -S(c9e8e330,8a57d46d,65a3ca70,86a0440b,1bc37ac8,8dae6d46,66c4497c,5867688c,c7f12a8,d727c5be,5d2dd18e,1a996ca6,b5477b78,a2b671a9,6fd6a391,95ca831e), -S(dc45e141,d9f18643,db12b41e,facbb17d,6d30da7c,65ceed2f,c481df55,1b6fa25c,52d23e99,46eb60d7,acd8cd47,ce592359,9216c796,320c6657,cb4e411f,e175f104), -S(f4b4ec85,6b55bb4a,aceee0f0,56cff661,eec827c8,8a452911,8bff2ace,3c0b4a81,18d14680,57ad90c7,161f7667,b512f34c,fce3bb84,c135c474,d67c4afe,49b589c2)}, -{S(e7ff8d5c,83bd5846,5c967b5,37ac0f36,b9ffe9d2,fc7531e,ef183cb1,7369c066,9a9c3c4b,e482031b,f6dc69fa,843ea90e,de165479,26ba201b,5f05b00a,dbcc30a8), -S(ad51f3f2,e91d632,a13569d9,2e0bbb82,f566e7df,cc8d5541,54dffddc,2724c05b,1039c9fc,c61bb90f,7050e8ab,deecf700,80509a64,8fd2520f,9789501b,315da78b), -S(2459de87,8ed4337c,fb77d945,4f6d2e15,7153048b,1ff76121,f5ea4fd5,cc77dec3,296ddfe4,ef31a5c9,65300ccd,6bdcf369,20e7b2c6,c1368f08,6e416a48,3d517fc6), -S(959743b4,de6c9311,b95949e3,5f20f06d,6cbdf08,ad40b2a0,5239cb2d,4fe99ef6,1726fe6f,2e6815db,96242e97,ef5dc384,b8cd9ff6,67ae475e,a5417100,bc882cf7), -S(fa08226c,62476f0b,88392127,219b071,6316d6e7,c21b3a44,4a07a2a0,cfad3bf7,f24e916,75b2860e,e6e6416f,d9e6b119,ee65e6dd,c27f02e4,3524509b,bf9beaee), -S(da3f52f6,1102d1e9,3c213935,736e4cdf,72ad32a5,32db4f2c,3e388eac,e403b3ee,93c3a997,4d4c2f61,9338054c,15f681af,d8da7b13,cd89607e,dd5491e1,9d695416), -S(893806c6,fc32e583,997b5859,870df579,dd750d08,49dce8a8,2cf47cb9,a92ded25,959c9301,c7982c96,4e4bd09b,abf38f44,bbb54529,82404e22,7b862e48,adfd6276), -S(5cf0831e,319d8690,ee7f690c,c0b15734,9152c12c,acbd82b5,49c8eecd,b4f17043,2cf5c316,25fed805,97bed5db,4cdd3680,f97d389e,c83a5fc2,1766bd9a,6f95b607), -S(7c0f67a2,ed9c4e10,7e06248d,51c79f70,7e62b409,afa37f0,2bac0b80,f2b04417,748bacd4,2401ffd,e374d639,86414233,c4b7eadd,5449bebb,9dab7248,c5dca538), -S(1c2380e3,d084e808,751c4e06,d0d815ba,a333c94c,ba5f6de6,379dcc86,79f4cf6a,2d6480f4,d237bc92,d05e761b,4818051f,afecec25,9afe2cc,cd032537,f3b21e8a), -S(411596,bca0efd6,f1262542,cddbbf3c,a90852af,80689683,47f9c0b8,919b0696,6774a5ed,2c06a3e5,d369fc8b,1c1ef075,bcd96b15,8f724e57,38ebf92d,7eb6a983), -S(862e0b2c,19500fd8,8d00f2cb,14af4628,bdcefc88,ae87a663,c9e901ba,c2cfc537,6fd77f08,124c45c7,44ec81b,e420401c,399ee4ca,aa8779af,9f4a9b9b,5bfb3c66), -S(fa787fe0,faa2a7fb,8dd1ec29,f81171c4,82e893bc,2aedf4fd,4a762bc6,dfc26752,428f4df5,8e057e0e,491fc4a,82cae796,1cad059c,9ef367ea,a15a4a24,42d91241), -S(e15885a0,2af497df,34b4c324,d22c88dd,a3e34da2,74de0b12,c2c9ce12,d566d33c,3ec3b7c9,209357e6,1f360789,a37b4c78,910d2518,3d367ce,5af7075a,842a1e08), -S(9c7f6bd2,8261d396,97365037,b57f2767,91ae02d3,4de1c089,646423e1,404fb32d,844efbb3,e720a3dc,a5431147,8d0aba48,221d48ce,8a05a385,9505f4a,458f7fb7), -S(b99277ec,fc7ced54,58300c7,783d1d43,67d40dfe,48cc1743,e99540,b46eed6e,91832791,f0aab15d,a293a4e,c107bf69,64895eae,ef0b7b4a,4db1de1c,f8f7bb97), -S(ea5c5c32,6b221ebd,47bf8838,91a0ab8a,abcbc30e,982a5add,5f7517bd,58f68927,9258ed81,2f732f1a,43aa6b76,f9982d24,8be669e9,42cc5f92,90925d07,b96c651f), -S(c8e45dd0,37f1538a,ddfb79e3,5eaf2d1,f5c43535,50857741,481b8bc3,b00270c4,46183384,f3460d3,702632c9,bc340b42,2baeabeb,624d2aa8,1275ced,e2d04df4), -S(2785615e,b34e2395,5fef2170,18ce8e9b,8520ff6c,7f0b0654,40e2e44a,99b633aa,5f4d2fe3,8f56db89,5052ccad,b7e2229,5295ce9c,9028f37f,709cc9ca,6b86368c), -S(bdba87f2,7b750cab,87e4f36b,f2a4ca30,49c5af49,d11d9562,fd67ee3,5215c2aa,507a9b83,dd4a40a2,3aa5970,673f89e4,3dc6c387,28b3db8a,78ee2c9b,40a2b99f), -S(bb358e33,a07a280b,b87b703,6df7d832,6e531a38,c1ff6f48,5c955057,e97a2524,d62efa5a,435d192d,c40c39a7,2c654e34,a6d8837e,b33a602a,1097f1ed,40f1dabb), -S(bc59cb40,190d6454,c356e22a,af552e02,a6f7f671,8e56ab94,10ed6e51,539ce74e,3a3b07b7,2404e40c,96c561f3,ce227241,e7035c13,29c7e566,8cb92126,c6543af2), -S(19654121,d2e13ac4,dc087c0c,373c8e98,e4447c5f,83c976ef,2358cac0,d7b726aa,9832eba,58a67ec7,4d993935,b2451ff,3118c1f8,bf4f2d98,5ac9b2b4,dc4347d9), -S(2f222e27,6c7059bd,88d87b7,a7268fce,c7250741,1cbf52ac,7ac1ef04,dcfdc769,5d7695a4,37686bc4,df42d1a7,43a7c025,820fde6a,1fbdf17e,846115b0,3e64ddc2), -S(9a34f22d,628e0863,52860024,7b4e3b76,60d2c88e,e663a6ad,57f673c8,238a7e6a,86c1a12,29bb251,c6e87b37,d135cd90,e2a7d01a,4a067f67,6d8895f7,57085b46), -S(e526e57e,73b17b34,8288e79e,4f26f864,95beed8b,f9476dbb,26cda51e,b4cec5d7,5b7d63de,97200b0e,e76b2bf4,82e01ed0,19324e63,16e5142a,8058128b,6409e8e9), -S(7a28a623,cedd623f,37b33b39,149858f6,ff7adb4f,f06b1661,3dd23da9,2b68626c,41144248,b2f62a79,e9019071,aacbf63b,b8ba1238,a6738d90,ac6429d2,d7a485b0), -S(cd3a96eb,8c378c46,de954c9d,8252dbaf,1db12f7a,88a55190,87d046cf,58df5665,9649b78b,22c76b71,919b8a2c,7a0d6a4a,5be2f0be,4f1b8a2b,ca2e898,15dcda74), -S(44201d8c,23ae0de7,6e9ca9ed,e0a052e4,753a4a12,87129b55,f33ab4ba,5bf095e4,730f8bf5,53e528e1,ab26d7df,a5767a04,b3fd8653,7769cd0b,8d1b5f49,bd95692b), -S(1d5fd8ff,14da9436,118e41a2,55df6bc,52a69e6a,755d7e70,a48ffd3d,ebc4c88c,a53b538,a3c553fb,4bec6c1d,259fc11c,4259126f,12a61f5e,1c4bdfb0,de34b167), -S(9f96c868,f95bbd10,486cf72c,a1bd1cb5,e45768a5,8a5142d1,61e03b78,8f1c92f5,7a9f8938,fd39796b,6eec3f74,a970b183,dea912cd,cce14843,86ba0ae5,e6b2e785), -S(671e2f85,60f16300,f60173e,18ff716a,9028b22e,8937c118,c21fbf11,f54b1e15,58310025,7287d122,2a866a6d,8e85a041,72531a92,7d727e8d,77c33049,32f50d22), -S(59215ba3,afb0aca9,1f61f7de,d69ac95c,3b0a6ab3,cc5fd312,2d23b287,7d645805,433b9b65,197f8360,d222580d,832c2cea,dedbc92,610b8c0,4e0ed5b9,45b52583), -S(ce3be955,ebf0a088,57bc0859,55898466,8b428982,ef1061ca,a564c48,9fa8b57b,81ce7ad6,224e95e4,d7449cd7,41628408,48249b,d2e5d0b6,6757cb73,7622def3), -S(5f6145e8,1cb8ca27,a9d1fd53,9058f5f1,cc423d07,a23f79e3,d1256541,689cfd5a,f129799e,6a9044a4,784ced66,40285789,c8b71aa2,2fb9a2e2,92a73f0,b7686ee2), -S(ae14d7e5,ce5ff7cf,a419effa,9272aef2,7e0ad99f,1b440679,9d362033,2640672e,5f8670c,cdc2b366,90d07259,9fb1e560,5e71e079,2bf6a2a0,928a8438,1c42beac), -S(61837dd8,7d096602,62119a7,f102eaf9,d01edcd,8c6a9335,488b5c80,535573d0,dbd49194,1eeecad9,3bb5688d,6bff2bd9,fb4573ce,b21dfa1,2766de1e,1b63c8c2), -S(3ef98234,eb70107a,f69be2f6,b3f935f5,f1bec759,2b66262,f048c8a0,8252ee83,451acc9e,7c4c21,346e9ee3,dcfe4a77,d35bf00b,d0f2e3c5,42591441,c90b5354), -S(b1e94abb,912be054,1c38bd4a,a954ccba,f92b41d0,82a74ca8,59ccbc21,755d00be,e8d76ab,ec5aa0f2,49b33481,ac6abb04,700edc61,da8627a1,26812abb,ae5f67e7), -S(a0cdddf5,ac430d5b,f5fd1755,6025d4ed,4f9a0471,83749ea6,232a8061,f27672fe,3c50bac3,f0c01cc9,5c10cc51,b14ef6d9,fed1a7dd,b6d07721,947cb606,8ac81cc0), -S(c0650540,c32945b0,8e42c487,50f2dcde,8c35dadd,2069dbc4,28c8a318,48c0b841,660e38c9,eeb11cb3,aa2b61ef,d7ab4796,85161be4,f4b1547,e701fdd1,bb3dfaef), -S(fc2efae0,77ef8607,286aa5b2,5b114f1,fdd82e6,ef425b23,5170fdec,5d95ffc1,f96a8710,7fa5aa8f,6fc0cce,9885840f,737e1b12,4d6d35ff,e1dccab2,4a863901), -S(d420dc89,758a24be,dabeda8a,27651138,2eacc153,3395db23,71ca98a1,8fd72f57,83f34a52,7245d018,d2d599c1,299845b4,42a06b9,c93142f4,74935632,9052fae), -S(af32c241,a6c86715,471e3ba1,4bcfb60d,c9c33ae8,84ec4403,97b35281,b36ee336,9fe0c80a,1962f8e5,5c2060f2,eb24a7db,1187037c,662cf832,18e0381f,4f92083b), -S(cc44e6b3,c7d4dd22,b4e24310,ba7fd59b,efcb05d7,1411781c,979aea2f,635c62ab,cb05b4de,c8ce6dfa,2f229629,48edb6e4,ec0f2a8,aa53932f,94cda08f,b81e3da3), -S(a7d3a168,b175a11b,ca46067e,c603ccbc,1d7cf852,edefe1ba,ae633a38,318bd97d,361fb00f,5344bc31,450732cf,30b8d728,2aa100c8,4c52b160,9b0dd3f7,66405a2e), -S(41ce228f,e6911ef6,5b93a0d,39d4c4ab,1b4f9ea8,9f34f190,56b6edc4,90834b65,85f7677b,61323fdd,7c0b21d8,572c7029,4118fab8,d432d330,dbaa24df,bf506964), -S(a3532f8b,1137f907,19baa4ae,b0f6f909,412eea8d,290385dc,9c0465e8,a3f9f900,94848f20,d1f41d8a,c433f01c,74a0f120,15f2423,23780597,6c6ddf2b,a369186c), -S(d51d0609,2a9316b1,495c380f,78cf6b0f,53f11fe3,b89399ab,6120d494,b18ec5c7,8efa991d,4a35009e,1b0f7adf,72207c6e,a1ac67a1,6fc009cf,fb25f63d,7706efb4), -S(2155010e,7820453a,4e18b616,6439995c,35e9f1fe,bd4b8c98,31c2f062,ad5db9c3,d951af7,792f7575,a0209ed7,3558efc,8858aaf3,a7dbdd05,1701538c,e0abd925), -S(b02e9c81,6370cd9c,a78da82d,927e1d43,ff27a07b,a8a3e773,a66fa344,331d1d1e,e184e2ed,276eaa1b,40cd9696,a98c41e8,7eb2f0f7,fa3039ad,9a18bfab,48141331), -S(d79e98f7,724ff7c7,13510c81,a00a6056,b769dc28,25ddb5b6,6e21540f,a0b9df8,dae7bca1,8896e67c,9f8855d8,4b2dc1f3,97e47230,d4915e99,33897687,c1e7ab0f), -S(1754242e,1719e21e,5dc63a64,5759d3aa,5003d20b,db8a2ca4,a5375e78,308c4423,7373ae8c,97c5def2,fa602af3,3491f50,b26a986d,b1255f63,9b3e1f26,3ad0d856), -S(a7b70ad8,4807a34c,45adf85d,93afb7a9,30ad1b1d,25d58847,c278957,bd96d64e,9cc8d7ca,d66f00c3,5e0c9476,ceb4f915,76cbf1d,2ff34b80,aa913e5,758bccc7), -S(a4e7077a,8be0e97,d322f62f,74fb5112,c885975b,4e5d106d,1df93a05,10382a76,52580b99,2959cfac,bb27800c,37e0605,7a26bd85,c97154d7,c51b5b01,f0496749), -S(14371fca,1e37adf9,3593be37,2e634fd2,69d004ea,50d2f412,77e0b74c,d82491a6,5130d626,4d570bf0,a9a1511,af29105,eb1937db,fae1f027,45a2e725,bd63589c), -S(3a23c190,995df13b,12556cd,90c4c05d,5bfd4154,8016d31d,85ea4506,356ca3bc,b32f623f,a95922c1,9579f532,9fe6d0df,b3b3c63a,adf1f56e,30b946d0,e6be0352), -S(643cf33a,9530502a,65e26491,b895ea3a,27be865a,231dc0cf,b42249b8,b8eade6d,58321730,ca9a20df,ea6be90c,a7f056b1,ec3da1d1,e2befd74,5a39a46e,24257f04), -S(35fba1a3,f33025ca,96401513,b443d042,c5036ca4,3221b0a4,ef5fe943,34c1a27f,5f5a4c87,a7499afc,4de8a475,8651e50b,d97c292,f5c4fb16,6114e871,d0d651aa), -S(fc62b528,b601895f,93e27224,843b4d29,9d542c5,2235430d,c3e85c1c,4a0685a8,c5ed07b5,4b4f18e9,26be84fa,9d1653a2,716c8e8d,3a0343d2,e6b78e92,53a411c7), -S(2b15210f,b126f37c,6bc76ddb,db6d24b9,dc39d531,8527a917,ed1553cc,524ea86c,deb7b72b,256402c4,24ae46e0,f2e4e09c,12471358,3b73f41,79fa737b,3f53facb), -S(1e011ea,5ad8f791,e430b18b,d302d3ab,b229f715,a68f3d49,c1c2f3b6,285fb369,b9dd2a2a,25937c98,6905428e,73d811c0,8e1d5729,bd6bfd8b,50eb91e8,4ebfb1a4), -S(9bbdefcf,cb0c9e8d,747180aa,6aa72af,917fbd5e,ee2e6dfc,f05bd301,56496e4,6824df9b,a8ce39dc,e7da66d1,a430be26,9faaa54,a83f5441,2d5ac6d5,761bc83b), -S(691a5651,e5773488,24a36cd3,755c20dd,289a17a5,953608d9,905976c5,4136d4d9,c03caa0c,a1bc376,b736d2b8,812966f,6f1b955c,1e68a8b1,a12120ba,ec4f12ab), -S(f68ec286,730a42b0,4ef5c596,b0235e5b,50eea2a3,94ae6f9f,a91086da,47acb9e2,5ef0b31e,86dd166b,f447b7f7,2b82ceb9,668f2a90,88a190a1,6bd5a230,8699a54f), -S(33685765,121d623,9f73b969,efe2ccb8,ad715377,c7f110d1,579fbcca,5b005ccf,cf71270c,c3c8d129,8d6f060a,f6cb343b,b7c807e6,580779bd,1df6d7b2,e90d80ac), -S(18c1347a,cd1a2eeb,7f42bb9c,de08e166,63676348,fdd4c533,d3f51064,b940dc16,a9ccae7b,d22c73ef,eca3a4dc,a56c3cbf,eb3f8177,d9e5cae4,48568a5a,2d83a31f), -S(9235cbd2,37fd6ddd,d596bab0,e2cd4d29,98a28d5c,b3b738cd,6f79fa76,83570357,60bb571,7ee5c69d,7ed19477,94b8d2aa,7901b993,89496993,1e3480f6,89d37742), -S(8d6f63e6,8b7e79c7,1d62bb8e,8e1f3ec,8c5dfe93,21f5ff57,c930ca6,f9d255e0,a1eeab9e,f6bc9a38,45836630,4a1021d,ab2d4f66,4c5cc6d2,c50be827,7fe61915), -S(e34a6e35,8163ec00,f6abbeb5,14b5453,9c7ea2c,8afac9b6,81402ea8,de5947f0,375f0fc0,882bd435,1f294812,b0fdcf5b,8f36b772,5bd93994,343d1bab,a3db8b33), -S(7c92a80e,483c9c33,bb18163c,7b4e7710,96e77f5,c182e4ff,95e8737c,9294b2b5,f9775ba5,6779dec8,dd5448ca,ba1bf760,5c531e2b,f71ffe22,2b8c2b60,93cbe3fa), -S(15d91f0f,49153ad9,3fa9bd53,71f98b4d,84d0bc8c,13310859,547a510b,94ed08fa,c0b61781,ce3b4f30,89e99387,e084827e,b148be8a,cfaf6a8f,1251a5a8,ada84194), -S(68f00c8d,4741c078,f99595c8,230bf510,bcb84a12,9149ba8a,5b495d0b,d3307226,49004e85,f9eb6650,83b1ed05,12199ba4,2da74f30,a70898cb,2ed05253,fc5a809f), -S(c2cf12ad,851d4a49,56a2f861,2cde0fb7,caf83f2c,41af4d98,b74f039f,b2a95bc8,f4643722,186a375b,be0e17af,9832042d,62132982,ef33a626,b6a02f84,f086b59f), -S(8d378751,b5f13626,2fb3eae8,5491a3a0,b3af4b01,f759f06d,4b418116,c3ba30a1,5a47d6f8,878671da,104fb6ab,7101efa1,718414cf,2017221e,8cb171bc,a13d4d), -S(cd4e82f,2592b5af,1cdbb44b,3dbcd3ac,76d0ad92,fca50789,f1152722,1eb4f3ae,734884e2,6d207cff,a145ffda,2f3304ca,3697958b,b1f5ad2c,9cc2c812,99128107), -S(b9983c8b,61629cea,2f44717b,3139b3c8,ad1dbbac,24f8ffc1,db9078b,92e8f8b8,1e0b83c4,349dbfd7,16dcc892,115e93af,2cc1176b,7d386686,dfa7a2c9,a56810a8), -S(1d2d687b,ddc2f510,f0a721c7,4ff6d8c0,ac157929,189dcdd6,2c508577,aabbb982,4c3427ad,4dde568d,5ed5555d,5de4cdc7,fcb6b071,afd342ea,7fb3966a,872d2d5c), -S(9073d8ee,47e31106,718dcc5d,e0e46e0c,bdc8e822,66bc8fb5,b23bcf80,ccf240a3,6a2a92f7,bbefae74,1472e3e5,6702ab5d,a6d20993,1cd7daa9,1a3d985f,5aea46c3), -S(25d31f95,1416d832,59f433aa,89e4df66,49d18a11,1395d676,b44759ee,46931139,40aa1c2,9a4ea4da,d24a915a,7d476769,3a1881f0,d70499ac,f4f78f89,91cf3b8a), -S(d04504f8,9b93075f,822de8d2,27dd8617,f6ae2fe8,10ac8fbf,97c7d788,bd459cab,7c4d4ae6,56d118b2,17abb932,d6283480,5be6a4ab,cb98ceac,8a85085,8f0e2d92), -S(a4afa77,7e76e1d1,64901460,bf63e3ad,c84fa1e5,7ee4cc17,d8a083e4,2e587f1f,f56ac642,f7bc019c,61dea3ea,6891c962,71147228,33d8055c,954b45fb,934325e2), -S(59eb6b42,7e586eee,677ce715,c06ffd16,35ecc418,caf8b707,5e2c9192,f838e4c,cf25adbe,5d0d1c37,1ab4778d,ddb1333e,6b02b377,8c73302a,43262b5a,312e8415), -S(6fbde8a2,a9495849,c0e94866,e3cc7b7d,891738a8,7bfa388a,cda84358,6190ba65,e988c40e,b2cfd713,597290f1,7c37d165,df711c9a,f2ce6989,52204cd7,4b8cce9c), -S(186a8e0a,c9a61bc1,ffd397a7,62f153c4,fd14c2d,78a03e03,8fe826f5,eb5d16b9,d1ccfb7e,fdfa1486,8d35048e,99050caf,73bb0236,ffd33bd3,bcb431c1,868e5e53), -S(3224499b,b9712ed6,b1dc5157,6ceb2d77,356dde1a,263c370d,9a71582f,c4e93ed0,5364c748,54f5e7c4,950f5aeb,d3a56626,7da78898,e3a37af7,a2c5a528,23cdfdd8), -S(b2de,174a7592,ce9b287f,82bb4f60,3a4aa039,4bb308f3,4d282a0f,8e8a1105,a9fa1bcf,424a0d14,5e86c4ed,be0d5a31,dd85772,cecd7fdc,ba1e4b02,b47109e0), -S(19d45a35,f42efc85,283240b6,8f69626e,92cba511,5d265093,b33b71bf,36601850,757b26d7,65853163,fd4818e6,91154aab,c81448ea,19277b70,da37e910,e2bdb66b), -S(9e23f113,8a337fbd,42335454,6e2e3503,3c888aff,f61b4143,3673395e,bfca6285,80ef2fd4,bfdfde72,ab5c2ed3,6e8eca00,54d01eb6,a93542d0,6a562d6b,3342f051), -S(6b494c5a,79789306,9e236dd4,33a15381,f7ba8b42,3502efc1,896ff5c0,16871c28,56ca6202,a860a1c,25898600,eb2f2fc,f5636c0,bb2ba0db,f32cb433,b590812d), -S(b3e4116b,3d05150c,af5821f5,6c33b111,c28a3f18,8c8cf2b5,e5a5f271,115839ec,3bc7caa8,11f4b7f0,c30b0bac,51852c16,2e256b93,dff1d54c,4504fa1,eef9f5e4), -S(9f67548,4e8ce41b,e65902d1,ef56e8e8,46193052,3fcf48d8,e1f49fd0,9d9cfe91,3d8dda39,bb6e6c78,1c0861d7,73461dfa,7c19e10f,dd20f37e,a6d3f152,b1bd1d98), -S(47aa3648,91f116b7,e4115bc7,7419efb,9a267adc,4bcff4cb,1ab58c75,5eca5e5d,1f9ec89b,b253b6d2,997abf0a,46d4a3d,de45d605,a94f4ea,a4ac136d,b57eff2b), -S(b8ec4a26,53d82b24,da269a85,f51fe333,d6f6e9ec,94dd4bd8,3a90b68e,1742baa1,d4564479,b9c3ce14,882fd697,1db7d242,c91a4b8a,da63dd6,41c17bd6,77dda872), -S(ad2d7fd4,dc176f04,2c8a78a2,7eea73ea,7fcd0b16,29bbe1fe,f9eb9589,9173af0f,b4014396,2f84f00e,6210258e,ca6120ff,987601dd,80df3501,af664ea2,3f6e63f3), -S(aa9676f9,85435e57,4db82def,70905ed8,a8cc4495,539a8ab7,42f9b934,e6f1eab2,60b257d,83b39810,b6220fb4,95e61578,f264e817,71dfe6f3,7ce8363c,dbf8ea1), -S(12c23100,2fd6b31e,30929a8,e8d6b02a,593a89d0,b3f20a54,2012ce0e,d74738e,bf8e1682,8b06c853,f061462e,b5f90191,e1af5a66,1d4b01d3,a7be42c9,7f2a3ac), -S(5d1f0df0,d561494a,5e8b9566,a297c018,9562b441,ee91ed93,a43a4141,b7383c13,88a65ea,c63e0dae,244e3e7b,b7fedd20,6fc32f47,35891902,c0dbdece,5e304ec1), -S(ea92ae52,1b21942,78ca6b4f,770c56a9,59403652,39533c74,b0b99ea0,1e32791f,22358430,bf3e4aac,e7c6ae80,7c315bdb,7b7b94eb,4c17442b,bcbae6,b311562), -S(961abd49,90513726,15d8414b,d68edb80,9c698317,c3317d94,d064e272,f2e7c328,b581fb5,949a2345,f561fcb3,21dfcaac,9c235e70,f144079c,3304d48d,d20583f8), -S(41e8edf9,b2b5e7c8,86a9c82e,2780da4e,cc551d3,5f186c0a,caf456bd,fa08d7ff,8afe0efa,fb1b41ef,189ea40c,2f7c1df,f76f740,b2b4d30e,b0afb19e,92cfe615), -S(18cd2b39,1cc5a7c5,8fc7855c,51e9a737,f5bce753,bf7f35b5,3b7ac1dc,b9138f28,86493807,f42083b5,1ce4114a,d159098b,ccd4b6e8,3bbbfd0a,bbfeeb46,6f065ed), -S(2369e0f5,5cfa67c7,788b1d97,a7aed58d,ef0a3727,10a82e8,a459e55c,8cb998df,b3b5c65d,399bcca0,71829793,55d59d4a,f8dbaf89,8c10aecd,d35330fa,dd2011d5), -S(722b21ec,9e6436ba,c87ed647,2d28c33d,e4e4c792,de5e9b0d,85581f19,32f91f9f,5d757d,d475ab0d,390861e0,fb204ac5,dbaaeb48,d2a48014,d3a03ded,3293c497), -S(3b6661c7,33773220,40a45f9,527f1e6b,b3657e8f,de4d5beb,b4213f6c,130933ad,d480a018,3f031d7b,c4ec6965,5b0d3ce8,bc0f5ff7,5694977d,d2810188,f739f8f0), -S(2baa92ab,fd1b3a06,7bc34db6,d3a1b82e,afa2eecf,f82cdfd3,a2bd2da8,d5072ad9,4583b0a7,e1c0b53,c165b5e5,cd4e41f0,27179f60,328fe313,4b0c5d5b,9b32b3d6), -S(2fd0279e,bb08f28,5e4e385,6ab7bca8,dac262e9,968c2341,9049611b,6db8374,e377f24,92d0bf24,89a8094,5516f528,4871dda3,26e6d3cb,a81c55ca,41d62d5f), -S(911e62fc,dfbb1636,bf80d445,d711e328,4ea6c362,629e2aa9,f8f48a4c,8a0bdc32,2339b90a,a771f035,4bcf1f38,d7dbd8d7,643f260f,65f4fa2a,bec27e3e,ce6f8471), -S(5ecf9075,7d277b40,fe4ef091,a525cafa,fcabb2d8,da8b7670,d3d25680,b1c425c6,9690ebc2,1de37095,9abdb2e0,37b3b34b,db367933,888d9db3,e903f8ff,c5b85d7c), -S(270a9301,2167aa21,5c5da736,fe3e32d7,efa97b65,f7c89a7c,62a6ed28,e3038e3e,445f24c3,8998530d,39964c6b,d51d75df,fbe176f8,91b606ba,d4557cfa,a71d9f9e), -S(bc9e7f14,8244cfe8,b408be81,b79d904e,bcec0cb3,f4e540fc,f6f469d7,f73151f2,5dbda6e3,49377393,c6d90189,26bef6c4,59fd597,c50848eb,1808cf31,13b7e704), -S(163e1b86,bf0ecf2c,61a630d9,428f2fbb,7772032f,df990bf,1e276e98,a84ba2d9,3c25bb36,4f1d6a0c,c70cfb84,70604f61,4bad22fd,bf305058,667dd0,5934711c), -S(1706ad54,9dc1b0f9,bd1e5fd2,729802a9,8e6f6d96,24694b2e,3d37615d,b5565999,b16c7d90,403b6d24,65ee6526,54ab19b2,5c43cfef,fb6b33fe,12c56912,5618df71), -S(7e66578a,356ac4c9,636e0369,a7b1368c,cbe06189,602aa938,95a48826,a5c4d2c5,77e51712,195393c8,f95d032f,2bf1d39e,60b805b9,f5aedc31,a511f1a9,ffd976d7), -S(ddae1e49,1e8b0572,95884c3b,ef5ffbaa,dc6a7ecb,d8849521,177f7d81,868caca2,be7719ae,508d035d,88cbc2d8,3ea232da,657c78ea,401bcb05,9382c39e,959d5251), -S(5b44e6c3,a382e500,2a53ba57,fd6e92ed,8296341a,2e81095e,8ca22a18,fa76b450,443bf958,ffd1fa9a,1bc8ee27,ef49e457,cb23e6bd,dc6d251e,8e28130e,e6ce6892), -S(33d32ee9,f66d00bd,85d7e24d,7fa3172,8352668d,56be6f1f,71cead36,b1035f4,d3372856,106025f7,aac97103,4efc5c51,4c6128bd,6737fe,325ff277,f25fdcbb), -S(7bbc0b90,9491363a,cfa10e65,84d693f3,8b2a2164,1d2d886a,3c348c86,d7f98e11,ccfdd17d,532ecbe7,c654ec54,65928836,1dd2ee63,136d36aa,415fad03,f94facea), -S(a3da83e8,db0f8d0c,ad680373,f92426,26aea70a,c68c641d,648b2d94,244d68eb,305b0d91,6337a600,4f17626c,835a1cb4,c5d97f35,f75e7e44,ae3ea4ae,10d5b40f), -S(f5155f1a,2b196a3f,aa07d4ff,5fb91890,d37196af,1354d1b9,88ea4412,c57e9244,d060c7fa,f1666aae,f38d5256,b20893b4,961c3b4d,40fa9739,7a52cd00,4a2af8f7), -S(c948aa6c,ee9b8481,fed5b207,5100f0df,db799e6d,76d1af83,6d198f84,d6a028bb,6943ef15,988941,3b274855,1e0245c9,52172cce,8eb29444,e7728c20,a8da32d2), -S(518ae279,d1dbc26d,3b940b7c,f7c98eec,bc7660d5,af24dc72,ab8e6b0d,329b0d32,c8bf4d50,74471ad6,2f4ad9f,df065490,c81c1ce4,6a8b8847,b1e1b826,99b5ebee), -S(82fd524f,467bd6f8,bf84b427,d81b643f,ad38940f,ffaa2da1,f659dc6e,263ffb9d,2ccd7ea0,ffe0dea7,f591df01,5d1ae314,71f2cc9a,67c610ab,5bfe8f46,57a0647d), -S(250edb5a,1b6e4778,4dbf0bc1,510f9716,f5682aab,b975826d,2f715427,8d56cb5a,a625aed6,663ac946,ee805c8,11328923,9aae6503,1efab534,e152ded,e4d1f138), -S(d13596ab,e37d242e,ec6a50ad,95a171b9,c0cad0d1,5e6cf674,35cc87d5,1be1a6a9,fbbc5a7b,b3592ca4,5a994365,cb67d31e,68d2cbc9,ff790d44,366a6a6a,f85d80e5), -S(70f6d617,e21a9df6,370d044c,53804f62,9e6589d0,5900b9dc,849a8d05,719fd55b,5fc30143,ea245a03,ec0e9f01,a1e99f5,9ae16eb4,e693e3f8,732fe9be,b2c9b4bb), -S(f633f446,9b1617aa,8731ebdf,2b5e98e8,8ec97865,751bf6e1,f509842a,aba63251,3de28e7a,de2588d7,bc53ede7,3e9acbf5,5688ab6a,2cca8910,2ec03998,f70a6d28), -S(e3364ef5,183476d6,757ddd79,39447825,e06491b7,9fb5e6b6,c98e3280,e9dcea5f,f061aa9c,c5bb20e1,9084fcf5,a8e799ff,75670c3f,3fad80e3,ba3973a,be12b76), -S(c98a303f,7bdd7f06,3e09dec0,e9b5f449,f470e4c5,cfa11162,25517636,2ad7cf8c,94dec242,a375b65c,b1fad8a2,ecc6de3,c2f4be0d,e8751764,f320ad9e,35dc5de4), -S(fef6c023,5025dd17,5c8f5f02,78f7d9b4,515b7915,359e1c8d,bfa29a4b,67c1d654,9bdaca13,7b42cfba,f1075814,3409879c,249d5028,b1ef10e9,77a73c2f,749e9ce2), -S(c4413aa6,18fe751c,a50aeecd,478757f4,b23e8193,5304248f,8d93596a,fa489988,7003e5d3,3bca34cf,625d8cdf,f6910bea,16a39e5,dcd20fd2,1822b51e,55098cba), -S(b9719377,b83703f4,efb68dfd,b61c3d6c,bf9bb302,3747dbe0,c5c95437,6d56fe3,e57f0725,462f5f5d,b4c5162a,9b01fc,f52ea86f,6a7a5670,3daed54c,3672d825), -S(e72c8bff,84730fb9,7342adf9,67ad5eaf,6a90282,ed52b70b,6d9dc90f,e2395fa9,10f49bd6,79c3e7ab,21aeecf5,bea893d1,9836fe8,9a228a5b,ab7289f1,5f911543), -S(4e197fbe,2d935c0b,9280ab4a,26422b10,93a0fd4b,85a686c,7abfb2d7,621564b2,2c74f5e6,4e5205a2,7efa68cb,2ae9dc38,7467e102,5ef54a0c,4acc7319,4d372a), -S(88639d8,35b91e12,f381ef72,2c9308e1,fe898804,6432d577,7d515ea8,1797f360,1a49a5cf,75b1c8b0,a842f222,565a35b1,41b3c2a8,8d1b8881,34ff86c8,9ca4dc41), -S(a951d30a,c53e183a,9d74088f,8fed089e,1719f04f,39368d31,c0cd7b3c,b873f2ef,7f9e5508,a782c449,3ce8eea6,52195560,a1dc74d0,cfd8bb2a,4368fcf2,6ec783cb), -S(67028a77,3ff55e84,d4f19a99,f651d9e4,abcdd680,1add3739,c1688c18,22ccba72,bb611a0d,d5ad4674,e9a4fa5,63c6bcf9,a5dddf04,f195a9c4,c917d36,4d5a2ebb), -S(ba7643e5,13b102d9,f8fb5ae9,cf106d11,5d97a50c,d7e5cbbe,c13d24a2,be04a85b,f52f2e3b,88a49709,352b2421,2691882a,eb853ab5,7437e712,b83ceec9,2c25d7cf), -S(b3673761,b46a0444,cf221e48,22ba2f72,36e0c3b3,d16962c4,6e52bf2,334f099f,69dfa764,cdbca112,7a173798,abd8148c,eced792,b4cde92a,833db24b,992ae90d), -S(d6815b9b,296aea82,f1504323,1e6145b,cda92a3e,915daa0a,8a179902,7becd8bd,bf3ef3a5,8086833f,c579f9d2,2b7af47e,f97ac341,aa3aa2ed,2c74eb66,58178360), -S(b5c7dca1,94b68a14,fbd05f42,63b0feab,9e1dae1d,42dcac2d,1a30f70c,bee14c34,ceada44e,540b26d3,c37eafbb,12cf0cd2,54a9528f,77d37e1b,c19cd226,1aa70d08), -S(5a73c77a,7426af6c,f2d393aa,40189923,e47eb697,58fd76b4,5c8159bf,f7f8b900,bc90f626,9d8572c9,cfb6cebe,b6700fd5,49fd0157,ab545a5d,1f1970a9,47786b1a), -S(4e38c28a,e5fce8a2,ebee4340,e0d99788,340dc758,f3740072,41a297c6,41d8aba0,ecdf41ff,e5533cc7,8a9ee3c5,77dcf2db,bf589531,ca9e1ed9,d5b9e23a,27915eec), -S(59fb08d1,c85ddda1,dbbe6b64,7745591c,68bb7a44,608a22ec,9a83902b,14acdd61,f4c21cf1,6869d2e5,355ac8a3,227345d4,eacf74bf,af742fc9,413354ef,8ca1884b), -S(62ac0b80,e2040117,14a508b4,42cc0564,40f38eb3,e4f0e19b,4d8d05cb,bd19382b,e0d4ebf2,5bca30dc,95c0cfaf,140a0d67,29341751,881b955,9e03eb70,98ff11ba), -S(ec16d69,b7cd751,c44ea4c4,9b7c917f,45cf3c57,efd49263,58af0837,70c32498,8c8aaaee,14344b77,23c17e31,752dd638,fd8bc3ea,cace7522,3c712b6e,82d1316a), -S(3dd4a6f6,9d614c5f,87de1bc3,101beee,8b66a1ca,749842ac,dfe5ed3d,2d4b780a,2d5e6b54,464bd991,113c5ed6,50ff5af3,ca2a18f2,ab43ed6,5437ea13,3ba99fdf), -S(5e404405,3710c999,a77d9048,cc651c54,718936d2,d4d8d8f1,ef416a54,51861aec,c6c2bc4a,1e8682a,2426b02e,92bb7094,2f8db6ff,fa6b375,79b50146,66f31f7d), -S(66032f1,f55b606f,fc68ac3a,92683cb0,d447137,430ce435,9d1f06da,10954f99,fb14ad80,f168e517,fdacf38d,c197fa71,6ae1157c,ccf0948b,a7f0914d,ff8d040), -S(25c4c534,8ee76e19,799d3f9b,f56d3566,57332560,693e362,b7935ebb,85d7056e,1d7b9e9d,6e52f220,e82647c,a560c02c,ebd3f608,f11260ee,c9b16b58,76123b6b), -S(fd70c030,435fa972,793551b1,e409739c,6f148342,e833bb16,c4dac4a8,a853f0cc,10870dde,23c4097d,505f2d17,d3dd93d6,eb9c1300,49cb0fa9,2ed63c0f,feb73e80), -S(ded2703f,3fc6bcc1,eb96a925,650823df,583ae86c,cb43836a,19ca31e5,69c1cebe,5957989a,db61c969,8d61eaa1,938ad6b,cfa3543c,e13811dc,cf5b4ba1,24d62a5a), -S(9943048e,7097dc4b,709012f6,d298137,dc8e471c,a66ccbb1,f023bcb4,938c02f4,57fa4b31,b80df627,b9c212b0,4bfbbdd8,d1dfdb03,ece420d6,35d0ec9e,4e86384c), -S(313dc488,9214c7ef,960f2f95,b55b8083,d1adde1c,775f7f6a,62b57c01,aed5b95,bc02f247,668a334e,349d8ebc,6d7a1ba2,1f99ff1c,ddd10c2b,59aed3c0,815b1e5c), -S(1b9ce18f,9360e5db,8da1fa8c,f5ff96a3,1a898f19,2eceb059,c39f6cbd,4de5c920,84937b84,5336904a,4047c917,6d1f54e5,4e1a15a6,52a97668,6249987,82f230c6), -S(4bfacb3c,18ebd5d1,bf71ca5f,b1b6bde7,b314d2fc,ca1c05bc,f4021595,e15c6cd8,a33c205f,d4ac1624,d4ebb554,816d6435,86e08ce0,6ccc762e,232cc7ea,d65aa5ee), -S(f6843448,522403ce,a3e4597,30648835,2399f699,421db1b5,2fe33bb6,d21c614b,ce80913c,eb14f530,d153104f,202dad87,2f000f16,fb60316c,bdd40c79,4c95ee85), -S(930816a1,ca19458b,c2badcc6,3cf66d0c,6312f52e,853b5365,1b829b3f,2666ca70,4b29edf1,55385f57,63dc4008,77c846b0,4c810747,4def410a,c796f58,f61b849b), -S(b9d0798f,2ead9231,7face0a8,31869066,76711e1c,f3a9a465,8f51c039,7f76c066,4ecdaede,bae33f4d,79240d11,ce0b0564,62ad9f0f,51b6d7e9,e69a283a,4770053c), -S(1e8a7b02,60d58ae8,902fc57c,5a1648c4,e14d1a6f,696e7aec,c2cbe5d7,2e5439a8,e8c76d70,913dafc9,d157d030,8ed328fa,e08150b6,4a48754b,907954aa,4aeaacd9), -S(ac754bcc,c9c7b4e3,6551b654,a0620086,412db1de,14e422d4,c9111c64,c8b08b0b,3a8450b7,e841959b,93d3bc25,ced04aaa,4df90b90,d1ccbcf1,2fd88bc4,fdb366a6), -S(7e04fd28,1770ae0a,8fcb64d5,6e911667,a50170a8,3fc691d0,b0a8e1f4,73de3c2,73c37d99,cdfe5941,62b7b620,34be369a,c7da1d8b,e7d863b9,a90de407,24acb7b0), -S(ff903b99,13bc9005,8f237e9a,50f83707,a6f7d24a,d62142f3,16fb89ac,fad9ee9a,37cd140,36415c21,6e899a0c,2e8ccbd5,8f3eacb8,c88b1182,8436888b,899b412f), -S(d1edc0e4,44e92bd6,be858374,8f8fecb9,dab0d6f7,c74d410a,c412865c,9bf95d00,c10e796,3dd91bf7,c1754154,ec82460f,817d919,d13c52f8,d6578e8,52a8f87c), -S(62ce4177,9ba5fd6,332d188b,3a8ed98b,3883f013,731ec72b,8b0842d,ef0d5e58,ff141435,2b26b61c,ea78f67,de7ed56b,7895c03e,e3c28050,151b5a67,625b2d5c), -S(c8e885bd,5d0d5399,47addcba,879e7fa9,b075f871,e484f7bb,69081c47,8540c845,2d0d3f40,77cf511d,f93a278,91795dbe,e5087584,eab4fb83,e18e5d76,8d939dea), -S(62b1a52b,de107e62,4567357e,de49b08c,30c31e8,9c1743cf,a033fec,6bb8ab3d,9ed15063,ce1c8d00,1f19b388,ec678025,9cd5d951,4e263453,d5bf98ac,bd64d1b8), -S(88589c8e,9d35e6b4,5788bf01,bf3c6672,32324529,3d8014ba,525f016d,6f721e1e,be4804a5,d5b49ebe,8dd127b6,e55a7702,92a1c0d1,dc431fe,f5e4e873,103e1fea), -S(75e47add,7a7f2099,1a12916f,9ebe39b5,1409e82f,67afdf7b,d1d7464,1b83a85d,786b9b83,818e81ed,e3fefad7,c7203e57,99b4100,7cdd291c,321adcab,31b57bba), -S(d56588f9,982aa917,ce28e887,44ffba41,4cc1046a,a0122d2d,afb8715f,a9afe3b4,b14c6ab1,3a1793e5,68b171a5,1ecdf179,d78818b7,9cf7b1c3,97841a64,97b5e3c3), -S(9be8f7c3,efadd410,8c24dfcb,3a14a279,8cab4de9,8f5ec786,de7a4448,d9150e52,705ae8a3,a554f092,c677eebd,605661f7,4c463b81,97444d96,a5bda8a4,60315337), -S(96c95643,ac2805bd,421dfbf0,8a4801fa,69b6815c,bd31156d,f12207fc,48831c43,656b790d,35e598a8,dffed7d5,9b0b827b,3c46bb1c,3e5163f2,a4b71236,c6bb1b64), -S(9dcdb2ee,239faf20,2bfa036f,5d6adf4f,8d1add19,8def404d,a9447867,b126becd,3b727773,d3587698,7605dc66,12dea6b6,46052652,abfc3ec8,576740ab,81291e89), -S(b33d2b97,e31618b4,d9273d4e,82893e01,d85bb2c8,7d0d1059,f989bf3a,7022d2bc,2c447cc1,6e680637,12a4789,6ecaed55,83cc9e94,525d7c19,9e47416a,8569d5d), -S(74232d9,547bf3eb,fe4921dd,92d77131,3f5c97c,203c0db9,12106698,aa9d5c8e,6fd43ac9,ac04eead,7566e40b,3d04975b,315a36c6,e5b72cd0,14d365b1,b7a3836), -S(937ffd12,72a7df14,21df0c9a,3e015d0d,be72932c,3489fa2b,d34f72f2,763469e8,55e9e0d2,54d3379a,a6e35511,acf9dcbb,372d5b8f,271bb7f6,4c2cf77e,bf624234), -S(1513a5a3,7aa52a65,d659a7f,b0e762fc,67a8a196,8f2b6ae2,bdb02955,5d92476d,8d99d771,6cc3d831,9eca3b97,8c91d239,a7ef6b03,a13eeb25,ad94f4a4,20ad3eb9), -S(c7464b4f,bdd39bc5,4ce45b87,e4db3a3b,22fc52ac,b649266f,f7dd69bd,65b2843b,bc0d264,e48aa14b,bcbdf505,9a35fe99,395f03d6,60635150,cb8424b0,c93eee25), -S(cfdc9326,cede0724,5a89824d,1cfe590,c0945793,88812f11,4bed6577,ef7432ce,a8df1cf3,5d471afe,ad43f88e,46e5cd84,ece5fe8,fadc55b8,e79d6eb8,2466a270), -S(aa5529af,861568f8,cd4ac26c,fb1f5e3b,5ddf564d,ba4f3b5e,8d3ec5d2,606530f8,3273795b,31e53e0e,e34ce1d,aaee7801,309c0315,926eacba,fbb0fb6,4f0a948b), -S(206bf37d,599c665c,1bd20187,93f526af,1099819b,4780f2a7,6f5c3797,4eb404cd,7de063ba,3271773f,56ca358d,335a015b,8ae8a45b,b4a9cffa,2f20872d,9bc654b3), -S(3f21852f,621d5a6d,4c91f27e,82018b7b,4369c15a,69664cc4,6cdd8195,1f3ef14f,db8e7b5,fe7d9972,6da564a1,78131727,3ee6e005,908513d1,3903aa3d,d036123), -S(4c562c1e,9e4bb491,17948e93,f94b4146,c918554f,7d351300,5ef7f181,2c9900e3,1809f902,c6f694de,7909c8e6,ea4e938a,c1d9e6af,7707bd05,3a7d8560,24875012), -S(a692c8a7,a3b306de,48481c93,8f0a9814,e081bf11,6857f217,4c1ccf1e,a8448a30,7a660fa7,def1429f,4c72e44b,9fad10a4,7639942f,56a647c1,d609f3d9,26a40a9e), -S(981d35b5,5998f57d,58a62d9d,af65e53b,419b99d8,2d2eeea2,bede4da8,ec400a2,d20db6e,211c3ffe,ecfa43c4,79a43ab3,8590a142,9d9520d0,62f1ec1d,9f1c574a), -S(8afa1616,3350087b,1e286bfe,5d610463,41adfef8,8b0fd809,336137a8,92d32e45,54924c6f,5c2dd61b,e5b1186c,7fb8519,29af1989,f468049b,bd5c3cbd,387a28c7), -S(ba7cc113,f1e3bc3e,ae14c2cf,94fb1ee8,bdfa60ab,52582ce3,595df63a,d08c1e17,ffec33d6,d42e2233,baf02780,a60272f9,3531b1fb,158a4bac,6c6a488c,fc23d03e), -S(166f2dc7,661c9e5a,aa51582f,4cd08cbb,47c6afca,143c4231,36144cf8,ce69ced7,132e0d13,6a292cb5,9f0503aa,589b37a2,dd1c9244,c492b8ef,647d79c4,778bd94a), -S(bc9fd332,f66ac57e,46ff7801,a7d38b0c,f2befd5a,2513688e,b29fc5af,902f1c07,8f58e1a2,2958600b,dd64a428,7b6b25a1,dda32351,dd45453d,d03b99ad,e406e240), -S(e363fb9f,77378eb9,2600491,386a884a,24839001,cc516bd6,44cf6e57,b1e66507,3f83ecdb,907afc42,b47ca948,fdfd3b73,dfcf1e5a,7cdfe1dd,41a188a2,1b5f8b1b), -S(c8883193,9b5b7ab2,2af8763d,52efbd5f,50939606,920325e4,805842e1,3faa3cc7,5db2a08c,6e8ad455,f542d2b3,9b8203e1,39c5b0a3,d1fb1ac,763ee4b0,4b9c1f7f), -S(76149173,1a20a975,16607b53,501c45a7,f94df1a6,e0f15301,bb0bbd4b,eae97439,e75b67c1,fc2bda74,9f834d8,c9439b43,c33aa4ea,f2fb9116,9804615c,8c1269c5), -S(8c19284c,f62a4116,a40ec5f5,43cdc2b7,e7615400,d1090f86,2f378ac5,81f4b5d8,bd93accb,5c42ca6d,a4e6ac37,b2bb8359,42bf659e,a0e6beed,bd754e5f,749bce8c), -S(7664fc89,5d8de0b7,b19f18be,cb9a9b1,783f97de,3167bc39,7c03d007,18311a7,861d8f0f,125d051c,9f808064,346bbfad,410fdddb,aa31aad,cda7a713,1d65a3a), -S(7aef0296,33664cd7,694a5d0,aecc0466,541535fd,b1540c38,8f0e0e9e,24e96b77,e02f2ba1,8e92d161,33d29d1a,c087cf29,3a91acac,662c7208,b9157032,d0c829ce), -S(cd222d7c,b49b957,e5252c06,7f649ec2,dae145c4,d82a82b6,8693a242,6b7ba40b,c261f956,dfbed5c0,e876492d,7325b964,3dfb2075,68ccc93c,14b1e8eb,d3fc1b59), -S(5055e224,c61b34ec,9cbe93e8,ea4c9488,19d94338,edf6daf3,72eda45c,da9f0971,4fe31a71,bc782d4c,720add07,4cf97c47,dbc1f38a,3a9d9cf5,955e1760,5f185651), -S(23a80902,a97669c4,4b20f49c,fee841a6,b5a99b5d,d423f4a0,5d573a3e,4833984f,6a57ed,265744e,f4d18250,435f695a,b80b944,d0153b77,e9e9a20d,bd98c659), -S(b9879ec3,2ad8fecd,35022a2,1625c159,a31a72b6,5d3f3c67,5dc8e114,c5f59de1,439d2afb,aecc48f6,310e18c1,2e31c9c0,cf91162b,43b153a2,f901a19f,1efe8e10), -S(918e367b,531fa89c,8ca89c2d,cad34aba,c937cc00,be3a2b18,bd1585ea,c4678a4,800078df,6b700c11,85418749,27a8402a,db41811c,77d0fd4,aa435c2b,7a3f0a2), -S(6cd0f4f1,c03f35c0,65815638,10906fa9,a41bbc26,da1bd7c2,ef39a4c4,66e49252,ef644bd6,ed42cf0d,3ad17638,5c239fca,61056021,b001ef9,dcafd370,cdc06156), -S(8a0c443c,3e26680a,3dc8483,e0a067,553f7ffb,af939922,1c35a766,b12286c0,6c30af1b,9a97958e,11d1e24f,3e8ce846,1ff37795,556772d1,56514015,a46951b1), -S(563b11b,a7f5d351,729b8537,1fdccea5,d7081262,8c1e265d,10c29172,d9a3252d,81c0a2c7,8b36ca17,29c9c02f,8050e3bd,ce46607c,5409c50,10f8031a,ec872593), -S(27e88b96,29eb9d92,e57ce3e7,75063c04,4a1f9f0a,dc94a139,abe56b05,77718f94,ea04c851,41e06d26,31564122,80c86d83,89c1f15c,3c7e98a5,610e52ea,19b1305c), -S(95288e29,a554b7e8,15ee68c7,16772a5,4320a7b1,20a38865,f3838345,f9edd5d2,d81b97b4,2404966d,3c4160e1,59f275ef,b91cae46,d9a33f51,34455ca0,496e4472), -S(b86033e8,e3bde32f,859f6af0,bb87b72a,b1b88648,776e1e14,273e52d6,205e0186,e120cc94,5de7563e,915979e1,15ee7cd4,4875d50,bf6b93db,8a133cac,227091db), -S(644a2090,82c7984d,447eeadb,2b21fb36,599d2c1f,366a3af3,44afd230,9b780c8e,b49cefa2,c0865df5,f6f6df65,24b39f7d,67eb07f6,ab6e550,390351a6,a2a1a00c), -S(1f2c4207,2e803f99,d1389efb,209ab0e9,2d7891d2,531f6710,60371c19,7b0f41df,98db8e40,69dab24c,4fc6e13f,37e805bf,45d30c28,9d4455f1,9670299f,a6c6a804), -S(dab5435,220297e0,e738e798,f1f8375f,dc813874,7a633f05,1be409bd,d6a3b8ab,91b6c193,de219ec3,ab3d6635,d4c41a1a,6059372c,a8afe185,7013e474,79fcb382), -S(5ae6a897,467fd90c,f693a5a1,d89d4fbc,4f11680c,86f5f99,30af1866,a1f27137,40612777,fde69d15,7d51d85b,137fe92d,c269c42f,4423531d,548fe248,44d0502b), -S(9bffceb8,9acee7f4,68cfeaec,6d597672,6f227197,6506c5b2,6c5cef5d,7545265a,a265cc26,fd6332b3,fe6c7487,23ce3d5c,12eac750,59947de0,9face60a,4df250a9), -S(f38cf54,b77eb8c3,2d339dfb,df288a11,3058b4e6,2f8c4ffa,2bd29e2c,e6c7b677,2daff1e4,54069fd7,63f422a,15e9cd91,65b5d97a,ea0cbf55,103dd751,9faa55b7), -S(350d6b26,8058c8ce,4684a5da,32e3eae8,caf387be,ea9c95c,311d0209,47122dc3,8ff3be71,e94dd657,281c9f28,780b015,1a2abf2c,2c2ed9fd,e7d0adda,6c5e0690), -S(1ab92290,615207f1,34859fcb,26ccc8c,ab9d5ba9,f30d12b1,ecd7210d,c68cf573,2f1c5e0a,53d449d8,3a5d1507,9992dea1,b481e607,e6c99f7a,5e0193c7,2a426d61), -S(9e98be16,cf2ef9a5,fa3a320d,5f844cb3,c715420b,d44db10c,8f24b0c8,be65cff7,9ff6de6,ea416ea2,72d8e438,e132a86b,a03c272f,378a4726,aa72800e,d0214a3f), -S(9e7b45ed,8f0738fd,58784c7d,a42312a3,53f12676,9fc3ab56,9c4cc69d,25a5b1f,22be7dc,e6e513c6,1a733f45,980f2f60,ff4653cc,49391baa,f4b27174,98f79668), -S(6b6c1553,cab82490,7c5c480f,88daa7f2,7e57b870,5110e1e,7e7a5be8,4314844e,4c10d4fe,d431a4d9,6b719188,b2027764,53885709,eeec2837,32832497,319c9626), -S(1d28f09b,37cc3c4e,3f7ee903,6adefb71,6423e5e5,8840c6bf,d3c03151,db723a1a,acbaeae,cbdc3e9c,85e36db4,aad508b9,9a152373,547613c7,a3455769,872e55b0), -S(55e861ef,3de7675d,857b8ba4,73aec3e0,de0f529d,3a9f4a04,11ec4d4f,5a996d75,a942b32c,44618065,af08a1fd,73e052a8,78df075e,e54cc160,eb9846b5,d46db7b3), -S(10f1258,4bdbfbc5,6ce7b023,78a5e908,9457956,65f4e49f,a53f7143,3deda9a,4ce2f90e,efc88f33,f12edecf,1af91612,e3f84dbd,91f45bf4,5833012f,63e02398), -S(48ae6885,ed275a41,2bc61a67,399ed1aa,cb968182,2775dcf,9012cdaa,a6b21ccf,8b4b5cab,e5471381,46c62a82,102d43bf,5b83d993,41d026f7,c1525ed0,8c2238fe), -S(c6f5c5c6,73642a35,59c06df0,18527de6,7fdb9f4d,75c98f01,8f45913e,932c1481,4a4d4894,e31d2adb,d150b184,51cf16b9,cf7e3741,c4ed2511,c0765480,2f59fde8), -S(f38923af,ff4cd9d,cb16d571,3a68e18a,7fc163d0,8835d283,3676caae,5156fe49,e36986c8,d7e07fb5,6a1f4266,d980c113,43cad9cd,f7e4619e,17a45642,6425eff9), -S(10883b32,87b20d7c,7e60048f,13f179db,e169b82,f9a95f87,5271861b,36170d85,59be5146,d328574e,d837776e,c0748043,369bad42,b38ebe6b,861861a1,8c5307f0), -S(87262e3a,832a6c07,d6d32fe5,8f0e85c7,40591c6f,21da8ae1,5f8fd137,454a383d,7db37cc3,11decb91,cb4fcb0e,9e73bf0d,c91b3a5,53292f8a,f5036dc1,baaf4473), -S(cd4b75e4,7fc954fb,b71c21c8,28322c9,a54871f6,2ba2a803,780954eb,46c9c54a,6cbe7868,8b5722e6,ac75f9e,c93a7a4,39350a67,7ef31f53,c4c73b33,cdbfe124), -S(468fce11,bbde91ec,fa738924,9a07a39d,b0851d0c,3cb60f96,cbab165f,f5c69242,93c66305,d55a21bb,e14bc51e,be8d9c8c,14f0e8ee,caef9b49,567a8f03,6b2d06ad), -S(f5d9aa66,9cc173b5,5850e784,fbab08db,d0f11e6c,fc3243d,ff6d1a7f,89f517d2,aedf8598,b11b8c00,34f1e3a0,ed4c6c2a,db1688bb,35bad212,ad692896,2b045d13), -S(48276e7f,91c2068c,161e97e,7587a30,a79ee120,cc30a9a0,571da1de,53f9e253,a59189b9,306aaa38,848b7b7b,4653e6bd,68944d6b,46a4899d,44ed2367,3ecc241c), -S(7709db32,f9a551a,23dbdb7e,824fcc7,720f24c0,3c58c68f,d2b5ce2,cfb59cce,f8b35a2d,ec4b7698,58fe791e,c240f54d,8b5ffde7,f24119b2,7ab20fcc,8ad07f0), -S(a7b6e973,d1c62f03,6eae2674,bb5b37d6,c5ce3187,41776833,d7f3e8c1,ed2e6ac0,116042cc,3b409748,162db6f0,69ebdb11,53aece8b,37c277eb,28c9a2ba,c7c8224f), -S(7c5f0e06,652e8870,74d0bc97,e9c0023c,e2cac507,659d1a07,5f9c9fae,2d77afc0,e9156afa,24565d92,fadc1aea,f49e1bc4,b28606e2,5bcee2ba,f7c9a87b,b510113b), -S(14a0e517,1a796c5c,1bcfdbc6,f0431dcd,6fb7a8ed,4d6f1621,be01cf2c,64ae0166,231ab7b1,1c3d84fe,1e35b994,43d7f7da,a0bb4e46,834e92d5,e5c689b8,427b24e5), -S(fec19af0,286c251e,82aa7ec3,c5a8b048,9ee4b6e4,8e62c59f,7cec1aee,45b7323b,18cb5d01,5506074d,c94d0a0a,261301ce,d042405c,e4f01f39,2bfb40c7,62b47a8), -S(5788e079,beda8301,e290a04d,dd11c173,6112ac99,76c4857a,ba479485,5d457873,e2c6e721,b5bca7ba,add95284,9257927d,86877477,e8468b6b,9235b30c,557fd7e3), -S(513c9124,d7e1726f,73b39525,377c2761,48697c71,594615b5,f18c6695,b4d589a6,659ffbe,fb3ff7b0,2e5ee01d,eee0ea65,8a562af,722076cd,3cb2ec56,16533beb), -S(d96da66f,fa79adb0,80d06968,bb9243c1,dc6dcccb,1e9250bf,6243a1e0,9578ff8a,76eb65d9,6d520da1,34941ccd,8af2f32b,6050feb9,2ab39835,931b901,60a5e481), -S(37033146,69c7eda3,e598a616,12c65c76,8b5cefd2,3371928c,191c3d16,4d1b495d,fb886600,ffb6e95e,dc704a62,f5105795,474ce36,45d54d24,8cc53fdb,7a28e978), -S(493d5ec5,ea8957ce,6608e59e,66e8a6c7,a8aab1d4,fa14230c,8c3a6288,37e60b2c,594cc0df,dd37f4ff,d235e2be,1cb98f61,8485e453,6c301d21,11267528,3bbb5097), -S(71e0fd4,937ae3f4,84d521c4,86f01485,a94bf45a,6a0d2472,d7c5b97c,19d99068,7551009b,73422956,afab9675,1dfa7eb3,9feeacc1,4d220714,1cf157,78f7087e), -S(fe36f2fb,971a1eb1,9a158190,cab6d80a,60601d96,231b5aee,b4c4b332,b35c7031,f72e5fdf,b8ac9af1,263f5492,2caec24e,dda604eb,953a3b02,4e29d70b,55266f87), -S(c734995b,fd73d82b,8555fa56,56465102,b6b14813,272103d5,2de7d6db,fb9455ce,713ab271,3c718906,3faa274b,dc2bfc7f,4f65dbe7,80e07c0f,7b625d70,89f31714), -S(e56a3832,f58b284a,6454f8d1,73f2dbde,b8212cc,a9196524,e1856c98,6dfd76b8,cb301f78,26b39496,6d9f9953,7302ec8f,27af592d,fb8e7e1d,acd5242e,ee2b8cb9), -S(c511bbd4,e242f5fb,a2202900,45f4f125,ab2b588c,f9b375d4,4910fa55,be8ca373,3b96300d,7713d05e,d22eb08,bc039eea,ba2f36f5,80398e61,b3a74581,5f884408), -S(f7ccc53,75c59fb2,90408676,ddd9f1d5,ff6d66fa,1172e0de,cba38ea8,a160a457,45081507,f4a14598,ad0f4278,1f14b8da,72ce889c,f23b52c4,ec5fd1f6,9939e054), -S(8219112e,48f1a2b7,7a03f20e,3eeee016,ac69818,f22adf72,3679e2bf,3586dcd5,205e4b4,2b9ed249,a63d4a5d,853ecc4d,4d37b0a8,4841e959,d46ca7ed,f42a7c40), -S(34df67c5,b0a9400b,9b9eebf2,132426c6,281bfbb1,402cd49c,1fd38bfe,c19f6afb,34066c5f,d45751fa,df681c95,791fba62,79bc76cd,a70ce02,92ba7c41,34fc5d58), -S(9b969626,16414928,6cd8ba65,75572291,f1a885bc,1ef82fcd,7c445637,da1654a8,12e52b50,2fda57c6,ea330d5a,415d47d0,a1e5a138,b7968c7c,3543dff2,9578c13b), -S(68add94c,a17a6ef3,85d23fbc,5d7763b9,15c29bc6,2a520139,24154a60,66d0eafa,281bd1a5,71629916,1a911be9,88a13f64,e8065610,219bdbe4,5271f4ce,2113d77c), -S(143eb857,7844f677,2b01db8a,d6cb84d9,fc1bda3d,638325d,b29d280e,16a7f36e,a50cd3fc,f771ca36,58f2b9ee,4133f17e,d72383f0,94492358,76bf04a3,296b7df2), -S(7b463842,1537aaf7,2e6f0800,cb9c0428,b1dcd22f,73694b83,63f9b2a6,86d94bc,3bed2d2f,c7b5a092,e6e8eb33,1f945a24,65936fac,90a3f244,942895be,ff42895f), -S(1857638f,ef86615f,7bf0665c,3b5d9cf4,c51690bf,c96481b5,78d30131,8a32349,64adcbbb,22267bec,c7a40d4f,6eaf66ad,9c133182,b4af858,6b0c4aa2,e30a37f2), -S(bf84f3bf,d726e0f7,2463bd38,4c14b35d,f9502148,4e78f001,b848fdc0,4d7a823b,4cbaf2c8,71bd8ecd,4439fba7,193a9bca,d26653d7,a4dc7a00,f0a35189,e1949139), -S(4482f7c7,1bc8f76d,9bfe9148,77ac76a7,6131501a,55fc5556,c4e95ac7,68c9ef11,f5af5b16,10733ce5,bdadc3e6,d1df5de1,314495df,3185f7c5,14151c94,908ffcc2), -S(715e384a,100bc5a0,20857ab2,57a352a3,b7ce41e1,a742cdc0,ab1354f9,d3483e93,13703919,b85f567d,87d2e6ae,c2ad89d9,743030f,9b32f277,34c3e9c1,4b5fb1d8), -S(ff90a61b,98f591b0,ffad3ad,3dfc0432,1093acf6,18b0f71a,f637a335,e9627726,908c8caa,f88ae7a,c215cc30,7d7fea86,1d69ca24,7b1c0949,57f022c4,ac130335)}, -{S(d8f08d18,ece61855,5b06a3b5,ac8e7cf,a6375446,cbc7c8db,ad924f78,69e7f00e,46a91d23,910957eb,db830624,73839954,2cea0570,2f67a09d,d7d19217,646606e), -S(fb32ea9c,4f434cdc,db41595e,58f16466,7fd92a08,8a182823,137cd308,9974551f,415b1d67,d845a304,a92f9f62,65d09c20,32bcc521,4303d791,95b05cab,95ea05c), -S(49523899,174fdf41,e4a551f8,423da35d,f3cf0ffa,1f2b8b12,d2a51764,9d8f8b91,6f9c0b72,c5c6fbe4,3fc3d956,7e4bb980,975b744a,dc9ecdfa,8ca42f46,d7164130), -S(c02d61bd,9ca243ba,f2907638,3dade862,bb6ec35d,861a9829,10a084c7,7dee331,fa82b2c8,f015d9c7,b7329bcf,51f60a93,60d54d5,2b24506b,db542d9b,23aa7e6e), -S(a344867a,cf07375a,295cd97f,68093020,af6a1da1,d871b330,a52ab3d7,b4cd0ae,5b1c6f72,531ff281,88ace548,4f193dfb,b8fb233c,b251c788,22dce3bd,3a824c5e), -S(96ba694,48bd703f,a8aa21f2,4257bcb6,2e98751,42d32af,63bb6a37,4ad262c4,35c74902,7d4d0a4a,1550b7ed,cf791da3,7aff1aa3,a446225b,5ce2c0da,aa85c82c), -S(278eba80,511ce15c,f00617ca,21d62211,35f5c4c1,87d959aa,cb098b7b,4b56e51e,ad903485,bee432c3,5ec613a7,68175d93,4f0e855,28b76b41,1c6ad8a5,510510d2), -S(554be9de,b938c4a6,fadc2fb2,77178b95,37719f20,8b7f06d8,7993d06f,c3500bdd,931e3263,34c1e96c,a4c88583,92a8b7a4,c17f7582,e4d0b7eb,6cfef36c,7e2d6f0e), -S(26a4f40c,968bcc7f,cc4002ca,b7ee20c9,3996a600,b4f81df4,66692d3d,5a6c19cc,67f7c990,ba734ebd,af5b5263,cc28624b,9014b7b4,443ed322,fecf49b3,3760b5e4), -S(67a90211,86d66afa,172fa6a1,dbd9b3af,9e3fc726,e5ba6916,59f066f4,fdc6af14,23ddf5f8,96203f49,9be9db01,5451305e,57e51d54,95672895,3968ae1,fcc835db), -S(d3bd63e,d5555686,fa88a122,294ba841,33be6280,17a21f65,285d4651,214b1ecd,f0fd835b,5f27da51,1216ebfc,f5af7740,8fc053b7,dedbdb37,40f6fef4,4cec8bf9), -S(f0dccbe7,ce8362ec,e7f8d550,b0967d4d,fbf6f9c5,1ee4e7fa,b3ab9b50,2b0411e4,7e63fbef,ed68f1ee,6f3143e7,a8e5f2e6,edc77db7,3d34b821,1e062b36,6ff0b8d7), -S(56cf2a5f,d7f41d22,cbe716bf,183a9eea,370f9bb7,5620f460,56c9023f,b8402952,600de0ed,c86b4f7a,93423beb,6a2b29de,749d05b0,4725b5c7,2fbb60e9,7fcf815a), -S(1a60d0d1,73316260,721542e2,33c6be2d,e0088476,e24fc61d,3d0cc619,dd3c1564,bc90efa5,3588b420,2cd46e61,a826a47a,b9f5e45d,eff920ef,100efa34,c179743e), -S(bc406d21,ba9b9a12,a38b6572,5490462d,2be4d0c6,8922fa01,b02e34db,ebfe8e71,6ca29bb6,878fc1dd,13cf814e,c9bff5ba,12a3d55b,13c3aeb1,6d588ddb,371c1981), -S(376ecde8,891b479e,490c80b,b81d15c7,c5b19a7d,4f838db8,b580338d,5745e583,9296ec3d,9256e491,3ccd38f2,e6331513,c7040e20,4d0e8344,6e9e8de9,42699fe6), -S(64cb1c7f,ec791b1b,7b94c8b5,969410b2,52243c7c,3068eb11,99d2a56c,aa2c1330,f43fdc60,76e80c11,4f19dba5,4f51da94,822a98f0,986ebcd8,6160ec7b,b249227b), -S(6f089f0c,2b95a26,e3cd8d95,98469f,c0795e0a,6be85b5d,fcb47071,c5413db0,dad7a3d8,e61e2a7b,ff7f9357,314d4405,8cdc1aae,c1bee22a,461c6b41,23ada4e2), -S(90b30e36,bfb33081,d54a5383,c77116cc,50e1a333,1b319150,98736d29,e4bad6f0,589000af,241a4c83,bc2defea,9b653ce2,988fe376,77b31abd,7f384762,758e98b9), -S(82f0acf,4a764dc2,59218ff3,397618b3,2e341ed9,6f4961c5,f5a6d559,654194f8,ac0f10a8,4728d82f,b8784cfb,b72814d6,868006b8,1d00894,26825a0f,3c3404b6), -S(3460815f,6036aed,4a2e264d,8e17b1b5,6c10d77b,5c021cac,69ee3a4d,ffb3df8f,c11a4b6a,c66ba79c,e6bd00c0,286aa96,de72f162,3a4f8d3b,1a4bc421,c9f33340), -S(b8c0311c,c21b7f08,46e66ebe,f3dcb726,53de4e83,4e450a06,e394d25d,195cb7e,64d4046d,6ef0fd1e,30a71c10,d85f0f07,8ce3113a,e904764c,c5a29ef6,c983b327), -S(f7bdf7b3,b610fcd6,cd2712e7,7a30d38c,2df3bb69,183ee96b,408bef1f,f57dfc59,fdb15f4c,61f276f3,343e2ca1,38d69b12,339e7e5a,dcceebae,39c768f8,95a0bf92), -S(ea32acb5,b5ef1dda,bdd4ef41,52ee856a,6e298277,f5f9c95b,e1adf49f,cba85262,1c0c5f11,3a3a033,790b073,9317fbbe,874afb39,72935a3f,52a309fd,6432e0d6), -S(e184d302,f708d25f,5af8d023,cb6b416,ffda5bbd,9f592edc,ab4f1890,3671b604,21c74686,4200438e,9cf66cf8,19292129,dda4fe13,965becca,8a1fd18c,e753abe), -S(69e75799,f0c0098a,3225e598,a7e8fd98,1218de4c,42aaa680,4ccf7c92,a45fe071,cdd2c796,c85d0930,8aeaa1b6,9a535c5c,6cf9d607,b2b296db,33d0b61c,b4d7711b), -S(a70c1082,119c47d4,75af4a96,1e61f0dc,284733af,c89e403f,9a5dd65,d465980e,3193967,8665bfd5,b37cd1a9,62f86cff,43b5f058,ae9045fc,c571cd62,bf390e9f), -S(f63e5154,9819926d,254f76c2,6d4a7b95,f01e612b,8b885073,f7ad23f9,dfe82d32,57521b53,d9a8a71f,71ae4b31,df7999d0,40395ce9,f0b70cfc,396bee62,40364b68), -S(9f62320,94d674fe,3959eaf5,b947df18,7e894594,8becef29,28bf7aee,983e108,9430b33b,5bf4d79f,1683da6d,ba74adfa,dc19489a,be9eb3f8,9f00a793,37fe9b38), -S(9802daf,4ba214c0,d19ba4de,77d92223,7f120914,7595135e,9ad3c75b,7731638e,98cbe71a,b035839a,3a2f3449,d6261dde,c14501e7,53523afb,4406c657,1fe5d2b4), -S(e86c5944,58017291,318caa82,8fd86a2c,d4ac8a67,c42dbd2f,f57b2b38,f47c9e0c,9e069a55,94596844,8f5bc2f,f97d9660,62f99bac,f74d46dd,5196b37f,f8503c26), -S(40d57e52,c21f1daf,3ea1d981,5f4da45b,807f083b,9e68f2c1,ec5b6d56,e2921871,99115564,76906b4e,5deea9ea,29ef8dcd,c1841b15,bd662ab2,720a28ae,d788e9c4), -S(b797d0a7,4ed78f63,475364cf,fdc42fd9,8a3fdaca,19c7decc,cc7cf10,7cf2f8b9,cbae44e4,773eae4,70f777ea,cc108650,fefdbf31,723eeb6,a77ccac1,129c3cbc), -S(a1b4bb86,61ba1626,c55158af,f04dd2db,b9bec0e2,943d91a0,1b043756,3fdea24f,fb8977c,b1088ff6,e6a462ae,1b8cca01,a0f6c737,816c3b3,d28d8ad7,b42630f5), -S(862cbd75,f1b8115e,45497c3,ce7f1058,200c3bfd,d9cc6ac5,b65b2e4d,abc06241,ddb98861,50925a0b,1c3445b6,a7f418be,7d5ee05d,9b7d1cf9,2ec5b633,9b0a5002), -S(45a2e88b,38c2439,53a33a6,e75c1e83,22a9f14a,bfd6e7cc,db786490,932caab4,23c86383,6a2e35f2,b9b7f8e7,a88ce40,f600eaec,af84848d,10ee1739,7341516b), -S(ebd1c9b9,e01beb16,7504b3e2,80c00ecc,6f44e085,a86a1b71,fe13fd87,3df558e7,d5ef72b7,10fd592a,64020176,a4aa890c,99ce47c7,f3d01e49,349aad20,b6e38c74), -S(1db6b315,14f71408,e876aecb,be1ffe74,a09b8e82,9f05c3eb,18186e9e,b461696a,c7236c85,b7436661,c2edcbb,5247ecb3,2a7d62e1,6d4cdc88,a7648b29,62dca534), -S(51704f97,7873b83,2e36660c,59658078,5acf0396,d29e046,5717ef5d,129a3cd2,672722c0,18401e21,e053ecd8,a219a972,b57b4b1a,56a8c767,7c6b53a7,f0c77a8c), -S(da77e611,fc5ca13a,65bc55db,af4c6c9c,43a7fc41,b58c57b2,4d25925a,99b22bf4,cff8b8c4,a8d3227a,919899c4,201f1bbd,49cdf4bb,506ad705,4c8e2f1e,a6c9dac2), -S(e7daaf33,ef909752,654c1b25,376be54a,22d0b5a6,b35655d0,87a204e8,d1830449,718d5a10,661fda9f,e6bb3fb,a1d3718f,fed1e441,64adc00c,f752ff1d,35e4b020), -S(ea15fe2f,cd9ae892,ff561ad7,7cd2be6,cff695e0,5cbbc15e,444cb45f,10d13269,d3d9b9ef,722dbea3,20a07f39,bd1b52f3,271759b,91bcf24a,caa6945,47d05cb4), -S(60dcb663,ab81db6a,89176bec,5a6a381c,bd6c8b66,de4dfda2,6d50c407,964492b1,42cebc,b7972c8f,e97e440,fc64c330,e4cb21f,114b852e,6cd7dd35,e9c7eaf9), -S(a975633c,5a609935,9c63714f,a474b40,72862cdc,1a3b1bdc,dcaf646c,1197dc9f,51f4cdad,89e63175,49c37342,d757b326,2b1da11e,1617f4a7,b0441c6d,8a1b9664), -S(b5d14a97,7e06d85c,f6189346,bf392516,56f9e92e,3e3b95e7,200cb68e,7a9bb4d2,27979c8c,d556d442,4d128608,8ddcc444,849df743,ca3ea38d,e077f8b2,71263654), -S(581cf880,1cd23788,8be62ec9,e99f814b,939fa6de,f4497b2c,bcfaf8bb,f9fb217,a211bf28,117f8b31,28f353f0,a3ecd2db,d35435c0,79b39b9f,2d2ebae3,e39c2247), -S(38e354da,80f408f3,48af877,138b8b32,f18c1a84,a5323e3e,6a275bd0,34a18ffa,b22ceb25,690855e3,e4e75553,b6e9d619,302d7b8a,f00226d9,8341e406,4d5d9e9b), -S(a62c3ca7,31e863eb,f630dddd,c75f7a7f,315b1a5d,8ebd7659,7d63294,7651524e,bd2de025,270f22d2,41927db1,b2d83c3a,6c4593b3,c93bd192,ee490b0e,b4b896b9), -S(cdf7529e,32b73c24,39c5e793,cda2367b,8cda3ec1,12b68572,5fade16c,5de12859,34003733,4953c33e,3aca52ae,7578a837,64218bd7,661d15,e4e6b150,88f5372d), -S(b00ee5a9,eec1ec97,a673404f,b67e8b01,26051e51,df23ce94,1bcce1d7,c9c0be80,d0ecff3f,45fe1bfb,7d7eac6d,1b27f465,80b22bfd,2b2b0853,c382c06b,df1b1be1), -S(bb7bd0bd,f9b827ca,28e7ad35,e7e42ac7,ac667dd6,5f64f18a,2af8b385,774f7382,ca9903a3,6fab02f3,31afea78,71802d82,6e45fc4c,e7f1453a,ada65ac9,fd15942b), -S(c2e32d40,c675193e,a8097d9c,9beec3e3,64009574,11e46e7d,520b5fb8,44119d69,63c49dc3,5c2ea496,894da7ff,d8b33e82,c70e44,d0b51caf,6e9d6235,c8d78f57), -S(20aa257b,4fd347b,4361295e,bd969d65,60366497,bd0f17a5,5f9b8142,827081ce,c8a82baf,9b95576b,34b6b80c,2ee4669,8bfd4562,59ec9911,4b58bc74,cda90533), -S(35095083,4f7f8218,6e0a8085,2cf56948,3928090b,84d2c068,e0c3c4ce,9819c4fc,1d0bb1ce,2c061784,35df09fb,c21596d3,2334bd77,ad1206ab,41515089,93589b81), -S(4f731112,8d44033d,7380e5d9,71826f5c,1f1cc587,fbdd361f,be8974e2,2526a2c,69d35d5c,e051f2c2,54c8b68f,40033467,b516378a,573d7f22,8ad5e070,f497109e), -S(34746007,54abb4c9,2b9f1a9b,33b51139,114bcfb6,ddbe9e2a,1e9182a6,ba52cc5c,29f6bf7b,7b31c57,b83e9f41,a9fb151b,744f0bf4,bd2dfa1e,5a5ffd14,e3528ded), -S(62f72456,b06b6bbd,70c2045e,8c1deec4,d1ca74c9,aeaf68c5,52d424f9,be280edf,13e619bc,d667afc5,81d293aa,3bcb80e,fe3212a6,9750e45b,94740aa8,286c72cc), -S(b1d18497,47415d89,7fd3b791,9e2a1cb0,e47efc1,2f6dd61b,93da9d5,99cc3083,19eee106,bf3f71ac,436cd33d,9fbccc4c,2ba50ebd,20e93478,ff0a6c9a,96fcd5fe), -S(9f8bdabe,3e85c253,40047952,812a913d,f9d83038,d869f535,e5c7ae7a,c286ef9e,abae000c,3e24af88,242df5cd,3a3786f1,7c8f1a7e,7604be96,7495b6e6,7ec09284), -S(c3d3786d,31cbaf4,57de58c9,c3ac3527,ff40e817,ef36bd5f,34c005f6,2967989e,b39ece7c,3e76a6bf,fd14dff0,a066e977,6565bc22,5c26d446,5d6b193d,d37dd7de), -S(749984be,1953ea05,318445b6,52c970bf,32cd173c,3b222686,a054fce6,787f634d,43c4b03,c395080a,20d13e6b,edd78d74,7e9e326c,c267f358,43eea751,d6ae31f7), -S(8b345416,f6b91613,4ae7c45a,de0d2ba1,75aaa225,795d94aa,4c554a66,9c08f5b,2166a466,d1ea4969,fcf766df,ecb263d6,339a8331,7b342ed1,a4fa6019,23af6d0f), -S(af805191,730b8c9b,2ac105a7,eeecbff9,497c9414,58ee28cd,9bfc40c9,5078c366,ff3dfd92,1e3c1dcc,669a3f7,799277f1,591d0176,bd707f9a,442a219,7eb6ae4e), -S(c626aa89,da7a7971,c7923825,d31ab64e,2305ff94,1b724334,f8c8f1aa,ae60e0d8,325304f9,926dc306,6002e743,e3ae4ab9,b2eae44c,ee907075,fd179222,5c051c05), -S(7f6dc30c,271e6382,db40583d,acf2d121,8803d63a,41980369,316950a3,a1490878,a1224a09,8257f494,331235ca,9d0fb42c,9f5727bf,74e98d60,f624e4b9,a742c7d0), -S(f90f030e,30cf9a10,582d022e,b148e12,d442a9fe,2345a552,564731f7,6c9aa92d,d1ec7fa4,677bcd7c,ae9602c9,2cb9a486,1ce7f6f0,9e6c53b,210144bf,608962ed), -S(f9844b5,6b5ee53f,d41b2d5d,a8eba633,1a8518ff,4f2fb920,368a15b0,6bcb091c,165af5b8,7ff690c1,e5e44f78,b0f04f89,70b6a370,8100e86a,ee82d24d,fd10ef3e), -S(b091a817,66903079,42158c,acdfa7c2,a42526c4,f19736fc,aa62bcd9,2548acd3,5e2c1b91,f6059ea5,5595a105,5a7c4827,4beb810,59c7fdff,e1365be1,a6c2454e), -S(bb291c6c,a65e98b,4f075b05,becee4bf,757ced5,33d97edb,f4920c3b,82880d96,4abf12d1,e910f80d,47c81d41,ee9fc67d,59f8b4,5dbc58d7,16fe5d96,4420af42), -S(af63ce57,fe9f7568,8422ead6,40b64638,d474f848,d26c9cc6,2b89b457,4bf42ba5,abcfd290,320b7554,fe5ebf2,2554043e,a61397e6,6b1b6b6c,441ee203,da003203), -S(563c787c,a9c7a042,d1d8e916,fa653eeb,3bb455d3,d81d96ea,6c04021f,764f29d1,4f5329e0,9aaaa37e,997c09b0,47c924eb,1a9b813e,da648875,58365385,918faba), -S(6795237d,a651f9bb,c4603d87,cf14d4cd,9ebdc9b6,b0143c7a,97a99cd3,2715cb5a,cfbcc0c8,a4ca9939,e7050925,43becf45,59d953d,840d2393,2a2648e2,e3ee1078), -S(6d6158d7,3629a6ed,9437b26a,2c91e31,fb6965d7,505ed096,ee74ec84,3a95ea95,3923c2a6,ae7282a8,dc3e04e6,664c4bca,8842a0bb,95164731,5b47b85e,2b3c8bfb), -S(88a45a7e,512c33c3,ea439da1,e9715f4f,c397125f,e26cb7b4,227f2227,628a57f4,dc384c97,bc2c5e45,5133e5f0,21c0d3b4,76680c02,41e8e31b,b1d96c71,3164b7d2), -S(8cf77e1d,7a4bf247,18c29f7b,66946820,bae990ea,262dbfb5,ed63a701,dc2bf3cf,8d70e07,e7eae6bf,47d224c3,46bae612,329ee6ff,e39a84ff,640b25b3,9877cd6), -S(5bf3fc7c,c212a2c9,a90cea06,44503842,d9f5fe28,fddc0a89,b5610fbf,1a38820c,1e64ea7,193f3cc6,c4c62c77,fc27d686,1aacd775,2b66b82d,f95952ab,ca6488df), -S(74ffe6ff,73a6a663,40e6c2d,77c410c5,c1b46e04,7ff796c3,85238675,e3eb97b4,c31e7707,33d8ecaf,bfa3a3fc,6ace4cb9,4faf3eb5,445f3701,1de882a6,2a4915f2), -S(330b3676,9e60504e,e3225ce0,36fcfe97,8b74c62f,e8ab9007,ea1452f0,6a06ccbc,cf80c153,1165f279,a718ceb4,76e90d,3394d01c,ef6f159e,1225b2b1,51bc3c09), -S(471e94ca,1b8de1e5,eefd39ed,7b5f997c,9e9f20e6,fea65549,8ba33f6d,a5976c0b,ad5b07fc,2a5a049e,fd210e27,b849a842,749c5e43,f6321e17,18e20dd4,4d228c8f), -S(b8133090,5a4ead1,dec7dd81,df97aa7c,daf67e09,58f16739,e5ab2f12,f309cc2e,49fa5ef2,c2a95064,4ebceafd,732fcd7a,3a4c906d,95902646,e779dce2,4021591c), -S(b251f7a,36774d66,f98d89be,15e553e,d85d4bd3,2a170b7d,f4fe842f,d35644e2,cc71d8f7,daa8e846,5b5d6230,e2a25a4f,f92195e9,de33e32e,6970fc54,97001a40), -S(c0ed75ca,6ee80f93,5f7d86ea,8e1bb463,c90aad6b,145873a7,2884f5ec,a18dd90e,73ca6688,b5221c2e,6e82c261,fdf19c26,fd167035,d71f08c1,9190391d,b88efd50), -S(bdc5e903,e371fc46,828133be,5c4d72c3,3f19a203,c4800fc8,59d343a8,7c844c93,ec59e7b8,ac2b2c18,c51487af,84349cfd,f6842a15,cd148e9e,ded4202e,fa0579dd), -S(911cc60d,78c5909,4bd95589,61a99522,fc9c66ff,68370934,40ce6531,e730fc97,8b7c67c7,b33a60d4,bf75fb25,a47d3942,f6c95aec,5a9bc3a,4e8012e1,1274459f), -S(a5e02e09,a00fd3e8,fa7925b2,7206d296,eeff1b9e,18528376,860f2244,1b174f71,4fda8ecb,7fbb77a,dd05273b,ef51f2fb,c9abd87,eb87b9f,50d5a3a7,835e9d21), -S(36917617,6a66b671,684334de,9d6434fc,269197ca,ff36b95c,e8f36870,6e475e8,dfb20c43,78817585,552cd193,2b45dc37,b66a63cf,166560c9,746a9f82,ec3c4fc5), -S(91ded03b,67863303,92abd862,c2f2e870,80524c2c,c0940a0e,820c55f2,175d7533,95e7aed4,46172d6b,ea382418,5f1a5cb,dc26cada,26451556,81b55f08,6bb82f9a), -S(7d5a3667,26e40c76,923867d8,6a5b5cc7,58d84663,8a8f664f,a0b79d20,85824482,cf50b22,7f9d7889,bcc082ee,30d2f08c,1c18b2a3,7443ad43,86d6cf87,a59d77bf), -S(929edbc1,75eb61ef,f1a564e7,d843fe72,c4a49e06,1b704002,56b49b27,7c632eb7,bad98323,4d603b,c85d2747,2e02f089,850725d8,2d905c2d,12d1e730,24bcfb7d), -S(179206e5,861ca493,b3336805,4eb8b46,3a47a189,d4210ff4,5b8f29ce,2b8b593a,1abca34e,f7c9b56d,d72ee602,713b8fdd,ace3007e,a88d774d,40a6aa20,6c1c3e69), -S(e3548935,e28bc944,d29928a2,935e5bbf,a0285c2,337dad5,3fa40a07,377b4de1,2a886052,358b95a9,c25af629,e6d5d2c5,a7dacc44,eb6108c4,46c07af2,cc3977b), -S(e4092cef,884cea2e,51a5a82e,ff8a3ca1,6cb38a71,142ea0cf,476aa293,f9e63303,bac63e08,b0d90160,d8d937c6,ce0eee8f,c01af5f8,a84d2970,ef2c9f8b,ad1bda9a), -S(fb1294c9,c564a667,6bc88f4,90ea39ff,e2dba6e5,4165f6ef,92c90675,138c82a5,9fa392ec,ef922e7e,6bd19f36,99682069,19e799a4,be30125f,5563d3f9,46e01132), -S(ad376df4,e6025dff,693bfe2a,665a09cc,ba64f12d,1b4f9d5a,11e0c880,ebc745ad,fa246c63,fd5f84cc,d104c8b8,ebdae50e,3b86fe7f,976c4a95,c94ac06b,9c6df68f), -S(8f723cda,9a28aca,dfa0f86d,fbf2a831,700dc839,dc40392d,61904711,1f7fbf13,9bddb64d,75a288f6,e92b8838,5affe05e,1c07982a,2c9a8519,d20ed505,7acbafbf), -S(4a674fd7,4ef0139e,d151a994,ad3f859b,aa2c52fc,7766361,949ff86,a1159bb1,f0e5ed3a,ee6a94dc,a2b7a353,dc42801b,faddfcb9,4f1d5b56,f606d77f,ea4df16), -S(6651b5c,307d465c,1fd4c0af,c6edbe5a,e292eaa8,417db4ae,82b53612,66c5e7d2,5d02e21b,68dc7c4f,414c0cc,650909e7,cd46add0,fc91c7b7,98e00907,2ab85c35), -S(e6229fb8,c2a0a7e6,c9aa31fe,71e75cd2,292dbf2d,2c5461ac,a57bf13b,f57c073d,86aef20,5c78e3ed,6cba8445,49aae8d,cb548182,f31714ed,ba2e0b02,2d594429), -S(aa55bd38,39e91fd9,a6080dd9,46b441a7,193ea997,b1e6f72d,f735c675,56e5d7e4,66eda908,504bcd50,19a3b220,1a16f7ee,3692aeaf,ae8b265b,caedff43,19abb2a4), -S(8932bd7b,b1d9bacd,2fc5aeb0,6ad7dd4f,989a8417,793d2d71,b0c1ed64,592822b5,72cdbd0c,56b29915,54b68484,b75dfb3f,fe04eef6,5d522c55,d1c62bc8,8615f9da), -S(10f3bfd0,ee76006e,c113a1d3,37a5cdca,3601da68,1ec1758b,d1286304,a49808d4,89a27069,cb6bcf5a,8848d3b6,7d65c529,749007b9,3143b395,87318e90,4cd4b53a), -S(dca42b0,8e19ba70,db8bfcea,e52da664,956a3a3a,fff18dfc,6f9d4ee2,7194cd14,f6c76a86,eb3008dc,206d76e4,94ee3224,d345f4dc,ce44b54,fa5810e1,903a073f), -S(1251d8e4,9d6c61ae,a266acdd,53be9579,c993ceac,1c62db42,94a4ec65,e942b305,2a722ec5,5f800261,a937883a,ecada795,efa50c56,f12fcee1,20f81ed0,269cf5f9), -S(28b48ca7,c8c57bcd,4cbf70c0,81e46910,d1964ad1,af2e2305,184c3e2c,d7a6161d,3a7a1202,90d5ee64,9c4c1bba,d43d7e2e,6a5710db,924d3943,ea06a6d7,ffbb3bd7), -S(675a33aa,76d1658c,54a956a9,2e8f6487,b24e1417,a179cad7,c0c93cb7,6f8b7f50,8bb59b9c,94156814,a00d2621,d0fc87a1,be4c6165,33704160,82e825ba,62845cbf), -S(8b5b6b75,1d7bcd6a,dcc0f5b2,6e231abb,9d613ae,f80a561a,51463d22,e0ce9acb,e0b17875,6c146090,fb03f5aa,b952d904,3a0b45d1,d1a66b8b,3773c94c,1c657ba1), -S(35b8251e,bf562c69,2e0d11d9,dbe01290,fcebdac1,fdb9f467,9b5c2094,9a0517b,82dd2707,cb4b6758,ba7e7b09,cdfddbb0,11920b0,9ffae6ce,d3ad2e1c,648eadbc), -S(a9ba52e8,4bd13565,1ae96df8,bbddd59d,628657c6,2e0a133c,e2f59a01,8c8efad9,bac10321,1f614972,70c26dfe,47060b9f,d50764c2,461c9bd5,11bf502,a0b83d28), -S(eba36b0a,c20fb216,f8a4d8bf,ff21a478,d80389ab,51d6ac20,df5b2b41,834c56e6,60440923,e9c15c5f,72b7dbe8,5c3c13cc,58fd4ab3,a9a99ca0,372dbdb4,d4af1658), -S(e47ef3bb,b6f8cee6,11c05d2c,681a7fe7,2393628d,77f93adb,b875461b,712440cf,30989ca4,57112c77,2c2cdfb8,bb9e3751,343e8455,6ac9e86,db43920d,8c20d3d7), -S(36b0132d,2058e379,c9b1b23f,c13de925,ff61d8d3,4e8c37fc,afe17d92,670fb23e,5fd9aa2d,43c9a6e3,ddd8752f,9a3bb676,c4049d3c,f849274d,34a60a95,c4c19e0e), -S(dbe78ebf,6db49199,70c4f04e,56e62811,d0067aca,b05fadaa,bde4bc0d,bd2b1dbf,9b40dc7,b2a4fe2c,cba721ee,ffad0810,f909353d,ac53e731,945e418a,2846a8d8), -S(19da9bb9,e0b2626a,c9069f24,3292462f,2394e209,82a7f8d2,fd0bdf26,ecd61d00,3dea2ad6,50c8006a,f4af6848,56348dce,53d56d61,d7f03cf7,aec76a72,559d7c13), -S(25d7a7f7,24bbaa17,83b79913,25ab7c40,da5f3d91,bb13a8b7,8101e970,b1295790,1b675e72,354bd3fe,21c0884e,f0a5802e,45f8fe8d,3b0c0d92,7a53741f,231ae06e), -S(a5ad3cde,de3d64e5,aa1ba02b,10771048,8ea62934,6781a0dc,ad93f3b5,4c15fcda,d14651a5,823fbd07,4a107950,7e55089f,fab0b4f7,5e8021da,767528c2,2e37d72f), -S(b2c32ac6,925348e7,1adcc149,656c21d7,3343d7f9,a97fc90a,6c0ecb9e,4835fc53,a2fbf853,602cf32e,881540f4,eea48400,6a67568f,4d69f2db,3adff02f,9b687716), -S(de3610ea,e95e73c0,fe303cc2,9b1bae4,c3ee5009,a5751e40,6e0dc64d,c2128809,83fd3a89,3e9264f6,b0d9768f,b2137665,65ddb286,9b53279c,b7ac524e,e8383e29), -S(d91d23de,8b442f29,d0ab4a23,182a429c,299cfde5,8f2f991,53139d6c,3028098b,e00a507e,48a68d49,c489063,39942d9d,a7a81cce,6865487a,4b18b34,b1b2e65e), -S(ef90ef91,265655f5,7d776fe1,a153289,87052919,448049c9,b3342a94,9f66dc83,a44f99d9,e9e3cc67,9b819232,14b4de83,d95a65cf,c3af495a,2e961a68,21511c54), -S(aecd0136,83f0c6b2,d9434651,94d6d6b2,c727d3b9,3409887f,821f0bdf,ce30101,59b3d669,1952dcd1,bb351f31,aa281dcc,b5f7cba6,a612d5b7,7d3da3d7,92da741), -S(192c250a,31468e22,56c25dde,ed840d9f,e9da10a5,b9dcd4fa,505f418b,9993c86c,e311e20a,cd56146c,c03db59d,799a1d51,e3955b72,7137daf1,5dc8939a,3e7d0f85), -S(85aae3c2,2a26d60f,c14c46f3,d789cf89,5b23cd96,c4515ba9,87609fd4,dce41a3f,54bcad5,166281d0,bd33587a,52a16a3f,13d7b1e8,8bc009e8,7c4f59d6,e13ce99a), -S(24dfbf0,c22d29d,bb3f59eb,27dc89da,7c0a83d0,7b42445a,4993e205,43a97bb5,64858a97,8471f3fa,aa838ff1,b3ecfef6,1d47e3d,bb684028,bfd6c194,dfa05928), -S(909ff9e2,d591a673,40cc7df0,e73be5c0,ce19c4a3,24679306,995f6344,bd692f3e,5b956095,a5d4598f,9dfd693f,893ccfc7,d77adf8,bdfe9ccc,8497125c,1c07046f), -S(fe24c76e,900f320c,c41bac2,e625293b,ef871944,b0586680,3e0848a1,e15a60f,ae054925,3338878a,b1e8d268,b6feb271,512aba65,e7e8b243,7fd4867e,74b5fc30), -S(7704fbb0,13a7ccb,5b0c73d2,cf6fd87c,ce4c8d8d,f49515e9,9145b3aa,e02b2d6c,21ee85ac,405e2cc7,c9fe7a8f,7b59c71e,82dbfa33,bddbf113,64435f8,53139dd8), -S(e136bd1c,9b7cb6d4,aac07f42,1f1da3d1,eb9a8935,dcdd8097,7c137daf,869d7c11,c9d44b0f,92b5e04d,aedb2155,eb1930ea,802b205b,880db2f8,62575a48,22acf521), -S(c6efeb81,850462e,72ae763e,2c1d2f39,741babf9,5b7559bf,c28d263a,8944aee8,f6bf9cd9,413259e7,85490c49,cfc74576,c23bf0ff,9599b877,2acce426,1d3e273), -S(5d09a4c1,1c1d913d,d83c33ef,1377ded6,7affae57,899b5742,347291b7,c434edf2,15a6d501,a857e00a,ab42d1a0,525089ec,cc48d185,7f5dbe69,e3687bb1,2982cdf9), -S(9989c1ce,c3865ba2,41cbfe91,1b72edd2,ccdb8b44,9a837284,730b903f,b45507fc,81cfc11f,e8de5fc,6f850c66,21bfc5d8,9d7d2bb9,e8b9b2a,dfd23f8e,d2fe8d40), -S(c8d0b073,2930e2db,f149c156,c5957f79,fecc319e,f4abe588,860dd44a,d74779c9,bb96deb1,e23ebf7b,afc79ea6,ff7fd012,e2faff01,8f2d17fb,38fecd52,29aed776), -S(7ba25516,877adf65,6719f4ce,e867b4a7,3d7bb18a,735a6043,47d5d5fe,47be46b6,f66f2364,5fd24d13,39407ee8,241b07bf,7e6a08c0,d3a1e683,67b450b0,f3eda69a), -S(be8f83a5,5e50defc,b8357409,3b727cf3,578a270a,c478ada4,22e0cb8f,907edefa,c38ed801,1af0e3c6,55989b08,af329cd,340f469b,d0bbcbec,6504cd34,aa44ab9b), -S(9bd6c57b,438e1ede,cfba0916,d744ef9,8b010164,ba46675c,1206d9cd,67c3380d,d15ae82c,33b85d22,9df4349,ce48b582,10c1baa,689fb6d0,51721d22,334ae972), -S(e8927a5e,9f511cbb,ef935f7a,a90c64b1,666c8be7,1445cc8d,193ec922,1662177b,cb6f084f,a41e1bf8,110a98e3,bfaff1,43ef6ccc,56170ca5,de520a6b,381010d3), -S(c4243e89,4608658b,df46225a,85da8f71,dc75464b,fa29dba,6d096423,81b77ea8,d501050b,89abe5df,fb9a11e1,6d1f2bb6,d081b20b,4f0d9895,70ec128b,21e2c124), -S(582f0c51,20f5c79e,76dde6cf,624b11f8,1e9663a9,5eab0480,8d4156ea,61e70723,1f0c54b6,1cff944b,b9bbae8e,1d2570f4,315e3c8a,f067d289,3d9860c8,4885d7a6), -S(d384563e,67e85943,67725600,81f4287e,fd7c6fdb,6e29ee62,ff4f447f,91a4882a,b90fc799,7f76171,c7a76d35,7aff06b,df5b3d00,a1d6f089,bbb2acb9,e749b6de), -S(5655f9e3,5bdea0d5,d7d023d0,7a5d415,52c39f1,a9530241,55b647e7,e757e40f,4f60c357,bd0a7577,475c8e5c,9c6e099,1a21523e,821cbcd2,665d1ead,c6075a39), -S(b1209637,51d5e9a4,5bfdeafc,5aa9f45c,9c29681,2c4769fe,6db03118,cf0a2d53,eadaaa67,96ecf2b9,57944958,c9fb1cf6,986f387f,50d1387b,d4b94eb1,aed1e625), -S(bb6ad704,477295a6,710cdc87,f7df5c4c,c3b82fdc,749f8464,474fc61e,b307d4d6,7d0d1fd5,ea113783,7071f705,7bb783cd,a4b55908,9af6eb59,1d6c18af,434ddb34), -S(3daa25bf,5223a09e,fbfa63a3,405e8c76,b059bca9,38d513cc,693bcfbf,514cbd95,e876c903,22d97d60,fdb0cd64,cc9ad575,cebde9f1,41d67c82,7f542034,5c7c6ec3), -S(b32bb726,3f40831d,a8e00e27,db8ce14e,ff1ddf5c,4e48eb4f,deca0531,3770c016,916fe7ad,2726bc93,c242f50a,4e3e69bf,db965402,55440262,ccc5c055,136dcd4), -S(a7f331b5,26d74b9a,67ff3453,2399ba79,4fdd4d1b,1b99dae,1b7806e1,8a0a7f11,786b90b0,72c5a702,12db8173,2dd486c8,ba59c937,ea9182dd,f85275e7,d6622c6f), -S(30086238,dd36b617,f8505367,a015f6e0,2f14079,3b4dc5a4,442d8628,1ac8caf1,9b87d837,644f4ec6,c161c8c9,ae923bb3,f40f6cb9,6538c0f8,aa8c4ed9,42eccc8c), -S(1ec0343c,f9afd13c,57ef2b2b,4006c740,dc03bb3,62ee8129,c4cb35a3,299b1ab3,8b645dc1,91012651,3df47f7a,e33f201d,35cc1d73,2184952c,f605f68f,ba8a2e34), -S(e8059ca5,3aa197cc,3468c797,81b36245,4ebd8b86,7227a9aa,21816967,52d28587,39f9b33,e91eb4d6,fc769d6d,1b43fc0d,ee8f1841,8c682c96,5beb1e7c,9280d23c), -S(fbdc998b,96eade37,61e0b0df,a6c4fa5f,7794576c,91d5dc52,f9753e3f,748c5afd,4789bbef,e1f68f8b,2058e41c,c513858a,29a48cb7,be41ce56,248ffe3,996d043a), -S(3ab5a2fb,fbf2acf8,2becd224,4239ff2a,808aad64,41b1b47,1aaa9e67,12bbc29a,d20c99de,14e44cc2,18a42ee5,34fed723,25f225ac,8c68f2ab,d6c19341,5921e5b3), -S(94b611e0,63334b9c,195ff7c,894cabc5,2ce902ab,5b17a572,1a697c3a,8a4903d6,d8d70dea,a7d8fadc,da7eae42,3ea8cc29,285c32c2,30a8731b,52710126,dd03769a), -S(2cd6e98a,65c1ec8,6596781d,4239a71b,8e0c8a0,4c3dd8fa,c7925a07,2c246e3d,67bb6602,75d229a3,a28f51a4,a19cf6a9,f138f72f,5bcc2ce7,c689d699,b23a59df), -S(500f58a0,e8929d68,f4fd8e13,5fea7e6b,afb562a6,ce1086a1,19871799,c5a4f2c8,80924142,bbe02b2a,7decc045,23b6c132,af14283c,6f715abb,113a12ac,a92b4205), -S(4c1ef59c,5030213b,dab7be6b,c3f4272e,b7d4e07e,981a3160,cde6797f,821c507c,d878f643,a0f82a73,d7c9928d,ff243584,77475dbd,2076e7af,aa1c54ee,e66ce565), -S(b69d8ca6,6b0dd8ef,df2e7c11,1dbf7876,a3ffcef0,424f1943,49256446,78ff24be,1ba714ad,96ba9f32,456e4288,5b9d018a,f3cbb43,37e5a0cf,ebcfc5db,9ad76c87), -S(53def7f5,bbace323,cb0a38f7,2268fb93,1e4f546f,a72e5b5d,2d5733eb,6d39dbb4,1533c9ca,5c0142e2,e1e1ec89,d0536b,282cb784,7ae5245f,ef978581,e3aee5ab), -S(a7f043ca,731d58b4,c5048ffd,12028f94,bbcfaa96,efc52a94,6c78c42b,748ed508,8ada0d66,1aeb2b7f,36eaa00b,56424547,ea5af2c7,954b8801,9e8e62ef,ef9e1832), -S(7d3609c7,7a0cb4e,5294c831,d05d9028,e1d16d60,7495da06,b241a87a,23fb93c3,9ade4159,fbe98e1a,41297877,383f023b,5a7973ee,afd17af,65ee4753,d24a4f9b), -S(a488a3dc,20442c4f,aa127f1e,28d85b20,5681be3,311e5063,c7a2a356,1312569f,4325102b,66f100b5,7facdca1,7973b3a8,f9cc5d97,3f018e4e,7d035e5a,5d2549d6), -S(9c340a46,94b8bae9,d7e6a922,db9c750b,3089101e,946c3e58,88a4222b,42a05d9d,cc580dd3,679db392,74ab94c,d054f264,42c9ff72,5cf5c1c8,a485a48f,8f571ede), -S(44a788f2,c070a53,5c4111f8,6cf636c4,5ca83338,e0b71781,44e7c542,c289480a,99d57358,ee53d719,9acf8ee8,b679cf9a,5c44611b,bc17a734,caa914de,25d7b22d), -S(3039da67,d1d2a063,9b92c0c4,c7c6f415,c142acdf,ce21bba1,98de3bcd,ee9bdb9,c11845fb,32021c59,8d7cb0a5,a7c3da2c,851306e2,75af5398,e406dd34,fb5b167b), -S(6381f67,a6f5e9d9,535ca436,c92bb8c2,9d8eca9d,b335e159,fccb4609,484d401b,9f480076,aa6715c8,2fc04c58,d30cc445,156b7d9d,b1e4c1f6,3744ebef,5060cf4f), -S(7ab7ff64,d2955841,1872da55,7ed988a7,ba182fef,480d36e8,3b65f1f,cf0c0c3d,76262668,bd45b55a,dd32839c,591b6a70,9e4e7ce6,e9fdcf55,c78e9e83,dbdd6096), -S(668e29f,6b3dcb44,14e4c22,cc2fcc8b,3a20c00,89f94ad1,3f279c1a,41d7df7d,4afeba02,4ea185d,caf130cf,f7f12af7,7dfb3cfb,1871d641,83dddeb8,86545563), -S(9fde56c3,ac8016f6,ef6dfdc6,da621198,501eca9e,377c594b,e063b24,e0721dd0,dea4c586,233873f0,3ebab8db,900b4c21,6df32c7e,12b1f1a7,be26d46f,880022b6), -S(70f3ea86,cf318a63,e44ab07e,a4cdb22b,929e42a8,9c1eaa0e,a0d56bb7,a9d63592,eacecebe,3e94160,bf370703,2fbec0d8,e83f5bb1,429ecb12,4f11974d,913d4332), -S(68794d4,cb77a07d,f2d09cad,7b14c8c6,a8c35da4,9cb9be35,ec6c19d0,a3e4fb6c,aaf0efb4,5be195f6,29b8ea14,ec137e33,f14cb692,b3aa59f5,a71bcbff,d8511633), -S(708c3036,27cdb4a,58ec9884,6c23e392,e7d8e1a,c7c0dbd9,d640dffd,23938a24,113daf12,a5b57f22,fbdebece,3727474a,8289c4a9,2474135e,13970c7a,d3802084), -S(c74bba7e,2d764df9,e6e76441,6b40e019,5caccecf,75c8f0b1,fb3ca353,2236cf10,a97b858d,1ada13c3,3ff98a0d,404e3e46,768ecac0,b224b965,7d620c3f,ce3aad05), -S(186dec13,501477b0,dcd69175,c57d33f6,264603be,256b3029,b5f9dd9f,fcb5ceeb,59a646ac,96924f8f,cc02e6b4,14a2234,f49d78fd,6b64dbfb,f8baa0d,8acedc77), -S(94486ee,b0535256,ecdcdc9,576faecf,9cbb7c12,8286352c,3f3f249d,458e8ddf,4e5290f6,bf22cdec,8f7d4617,531562ee,f7402174,b13d149a,390fd9fd,17ec3e7e), -S(304f7074,5b9561c0,7facf83e,8e593af3,cff8d174,2d2472ca,bcc08ee2,9b7617ba,77654948,8a95197c,612d6bb9,20e6c9e,b2c2236f,5e28ccd5,6744152,f46ddd9), -S(97046baf,d42c5a5d,b8b892cf,7c36ea67,86dee4d7,bffbd572,20f9a122,26038a5d,7ab1305a,103c1cf5,a77f298a,489db57a,2c9148c3,6a834da3,ee108971,8eb3d43a), -S(e4b52916,3f73e5e6,45c44686,3b786f53,46b048af,3d1fef24,e80ded13,ffd89b0b,7409a638,452fe0a8,7f1e717c,b0e3496d,14b9e3f3,e6f4d048,52f622f6,ba4ac2fb), -S(b9d303a2,75452bee,7800cea1,1c06db97,4057adc5,62bf5aa,41c34e5,18f5ee9c,4c818cd8,a24b7775,35ed8738,bdd8d45,76408c87,ad172563,6c536ff2,ce6475dc), -S(fc459ce4,3283c842,1a16554b,d5eac61e,3e4b60c6,2b090c52,465788cb,120d2295,2b2e75ab,10a60dff,1e11bddb,62457bd4,585b262b,e671f5de,84ec3bef,d5b0b232), -S(19828f90,5f901716,bafd9bfa,856e8fd9,c19eb83e,37c8e5a1,11366a77,11a26790,5bf76d98,46398c34,6b021018,6dec4ad8,c03b866b,e0edd8c3,9f09fef2,d7c38bba), -S(e10dbb26,999ffd14,f29fb5e7,e3b3b78,1519e63f,ea0fd26b,b1b593c1,8267dfa9,c3c04bfd,799303ad,de767ff4,2baf9759,82c48d95,5f127ad1,d59ff73d,cbfc456d), -S(2e53cd28,acba99fc,6763f788,a644e314,1df5e17e,c50003af,48206aab,d81a3396,4393815b,db8dbe25,6b0269f5,4220200d,278fa537,666b5cea,34cd8e77,854ac02b), -S(f6d174c9,60516f44,6054b7ba,a0f82557,87ac2e94,c966762a,f7c428c8,8b9de7b2,68ff3c54,a3257f1,7b27a5a6,ee7cfa88,97493d3d,b0899b47,c56d4950,ba263a9f), -S(7d18482c,704eae8f,c6a33f77,923d9063,eb3e8e5c,28ce3d3d,8ffd3e17,ebb82881,a126d78,eac1033b,a223cf66,81faaf93,bf523dc9,409f03ed,abcf241a,b0a6e3f9), -S(b2c02f09,b930691c,a017197f,bfefa1c,bedbfa2e,640a66ea,fcb1c11d,f574d9f4,19fa7f66,cead7607,d404c33d,2491a6eb,ea0d3b00,4ef41bbe,13148508,b0a9d29a), -S(253d6786,8bf2626e,acf690da,8a26d777,bf9807ae,ccec3804,e1b7808,bd16ab91,145f6933,f9ba0d51,18eb8985,43a01106,bc702915,373bfabe,4ac970c5,27c17a00), -S(6e496a5a,28a74cad,4b4fa30c,48dcc62c,3f4b4fa7,e8151a10,3540aeb6,70c20d14,c7884130,274649e9,4e61623a,ead39ff,ff3b8a4,526509b7,7ae8586b,fe315ece), -S(774a8bed,36e7eb32,8e89734a,e5c0568f,f1659e3a,73890010,ca4a0e6,dd24a4ad,cfdb3a1c,1d8bb371,2e8f2ca7,2c578568,9db680a5,68c18e5d,4e423b84,df9fe798), -S(59bc8e0,e63848e3,79e0912c,4a0c9572,10023a93,a0dc4303,7b3b9e1b,7b834762,db8ceeae,61f6adf4,ac08c5fd,586209e6,f4879fbd,6aa9a1b4,4c67b4f6,69eabebd), -S(46659043,eed0a625,42513ca9,678cef04,2fcd952e,29be4926,fedf79ff,acc8b686,3a5f51a1,4c9fd813,3f11ee7e,6eca075e,f90c91fb,a10fb251,250b4cfd,9281082c), -S(aa92c411,308d9d48,fb62d7a1,2999083f,c52b5d79,196dc91f,e829ef04,41745aa0,d70ec349,f27a1393,ba8d57fa,968974ee,ab0d8e81,a497415f,d38e156f,bb029864), -S(36382200,5bea75e3,8c2483f3,eb95f6b0,a7f53f10,32bfb1dd,537cbe0f,4049f56,c9b9c28b,c2bf0056,91eb3e99,2efd5bd4,ffeeffb3,e7fed235,79af40e0,961489ad), -S(c3e4fb46,e400fd1f,e106c056,838cfb2b,c1cbcd66,ac9c19bc,e7df1e29,a7bd25ba,96b6c598,512215b6,a30486d,9f8b0c91,4589022c,194df5ee,30d62c2a,b9e83fbf), -S(71105f47,e372fab4,81cf29b0,ab5605d6,84c00224,ae1b9449,7c8d3c59,26077cfb,f7218aaa,d2a95c0,55f30f69,3fc087f4,101f5db1,1c9ce88a,629c5711,a1f1ef51), -S(676066da,6bc50ae2,e2e46f61,dea75ac1,12cb085f,2f00ccd8,5fef1e47,56059f3f,ea9e25c0,6c19d572,8b4bb333,35e94202,d252b9d6,33a1b04f,a7b4129a,2efa83f), -S(2616418c,11f5536b,c8873830,9758a819,f7b30e86,f4a16f90,ffde0685,e91a12aa,80b92bae,591f59cd,8d480401,644ac3c,940e917b,a32e7a4f,f4a2d5c8,cc417de7), -S(3bf5d07c,715fad35,45ff092c,18cee285,3de0d50,c9d68225,3596eac1,42111d18,e382d006,2c4b4536,c6432557,afd0b909,fa047ef3,1cbf2d8c,1eff9ea9,9a95fac0), -S(5e9d4316,db96d6c0,a5247809,8b22c654,7d873b1e,a4089071,86f81da8,71d057b3,e22c05b7,dfb5dc29,c07a735a,31bed0a3,2e071de7,41d734cd,dadd832,1dfe56d9), -S(3c153e81,e6ded587,dff1c8a3,ae5758bc,58c271ec,aa9dc005,1441ab2,a5aa123b,366fff49,b67b57f3,84b5f027,83b02d5a,f731f3b5,c6e8c089,949a0f2d,998636cc), -S(187518bf,347b87e8,e9955bca,b7937e80,7c41ef41,97511d9a,daa50f3d,9f628708,15f4ea6e,17a6649,36a9c04d,c76ed314,64632d23,6fb6a9c9,2aa0a4ca,afebfcc9), -S(edae6892,ad2cd7b5,9f559f88,b2d72fed,6bb27aa8,c7351194,388b38eb,4af9a6ad,e97c8ccb,225f734c,8416c605,52f24689,fe0e4f10,2d62ceca,d78d9ed8,7bf3c3c1), -S(e8bf332f,26d4471e,fac8264,2b3e3cf0,6c210792,ae39d343,d7c7c4c7,46ce79ba,60f53327,95e2a862,f6d82ed8,5e2d652,70fdfbe5,8118033b,105c3c2e,53257b73), -S(cd1eb398,4dc73522,e791f8ca,ac528da1,bf9c908,e446fd9f,7bdf4016,51138d2c,8a845cc,74325e82,14be35fd,cf520f3f,2a64240e,18d85bb2,18d97d0,4cc6b366), -S(7d7bed7b,2dc04b84,5b9b8460,e366d1d7,a49d87f4,45998a12,b6e379d9,461b035,bb7faea9,bd2a992e,1535cbcf,bb78b955,f89d8f81,ea650384,75399ea3,fa63e6ab), -S(b9de73cf,8fe63fcb,56b992c8,668e6368,7672c856,1e9be11c,9de51d7b,8eeb6516,c6884b86,8e115321,1bb98a8,1ecc8165,25a8600e,69155f49,fca83e5d,7dc8e0c1), -S(b5622f5d,2ff1b4ac,5b1a675b,192dc2b3,595a43cb,1120f249,fa55f7a2,69e15b8f,d8f3afc1,388938f1,25c3d4fb,fae7bbdc,93925fa6,e46298d4,e0d7a3c5,451ca1b4), -S(eb0e1fb5,8a74273c,c8912e76,5f150947,2cc12c33,2329a24,a7f7423d,83a3a049,e3b4fa95,1b958a1b,92b3596e,9e8905eb,934a121e,f15cf758,a5112575,4702caaa), -S(232a33f5,72cf2459,fe985373,2de8fa5,df1efe7d,32b14eaa,43190ec7,6a9450a9,144ca6c,7a114e35,37434426,699433c1,fb0cf4a8,bb9f65c0,14011849,f962b332), -S(e32e4c4e,b57ee32c,173f08d0,ae571335,cf4fa22d,d32e7754,740f174c,d8914ac0,f0669f6b,12525ee7,3d1a6e65,af27124e,89df20,5829eb27,2bbef862,ac053ada), -S(d89046a4,a915391c,856fba77,d4699c48,2b72200,4efd83f8,893fcc1d,f944e2f6,72595560,28e14090,c76d1219,9d133bb6,156a2cd3,aa5df1bc,c18c8b58,27a2ce04), -S(ea2fe94c,ff11c532,6c867e75,7544beda,8c39bbae,c3c2b8a7,62c3fb5b,5dc0b23d,10b02985,baf66352,e86f6e9c,a2c0cdd2,cda7ef48,79460ac9,d58f3a61,16663437), -S(71b224c3,7088851,25ed762,3caf674c,5e3863dd,d5eeb116,29a056e8,b054dd79,6002d88c,2fe7340,6dbf9c34,40eb5501,3a3757d,831e5f96,b35605fe,47fffe92), -S(29568f1a,11070ddf,bedb2f41,10246352,cab977f4,dd6cfbcc,be397575,dbfd270a,a68279c7,440fe321,fabcd58a,f7ab6923,e0f627c,909d6ecd,d009d130,aeef7b7c), -S(57badf5f,dd22af1b,11dcd60,e875d9b6,86e043cc,d4ff11d1,c91089dc,cc8230b9,7507b060,bbca59a5,aa19f813,eed95faf,8569dfa7,6d2bc327,660a06ba,8fda2b3f), -S(30d84aac,10a7b86d,d55fca2a,377e007d,1f8b8cbd,4fa9d7a1,4eadaf8d,d6481491,cd1df453,b553de9,1ae59e95,d08fbf64,eb9af82a,d0d4fc46,4d1574b4,f9131a3e), -S(79ac7c66,ff73d627,62a749be,c66c589a,67e33546,7a13709d,d72d9a01,98ec405a,803f34c1,e8b06902,52a3805e,abb30bd8,3942f1eb,84433ac8,57d22cc6,4ae0b04e), -S(6700636b,cf6a757b,8afe6fd6,d26def0b,6ae61da,ba7c502b,2a34301c,203af68b,91fbf4a4,c94105fa,8fa7de5b,6b6ba4a5,f34d677e,cf732db2,b660db50,e6a654d8), -S(84ab5f25,501abd97,a9d56f3e,5fe50bb4,4c2baae,85509b98,d38a91d9,74dad801,2dac84da,6b805b3f,6ab306df,22e254bf,d6c14574,f0f42be3,8d37cefc,38dde8d5), -S(e372663a,7464dbf5,48f0d0b9,c91867d9,e76ebcc4,ccae7105,7046b8d5,360365cd,6e80f9a1,21723a6e,da7dc2d9,b82afb01,2e3b1712,c7ccbd3e,2fe5b4c2,270e58de), -S(4a9ea0c6,57e21f97,9641f891,8975dfd0,28118b66,c9a2d38f,8b197a94,bdbb09e8,815246c3,2173ced9,13a82877,393df34,f8de1b75,c2b42abc,7dcd80c8,d19f1b5e), -S(a05157fd,f91c475e,97e110c2,969869bd,31435fad,2aa242fd,c4ac2e3c,c845b0bc,76d82bab,176ca9f,c3cb1b25,541e0407,91b79739,2581c4d9,fdff832d,3685ac6f), -S(bbd11f9a,62d74bf2,49e4831b,fb253ceb,8e94eeee,bba1d08b,b88ee5ea,53e940c4,762540c6,24e7ec7a,487586d,727949bd,d4d7162f,b5d1dd69,3a10f6db,f41193e4), -S(a7fbbd53,62d41020,6fddadf2,36782aaa,f33d5945,5bc00106,9ff41bd0,41cc53b2,aae57e60,607a0d7f,5d12da7f,62a51075,5aea3686,5b12b678,3d27456b,6a2f8a04), -S(6d984c7a,816b611c,8731f553,2ea1e6ed,54717a1f,4163ea72,9825bbf2,814050b9,c551d373,8b815e9b,5256a8c6,4152db2b,d8bf881e,c10254bc,a584f7c,f5dde7d7), -S(ccf5595d,81440526,6244e5fe,87eb293,3dd5e684,b90d58c,1eade733,e7c1d2e5,862179cd,ed77b0f6,1adc0f6b,334f6942,94d71057,f42a017c,9920277,3021dc16), -S(e0b6855a,e19ed610,51c9fa8d,4bb9834,a27e999a,81d4584,1945963b,8c5ba5cc,9626aff2,cc89288b,768fe91,3ffa5ca6,8a99b9ef,d904677c,fdd02892,815ec4fb), -S(4b3347b9,62a0b644,4942cf83,a30420c2,f164bac3,7aea2003,ebe5d232,58dfa3d3,5e38a814,d2ec02b9,7f12afdb,ff857692,e9ff35e1,1ab85cb1,613393cd,3e36b365), -S(646ffbff,5ff88f03,863722db,f554d9d2,64a4e14f,d2ffce79,d9f965bd,aac5c401,335e01bb,bd97b4c2,36d18b0f,53ff37f7,f5fc39a4,79092a76,1c159e56,c2162340), -S(977b9528,ab51f6b0,1e7a33d7,2a85216e,e5fc37b3,c0acb9b2,de3ecdef,38ea1e77,b16d9644,394c5ea5,2c7aa42b,543763b7,1b4d284b,a81c2fc,e4866d87,b1a65234), -S(3e80074c,b8c8b1fd,3dc97c7d,9e79fbba,1ae672fc,5eb43b3,c1ca69a7,8b70224e,6069492c,139fbced,707c65af,1e97270f,818af208,738a5b33,f73ee222,a90feed5), -S(15b035b1,108ad096,a201b0db,5cb152f9,793f9355,22e8d68c,adedbaf3,eaa1824,a95eee2d,e2f7fd5b,1d07c262,d07837a2,20683b29,805cb5,a19febb8,424a33e8), -S(e195cb6d,d4c21ad1,f054188f,31664108,1f029be2,22850118,8a6464f0,a2a93449,9d1babfd,9848c2be,15c89136,a3aec42a,8f85c2b,f91613ac,12db2737,b6bf41d), -S(1a309895,5513c42d,48db553b,22e27fa8,7d823df3,2ecdbceb,45ddb4c2,8d874bd7,69c52bdd,8835d6ce,99e3afa4,259c1513,4f988c24,f64fb913,c9353775,7c86df9c), -S(83aced50,fd6ff475,e135c85b,c705cafc,7e5eea1b,c6b370b5,728ab888,54ec74b4,d0ccd0a3,3e276d64,90079d05,4aad8732,6de6b6db,5e909fa3,c2546d4c,aa9fed40), -S(f2619c96,b0e5ae71,fa78c661,b40f321c,f96d6b25,ad8cd2a7,53fee657,4d41b147,9ff732f3,4c68e66e,6940e4b0,e5d0d94f,f223d53e,6900c80a,eeb60778,1d64f77f), -S(a49c15bb,3f6c8aa9,11117942,9f609456,ee4380eb,3fef3073,ab0f6c1d,33a4e3f7,70874663,301c27ff,551962a8,6c561ba8,6f1b36b6,20325864,a76faa52,31cbfa26), -S(e96fc9aa,2e1032b9,2a9f5263,4c35b7d,f583ca,fe774756,97c33a2f,703197f,54a1bc34,1fbcd484,34d1254c,73b9533c,8cc11db5,92363fff,10a996a,864f79b8), -S(64489edb,18791a7,f1f4be16,ac93de2d,e5445cce,ff8172d0,bb467dd8,e7971d14,5c343cc,b6723d79,ec75ad08,69aa1308,4180518a,679bff85,6e8b0e3c,21c41115), -S(9ef3f569,84c53365,8bb39b13,9271e54e,c5d376c6,f9f533d1,adf94921,ea7c066e,f87998e8,831d20ca,1b611314,7e426acf,768ca63,f6b7eabf,a4e6fca0,ac33c377), -S(5391ea1f,ba16db25,999f093d,c8308dff,a2ef9aca,17cea315,6c974bf,28540218,36dc27c7,c3a74f8c,332cb471,cdbfe71d,22b12ace,a2c86e6,24104da8,bef66212), -S(b98831ce,adac19c8,2787e84,cb443685,4208f189,b24040ec,2bca6366,6c601c5e,d753c01f,8410fff0,8278a570,16bf736d,a5ef8a0,f1d9eec0,c17a0f22,74f8458), -S(f2f9050e,b8d42461,b8d11189,3a3de4dc,425a7468,5b34a0dd,7bd3ee98,284496ff,74dd4077,4f0ea177,ba875cc0,f8b504e4,f7d352ea,8ada429e,bd49510a,c155cb9c), -S(e76ddc1c,179ef377,a8da15d7,8c3cd8d1,a775089b,8d542e42,1e6220c2,4390aa35,ecc8baba,1cf42a6c,87918ed9,f70cd24f,b1a3deab,8ed86640,fdc6ee89,ca7ffe76), -S(e1c86064,1f85ad29,afbb6092,9dcfe648,82fc149b,952d1c2e,d50c6a44,13b2d5fc,1d418333,15eb3b54,9c067140,97283de5,fba554ad,2ea510d5,f1c12d83,e730e25e), -S(9dfc52d9,e3e55bd4,2bb21cd1,74a54c02,dfef16e4,758c10c7,ccc0bc81,af509ac5,be552b18,e576d5ec,6961893c,1498253e,c1539068,aeebae6b,80994a10,8140d7d), -S(24e672b6,905f5ba0,186acbbf,6a344c15,f3c59291,8c23922c,fc928b2,5aab8ad0,3b4799ba,9e23bc85,b622d248,9343f39d,59e80244,e25806f7,7d919504,89c5400b), -S(e4be87d5,2cb2fc8e,bb793449,5c94b07e,65aa86a1,6f9b63f1,b24a859a,c0737096,ac28b858,a4083916,eaafc195,81dc8f7b,e163608c,1f69c9d0,87a76446,71110b4a), -S(4379567f,ec797600,9a98d7ae,e3ae123f,dcbb167,2de5e367,bbb40e9c,ab87fdcd,9a2cd1d4,7ed65b8,c2ce95e7,451ad868,c1ffd81b,929ec58,49d82a1c,753440a4), -S(923722c8,f0b1b91e,261a32c6,75fbb26,ba4522de,b9610173,25764974,8c8eb107,b51b46ae,8a3951f2,7d564cd3,395a6d64,27b5232e,2c5b9ad3,6419ef5,d4a5cbaa), -S(7f749af,3301792c,826a1162,b3e86f1,35d1d9c2,e82275c2,a112ecba,bc0f374,d31fcb26,20b1f7b2,d671a52d,ccee8b1c,f47858fa,d28bfb91,475c6889,dc19cf47), -S(c657ab98,6bb3b2ec,87c09d23,530a9136,e85ff051,4d588230,bb9a2326,b058a052,a4f46786,410619bd,60d33aa8,1d8b7def,62c47ed1,bffc872a,941dd1bf,198c8ba3), -S(7f6ff017,2459d2cb,4f305aaf,ff17cac6,5a450ad0,d705310b,418184bc,7bd2b6b0,7ff8f3c8,782d2bc1,8e466df1,f3463a0c,a73dfd06,6cf874dd,65c8418e,91e6c1ab), -S(79b46336,478f2d3e,60e8d0cf,2c905b8d,c0b981af,6ab4cbc6,b36d238b,9d5acfda,7a31811d,95662ab,dbbef71a,5a0672fb,eb34ef37,c39d9ef2,e6f4f27,6e1d6514), -S(df51181e,5ad2e6a,5392c92b,14d762a3,f823123,d4243b57,21c1fa89,bdb2c386,210b2061,bcdea7ab,2e2e98e7,66fd68b4,63330ab6,9e7b1349,5a349087,fd18dc63), -S(5d60493a,4becf377,f66ff41f,9fd3a6fd,5603e504,b4d436fe,bb53c1f6,9038b75b,83de8acc,d2fad488,aef0adad,5a4c314b,6e9ed8b4,9adf56ad,57bdbcf1,a4dc947e), -S(f5b49912,1eb62fa2,c8db16b1,c3cc8ec,f89bdcfc,fee6c5c4,7978bfc2,16ea8a2f,5b0d4f37,8a436098,6b4597e0,a90557a8,a272c668,ec1ad310,c68e30f5,8a409927), -S(67556489,5729a58c,719c2c90,1e6ed73c,16909594,74100b06,2f64e242,c79a1ce9,2df2fd1e,ca39c5fd,a73bc75,bb9e5ad1,ac6571e3,322b433a,1b09022f,80ac4e63), -S(b6e3dab4,d13b42c,54238d14,4a47aff8,782562b0,28422017,ab775b2e,51baca6c,ae4adb5d,67855986,92c72c0b,c617ab63,4c65068d,d603e762,a75c273,e9622722), -S(b62a111e,6f15ec98,6c570b78,316f8857,5f59844c,deaa7fb4,3f76642c,8bc4b064,16a1dfb,551d006c,ca3fb15b,2d250287,41c2a5,35944e19,f7f1c2c3,59b0288d)}, -{S(ca3c008e,cf9efd5f,75cc1035,f9edaa7c,46b17d25,9895b0e3,b3523b6e,eee9daaf,a676aea9,3ce9bb,128ffc34,deb96b0f,72179d28,77406d04,6d0c8b5c,3572f4d2), -S(cda11502,15f6a502,96b3e042,445220f8,54e32a97,32f1e883,e41cb082,90e51c56,ae62e394,7f16dcaf,e5a6a54a,5beae349,a620d996,599ff570,36a9b6a0,3be63dcc), -S(43a90be4,b0efb9f3,422e5374,69fdba07,6f746874,b513f247,854b78f6,4937fb15,4799a0ff,b4026ebc,f57c8b5c,137d4373,ace4fad2,4e2c1705,34940b03,c6a2f0df), -S(612fbcdd,9f251b85,c43ea00,57b847fd,db78f2d1,6031505d,26a81920,e4c32619,aeb8a7f3,332bb112,fdd78825,fbaaedf1,199431df,929c5cde,b5a173b6,721fc139), -S(a2417653,34077e0f,3201dc47,f6ec3fe5,546b08e6,4f12dfb6,3e0ce0e6,18db62fb,271d6d97,9f686ac3,c4191cb2,1a3cfc65,66471502,b9e85207,47948345,1199a73d), -S(fc216e07,b2bc34e3,bba2f0e4,db770bc,33676cc9,1a5f24f7,cb2028d1,7e4c5f9c,fb16790c,386611bd,e567b83e,571a8fd8,97332566,6d2aea7c,903bb4a2,b5354b5), -S(6d44d409,e5f13c7b,e51c1835,f5b223b3,801b3895,802f6164,63f5a51c,449da3d2,6389e29d,957a6961,d796620b,23ad36f0,45dfddbd,533345e6,679bcf06,9ab214d3), -S(7783276c,a37fc014,3ce53700,c7ec741d,33c5222f,f4a10434,270fe9f3,cf70e9d3,9939b8b4,1c64a8e,6efd144c,78334bd9,33b86122,88ca1de4,22cb361d,eda16a82), -S(89339ebd,e4693665,ca9b88c7,f0a4c76d,2639e81c,86c349ea,aab9b974,a618d2de,6fa55c4c,ae7d0246,4e6d6f05,8ac772fe,1456c5c5,2d2b008b,afa9e4e8,bc7e99ba), -S(1ece996b,4408d,f01a9e25,7a6d8746,cdc75105,e614f6b0,5ac9c66,1226e55c,ab521d8e,effac213,38abac36,12958256,316d6858,594ddc46,9de7718f,d2714f48), -S(9c0434e,e311b25b,e1c4f60f,52e17c5d,59563a8e,c1b5278e,595e3ab9,32ceaa6e,a56270e5,c5e402d8,a1b84f23,6899e35c,b558ad6,3a168172,e1d60cf8,da904791), -S(87af4f94,912398cb,174965b,ca3e7e1e,957c67d7,fec69db1,a334154b,39fb41e4,5e981846,bff7a54e,ad594fc9,4cee7666,1a532bed,77e20165,12b58a3a,208fc410), -S(7bc7f81f,98686420,9b81fee2,aa157f6b,28b668ce,440dbaa6,f7a84fb3,5f3efc42,fc60d70a,908353ff,2f59fdcb,83a02ba6,5e20e6f7,5a73f0c0,b7cc096a,9b745208), -S(6ab61063,7567c0aa,c32da688,1d8e1918,b50a359e,c480a235,eea76e03,56d3472b,455f4f81,d6b88c81,72011644,f56f97b6,f2e0d2e3,e93780c1,ab0fe6ea,26388c16), -S(ff71967a,d8766265,b45a9cea,ba7542df,5bd35c9c,60fb5306,4d4de071,e0157e15,edd9241f,19d3bcba,c2470941,4fe7902d,14ef2c17,b3a2cb3a,481e4238,1618e94b), -S(9d4cc871,2f95c218,52c07b13,5c783ca2,3d9d2dcb,e8f2a78,8c9f042d,4629979d,ea4bbdfe,b3fffcad,9ff3426c,fafc59c7,254b6977,601eac7e,7355bf3d,ab7d7ffc), -S(e19a2aa5,49b720ea,2002b863,47dcccd5,b764f5c9,9bf63760,93612d03,cb5627d1,16c930a,b0dda080,45b0c758,4ffbc063,37a9d42,27fa5d8,33f61e9e,356fbbb2), -S(fbf6c918,fdb5292b,17df3aab,e54664b2,80e59ec,e9ed6103,e5f3557c,e7e9320a,84454694,62f6d530,4a82cdf1,3310527b,50fcc8ff,13751550,cdd6da1,ccf20b9f), -S(f9912cc9,597a48a2,7a581be2,c72cf767,effcfaf,c0ad7a04,af2aa105,8fe1a19f,dd2c8c9f,da952245,1e9521dc,f5899430,51f4ea56,6ce31d67,d2936ad8,209eb005), -S(52ea2681,cc2b8988,3d283a50,77ff1af3,95ba85da,3c70f20b,fd1d6652,1f9aeba,c6440e0a,8d700973,5c5b6e1c,6aac224a,76481a30,5f732630,30353cb,4cd630fd), -S(164d8059,3689a410,d49574a0,925192a6,f1a55289,187b3c97,30030142,36d940ec,46ade58c,909d01a4,fd827090,d266362e,cf2a374f,95b2463f,e184288e,9534ede3), -S(e32e1230,46171571,6410013d,b1fb8ba2,f8914aa9,43cafc5f,91ac552f,4d8e24a7,4af269c7,ed6218ae,6c1db9a9,4e5832bf,a29457c8,4c814d52,24dc9e2e,42674407), -S(d57bdde2,6e43bd76,5a33cb8c,a4e54db4,df3798da,5d930148,37eb0dca,35e0f999,7a74180e,5225fec0,20a10d63,2cb2134c,c4109799,22508f5c,d86332ae,8ea7c89e), -S(b5bc01b6,4203cb60,caf4a7c6,e48a1c25,a92d0eb3,bac74789,cf5288b3,80839576,30403b6b,2824a95b,7810301e,b467cc7,b882e5c0,a02c28bc,bae550d2,5c83289c), -S(73b1be34,b9229a1b,bc7e8cda,6027b7d0,4c60ea20,3942fa98,98f5a4b8,98b510d1,7336599c,9aeef8a6,296637b4,13b2f22,4c5ad7d,fc00b225,9152c891,249539b6), -S(a165d932,4b255170,998d39ce,39d392b2,cbccf282,2dc1acd1,c364fe28,dce909f5,f24c5fc8,cd8cb2c9,2bed63ea,a9a2dfcd,932915d9,dc2e9199,d2626fd6,b360f64), -S(92eb21ef,fb8d4e26,89bcad2a,2c4f1e57,85a8fefb,e4b6f8db,c0fc1681,3618058b,7ed25a50,4174b429,103968f2,8f4a03ef,96b583dd,840c32f8,ee1e7774,3e9ced10), -S(6a15d7d5,c5a1d77e,a7544c52,123d0e30,492a021d,3ef16056,46dbd533,e181ebf4,d4d14e77,54a5cada,520f218a,58611e5a,dd6c4c1,755abce8,6050b0fd,ad239957), -S(75ea5369,8a9f0d5b,49a0401b,b2db3286,5a8620cf,d29212d0,1bb097d0,1547cbea,f3e1dbb3,d50fc3aa,e6c16113,1271112b,4fc78855,ea6f303e,51268c9b,2535b159), -S(a3c4dca4,1ba14d89,51b088a,5667f8a2,f8ae1e3,e0438a86,c330c484,4ea34fe8,8113e61c,bc74488e,96fa68df,12fe199f,b0b2366,de19294a,de19ab0c,a24dbd31), -S(be54fb56,80bd0b30,3d331242,63714604,36c66704,8630035e,191c4a2c,f69400cd,15a679af,a8b0c05d,b5408a2e,b3ddf648,86bfe8bd,721abc7b,8bc4aca9,f1eb0e5b), -S(ff1244e4,a157e177,f5700b47,9787853c,c517c335,7dc1f548,a19ad178,f6a40b4,db21c79a,12f90142,befed50c,e9763426,b99b4d9e,f3f37c17,25abd50d,7cadf848), -S(84038a62,5d232480,997e8ee1,5b0e04a,547e2381,74955b30,14da26ea,8aac7c1e,87552fb2,b09c56a9,a81e40d4,9fab776d,62c1a5bf,63a84e01,9b869c9,40f7ac51), -S(50f7f61f,46489c82,2a8ee22a,7e79ca89,1ae4a185,9004a039,da3d16a2,fbe61608,6eb139c5,f399d702,5094ae5e,3035d3a9,e355e4f4,2ccad686,566d298,42eb788d), -S(c05af73b,9858124d,8ccb5eb0,232d8821,d98d220d,f4ade4fb,99519c07,ac665ab1,7493a780,35acd676,966604de,13af29d0,3a78a962,7cf3bb3d,1b1663d9,6a7e36b3), -S(1f480d5c,2a1d1761,ea954284,d2a072a,a66bb6f0,738d2640,4ec9cd34,bcff91b7,10207028,def341b,44a34078,f07af764,2a879d2f,a9e3a18b,ea7450be,1d3e1770), -S(a0676e87,8944445f,d40dd575,fb0214b5,983b164b,2fede667,b36f16da,4ca3e338,6cf3c93c,9ca2fd3a,b0ac23c4,33064a6,d1a6d275,3614be7e,a72cb3ce,e9e02f0e), -S(13e73034,7c823fb6,2769ebb3,ebe492ac,243a3bb0,2f84bbf1,6de239a5,f1fe62a4,564f2cda,316ad30f,5a552164,2a1ff7a8,92ad0afb,8bf2928,ff5e3970,9005f251), -S(18a96b04,1592fdec,101b7df2,6dec0d49,6be4ca32,be96f54d,436242f9,8092c481,cf03371e,e4d2d4c9,2ea7ad23,db3f8f97,d1a96a73,13b70e82,c3ee58ea,f7567ff2), -S(9592f438,339a1044,85ae414b,d30cad38,929004dc,e73fdf8,c86fa2c6,776e5bac,40de2fc4,66571358,ccab78f2,fa40acf4,d7c98188,31d475e5,556e7b68,d6c37235), -S(bd76f4f0,b9ffa96a,1a563855,6b35d855,f07580d4,45d10505,b1e5f546,255429fa,551cfb81,d1d05bdc,e66cfddf,a4843228,423540a4,278e5a9a,55137a9b,37866d6b), -S(fbc20168,bd1f044d,2ebddf8,a7dc1b2b,97d7399f,21d29fef,fba5f8f2,fb60b84b,d459b367,6516cafa,b6dcc1b3,8ddb10f3,8ea3ac,7f73b4b1,3052ff45,6d624c2e), -S(240584b5,5c64bdcf,4f233adc,eb7c9c7c,41d1863a,b0ff7ba1,68f74c8,1ddff33e,221e273d,ac154ab1,f4d259f7,e5803f5a,dcb297a0,48a39637,6e15327d,fc6b194b), -S(76798d07,c586b782,51e6accd,593a2534,70c77c59,da326d1c,f8ff561,8ab0e8c5,64ae34a8,8c9dbeb3,901a997b,eeb4a9ee,4b486c1c,b3dd9da3,218106cc,7d07292), -S(7a9f198,966c08ef,f9259fd9,5a3a198b,eddf9f77,384b671a,cbc16ba,5465b618,abc994a5,8a0c8dd,d98200c8,eb951e61,16a553a2,27ef6e16,bbb27bea,e0191a66), -S(dc8ca205,279a54bd,8552336e,31e02c72,909e4c9c,d7560616,1ab4e439,173edc73,b08feff6,221c061d,7891890f,be84a459,a57eb118,b67c4ff4,7ae62d56,7c158f9a), -S(575a0e7c,dfd55dc0,f86bdeff,7ac8a740,168f976f,be2eb9a2,2bcfe376,290e9085,5f0303eb,5d8ee545,485c945d,5ea765f9,7aeef7f4,e7d6b802,184261f4,9995f574), -S(50e48366,e86ae12f,14a9a78b,22e76176,fed8e25c,ccec2033,f85e7473,96756ea2,8af4e0e2,57b6479a,d58b2f24,2f256a20,ea30864,89b84b2e,27da8481,d8eccd3b), -S(9c98498,d5bfb24d,23f25983,952263cd,9513fadb,a91dd60a,26b7dedc,6fb42e6,c5ea0af6,4b90d3f3,37bbc24a,c2138426,bb349f6c,d8b23829,d0ea1da0,2107ecd), -S(dc253e10,17608817,898ca299,2d325aa0,20f88ac1,676e81d0,d81e75a3,884015d,add05f5,1d8ce337,a62e2401,399015a7,608c1446,7cc042be,2da908f9,b6ee807b), -S(9ccddfc1,8c88e1ca,cd5773b2,b378ee98,e4ed6084,d8fe9a06,e115fd67,a6f01671,439d7033,6ad30482,a7bb89f5,425c5295,cd888c44,b0a0bbd2,7b2b0ad9,499b8ec4), -S(3654e9ba,ff41cae8,6129545f,9207cc3c,315773d0,b230e4d3,24456721,f220e8d4,98eb6499,702161fb,feb0d263,1702bdda,52aa5ea1,867351ba,779f485,7ae3d59f), -S(af31613f,e474bdf1,7320682e,4d1b35f6,ed6ae63f,806a7cb9,f9a47ea2,fd8a38c3,c5fdf037,2cd6f61d,bfb96b98,19819aa3,3848b84c,4b1b69dc,cbb6d9a9,5e3fd807), -S(d8e1f1,d2913c6e,553ae630,64cf7673,437c2843,7f715720,3567b881,7552c73c,e20ce3d1,b6d10cc2,517dcd67,ea82d676,555e66f2,3ed742a0,597065c1,d849b9a4), -S(b3ef1895,7f8f2cf3,3545a9d4,7e0c3c4d,7e24e363,85c1d680,67104d9e,1f2884c0,8c2f8d97,32ab264f,a5d63cdd,f36cc4bf,4cf4ae6c,8e0fb04a,c232364c,37b0e53e), -S(d2d86d8a,68ff342e,a6c3c79f,42ded832,9098af79,dc2c83e,39e5a728,889f1bd6,9cd4fae9,db605e9b,fe25c52b,14d75e2c,a8c9b58f,c6c18d76,c5fca9b7,f6b9d2ce), -S(a4ac3b1d,39a44643,b0487b6c,76cf24f1,114eac8e,2163740e,b63776ea,52432f91,b2278137,c5a81c23,e9bfca31,fd6cfbe9,f11cf1bf,d1f32573,f581d68b,5acf4a99), -S(b12353c7,56fc4737,7d7f0383,6f6c6f62,594323f3,cb27d4b2,d64c4b81,ee3e0b7d,6813fa5b,a5ef894f,6fee8ae9,ebf2b1c1,c6298976,560c731a,df87fcbd,f916a837), -S(5f1a8fd7,b5299929,c5e1865,c28eebaa,13c558c,cce6f26a,edfa80a3,a1450646,b043c995,c6d66c56,77f7dc03,f7e599e3,70e89ff7,899ca5e7,165ebb15,f590d867), -S(ad4222e9,583e2afb,2c56a116,500514d1,92c0b10d,4eb66592,2334c817,623aa28a,97e34c9f,bd9650b5,a5444e2,4a04c5a0,78ced6e1,2e21f516,60a3d4a4,fd2319f6), -S(289585d2,886d9020,8870975d,93373b87,b3ab1909,21d392c,82abb695,22681e2,a40915cd,21358a51,798e18a7,9595b3b6,b7a645cb,2905bf75,db2c2438,2ad63073), -S(3ed81e00,a9607ac1,8167afd1,e25d80e1,9a4c1a23,69682ec6,9f40ba13,d86e818,59ce30f9,8f646855,ce9fafb,abf7b2b9,deb1be30,de5edf17,7462fe3d,66f02e27), -S(5c12a417,91a0f2bc,42cbb301,346b4e09,d68d4720,aef188e,7ba44469,e2e63f4c,540ad65c,9432a241,5a1e1af3,2d6f8c88,8c47a741,52d6224,f3d5e486,7a219c6a), -S(62e3fef7,6ec4db38,5010b30f,ac2803ec,27088e79,2db7f8f,72be35f,895ffb61,c0c8efdf,f9589931,14c1bd72,891e2743,b3189ec7,1f05d5e8,a0d7cfd1,753279af), -S(677740ec,ea09a280,7968ea8d,fed5cfa0,58d9564e,8f22f96b,79303074,58015089,cec6fce,30608c7b,2cf3bee7,353be7bf,a8265b2a,a6f058bd,1fd87059,f261beab), -S(ccb0c3cd,7d9ae81,f366e10d,c5444cb6,b713088c,739ca70b,fa214359,9b806937,4562fac0,408cc5a6,a961d8f3,92ac2566,cf02b599,7d645d57,bd81f678,dbd9c43c), -S(2db401c8,d474f7ea,a25088d9,d835a9ec,b1ae4f04,bedd711e,154ccd12,79a5e68,654a9bf0,ab608472,51922ffb,aea4769b,29894a4e,be1d175b,973fbdd6,7393bce3), -S(514a03c3,5204855,f4339a8a,d8894a5e,f0f7f8cd,b02d597,6d4ff85c,7a37fd1a,25d67f20,94a0f6c1,49999c5b,dd4808ad,d49f0875,882bfbaa,b391a8ee,7f7f32e1), -S(90e74327,cd112d5a,b93ec168,56b3292f,45eb178f,5578ea2b,a51a8b03,2b51c78d,fdb46efa,92e1972f,7c269259,3ed95630,74752c76,cce15d51,c1fcb011,19b7f797), -S(a9ef7f4f,857083f4,1eb3cdf1,76b738d7,f25b8c3a,e4705a26,21d791c2,abdcea1f,8dd007cc,7c6da435,267329ba,17435394,6319fdbd,8cdc9ce5,2250cbf8,252d8de4), -S(7dc56b22,14d62402,1c42f6f4,f148c146,6156c1f7,7d14d505,6e65ac0,693952f3,ba58259,523d0aba,a8bebda7,dfc67df9,4e28aa03,957357d7,235725ff,bd6cbab0), -S(11f8b2c0,a75a1423,42da84dd,4d04e5cc,e499f5e8,cefd2b5d,e73ec422,1718239f,29e26227,6ed2f32d,7824ec3b,5b776fcb,ea5800b9,2acf0a31,bff27cd0,7c8cee02), -S(9d0ce33,8fbd0443,3de6d15b,6dc3605c,edff75a7,4cd08e53,7e078ed8,bfd3a1bd,ea0b5cf,3a63c7ea,6b17dd3,fa19139,9078d02b,760f7d2c,f56d4a83,a8f0bffe), -S(9116520a,ff9d1ad1,e6c1031f,f9388b1,b1b2bdef,52f49937,a93752a0,75bb21d7,2ab7c4ff,47368f76,c1df0b33,54bdbee,157d7b2f,df4e19d9,d1f09c87,75d95c0f), -S(89c5fbce,ba4859ae,2706d0a1,e4ea2956,ebe71d40,3d1eb34d,7042291e,6f584015,c3a99137,2fe042ec,1dd7c83d,4e915231,cd5ad4dd,5bdb3877,bee1f9a6,8dd368c), -S(2f4fba9e,eba5a0a7,b22dbf3a,9867bb06,ebf3c4d4,ca5353ed,315b1752,3163d4bb,6c156492,d245e1cf,7673aa12,e78d0b45,d6171dc7,be574418,aecb9f12,3d6e8ad9), -S(905912fd,599f59e9,a3009b0a,7eb38034,fd9ab746,336831cd,a1985ba5,37d39931,9a7716b0,3524e8dc,714c76b7,a486660b,2ab30e45,b3bed8e4,f24e62bc,d1705272), -S(13cbfa57,515d5d33,1d8823f2,a8b5e083,19239bc,b1920aad,42d4f6c6,9934d0d7,f36e2353,700f0313,9236618a,ab0b5fde,5a8e14af,8e5e12f,47fda9c3,79ac150a), -S(cc939020,199611b1,c97458b9,cb9494cd,a9dfb14c,a2cce863,3ea361b4,68fd0857,a33978fd,e5c6a683,90dc368f,37e01e76,e2c08a1b,512fd2bd,d71abb9c,87ab7bf4), -S(6ff68519,e62b3e23,744a2136,2292bc79,3c7bda5c,4ef1ad09,81843ef7,183dd564,6d4676cc,baa85268,a4694ef8,55e86386,1f0f5a3c,38c8cb94,4ff81c53,c0737da1), -S(60a82e4a,5084495a,ad08d440,45639dbb,e0c34867,6dc3bd33,4f447815,6702418c,666c2a2b,ff70a40e,c01c5f34,cca48f00,16896e55,f14d21c1,e2fa80df,d4352943), -S(57231292,66d1532,f352005f,b3e789d7,b19409f8,cebec41,b8b43330,cef1a7,5904c51,ad1f7ac8,ca6a0ad6,971588c3,42f98ba8,6fab3f9,b07b648a,26f3269c), -S(c50d8b68,bb031e89,131a9be3,1882c8dc,bb109fd7,6df989d0,4b0009e,cd2db9e3,10286cb5,875480b9,3bc78987,9615095,9126c3ee,c66e23e2,3b21231f,d41fc039), -S(ea74572a,bb5ac532,fadcfc73,b85328f5,de42ce24,d79950b8,7f6e0c98,e6fec3f2,c68a3ff6,254bd3c9,febab9ba,c6dba6f,33d34551,d8bf2c14,ffc29c09,10ab374c), -S(430f73e0,8eec3d03,8bab8afd,9b30a5b3,5008ddd7,4cb85aeb,7b836ade,3f25f6da,27e179cb,ed69a2ff,ccceef02,cd1b8b9,6591deb3,b94a905d,df9e0df6,f6e8fc7), -S(dfd0f623,61e9baad,2fede6ed,9a6dcff5,3bf259fc,704c37b7,6b9a3665,a0296709,a9ed876d,5cfdf560,d3896579,57ce1aa6,13795b86,1e2e493f,719b8cd1,85e11f84), -S(f486a524,89f858be,ab920853,b27e5ef,945ebfb1,def5bbdb,8a7f1761,451ec105,f50aa3d0,cc587372,a1e941d7,608c86bd,10bdeb39,60cf57c8,482113a8,d3039da1), -S(3ddb3b7a,9b0218d0,2fc62004,33d21317,5d811aa5,a5d6b9cb,53ceee05,75341982,84017fa6,1ed2827f,f65d3bc2,3343effd,403f77c0,4524be5f,4c763bcd,d04b70a7), -S(c5938802,42f1bf38,5f5574e6,815ea291,b13578a6,cf8a31ca,d516d3fe,ebfb1488,5c0f3858,e6dd3b7e,f68b4368,dc3b5a95,d866e2bb,fe269527,fdf4b3af,e9196375), -S(11c60556,d6584b79,882f75c3,92e036e4,2aa702be,1f545e15,403eff6f,e27cb59,8544c8df,51e9a3fe,790fbbbe,f768e45f,c8a39319,1b18b4f5,8ae85d17,eac28fed), -S(ab609b1,52efce6a,eaea4c68,e498d414,9fe8aff,28196efa,a39a897f,5969382c,a4f7fd94,e87c1a0b,b9502f5,438c7a30,b6fb836f,17a19720,ab07e286,f94c8eb4), -S(7c188bb,109dc167,bb66cf50,58f263c3,ca8f58f5,66c9c0b6,b838bf9c,7cca26b9,1236a5a,bb04ef11,81b22343,327607c1,8693eea2,3c129a3c,377ee493,d332a5f4), -S(bae48149,f37ba68,24c47e5d,1fde4ee7,14f1cacb,8cec8ae2,de547927,768699e7,433d31de,c9619480,c2984475,5e7c3813,bfec984d,b0d9fed4,f25e94ea,8e747cd6), -S(88ec8b53,d57f2ff3,db3661b2,46989ecc,63c0f757,6acc7c17,cd0f5792,b006b5f3,9f35942c,28f0198b,cc3afbd7,b8f28ddd,1dceafa1,4db9557b,35d4984a,e80160bb), -S(67efbcd0,b5cbc215,c453d642,d1b19bb4,437509,33ff6afa,1ef923e6,cc83768c,6575c0c3,489a7bc3,7865d32f,dd8f2a24,a4be1df3,ec7765eb,ae09f10d,342538cd), -S(12f7791f,4b9310a4,c9d333bc,eabc3472,9762040a,5713829a,9a58bc72,47e51db5,15eba5f1,e156cd5b,409ffcca,876dc51,9f4f6e17,93ecef35,7b32dedf,fb12b402), -S(bc145b46,130e431e,18b357e8,a47f90a1,c38842d2,7fadd3b3,58d21959,daa3effd,4a62a5de,d23f1d44,ee86ae12,a03e4a6,5d1794c3,d7621871,cced4b58,116c97e5), -S(514fc2c,e7c864fb,b54fb8c4,545dbef7,7fbe45fc,d7ae312f,8866c608,12658866,552ca131,45466fa8,b6ce58ae,77c01a39,1f9001a8,bd9e6a4e,fb434b6b,9d63b79), -S(7c2bfe51,f4a9a32d,2f7feae1,96fdaa4b,45670ed6,f9c02940,633680ca,afae3f88,88bb43f3,996bb5fd,ea4a37d,e8c5270b,571644db,e1704bf6,aa207aaf,cc2742f1), -S(7710c58e,36f3ca17,8b96dc57,21acdbce,e37f7879,6f9f251a,df4c8dbf,599c6185,f600262d,d2a15427,ed6ea68,4482efe4,f57084c4,ce1ca445,8f85f646,4d954696), -S(5d4cda56,c705e89e,8afcd145,5490d589,63de5bf3,79d20a4c,acb1ba1d,c2effa6,f6a2f87a,cf9acd28,c7b12c4f,a42bc4d2,3e5c726,1d404813,30b99d15,533cca94), -S(e3bff796,4e38d5a1,946d54a5,5a7c9999,8faf4e08,2eeaf460,7dbb37fe,10b49bcc,7d6b4ab3,5d711881,a26d7327,bcd8eded,61cf85aa,f56b244f,58d4106e,8558f3e6), -S(75b80f78,c88f6e67,9ff252d3,e7c10a87,c2933642,53fcf204,1625457e,542c9398,db3b2fde,be9e05a4,a722ad7a,aeca21e7,3ef934d4,372f192a,a07b081e,c6419681), -S(4f640190,51d6332b,d29ab6c3,7511cb28,ba111146,189e4ed9,8b945e96,d4ceb5a9,626d0d0d,ef4192ba,a7874638,fcc07075,fd65b688,4615cb3e,5c63167e,965293de), -S(4f90520a,ee7b050f,cdbcc57f,cb03f361,f950e5f5,bd723d1,33de2990,df09219f,f12a8382,f2b1a67,c9868b2a,566e8734,2ac332f3,87d7864d,23ab4d33,395c4144), -S(f5ee8ddd,c044fb9f,babb5ced,4ab56f0,c4d357e0,69066828,23b02321,6fac446c,ec53db7f,cec7c393,d8b74749,981f6f32,c4462dac,6f0a56e4,34d52b34,d97b9d3d), -S(69727ad7,b48c376f,cb2c4cb6,b5c0e4ee,cb1f5925,f1928599,c55c4f2c,b31cf7be,39b486c2,3804bb69,b39d727c,eee110be,966da862,32eabbba,73ef17af,1c8df334), -S(23d1da9d,42bd74d7,cccdef4e,aa79e725,32fde7fd,b43522cc,b0c8166,1090f19,a168e435,f673bfaa,84115cbc,85a25973,5aa26ed8,86a1136e,ed3fedaf,b939e9d1), -S(8add82ca,322cb7d0,68e98c5e,d4f66993,50a2b2af,5bf0ba10,4e012389,f90a38,cee02a7,1df433a8,46ab9f11,503702c8,b93d609,fbf882b5,6465a9ca,445238eb), -S(874552f4,f2b5552a,b9e9dd9e,a8bcd62c,52f3036d,2b7d7a7a,3bf206db,18490830,12197e8d,de19c33f,37f50ba2,362642a3,87741090,68b2ba51,c5b13fe6,5d3b3a18), -S(7b5e3f54,d959d208,17c7c518,62628a07,ae2ad59c,6bc4458f,467e213c,ba145fe,bc3a8595,527be77f,c8cad2b,e9cbd810,8fc7104,9eef7ef1,924255de,6aa6fce3), -S(298e18e,d4790215,d0a82b37,b09d6b7c,90ee8408,13f6cb33,b150a3ea,d14fe41c,a2504d96,a1345a22,8e14e82a,eb160798,c7bb5cda,6ccd4bb3,74093c69,93e0294a), -S(22bfb660,2b823430,e44d0358,300a5fd3,853577ef,79b73104,12122749,74af1edd,ee318018,3617fc09,4d3a3707,df38e9a1,bf9ec587,45e251fb,8a127137,3c9b3e85), -S(41dcf360,e9b5b5b8,bee689f9,1446a874,5a4df0fe,1963c132,5d05227a,313d08b,103125ef,ac9a3fcf,f8033bb5,659b81f4,982a2f31,7382c0bf,b4c4a73,8479da5), -S(71b0f642,7f6127ad,77318fe5,27f57c41,e34af0dc,311669af,fe695a46,102dba7f,b6bb548d,f92c9087,c1f0d543,2737e853,d5a03e2f,e607057,352084ec,3060d823), -S(c36150f6,be139991,3df1cb29,3324da28,bbf75056,aa8102b1,e2be7e8,a669eaef,ec869956,1d5d9e8e,73268641,d7a7d01b,f1613d5b,145d2631,97abaddb,ae8eadc9), -S(26c0a835,20d9ae57,77ec9e5e,af9836fc,389a671a,6823f705,6eb5562,bde7193b,1939de0f,da69f7c1,fdeba6fb,f982cc12,b39640b5,f92253ce,9c84667c,9e75d56f), -S(5cce3427,e2cd7404,2cbf501b,2349bcdd,e1e9cc1b,d9ac179b,e848dd89,7378be5b,8148375f,ad9d42e4,6562dd11,463aff04,281c00be,12b40b8a,b97b638f,3a525901), -S(cdb56ff0,9c36fe2e,74546bcf,44b996c7,ec11862c,a5c0f0a6,1c352bb7,771f3f7b,f97dd0c4,6d0409d7,3559d6b1,a450a8,ba5e8d5e,dc0f1a32,df840f06,20348fc), -S(379abd64,fa180ad7,9343b3d,d2b6ab31,5534a19,dd59e25e,9a37271b,de58e2e5,512f6ce1,c2fa1202,2a6dc666,25f3b8a9,56c1a5,ccd5ddef,6c1b94c1,1c507472), -S(8c32725f,d1fa4998,794bed8e,eafeb3d7,c24caba6,4a693aad,14055160,e0eb4df3,e91ae4de,54a8db16,bfdf48de,d3835586,ed1cb6f4,f767eb04,343cc260,c2a008a2), -S(6f6c310b,c1afe979,cf032c40,2f594512,ab074b31,f336579a,b9e52fcc,6543e882,87cd5368,561c5897,d00a2a97,2166950,5b4f9e1a,a1aaf8f3,cd817e9,5e48df08), -S(299829f3,2cb34343,5caa2fb9,426e24c0,5a84466,2c2aa34a,ac75d454,50b54b39,3bbd3e13,50a11a04,31b44d63,24eec80c,64065603,3960c6e8,b82b6711,d660bed9), -S(5275ff78,3529d268,51fb398d,5559b300,ac09ddfd,39cf0bbb,e02f50d4,13fe62de,7d3356f5,a74c829a,bbd294f,cb302d69,c30fdaa8,64c1ab4b,fc734e5f,ea8f848d), -S(3e04cfc2,e7cea4e8,4c3ca490,2ce0ff69,883e19f1,6952252a,51edfda3,6ad04b5d,39536901,283e998f,ed4ecf2b,e708d5d3,9b19c290,c76b8faa,4cd4f94f,7f05e813), -S(58273a33,3dae61a2,71970034,3c72d8ba,697a1fd3,527bb291,e098ad6d,173525ba,c2f0e095,98d4d04,fb156dda,49676761,774d09b0,e43fc92c,7957ae66,396e57a2), -S(4f43ee17,95d428aa,ddff7252,536a7bb0,29fab5a8,cb60f3e3,21ceb52c,410e49a9,d17315b,c0288557,c4a9a48,8372722f,ce0bfc3c,4ee0572c,6682934a,18fa2c75), -S(b8b61408,4abbb43,10b2551a,8fbd7503,9856cc49,4f793567,cd7c205f,21cd9174,b45edf3b,ae914c9e,cd7fe61c,bee4278,5bfd96e9,c6493fae,b465e10c,8e6aa815), -S(9ff66284,41cfba00,c15074b4,aaac29b5,c12c3d0,59009391,880db30c,69bb700d,95f71bb3,8875faad,373a2dc0,b18f1d31,cf161cbb,b1d1d5fd,fe2abeb2,e1a6df69), -S(69176264,329a1ad7,8bbacedd,3b99a5d0,c3694973,c4a5df27,d7facc58,b25b3231,10fd42f1,1bf91b0a,a330bbfb,b598b7,be2c2faa,354e148,b3903a6e,697bd350), -S(94546c5a,b4a5dcc1,d9a8fa0,ac117012,470247a7,913d0acc,e8c7c2b0,d98ad04c,7894e112,11e816e,a03586c0,33a737df,8e11ec0,7c85295b,1305f575,2a9bf9fe), -S(fc476882,d286cf0d,3e29b73c,744cee4b,563289a6,c367fa59,ab3e93d2,b0f71314,8680b7ec,6d633583,ad923db3,1ee3dec9,6b4ddd95,c331a670,d759ab82,ffa07ed3), -S(d5279e6f,62490fff,5ca2f0b6,7a8153fa,3a5fb95f,2262dd3d,4e62fdb3,bfd116ff,831b6dc5,7f16d6b5,c25c6b46,9111fa5,48cfe44f,76eeb9b1,55614b7b,aacec99b), -S(8174add4,de57b198,9a999ac,9ccfeb1d,78a21fa4,bdbdb88f,792829f6,3d21923b,39292fef,300539b1,ec4ea7e5,9a943b18,e4cab57b,36c8fcb,47a96d0a,73facc18), -S(dfd1f8a1,88cd5554,6cc5b417,c2c30cd3,c34ea95e,a9087a9c,cd240cd0,9d6b8494,6616b3c6,881b9cfc,cf0438de,1e9bb54c,f213c9c3,d0458ce1,e49f3da7,17c6ff33), -S(40d6faf6,aca0880b,6f639406,a187f116,6e1d1656,763a223,cf2d9805,f8059521,26402921,86884ddb,59030708,d12a34b7,1e1f592d,b8316aaa,50f3b95,3dee82fd), -S(a06e4e4e,df868121,9ee140b1,1d688bde,1e9f0050,cb9e122e,e12bd046,b6fd999a,76f0b3b2,522571c1,28cd7423,273e0a0d,5ce2e41e,dcf844ab,3a44b18a,f29fe0e6), -S(8ed7e5b,efcd7322,7b537ffb,728d5c01,450445f4,5f187ff1,5182fd57,817c7e02,fdff3f74,179e2229,a680a538,73288b80,17819a8,953f358b,25ee7b8f,c2c1a89c), -S(1b7d6838,d0b5a412,9c0fd19,cc917166,c9c351d1,33d8db84,7f39ffdb,463dcfc,c50a0eb9,a20ff1f7,67c21dde,9a74271f,2d2e7c8d,3a45251,8bd61ba7,9953c58), -S(c991fd97,ac37ffa7,968bb26d,1793ffde,49ed283f,699b4620,7520849e,cda25769,9cc861dd,b39e36a8,c408a09d,cb2b22ce,c0302a6a,3b1ed1a9,d89f9784,e0f0b766), -S(849cdec4,66bcc09f,9a689c,299fce1,d1b37e8e,c59d9184,3d519da4,937d2117,c759660a,92c29619,70188f0d,8a539585,88ca929d,f9468ed0,3be6d6fe,cbcded23), -S(4ced9d61,7462a2b4,3cfa38db,1e4489f,3e527425,d48807f7,bf73cd93,a731e351,a9954e80,fb6c42c7,165b4cee,976199ac,2e6871b3,b088fae0,f040f09c,b91a0ea7), -S(fa952014,80bed20a,514df1dd,6d8541e2,f7bb05f7,4eda2a56,ed1d2a0a,6300ea2a,3e887eb6,edc0c858,18b1bbb4,8a54027a,aaa11988,c8063f14,98f7d1a9,64b8d818), -S(aafb82be,ff591455,e3c11ee2,ed724caf,46f86053,708699f4,38180f5e,a0156d90,63bd1026,f928de57,cba2fe5c,890d02b8,1afd2eea,2ff8a5d7,6708c70d,6172dab1), -S(9788ab96,c57bcb54,3797c014,a20704d6,56eef193,f0459b4b,b2617a90,3ba30842,1e81188e,28ba4be6,d244ae0e,2574d0bb,ab51fdc1,5ca4472b,b7b82a9d,dab005a6), -S(58fffe9d,6d6e176e,d006b35,52133322,c8e95d2c,4040fd4a,3a04ce94,dd5d0241,6f8bf132,7d0aee77,4e88f397,e2cd1594,39cd3c32,5a0313e6,d63e5e52,5974a647), -S(65d3d1c9,f10eb74c,6a27fbdd,f39d4ec2,8995aa50,3bdaec76,2f7051a0,23190b4b,42c3128d,959d7b3d,b585043e,3d042252,6e2c1b3e,714a2938,42cafeae,22333ced), -S(5240e75a,419ff988,d9e9a27,1a9719be,3d2c960b,eb574aee,fe278acc,5466fbbc,56aaa8d7,76953819,904cecbe,cbfd680e,99df80e5,c6a9100b,1fb8a570,6d28fa7b), -S(6f00eae2,ddbcbec3,cdbb2079,d7300565,12087a6d,b2f5df8,8d2db4ec,9358a8b8,81ae19b7,88ada62f,dd68da42,fcea16d4,699467,dbcfb314,51cfa318,e71388a3), -S(a7c58025,ec88b71b,bbe8a9f3,15b3b182,3ac7ea83,95ff1ae5,eb0889ac,d7a5aeb2,4decc4ac,78e45b5d,b76f969f,59dbd448,c0100f21,79aed6f9,bdd089c4,5f02dccc), -S(f5534fc1,b0bd55c7,e0af5eea,c11567fe,b5694f1,cc60830f,cac6ebf,ba0bc0b2,a7ee28d1,7624a2ae,32841821,e1ca4934,c10e6087,819ef9b5,f0b56e1b,4467a9c4), -S(f43aa167,8f4c4a1d,2fe2551b,33c4eae9,5d7b12d0,276d37cc,a4e68e01,71521f6f,a64c65a7,1c7db76d,bc11cb6f,e9842c12,ba6653a4,2cf0bd8d,46656e31,feee083), -S(28cd19c8,3d8265ab,f0d38cb8,9f8be926,ee8df072,f096a363,94193af5,d16d9923,58625794,ac267f89,a6734390,a6bb719a,d5e9e2ae,6e0ea241,aad5407,7cc1bc26), -S(572703f6,5d834c93,d0e09fab,e92b1add,34245158,33682bcc,2e62c218,451ef85b,44daf6ac,a9af4ae0,a7026240,8074e4ae,72ad4d79,8145d431,760b26a6,33d05799), -S(27c6a3b,92bf753e,ec6b35ec,491fcf65,ee5387cc,b96cd73e,651b9b11,40b347f3,a881835a,4d28683,670934ab,95939dc9,5a0e5974,7cc9dc4d,c39d4a9c,12fe763e), -S(30a0db50,ecc1bf4e,3c34a171,ff648cd2,8a3fa45b,786cf15e,de01aa47,33a99eee,cb47e7d0,cae5a279,702aaaa3,a2865888,1676d851,9d15805b,cb8bf75e,23940a1), -S(d27e417f,f83b3a04,36ade27f,1b5448a6,fdc91da6,342584af,47f2b8c0,3d21ccf5,6d304d52,c9ddda31,14b68be0,49b57d55,45d43d4d,501b07c2,8d295a33,8f8ec396), -S(5bd5b0db,57c473b4,de32fba4,fb7b68a3,9f6e6c46,c6e72e50,b6ae8fc3,259331dc,cafd77c8,2b16bc35,a46a7c5,fc715c3e,cee644e2,4c000335,b472aa5d,4efc5a7d), -S(37e99dea,23a18371,1f23b80c,1e05f3ff,45ba6351,10c9fa7a,b927c808,e3e6fc45,3dcaf312,f8dfe055,ef6abba1,3e5eb0b6,70ce3c7,5724fcbf,67c61730,629ae0bf), -S(6b001dbe,be7a3db,6fa70b38,f46d13cb,77d759d6,ce6b7fd,153b87b,aa67f94b,7cbffcc0,f3d48278,d9d6b09,7923f646,b56d9fe1,77ce1111,d2abd2cb,6244aa85), -S(e4bfded,5c81c0b9,f1ae3fb8,7ac88e1a,d468ef72,bb3321b3,c3a4d549,fc073820,dcdce7a6,76b0b3f0,45b6331b,fb75ae0a,610473e4,b551a001,18674a8e,a3ef1d73), -S(ac834f65,dd566124,f837f049,bf0d73bf,4884a1dc,f1756462,3cbf375b,6c57aa9e,1bd6227f,c5265e61,53d0f350,6c698bc,a973669,1260d911,2e918308,48cedf1b), -S(d36b1cc6,e6fc735e,6e83957d,87e2c74f,8cc50202,ddff7610,fbdde385,22f40d3b,293f6494,c2ffc78c,8955a544,fbd4ca05,898e3560,e05f0949,cb6aec2c,a18994ae), -S(d2a214c2,b88a5126,1284b25f,d7f5ac2c,e04f8333,144ce351,dc057262,c9a1fce8,17fccbad,720577df,1db1230c,e2c68fb3,b603ce29,a26a6370,4fba4060,8c4dac60), -S(f3f9329b,ebaf25c8,7efc393c,66c308bd,461f55fb,c721975,6a504edd,f46d95c7,799cab78,1d1c65f9,2a5193a3,e6124166,586536c,f4389a35,d886bc95,f033ca0b), -S(3aa1cd82,ce4a7838,4cbfa6a2,85fc66f5,53edc1a3,2816b1eb,85142e86,528e0cc8,4b24bf4,3a8266ec,4223b77d,3452f3b6,72596458,11c5cd2f,8f043d71,88f87dd9), -S(4abb7ae,40395b18,5a1017e9,d8887ffa,480f57c5,41c9eda8,578f7e16,538c61dd,4b96d913,161669fe,43230df9,a18bc71e,e8d36dac,de48c3b,d9600b46,a29babec), -S(89ebe2c1,845fd4b,461cb4,bf9992e,5f08ca21,d9d24f32,2733f259,c53d8a92,dfeeba58,f1d23a91,a85b3405,2b875f04,e056732c,a576f8df,aa5dec9d,2dd747a7), -S(92915a37,29c505d7,493cc142,b2e16913,6c8d2015,fe68992c,eae45b1,62d465c3,1ac2d867,24260b1f,396777cc,61f0261a,d8a603a0,e3efbca4,fbe5f485,378ef947), -S(5367ad90,3c5d684c,920f38,76c3bc32,c0b42a65,e1ee8d0a,e59de048,15bf8e80,82bcfbd9,11bdc542,306c0a1d,dc4aa5d0,353bb0c9,3b36d255,8657e40c,85e121e1), -S(dba0a47f,2fd5e7c8,5c2c8bc3,69981126,15769156,852b0f24,1e6ea83c,e56a8817,7a8830c1,377a2973,35a66c63,40cec55e,7e57648,29f32586,3f4ca9ff,8d95c0ed), -S(ea85fbf1,911e9827,59ec5e0f,a87b1c39,ff555ef2,ab294982,1aca68a3,648251d9,164f58be,9b8c16e4,ac9001a1,815d5f37,4b7e050c,21cad8d2,b2be4a19,ceb0c359), -S(84e3099c,ddad8d5,82c7dfbf,df03f19c,54e214c0,a0d5e679,7feb9f3b,dd32e43,980b77a3,1d08480a,5ef191d0,5c8cf0fc,48d5039c,583ee3f0,d37a8151,c49fcf90), -S(edd595e2,f8cddbdf,71f39b87,9a063da9,8ad70ea0,f030d9b7,28bb666e,54eb9286,89f1969f,95953dba,a1ad1cc6,29cbac93,a4620a8f,5c9f63da,a62ee923,98ee0f49), -S(1a3f3b62,26834d98,23f80f02,963e0878,90d60328,d911374e,167c75e3,51247b23,afb1a632,652762b3,db6b6259,ca8452c0,b194eb76,f16e2cad,1096539b,2386ee41), -S(dc425571,5dd53bb7,f572a949,895fa277,23f6c177,a234d2d5,e3c6a67a,fc458f37,f1c54b9d,54679c34,dbd9452f,f5813e9a,138d56cf,c7d8162b,c1eecb9,20edf717), -S(f86b4286,8b3f187e,4ba6fbab,91b83a4b,60acae17,b800e594,cc996004,138ed24e,7ea7b45e,b5a2340b,92fb24b6,f02c51d7,14c02c88,e9fa216f,595253dd,58e6227e), -S(46d26f41,447935f0,af56788d,b33b640e,e661de65,ed1a49f3,db91ff13,48aebe29,5e79cbe0,80117377,6db73c6b,eed3fe8a,e7e30979,2208cf9f,e6c40850,f7257fc0), -S(fa42a015,e023a7e9,cbb36e76,b94593d3,2306a05d,9067ca2a,717c8ef3,2740575,9da9d901,41de45d5,52c6bc89,6c43655f,f8a35748,ac145c9c,ebc09dce,df93b9c), -S(d03e4507,fe4c815a,ea50b0c7,1469fab8,e1215ed2,c32710c3,ef90e85f,8123314c,d3676737,18dee1f2,a1c4444b,9f1f1b8b,c049717f,9c4cdf50,3ba74ec7,3d404e50), -S(a4aecddf,221518f7,b058d538,918281e5,7f36b313,d00aa7d8,d6277fab,13f6ac95,77738ad8,eab86a97,1711b719,21edfee9,edab979b,8799a123,b16d8a58,354dc0ac), -S(f0c70330,433998a8,627c2116,e5352b1e,d9754c24,3d775132,b48d3db,e150a7e0,5392f238,cc30eec0,aa887b99,29759f5e,1d9c252b,dc6d8989,3e46008c,4129140), -S(4f34fd4e,155fb49e,7f1d2407,f65d8d94,5ab8bf,14c33255,e764579d,28252d6e,29f3e40c,2fc42f54,dada4b65,3d103afd,e38027a2,3dca44e5,15e6c561,16bbb839), -S(ae34daf2,44babaaa,fe89f02c,8ed39b2d,ed4f09a0,db8cb7ba,e4145e61,954ca965,16b58ef7,f394d988,24c7019d,738a7dba,5be8afae,45bcc2f2,4cc7dd44,f60561ed), -S(4637fc06,95c91eba,d195450c,4067cd74,14c646c,8885beae,e99e6338,dace2e20,43a38d49,362174ae,52683128,ebc753f2,71e398d7,fa906f5e,22ff4dc2,2622171f), -S(7cca0cb7,f940ad95,6a0a4d4b,e040a3c7,4b7304b2,975eece3,eac0b4f6,fa240c08,34845b82,6a4df5b0,10f4ada5,b6c83ad9,5f932a33,8b319027,92796374,35c0ed9), -S(bc374aad,71cf40,8a1eabe1,20d44340,faf0f3a2,774b378f,90f08faf,3a7c626,4bd1b099,9f649446,20c7a58b,45081f50,178626c1,5f00451b,b3617b09,5ecabf74), -S(cf3bed1a,37aade71,b025c9b1,dfc46205,51b3dca3,10ff6bf0,4a89a492,85c6f4c2,7ac96d8f,1b856617,3896f216,d6756362,bd5a9ea7,9e521668,b0d3a05,f778f6ee), -S(e36904da,5d6970cc,44faa475,c6dfb02b,579adaf0,4612dc2d,a7c9a166,e7c771ab,1f164e1e,24a1452b,af2dde00,e8ee182d,2c9c84fd,1cfa67e6,f8ea5f00,376cb404), -S(f6b29ac4,3a3b28f9,453e5a58,ba715cda,7691126,bee6af97,e1c5bee4,199cf34f,81156562,89bd32f,f74a1484,15390fc0,a1451536,99ec5f72,97b191e7,98d75e12), -S(855b98e1,be5557c2,cc7825bd,ceba8296,4921a391,12ec245c,3d89fb52,a443b680,9d4d92f6,af921190,1129dae8,15e93939,9994d482,ed93bea0,a88ae69f,c3614f22), -S(c534fa2f,e0eb93a4,86a708ca,2bacdb6,74b17471,11fae4a5,1d4dc063,ce06873,9ee94f74,b1239ee1,cb96fc2c,4269b1e1,7980451b,881145a0,9ca5511e,985a57e9), -S(1615956,54dbb60e,9d446655,7b673,c5f7b662,ae1bd976,2096b356,1fde395,5cf45f18,5d88f4e9,3d8eef94,aa64996e,1648cb98,3bca5ae3,8f5d2a96,b1cd241a), -S(61ca23d9,875bfabb,d23096fb,a12f043f,d036053d,a4fd7f40,ffe63b5d,ca176fb1,699b75c,1391d3da,18405c5e,825520a2,d0c49c60,b07417ce,89bcb2c5,15ba1a05), -S(8ab48e3c,5cd1c014,473ed567,89edf015,917f7b09,47fda85d,294e531d,89124079,58b7a6d8,2bce79f4,189f0b43,7d009e06,43127468,1dd4d50f,ca2ac326,99dacaad), -S(b56e89d4,28960847,be87d5f6,59727e68,80f71a6c,a023dcd7,c5f0878,e3146d99,bac8519a,5d2c472d,ee3a2578,d0ff2a17,5e6801f7,8eead578,116c59b,f5bda8bc), -S(197dd8ad,b359a388,b7920a8,9395aa80,1c98c278,888dd30,cce2f2d0,2aec4d27,383205d4,8c7b943d,2e66c725,979acbfb,d5a62947,bd251407,e4481ed0,d5faa6e7), -S(b8388b28,61f8c667,18653876,526d02e5,27d20c29,e612002d,514ba09,853f694a,7963e44d,997c532c,bae94319,74aef26f,b5761b3d,5c8a2e76,2d35907,cb3ffd28), -S(5f6eebb,2ca12aec,b80ad8bb,b926fc93,53281e26,60660c29,41ca2cd3,b16c428c,5e5c92d4,41644c68,4d68e47c,c63c71ff,54634805,97955591,b8f68915,c506d92d), -S(cc4f7d7b,8e5b1d1f,f3c166a9,51832dc0,9503cc2f,e0fb1784,6f4910e1,eccc396b,a5701729,65400983,90d49ee3,10629444,b53f7a5b,3e31bec3,7eb99ddc,f02c8d95), -S(1bf0da05,6984e8e3,3741cd04,16e74372,2cc918b6,bfc964a1,1d63d0cb,590c5c86,e461a594,368cb7a5,4c93c589,67928a37,b6037b72,71113804,b2e64d8b,a840d00), -S(217cd3b7,9c1d9727,fd781ced,dbe735b4,2d655e69,e5f7ba8d,ce5eb68f,feb1913f,fe3fff21,ad8744e4,6e3fad85,4bed0d9d,f28b0bbb,96df1b40,b711ea21,b5241985), -S(55b99e36,7b8f7cd6,24ace387,2cb2675d,c25e6226,b1201b4f,4e1b039e,38365d75,706543ad,5c20ce2b,5501e8b8,4bf1d26c,fc07e60c,f40ae25,951fa46b,9ceee474), -S(db0bc491,688dcff1,6c81f280,a80ab2f6,c5efb3ce,2715f202,3f999ea2,805a59bc,2096cc70,588ea476,613ccb8d,c98a1989,8f729420,9adc1a3e,c77b126d,b277ecf6), -S(d961e10c,a83ebb9e,f39e3019,c1b378a,d94cc902,6eab0f3e,d203585,92a8e44c,87f46ee5,14689bde,3821f844,9f97a2a2,bb1db0f6,d2916674,1cfa028b,d21f40a3), -S(18ecc615,8d15a17b,50737a0e,6bc6953f,ee9f18cc,e20de26e,642a434d,d292032,63ada9c7,e3a8e367,970af87,20417ad2,eef85059,70b81b76,609fe8f7,c3a00ca4), -S(6ff356d5,262df09a,33ec10f,eb2e48b7,db91d6c8,dcc92f9e,e4fc39a3,813bba67,5bdd7a71,c46cc142,7d8a1835,e7ffee23,d0e025a8,e3027b1f,4892af19,2a2f0e0d), -S(49263558,22218dc2,943140c5,3a706f11,46faabef,f0fccaa9,77df5f99,44a77b2,d4d9db7b,7999d45b,9b51d776,6235e129,80c2d936,1943d867,65c4a54,5fb58e14), -S(ba68fca3,2b5e907c,896b3d2e,b9869a09,9d0f0fd8,bf8e06d9,64a6938f,3175f281,694d19f8,c8428ae6,16a78a85,57c9ae25,96a56c8a,1bb9f679,33d6e351,4d59fe8f), -S(5c461a52,3bc37bc5,39ae9769,5b59599a,86d3046a,36f4922d,a6f68212,19a89bff,d98b7b7c,5190ddee,481a5c3f,7982b4c5,b483822e,a211ccff,bc44d03e,983295ac), -S(43e3275a,bcf17dfc,7560d135,22f3154b,ccaa6090,245a79e9,373bd867,f48da149,fbb015d6,9f2aa00b,63c81226,b9165afa,1ee6be9c,8e680adc,4d2e5256,6c7723c8), -S(384bc1cb,8221098,4ff0a800,dbc85225,cb4a5f1f,477b4228,5c59c7bc,262c29ad,21061a79,e7dbb527,9ac6fc8f,e2d87642,cfd71eba,12220403,8792cbc7,9d8bce1e), -S(460c55f2,fda793b1,5aff59b4,cc819f12,de803b1d,5c938a2a,d30649d4,a38b58d0,832f6713,e63fe5d3,dde9534b,29d216e7,2434dbe5,6f54c9cc,ea683b17,33075c2b), -S(5e4a763,28fdeb17,b7cd2a8c,47b58307,538c6f17,397fcec,c9e5a377,6a39383d,3b3eb0ee,d7e28701,7bf034d1,dc1f239f,64756481,531d3692,bf639eba,2ad6e02c), -S(5ee48142,c3cb1ee5,45f6579,a36c589a,f886719b,c0b7bef7,c49c7a93,f3b610d9,55192e86,467835c4,b488b869,3f6cb7fc,94e49b03,8272abf6,69cfaffe,234c783e), -S(13b5072a,bb3d2943,c24fc4db,5b5759c2,290d6c92,11bdb80a,3b729478,71f3322f,ae8e7641,39207e9,ca438902,e75cf685,641cf5b9,674ba9a5,e9b26195,30180497), -S(2f2fa1fe,582dd71e,3bfc0e34,f1f5e8ef,12598b52,1ac2847d,90b5dbe9,152ba45e,82967c82,1d7dcf0e,6c624483,863c6c28,76ec8adb,43bb44ff,b211ded5,e7c397aa), -S(1b7be0da,e6633eec,f7895c64,29ea8088,1c2ec66f,2a273819,ec3331ee,830d7c1b,cd884cee,15652542,4bd8b512,8c05a77f,3c292260,c8d30471,8eab87a2,46f75ad0), -S(247531dc,f0bd40ff,7208bf59,2fea5982,440e3f05,8da7ba03,efc7cb94,4b48180,cdbf3227,62033470,e47cef0a,a5c9f2ac,9ca08b01,82140d52,549d24bd,d0f17ccd), -S(274ea538,f2e50569,9f52a7ff,bd058c83,95fd75fe,98fb66f0,ffab658,a1e1556,5aec461e,79c048e7,794586e6,43d10236,37f8c376,7d158968,16ea0ed1,56fab125), -S(82935503,db88453b,8794b70e,9b5a3e37,a804547,48d80c3f,d2e2a85b,844ac085,d507862d,98c035d,c1dd3d1a,3a7679ac,bd80df3a,4e8c4fcb,5b5761f8,c9605d7f), -S(cae0cdae,216c0e62,e8324d9d,95b15285,e43708a0,dbf435fd,d355fcd6,227d2536,f442e7f,d546d149,d0075926,fbd6e15a,805a85b0,a78ee674,c15ba3a9,a6d67b70), -S(a5a0080e,55ccd7c5,d6f708d3,34a78c49,b22442d3,5bce311c,b660af79,39cc70db,c71d761a,98c974bc,570f303e,d64875c0,d9e64f44,63d9db4,fa2d0e8b,80900c12), -S(740c4a8d,2dcc8a6,b11feeec,8f60afb2,e59b02ea,788d5f4b,62da8397,dc88733e,c8f3eb37,de1a1332,c6e010e1,913ea2bb,14b10e1b,d139dfb2,2858e760,eaa16f05), -S(551b7b30,507b2df3,c07955b7,ae91260f,86d899d,ff28e68c,67d8abf,cfc0d936,4c21135,c84fd85a,ff5839f,5192a854,25b18720,4a92582a,1b4308d5,a4c0db9b), -S(e11dd54e,f04d524,7ebbd72b,edffb50e,d0d4ff23,8cdad3fb,f1ea8067,93378b5e,46bb0d5a,be23f71a,3f16f455,c25b19c0,49fb9d25,9db6c94b,9b6b1f17,6edf8fed), -S(570d4783,29cc718,55de654,48255925,a5b094cb,5c55f10c,4793e532,60c9163b,331519d1,e5444f30,a4b1b753,a769eb4,d21d824e,a8151a40,2fab9b47,1c2d5625), -S(20a184e6,df5a35b8,30e97ee7,c3d4390,eede5a69,ce1c36c5,a77948f4,edc4812f,e46f676e,7b524c40,a6135f3c,7474d8f3,c3b0d45a,1a5ed4ec,91308a8b,b89b5a9e), -S(c7daba6a,960243f7,ef0664b8,f66ddb24,8a7686a1,2095370a,36316ce9,a4f5abca,6207f622,619ff1eb,fbe5264c,7f7bfac1,fd0d96e5,fe1a8298,a7ff4d3a,83707327), -S(b9d8e4ba,50549b01,491df2c8,dd596ed2,4ce5ac19,deb88450,a69a8237,d45f6507,5aae938a,46a3b4c7,6dc96894,798d2dc8,443795ad,6a393f31,a042d5c8,83ec7d12), -S(5f9629b7,ecbc8b0c,62374b50,620146fe,980791a,dd24d2c8,b2b3b786,9800a4c0,1ddfd8f1,ef4083dd,c6da5173,d16d68d5,7425fc02,e3943d9,a594e98a,ec06285c), -S(33d159bd,d0610753,10d3c1f9,ce89bfa7,affc80c4,5d193df9,55647519,357095f3,42c8b3e6,9b81c478,57a33b1b,1cda5b68,3662c1ab,f99ef9,5ed1b250,9a5cfb90), -S(8788f2ac,518a4024,3607d127,381f1a1,ea3e581c,89b8d90a,2d2c6e70,f94ddf6e,14112b9a,ef954527,811f9249,5de47e6c,eed1858e,5eba4aba,b1580360,fa05af7b), -S(804b97ae,219b7647,15bd259,255d3275,a5d5cddf,3e750578,13354081,6d9b6f81,abc3a542,1e195c33,88c0c4a3,f8448ebb,ca3ff868,a41c7c0c,2ecfdfa6,409bcc24), -S(195bde17,6cd7ea62,9611d9a6,c55ce4c,e7cdcd37,2d64ae45,f7d449f2,ea32f6d0,6005b5a6,890e472,af884f6f,6d5c8111,1003e809,6e66e22c,1468c962,2724111d), -S(9ab1e545,c9808482,2fbe050d,bab124f2,71b16028,e6e21247,ccd63332,26500c42,cb6bd747,4b6df912,e130b611,c762583,c81f7c5,38dc9766,e27f9194,6d1aa02e), -S(e87cfa04,8fa5bd1,305f73ed,971c6d23,81fa39ad,3d583744,c243bfb9,fcc9023c,7fb05d17,d789734f,7a9c1644,21a28365,3321f261,752025d2,b91cfc70,703e50e9), -S(5195bc3d,5ab8164,4ec40b0c,ff5fb1a6,c749064,9dad884b,ba48e92d,6f35e5fc,2b7ec6fa,97b441d5,ecefb879,35e059db,55d0e3a1,6d693899,d3c0b213,4fb04981), -S(eb2d3530,17df63b4,eb17dd73,ee58d282,78d01137,34a41020,cdf0444,8556792e,58a4f4cf,9247f908,3c28a9e4,da38e8b0,3cbf9e4f,2b92715c,28781d86,771ffee3), -S(8169465c,2da73cfc,daf3f3e8,538a47cd,ce088ccf,475af747,11585bfc,14c39426,1665d78d,e7ffa7e4,810ea80c,f12d3925,239b5c6f,69652fd3,44ba8bf2,e0126db3), -S(96d8634f,aa85174c,69e313c6,430eaaec,bd2ffe3b,55a1a0ae,e78fcb66,af33a3c8,869f9e70,344df870,be6a021,8bcf5e71,afc8a290,51d875d0,5c76f72f,e8fbc0cd), -S(3a071936,1f0234f1,9cc3c7df,40eaf836,4669615c,9520b0e9,c56ab987,dbb36bc7,e43415dd,cc244c05,fff14e0,f21cdc29,dddcb403,5678584b,1a3c5484,e98d9625), -S(cd3f1530,5cc9a03e,d05ab14,a81c58d,2485785,289e2b1,7382d45b,b935ca4e,c451f28a,e7aeea28,ee7ae093,46b352d6,bcbfc3a9,b0bc9d62,9eebba56,877ce9f1), -S(677e2061,8d0b42ae,6c38532,669cbfe2,56ac4b5a,40f1de16,42d97a45,ae34fdb7,ec23dbc2,bf750958,9be01e95,ad253816,7a24b700,1d9a8a20,218f0866,2dc2e378), -S(f816047d,1606074b,c54ef03c,e205dc5c,cc8182f3,739ab8b2,7dd09fa0,50d2912f,de012e8f,89ab0ca4,d8f8e323,6e0c2545,a6105fc3,602e978b,f42a5652,fffe864d), -S(11f9ecb0,4f273b9a,a699a3ff,4588ea19,2504c00f,55145cf4,10cecd40,b5f46f8b,168c4fb6,afedb0d6,b0bed70b,610c5538,e796e0f5,851e6d36,99fc49a9,f62c5b10), -S(efb9a14c,f6a30d5d,f30de8fe,f9ce92eb,6f566f8b,b65152ae,323ae56c,88da79a9,dda5df31,f184601f,a45747b0,3017ad22,e49c3892,fdc28c7d,c0d7e099,7cfad33), -S(e7b66913,dc55fe07,a9941600,17241de0,7867a77,8fe4f998,19efb096,8d426966,adab1d03,c8b96717,db800f98,e09ae855,2c653266,84886f3f,15c08bc2,10bab6e5), -S(6fd3c1e9,6c176c59,f94791d,fb9cff5e,901f676a,fd7e66e5,f69184ab,7b4e31db,ebbac252,36e640f8,df593a37,817911de,b85a5597,bb0d902b,7a97ff4,18689609), -S(2667971,943d720e,7d64d2b6,3d7fb50f,525c9214,fc89c957,7e00c007,4c39a907,9c1fb427,29e57196,33af3187,ee109b46,fe708cd8,5f222b25,bc0c5ae1,300ca331), -S(e34d8507,b11a4ddd,9fdd654a,ea6c4876,5473bb13,c9f18e6f,c8b6e3d1,5eac015f,d34c6080,22a54602,fccbab5a,e1cbd5fe,7ca599ee,75c51117,b9537c7f,44f90268), -S(e8b6557,441ce4af,7ca27f49,75107ff6,3b108058,d42d5e08,86bf3bd3,46e52e24,b15eb15b,b3fcc5f7,e3fcaf48,8f5048dc,a4c587a0,5b982613,c78965ad,b0d2027e), -S(b49f84fc,3ed84f9b,3ced0a5,7f953116,897c892e,d0249365,d8c733aa,b97d4b95,4f0a63e,42aae565,32225dc5,894c6fce,15f2b25b,e762f49f,a1d74d5e,6a23fffa), -S(99b0e1f4,cf7fc243,ea34dd0d,73705809,935b6c03,c0a687ed,7bf8d69e,d79dc2cd,b61a5574,17e236fc,a0615fcb,4d6ba1e2,21fd49a8,4003e8e1,b4e4a648,b6a088ad), -S(1fce8906,c4c420d3,75ee3ed1,2e603855,fda8bcdd,f47cac56,3595d3ee,6b4cbbc9,daf0cedd,acfa2409,e861d1,5cb260b1,eb84e1fb,22f8f483,e4524750,8c3bbc0d), -S(df85a7c0,fc08b916,43ebcc41,6bc86ac,bf4581da,fe0f7418,66704eaf,c24efce6,5d1866a4,3f06fa8e,a36ddf3f,39afbdd4,97372ac5,2d13629a,d546d4aa,ce7af9e2)}, -{S(8a4e9691,3533875d,b8559500,65c90785,a78233ac,ef24113c,f6ed543a,e6a40024,57d9444,8d091df9,602e6c7f,c3f88934,d45a7c76,18da574b,4d4c15a6,6925bcf4), -S(f8922b8f,c310a77c,c3e33a17,d88534ab,ac952dea,355fa763,14e2d886,44b70136,dad313f1,5e0ff701,acc8fdc1,b849a1d4,569de031,6a6cb83c,51629e89,99aeddfd), -S(d9e5586b,cdef070f,978bcaba,36cb7828,8ba43e5c,f0273389,750c95b8,4cf76c,f04abc01,6a060cbc,3a0d1d8c,240995ce,bb6c0d2,d9cdec87,fc8b9f39,dac5b50e), -S(6a206413,757143bb,c552fa3e,180d8e98,cb96a816,136dbc2a,8cd4c7de,6f508a44,55ee4d0f,189bd91,5323aad,b452a7be,298c183,b6843f5,25cf7b4c,ffc7b6c), -S(130bf00d,5caf1767,83d11a2f,acfc3cfa,ed0549c,5ecc381a,d1927051,517e4e88,506fc4f6,8b8be0b4,9537efba,d532f50b,156f5370,725c23b,66b0b758,50a45c71), -S(d85e7a59,54c93649,44d0aca6,8a534e68,42bfaebe,1806bb41,1af01358,d2d4f47a,8a8d3741,21f7390,879a892b,fba08959,23db88ac,867b9ea9,6888c43b,b651642d), -S(88c5e26f,91f4dec6,5d222318,81d7eb57,d3f7e498,fb1866f9,5015e045,d0108eb3,59d66b66,cb05e136,95d5bb41,d25e5b87,6b02af1f,7f29fc10,c67001c4,4bbb7cc9), -S(be062a25,7cb5ede8,e5926608,9a762e30,816d4463,cc5b2338,f4aa6309,f7722aad,16f30af4,c27c3f38,82219d94,a49468c2,3e8cb1da,747ff22f,e23c7dbc,b032d3c1), -S(292e8df5,2c77c161,6277b962,e10c43be,1c820aeb,80f083fe,879dd961,51cb84ef,7c7bafb3,a3bab2bb,2f9dfda2,68904ee7,823e6fc2,2077e41a,af16ed6d,e2ac43ea), -S(b14d3f06,8a0eaf5d,6dfa519a,d0a692e,3020b5e2,8c31b79f,ce6400f0,12e0de71,c383938,630762a6,ca5646f1,f2f02e6f,939575bb,353a9dc9,2a42d50a,857ded94), -S(f41b4e53,7560be3,b604d846,558b6990,639d00da,c6c7e98e,c07d1574,a71aa7f5,c34e8e3e,8102f564,fcc5f376,94d80a65,b616dcb2,d025b701,fa615539,6a105255), -S(5fb4006f,35994912,403a952,a1f53d15,202d8305,389fc093,4e4fa6f1,236892c1,1c5d613,e61f1cb0,e0805743,519fb564,5bf14c51,e61e6cd8,bf08c5b4,9417b96a), -S(e4e428fa,f6ba9c36,1593230d,e73afeee,9b580d5a,ead54f55,2e464031,bc6dfa24,ab8d0919,f7e8a7b4,99719862,6943e144,25d15360,ca0da2f2,637d8542,10158268), -S(53e304ca,eb03205f,f80fea6f,3ea38010,531e1d2b,c6d1fd25,804ad799,e2f05984,434777cc,b848ef4c,f6c205f6,621d5cc5,97c8c2d8,34ed12e2,28e3fc02,4bc4fc6c), -S(664a810a,a0894cbe,2f85817e,93b1d731,5a4047e8,266df3b2,e8ab5aaf,b790e0b7,f5ebf5e8,38f7fbf4,b904e874,48de1d1d,6befad46,ca68db2d,c08f8d43,4b6e57f3), -S(4a697e76,a5db2e31,34b646b7,a59e8ad6,9ca45eb6,b77aee2e,2f82f113,4d698262,8d5d47fb,76769327,7b24d6d4,6221e67f,cc9b937c,31e30fba,9e5ae198,597cedd6), -S(7e227b69,18cf61b2,e33e5996,192a0ff2,89cc6853,9e8a5ce5,65163662,83d8c423,299b7e8d,d2e45efc,166a37f8,d1036a60,40c5b43d,d88cbdc8,729669c1,98d5847f), -S(88afc703,96dc444b,70b8c36a,a30f5a6e,212dfa93,d4eacd3b,11e47e25,9bc7d42d,844425ba,79016a22,cb99d0ee,6ad40ec3,d0cd5639,1717eaca,1425e3e5,98db73ef), -S(75ba04f8,349f8c8e,69aee4fd,662eb9b0,aaba10cc,555caaeb,c12eec36,70179d36,fc0a0931,cc6d5662,ac8bc2cc,c7dbcdf9,db139e47,c5ba80cc,8778d11f,ddb3caee), -S(85c4f2fc,b3f7103b,6970a16f,8ad3d1ef,e1cedc24,3c576235,d9af669d,5f7a5a94,b575c9df,4162c450,4b61412,a3887a44,94bf88db,cf4c6ac,52af5e0e,52382ad7), -S(5a3265da,5b752377,50fafc55,e2affb2a,b2721932,c9021dc8,5bdc79ce,66d0bf0d,8101544d,688db281,c9a7588c,dd72dd63,734561a6,a91bec5f,52641a23,d4e091c7), -S(6177daf6,809f918,f8fca135,f71b89eb,e8700dd9,47243c2,c36fa883,182df3b9,8ffaf7ef,3c8c6422,33d7d43a,c01fd1be,a74c3dd8,3554cb81,7939ef62,cbc8b592), -S(3b8f7e37,b09e7276,36068698,fd87351d,950129ee,eee44a88,9c7a7e39,d49e2c5e,8ce941d,a2ba686a,e3264228,48a6e76e,a0118a7c,55fb37d7,7fd6b9de,15b867cf), -S(47892789,cdde36ea,29dfee45,74173afc,11515dcb,fc53a82b,5c2b29da,9201c8f4,d4717288,94fbd69,44c690b9,97ade5ea,d2c10917,4fe36517,57118d6f,b6264461), -S(f8dff091,8493e499,fc13a155,933384d9,fa83972e,9b099bc7,236bfc07,6e24966b,a06048a0,ca130916,94217147,1d803d56,99cd9c6a,cb98ee56,96637e5f,2a7d923b), -S(dccdbe61,aa1ea411,8443d950,3887f76e,c5e09092,de7c9c7c,642c5755,da678a79,f4cf61f,c7e1630b,2cae9d87,6eb29ceb,dc9b24a9,76c9540,f7845233,c9998493), -S(da4f38f8,13dbfd52,b45af510,59377f94,7f8f0158,38135451,d9713746,80e9c3cc,da4a6ea6,f8526f63,46edb7e0,cbdf3ffa,586f64e3,280b8052,4d2c19b9,f343976), -S(999029c2,9badca65,16360432,56f3bb93,f1b608ac,5084711e,242d9b76,2b1bf371,dbd72bca,1f01a2a3,2a760f89,e45df463,319362d4,61df25ec,1ec9a71c,e85140e7), -S(6c502c,1cf38e63,65275058,dc610392,2bceeed3,ee0a1aac,2838327a,a4543303,f0f4c4d7,b68d69a8,7209c888,7b725b2a,2a8c2c5f,b7c9ecf7,6c1f71fc,e398b92c), -S(9c31fb8b,f57d654b,a0ff1bab,9fa0ee2c,9bc86017,67876b66,83cd8c09,1124f421,b6ebd670,b4e352b6,320134a9,fd765d26,b2e1f109,f5f55958,23d7eebb,d1bfdb31), -S(fbc3232d,c40bf025,1a0551ef,4f3ad4c8,51ab66a1,f2c709e4,70a751b9,9f9cef27,552b310b,6587b1ec,1b84242a,3df96073,e35d0f7d,d47f09ec,b3021773,1fdf308d), -S(90e71b55,cdc8e2d4,f12fce5e,4719b8f7,5da7966c,4480557b,58e567c2,eaf48ddb,ff989ae9,1f195713,886dd3bf,6fcbf0bd,70d62153,9d4b4ee0,b0d2d15e,65340644), -S(829c0322,efef509d,a5284d8,96d3df37,54c21f77,f83a1093,1cf2fd92,a1594905,8b6ae670,d9b03d21,da2ae14a,5e09e0d3,65d31b3f,e1da61ac,7499a908,47715ec4), -S(db748c28,5a6b3d42,9b9086cd,8a50d16e,15788a48,2f06a43a,2b7da677,d41c8f60,f4bf5a7a,bb4492b,4dfec99c,e7c4cc15,2bf32cec,78a3cf7a,4833c10,251f411a), -S(e44f84e3,3d2ec8a9,2d905c8f,1d6d46bb,f8b730f5,a07fc25a,47e3eb50,4adbd5f1,d1fe0cde,a9becec4,260d0700,7ba21d92,cb7e069b,4f81bbae,bab8da7f,9ba68594), -S(3e9c39e6,7d0891e0,9cf7eed5,b0abaf27,b98798dd,c926dd87,12be6af9,6610f6dc,c04e44ad,a09d96ab,5d38ae1,94d65109,ecb95d3b,6b79d019,9641dc8,699789d8), -S(4fed63dc,b7587725,113e087c,fb0b25b2,6056314e,690b6312,1e906e0,5d98c34a,c69bc4b2,ee67000b,b66b6f6e,648cd1ad,ef9ce6a0,4add42ec,38e0156,dd8e8af8), -S(501c9927,f0b4c19b,6b0a9595,2387324,b9f31d90,93303544,ea002f57,4b83c51d,14770577,38a701ed,c15fb98,c6e224be,8464e4e7,1f0e3350,899bffc9,c1ccd33f), -S(98af3ab1,9c4fff23,8d70f1a,efb4a80b,234664da,ec2e44c4,4df93226,e7aaf714,f84cfcf6,9cf1960b,6d13cc27,aa875a5d,3b29907e,455d5925,c0a3096d,44924405), -S(849672bd,d259016b,8e07d627,e57813a0,e355bae7,ed64ccd4,251a36e4,48d0821c,8d0366fd,764169a8,779d21ca,f53ab78e,caa8a627,32b74612,5e831d17,9147d2c), -S(34f142d5,744dda88,aadad850,e7f469d7,140dd5ee,fd3dba28,86f3503d,16fe60e,3c3d20fd,c13b78fa,d0b7fe35,3bec2bea,b1509a12,a03b1e79,c5ad2294,41292728), -S(ffe5fd9,b78378bf,4738931,e03752bb,75855c54,f4e3dc8c,c369c070,450e24f8,dc57ffd6,b87dd1e1,dc466dc,6423e1e8,4174a5a6,c014e069,ae812d80,3c6abdd6), -S(b43a85b,808e6d6d,32d56edb,5d64af6d,cbfef633,2cf662fc,cd137d2a,8b505c0d,1e61d507,8ee9ec4c,c6be2a87,657cd3a5,f30d508e,c35e459e,e2d0032a,702bf4e5), -S(42be63ce,a0b6e88a,5d98661e,c99d493d,dbb78f09,ccc8fd30,eee4e148,ffb0cfdd,38d7e392,19f5a87d,e36b4937,8f1ed166,23e93619,165e2968,84294946,adb1e9d1), -S(9996eb8f,f8c8bfa,d4a4c502,2d8ccf86,f59dc8af,750734e7,e054f783,2b6c0f05,f1c9387d,9720275b,171a93dd,4bdb8ef0,7b73763f,5323d5df,df515ead,2bc40aa2), -S(66f17b8c,fb9b6003,b6160370,8f86f93b,3555c338,d3a346f1,fd9db3a7,37c197d3,4d0233a2,eb52e023,33c7d4dd,53703ac5,c566ccd5,b1e76b2,423e891f,60a8dff9), -S(ffd5e8b1,b2587ba9,79e90dcf,c6acdb82,86328779,224a4edd,dae1bbdf,6db06568,d75d57a,4d17dab6,43fa10bb,35857dfd,f2f7afce,f6c5bebe,7e13645c,f6f8e3a1), -S(ae1f1297,8a7a37ad,87a8aa8e,1e89f0d6,15040c25,d6d47193,e33f12b8,e28baf60,e38669e5,18c7cfef,4ee61807,b51fe9fa,403f1528,ebf2b27b,af0a15b4,fd39f5bf), -S(d330d887,3bf11a6c,f9b0c1ef,46ea64d9,973f14a5,a93cdb8f,7d84f515,33a34b90,b56e5c4c,8f236f34,78ab2620,ace7ded2,1395174a,76c5c62,2ac50b78,da16ae14), -S(1d2ff433,4e908a9a,fa5572d7,8dca2a81,8f8a651f,4bda506c,ec0aeec0,91a4391d,292d6a4e,5811de83,e318a6e5,861581c2,192b1f59,30f42d1,40893a20,efefe2fb), -S(8dc6cfa6,cab6f691,bf468059,7400efbf,8dfa76c1,8edfb8f7,ea78c24f,3bce2bf7,78874b78,47543ed8,2f983f80,c1e83ee4,b0dabf2d,3fb7d695,ab1860a7,967ffb10), -S(5ef0e616,b545e053,21bca097,ef424f4a,ed40b6f9,93a550e5,e11bd637,59266713,c739cd37,7700a1b2,6dcef2fa,c219d05f,646d86a5,850505d4,21ba8b38,54d0708b), -S(60b3faed,cd527d8b,6f806cb0,f234a3ff,df62a755,87d3f543,efab95ef,e6ab104f,e1e0cf1,e737f246,c1c3bf6f,92140a3a,34c98d53,32ed25a2,d7a48247,98d5ccc8), -S(d160c9c0,133d78bc,62a2e946,49cba513,783682d0,dad71915,ce208a9b,446a303a,bf466216,73b02b7,a782178b,f7113433,73cb299f,233b11ca,4d4014f0,2fbdafad), -S(201b7a0d,5f431299,34172b40,1744d18f,477d0724,6ad2016d,c8ac7d3d,32ce0e93,1fb192ee,55ebdb37,52b6ac29,c7485a7e,f8b8a0a0,a480def8,fa07ed29,d3afdb4d), -S(7d104d3c,62abee57,1f2d2243,c95bdca5,dc702807,fb060577,bcd1e50e,697c929,a680c234,1c12a157,f604ac5a,b74ae532,5fc59b5c,d8ad784a,5d66fd27,ed3958bf), -S(8e279e59,c87df705,b764c456,563703bb,1836aea8,93dbe8d4,b0249223,13e3801a,aebc7cbf,ea3fb75a,6f059f9a,57bf8ea2,d0758d51,c0d57696,f5eb4d38,6d1d61ca), -S(b206020b,a960cc8e,ba4d0263,bb0f2241,a91341ce,f0102509,7cf7ef52,97f96935,a249971e,6bcfd543,c4b603a2,70ea667b,8524c136,c15913fe,91bb009b,796da003), -S(1e6cb8e0,4b998c17,b0887731,24ad3f44,ae7a89e9,b33ca730,62233a4a,a6b8bac,a50a3841,9da361b1,f89a8fc8,f29a3fc9,a6f8aa5c,36516ea7,2ca4cc15,96330dc0), -S(449005b9,3279d7d2,9965e131,50fb7cdc,18619541,759706ac,6908ff71,ce5c2cd7,62f1e74d,1f31de28,221d0dec,3d063f76,ba5e742a,52d0b48f,22d01ad,58791862), -S(4030002f,2374d275,3e9176d4,3bb4c2a1,c7a4821c,f6b7119e,bba2d4b1,2e4b5bfc,a80b25cb,a4a75603,af82a624,b493ba8f,c46ab68a,968bff49,a0e1cf8d,9b7a4d93), -S(c75f32b4,8122b7dd,bbfb4879,30fe0ba1,99072105,6891b932,e2c7ea3c,eaf270b,309afd60,f5a0f780,5675646b,37029da9,601468d8,71ee3685,cf6a3ad,104f5017), -S(77a73c5f,1548cf98,9c284c5e,9f1ecb9d,ab55d2b3,982750bf,65eb7097,ed159e1d,112d6329,29e9aa4a,83c2fe95,531c0717,d84c9ddb,87ceb9b0,65e9328f,83c3699a), -S(f6a55eb6,d05a9183,d3908776,40a5bd0e,2a6b83d2,40cd5840,e25a8bfa,d2116328,ad0834ef,8672b707,dc99c4e7,1c9fc935,725ebc8a,df45cf00,99cac306,4a56796), -S(cbe913f4,48359096,dfb1b168,fb42d92b,d873b82a,956ad9c6,5e64a2b6,d826614b,893edb65,d2262b17,f5e466f3,88592e96,ddd70b65,65606ac8,289cf396,991a25aa), -S(f29ae654,8a6aeb10,849191e5,e87e2c0f,d8e70af,a15b8ec4,848407bd,36389d06,1dd72984,6e220fd8,90a1370,38c98e04,b096de6d,a7ce7339,ae697daf,db11905e), -S(32307117,b8d2902e,e325090f,97b518a8,beb9e27a,d3cb4d69,fc0b54ba,ecb14316,7970c3f5,13f69df0,400c725b,e84b1267,fe7f205,7a70c5ab,56ab0ef5,679ebfb6), -S(426e118d,b8ff1f7c,18ae29a1,b88e0f2c,2c286658,6c1c2179,edbd719b,31399dfc,7889d383,427740b1,4c37ae36,e51710f2,f5a8decf,a456d0c,a83ac66d,230828e4), -S(229c2322,7c4956af,938ac061,9640e04d,2c647692,e0e985ee,28cdc767,96f260a6,a056790,cbf36663,b09cf7e5,4b622f74,b185454a,6682d9b1,6cb2af2f,3ca8a7ed), -S(bb7cb68,23726026,12072e34,8cd4504d,50a3d286,669cb748,e69cd0ab,dcc93e8a,9d537ff4,532cd020,17756733,72ae3cbb,7aaac7eb,901c1e69,5fd57f02,9c336e5c), -S(d3460edf,f1405cb2,ef9c9fab,eeb71796,c9d48f66,96f8fd20,56a99863,2d278e8c,d9cc7b14,cd657e73,e5fb7207,9d421490,46266a34,7610b3ef,b631c78e,ed02419a), -S(d12b97a5,d5b7d74c,c8dd8f7d,45fabf75,105ebd5d,9990d99b,7d0738f3,49db1180,51dd8885,e6131a1f,320e1516,3d6e35dc,4978fb96,b531aba6,67231968,a2f0fca7), -S(f75899e4,e383c412,f6f9c764,38d38cc0,d0550d28,a150292e,45a2aaf3,c7025ff2,7ba7f1fd,d978939a,79b482eb,24776178,ebee022b,48f66c33,e7a8de58,7fc3870c), -S(9d3aca30,fadb9f90,778aab4c,b7b88706,cfced983,ca62ecdd,4724d58e,6575a754,f0f41826,c426e8c9,a832a211,c1835693,9a1c7c63,3de95bd3,7e6d9b6e,db41d16c), -S(63454665,5133d840,de3af8af,def0395,cce4e97d,8e0030c,94f8cdba,cd72c3b5,19994348,daf379d,5c626f75,12109e43,bda0e527,137d425,9d9ebe32,2fb9aca9), -S(4ec235fa,47217cc7,9e2cc90,216626f4,2861f8d3,e61665f4,37c83ef1,acfdb8c0,d0b35b1e,ac498e36,38fa5da8,310a8f64,62cbd671,9d4b9c2e,c3be9835,cdda0a8e), -S(27dc4da8,e16e0d62,4a0204e2,3a8c11dd,4ebc5504,3cfe98a4,7d91ab19,92bfdfa7,6ad18e5,fc0e8d1a,421f6cea,8276b506,96e0308d,3983823c,de917e88,195ae3a5), -S(7479c3f3,6a4b4d1e,fea25a45,a3c4b79e,919707ef,ef92c830,6d693c00,e9ff2096,5faaec2b,a9343e26,cd32a68d,7f441d7f,3ea614c5,3703ec81,c43962f6,9934b3ee), -S(3420c98d,a020a034,e094ced,fb80c251,6c84a959,f9ddaf7e,ed889927,9d98cd03,b6af487a,c26a55a7,30552322,b73b05d4,a7e819d,7fd84873,4345870f,6ce5b8ac), -S(4afb97a5,68556ba9,350dde2d,85709057,ac4f34f0,e9700939,57bc90c5,540c61d3,1a129c50,23c3e419,fa0d5bb1,74acacc8,9aaa1114,ee38b937,406b5da6,b99fd29d), -S(e431caf2,6d33fbc7,28a789fc,ce00f3a6,c4629958,6a03ccee,e84a385e,cbae856a,9d11cc02,df57742e,d01e9169,7e5bb434,5829d076,747b065a,782c8619,da4369c7), -S(94a651f4,4b112523,3fd880a8,99191f1d,9cd5064c,227c2fc4,de1eaaec,9439ebf9,85eca2e4,717816e1,6c28a5f2,c90fa6a7,fe4222ae,f811ae1e,acbcabb7,6271ed7a), -S(96ea121b,60d051fe,d5381fc8,38b70e86,257626b5,91184577,337fc62c,529355f0,b3a56efa,b898b7b6,b2d90341,cc91faa2,24e410ef,fdd9d7a3,6770765b,c412dd82), -S(4b7e0cfa,250661d8,fc2e52d1,4a2969d3,b301de21,cc7eff3f,d7d7d7da,e2404d9f,d5d48777,c77930ba,96d179c5,10734cc5,21ca4ab7,a8d7cdc2,2960ddca,c03ecfdd), -S(7ee44334,6c87bae0,c3bee1a,273f09d2,d687fbad,fe060ce6,ff376c10,1ef266,ca4d7e06,2a28edf4,3419d107,41ab1017,da1bbb4,2e26a282,5d8d5a07,6e377b5c), -S(e31aa2dd,5bb618c4,63da1ee6,ae50ab1e,ad967b48,ff8df86c,f0c9ad2f,9e530ab4,3b3f92b7,7845a7d1,6a5b02f9,13354e6b,5388583e,546bdf9c,34cedd17,a9d4e11c), -S(15755ea9,907f998b,f75d38af,d4716cb6,4ab3fd19,2a3b62f2,f597708b,33697405,3ae19c16,8fec504d,8cf4320,c08c2dd7,605e2fef,1d8ebc74,1330e78e,9803504d), -S(2d2da66,d08289e9,f1674782,1214edfe,9de40a91,f1a378bd,e5802bc7,95023cb9,2e48b7f7,6dd20f2c,df2b0c18,1d5c691b,7836c6e9,8755aa05,62277426,53df2a99), -S(1b4bdf1d,d34b1b24,384d28d0,27c404b4,2691ec78,3949b8a0,65615a35,ce5c6c18,33590a6c,679a3058,5fd82459,f609559a,edf525e5,7eea0870,22d60d8a,dc57af5e), -S(3de0d336,b7bfa62e,5bfd8265,4a149e0,fb9a9add,6ef9679f,1e96b911,2f4bff69,ea44028d,b24468f3,bec7b60c,22c72efb,ae8f86e,90c3e2c2,b885b228,f7a1e123), -S(55d6d2b2,9314bad1,ae87da3e,e30f01d8,8844d27f,6e85a071,539824fa,dbc064c5,ae68132d,6f412ca0,3d70b23a,cf88d7e1,2443da6,cd5c2914,1e44199a,685cd459), -S(7ff2bf7,4696ee5c,fd709fa5,5d6bd376,b67fec2f,1c8b8982,64628e7,445cdc13,aa0f1082,f90052a5,c7a92350,cb3e27ed,9ad895a7,a73d4929,3864223a,b2640cea), -S(6fd69f09,3f4cf5d0,26703a,a0836ff0,2dc344c7,ba36bfdf,c98fe932,c70ce775,a2a95599,4651742,728572e1,5a9854a2,3cead0ee,c7edf4a8,f79ec569,36cf300d), -S(c644d73f,c2170115,78c4572e,9b8ed701,c36dafd8,e1602efb,8788c0df,a0b6ad48,38fa94e8,46ac717d,88862e2c,94e90e15,97a9144e,2e1900bf,1cb40218,e22cc2aa), -S(864820fa,f8975085,f69432ff,2f638054,8b972f33,7b74386f,d113300b,d672cd3c,b08492ff,37610ff2,fe86d3aa,a3c62747,3be55698,f183bf58,f67872f8,cfc9cbe4), -S(cc3f0782,8c7e73f9,a3cab59,be37008d,6574acb2,f7c4f0bd,4cefd6cf,b10c25e1,41751bc0,b9b0ada8,9d7e430b,600b00f2,987c0639,bd910c32,d1e8ede1,b183780b), -S(a7c1d70b,73e901b0,b892059f,4968d287,7026847e,187766f4,7b82ad0b,e874fe5f,87a6357e,83bc6dce,d3a3700a,1536920b,b0dabf6b,2ea70f7d,1a88917f,ec51890a), -S(f10a662,f02cab01,f47c6415,70e9a020,2584f160,8a69c02b,cc5509f,e54a7391,70422b17,3c20d128,30da1a71,57935a87,7d6db2d7,b7ee5272,5b756a5f,a0ca8891), -S(36ae45a6,efd7f4ef,7f66a206,82d027f,25b8cdca,410901da,1152b2bf,2df0f14a,ebd682f,c4cf31dd,c39b23bc,de979cbc,7000724,8d4c75c1,dea2c62f,37823e63), -S(ae3d1eaa,e04070e1,610c70e,190f599d,b2ed8dbb,5aa4be6,1af5c82a,83757f9e,6045833e,b1521caf,3303bea,eecff1e,a98477fd,ca29999e,4ff55264,24e87117), -S(8b961a4b,917a59d2,4ad0f94d,fe7840e8,f7f6573c,61de7f50,b3814920,754e5891,3a198cd9,e2d40f2e,7d5796aa,fef0b84,91dde435,1aa57366,65263ed4,5f136fee), -S(86d77e77,f7c5e4cc,dd2ff3a0,1589e422,8aa30d9c,162370e4,1ca47040,89b4e0ab,c0cf8d72,aa3b90a9,56bc8827,d3b33c1c,70707114,e3dab774,68894c31,3ecf21d9), -S(ea77fb69,a07e27ff,a2bc1815,27a7219e,2433a38f,98a05f18,9faba452,82722666,38f055e7,cab474a0,79bd635f,135d608c,c0b8b2aa,b48de933,c2e48386,74e943ec), -S(d5612e3f,304cf63e,23c280a7,872679bf,9861ae4c,965b79aa,db2e1ba4,cdecfd94,29e27659,26aca4a0,da8f3a61,dab6ee38,23e47fb1,36dcf792,181c958a,3ac24a78), -S(ce8968de,589a9b5f,49ddb8af,eb06ac29,ea053b5a,ab3c6dcc,69dd132e,5f2d115d,26f18c48,8de54fba,bd476b9e,8a6d049e,25d3d750,b8fe9595,a9eed52d,1865b98d), -S(728ccebd,7f098fd9,96bc257e,919961c5,4260365b,50f31d56,bb749b7f,6250b577,298522b3,d6e77839,97fc8fc4,5d4e853c,e530e768,6363b86e,8a68a717,fc5e4742), -S(ac7e69d1,d7d529a5,42fdc047,f9094729,45fd8af1,4ae3d71c,246a7c80,3cc7b1bc,af4c4fc2,9680bda0,bd2506d,7f64f4f5,f7b891e0,c50fe059,3246f97b,ebe10d1), -S(633605d1,9d61b598,da661292,2b6e5763,c765960f,c044c5e3,a4405449,cbd0fae4,fcce18e7,3c419aa7,85a55b57,41902cf6,855d2775,e8be678c,18388a0d,cd2b5de), -S(ea93cce3,888035ac,5a187cc9,70e6232c,37e2d0cb,31d9b5ca,33e567ee,62948add,d842a18,e2153217,98a620fb,c6e40ec8,66c9c6e,aabeaa31,7d6a01e5,294a8b0b), -S(75d25df7,63b00703,5e21753d,7e4cdde9,3001a820,6dd834a8,6e4e41ad,38e9cfd4,ddd41a0b,4528af7e,df820374,68eeba16,e2fecdd7,1378dea1,f6d0f734,8593233d), -S(b28186a4,b7bb240a,8987119a,7114faba,d163c3b2,66349ce6,328ec7c1,62ab3fee,4aa77c0f,8db9be55,58488234,61d6206b,80ca3788,f195a47c,ccfb7688,18bfb34e), -S(43638d8e,3331ad3b,9e4cda5a,fcfe5c76,b1a61811,1f08ee42,1c008d4d,187300ef,fa90b3a1,44d0f073,64734dd8,698beec8,8b916fa9,a7aa7d9e,d019d69e,5bad5af7), -S(19eda20a,1ca63328,29a7404f,51c7fc4d,93d0ee1b,76461ee6,42a07c07,3d73a1ea,a6c5aaf8,6a9546ca,81689f75,68709261,642a2d37,d104b7b7,98a4ebce,f42c5506), -S(f6a557e2,68fb6b99,5e2a9342,d5e4ab19,b95bf279,17285ece,11268477,427d092b,b10451be,cc64fc69,7801012d,7d58e4c0,17365faa,6a9db69e,fc7ae505,638e4204), -S(bed211ac,c6fff91,f1baf145,27c8d007,1b19022f,13e54f41,3fc83b7d,1c9aef54,b97ef30e,a42822fb,fde43ffd,28184f8,fd58e314,ef69bd1f,b1961314,fe4bd3ca), -S(593c25d2,f6059501,347cd47a,9658b04b,9fd81c8b,5754dd32,35ef3d51,c7ce052e,1e3f108a,c81dfbdb,eb544d31,d7892d4d,27d4e146,779135d6,eb2d81c0,c3ebe674), -S(207d923a,211e86c7,7d8357cd,19b95bd,ba4aa7ee,61d147a3,a4149942,2a23ab47,92fae109,11615ee0,9a3932c3,7945aabc,6b14e5e,a5934a92,b6dfb9d7,a68ba39e), -S(2c2029cd,d7aa039a,1b43c84c,5f0db4b8,8093192d,584818f1,f938eb4a,5c5accd8,35a55e55,41a70031,c5ac72a1,2a94d94e,1f467015,8ebfe17,70d2aeb4,76478cd4), -S(4f8e148c,6fdf65c7,4152d84c,5462eb59,e6bedfc4,3ce6382d,db24d20d,43e0927f,12fd3323,143df955,9f3ce8ef,30203320,893fe063,b17a9f58,5594062d,4478beac), -S(954cad68,1049614b,9bb5995a,f69868e9,44efaf89,5ef61aef,7d09e74,24151879,56c8e285,5df18b97,4147fffa,a561d425,c1d0b1ea,8cfae8d,4dbd3462,7bc57614), -S(d2b06281,2acb2483,bf26dfbe,5a61fa2a,2dc995dc,835a5ca2,86fd2d33,b273a129,debd115a,2a711cc2,16ded426,d442b504,475a5f2c,d7e651c2,13b79f99,74ab9997), -S(1682ab4d,ae292e8f,26520ab1,b8f8aca6,33cdd6a8,a0d585f3,5048551d,f4b6d354,80c160a0,9300aab0,f30df084,fa0bd259,fce78972,7f0a78b6,96562edf,d820667a), -S(b9252ea7,f64ee2e3,4cf31c3b,d9e065ff,1e0349b6,3f6669aa,19e42a71,72312586,4e48711b,3f0fe7a,89fee250,b116862a,e00da579,d7e29427,fe2ad3c5,e0ddccb9), -S(a1123f7a,81cc5e43,2a54785d,f1cc614b,7ebe0dd8,b6362e1f,cf41bd65,c3c4faaa,a0d31492,82dcf09b,2814c88d,d5aeb9af,2c16ff1d,3e1e05c2,68c8aa5a,8f5716c4), -S(f47f6d8c,a7950f23,a4a08d07,f5b8889b,c30e8ad2,8510d198,3dfed29e,e47af463,6873567a,2820f91c,506878c1,69e98a70,f3d6696c,455f1752,21a4e1c2,44dc62b2), -S(8efbf718,f124b5f6,807d3493,fb3dfbc6,f1c4f0a6,9ce81d20,3b13f422,b6ac1c88,6e05c0fb,77d12e84,64fe1b30,8207ceb9,a297334c,e937eee7,a9a45ea0,bfffb734), -S(56a8aa37,ece2a01,5f0efa3c,41f541a1,a9078c03,39b6af5d,9c9486c6,93bbf553,fa191d76,62b7189f,9ad68823,8655343d,71e7527f,2e72d3d3,1d25a4ce,719c7146), -S(cc2d4945,5659cd0d,19924df6,6be02e32,16e93423,9ab657ca,9003431c,cfe8e450,94a34e9a,a0814633,33b53121,3c375d6a,dd554ef8,cacee52a,a177ff9d,42cf39f0), -S(ea38154d,ee6d08cf,50c3497e,6e15a1b2,d265fbe2,cb945a09,a34aec36,35f18583,d1e16b50,cc5a8d51,f043ec05,1992ec53,d7020cb5,5d05519a,25d364f7,e498b28b), -S(82cbb42b,854e7f28,a2a786bf,6cfb4642,3fef958a,dc2fae99,5590d311,82d46c2b,96310134,eeaeb35f,5e2ae9e9,2c26e731,e0e65da6,b37124ef,c6c89e58,b7434314), -S(5f23519,92aa09d6,1ad78103,df0a060c,e939782d,774ec196,c261d6b4,5e42ff01,7e02b11b,5efb1a31,43fbb204,d63a7c5b,8a04a66c,1f5ec292,277ed353,adb8f95b), -S(d182f035,18ea0c6,a16056ae,a071a1b0,920d7a9f,37137429,5fa89f4b,1b4b229,268c5c3,f0d47748,effe1eb1,3b1b5340,4f61da2,6e56db7c,f2e35d89,a6bdde8c), -S(51e72ca2,3f22bfd0,f6405e3,57ba5221,310fa8f1,fc054e30,a34a0271,3051e9a0,307f4e74,b97c917a,281acb4,25d1df8d,ffd5e578,9b1d80f8,160c1ab1,ed79322a), -S(bb193d73,f08c5946,faec6f10,aa13f855,aee34bc0,c4b60c3d,2ae0c37,359f7b83,87cd0d87,d9d83fb7,3b382cc6,35d6dd63,29116267,5f1e3647,ca62a68,fedf7143), -S(9aa07141,e67fa1ff,cc307760,5b73625e,f804246b,a4e8e568,f0a7c111,76c61de0,b58aea99,47244021,1020a64,584172c,21c6f641,a14c43cf,377c1f68,b8ced736), -S(aba5e67d,8aa2366d,e77c9d58,1e221fa1,b0f0db3f,2d3679ab,dfffc4ea,45ad84d3,4fbdee40,48ffd408,712e17b9,2b9fbb67,ec7c9ed7,e6ef052a,b8dd0ecc,62fa91f), -S(bb9a0c87,e1fd476f,e8cac1fa,7f6cad71,78297b32,9fce8d9d,332758c1,1a8ef09c,a9c38e66,add0e7ab,538c62e,fd7c2eaf,3ee221e3,cdf581ff,3fcc1bb8,bf638332), -S(b531f3ba,bb94cf91,b492d253,a36de81c,476360b1,91ded661,7eecff08,403eefec,3f653457,6dadc53f,f2a268a0,b8389ad6,a21653aa,c4b65b72,758fd6ca,27f3b570), -S(f7e9407,d1f8f9de,182e273f,98984d57,de4f7c61,227c98ad,36589c2d,64728812,f3f15a91,8d2a5c47,d7fabf29,dd2a2380,73ef645f,924d04ee,31dea489,f6882844), -S(3aacd2b8,2013ac34,75a7cb05,e52c1853,c10f7b66,68e5f8fb,eaaedf64,342e2b82,2d33a32d,7f745929,3915760a,4fb04c30,f649541,a246396d,8cfefbe4,26f6573e), -S(f11a09a7,edc46b58,313c31ea,93364d17,4940c58f,8a8fcc4f,2bb132d6,bae01730,7a42dec,b0eb3b71,a400cc5c,4ac848aa,1e3cebcd,c38a1407,3eb6f568,6dc68d5a), -S(642ede12,2ed16043,ca028a10,e014fcea,52d6a3a2,9399cec0,afff3009,598e967d,7f86f11e,f79a0e2b,66ccc91a,3164617f,f08c85db,c4f1e4f2,a0972c43,8e15b6de), -S(a04415aa,28f065b4,5b60f57,2f665229,dbfaaafa,e8c0561e,9e37e1a0,79231a49,a32b2e0a,4e9a23af,58b398a6,56aeb0ae,6a98ba4b,abd1db60,8959da55,14710f08), -S(b0904d2f,333c0cad,9eb4f5b3,ebd1c176,3488ed9b,25f640a2,e9379df8,b4d170a1,ed8bd456,999ae102,edb20bf8,3f903319,97233e29,35e1c52d,13a52cce,32a5e958), -S(e50f98e1,162614c1,6f2effc7,4853d7b7,2fa13e2f,2fc0b864,dfa1656b,2e1a0a40,5e7ad119,80f9533a,bd541065,c1309f90,1eb49aa2,34386f14,88ddc3f9,3406e986), -S(5d6772d0,2007fbef,4d385766,ab4b4fbf,1b3fc017,6f883d5b,395e5a35,763c9e12,f4dbe650,89e165c0,1fcd49e5,5991db5d,3cfff2fe,1730862c,3f3105d5,a9433e6a), -S(c971d45e,c78b70fb,70d2e4b4,b427b82c,4c569d0f,1d9e85fb,e4703d27,58fa97f,9c148ffd,295bb61a,d3a34548,625a447,65a7599d,5d0da8be,c30dad98,c735440b), -S(f118ec13,304f8826,bb744d7c,eb87181b,fe25c3a5,ed8df1a0,eb05bb65,860b738b,292a85ae,eaa3cc59,3dd8adc,64fa9e71,2824227a,2139d7b8,5720b289,f1ea54fe), -S(6b38d88d,e7629ab7,82d2af4c,93a62371,bfaff595,d422b5cf,b12e0fd,1155f5ba,b1a49c69,5439c867,5f491cbc,e3c5971d,87ae5a60,faf13c1f,7cb9536b,37f780b4), -S(95c357d6,24a2f744,d8989a28,8bdb7c0b,241413e6,5a26c877,8382270f,c291af61,142845eb,991aaaba,3e755ed4,3ff0afed,34643413,5bb13034,43b21a83,4f3c0e31), -S(feb4122c,23e68298,f4601b3,edb1de03,b7137341,6527e483,f16a14b6,660425f7,2b7f5ab8,1a2fd416,24d3fd71,781be6a5,1e8cb43c,7ea8265e,e5d92978,30388bb1), -S(bc0eae5c,fec4873d,5d34f0a0,86a96ce2,51369a01,ad2d5137,746bafde,a574d9a1,1fe1f281,999033a4,39f4c0da,5c1cf6e2,365b139a,29f82785,caadebef,ba5de3a6), -S(93f71e0d,d7ee6b9c,a017de05,db2a52e2,d2175cf0,2c1aa194,1c6256d,74907872,1bd2c197,6108b712,27e0bd78,b0a2a036,6564c979,5d1ab6de,7a12a0bc,3913c8cf), -S(f8388a97,45191a86,efda904c,8bc06801,faa3bc37,8a2425dd,2dff9a4a,4ee5d7bd,af2b9260,c452261d,584144b2,91b5388,3eeb5014,c0fb0a89,e8b78f0,9525b5a4), -S(c7e727a4,a0fc2d3c,4a5cdea6,c93049a4,52d3646f,35951918,eb379c56,50c544ad,37f5bade,6d3d9076,45a4154d,7d30ce2e,cb77a3b5,695080ad,bbdb8a33,4c7f7514), -S(328eb6a4,7cb82340,768d099,45902d56,3707c86b,261b9ce3,aeac6734,e76c4d48,ff1a5828,4f402090,c32f7b07,7e8c3098,7c3af703,604c22ca,aeb4acba,e7f52c97), -S(beb0522a,acc84b29,e0ab8233,6ca02733,9b4df195,bfb01a18,b38dcb3b,7c8a1e21,82d7508e,9491e2d3,d74a4229,df4d6020,1c6a86b8,a3a448c4,35dd20b2,f993e6b), -S(d3dada60,563278d9,38e48e79,f2e6bf8d,5caf0f90,affbdffa,c30d6e06,3f69cee8,8dc2beaf,34b916d2,b542121d,8e181735,1c55a766,ee46f2c8,bfb8b7e3,d5ff6826), -S(42111151,45ecbd47,1c8a812a,192b3a7a,ab43cbf,ddc49dcc,5a92f350,86069c33,f9428e07,f33cbf7c,7afd7cd2,f6afefc7,b0fa30c1,ecebcf92,30e20c17,7d94aeb4), -S(bc2034dc,72217bef,895c8d3e,5a5414eb,882e8efe,3dc8cb0b,cbab0edd,1bbca0a,141caac9,de3a48ed,ac6eb47a,fb195238,f3784171,4d7f3807,8d492a9e,a70d386f), -S(b8035a3e,9bdac3c2,58da038,5de2ee25,98ca621,d90db03,4057b674,21e2bd1d,f7af5751,a8e51665,4cad2e0c,61a94970,6b5151ec,1eb07cd8,1713c716,7a44f357), -S(740fa667,cc333c48,4880eeac,ebbf5fc9,34d3ac55,ea04d8c,9365e5ad,c3a404b7,33893248,b4e2e874,8694ac43,d5e6aba1,3afe26ae,3a51a613,d7e0541c,d9ba91f4), -S(673c1c4b,16c6a75c,28725630,340aab0c,8a7b8648,4b17714b,c955f160,e3ee09a2,c3f99423,2521122,d0dd518c,d9fc94cc,5b4c836d,9665cec1,1a024995,342f31ea), -S(a74784c,dd6cfd32,972124a5,dbc0233b,f0222de1,9f90ac0,87e95ab6,f40c62bf,ef2a3085,9a86e0fe,f96b2e5e,b7a63820,122e2dcc,a4f2102a,b501f2d8,1a88378d), -S(db1d8dd4,bbffccab,bf1b90c1,9b92535f,4ada68c,9d3cbf86,c0d700fd,61d4beb7,ddaaf64a,54972f9c,ea2c2fd1,27e17223,1dc38360,6e0589dd,a3f8d62d,80c0a5be), -S(ffb9ae70,2307914e,a9e4160a,1cb68f84,3fd03778,8a013f2b,f9e1d725,b09d8b40,352b1e7e,69e5afc2,6eae5b56,b2b7ba9d,ab174019,a03df463,ba510aab,c4c9e859), -S(ed27b183,29dd25c3,4a760942,b1aad66d,a1439b86,250db95d,98799c63,a9bf2fa8,8460eaf1,554c31f8,5c6baf21,126163e2,cfa9d290,17bfff10,9d295c8c,ddf391e9), -S(70a453f0,52682a36,1dd33a79,a65e4080,7bb95541,5d0b0c72,ca3d2b15,7e57bce3,2e40f3c,25554c85,cafe5e78,9aee14a5,131ba6dd,b9edfbae,338e8db4,653e908f), -S(377a14ea,78d4f864,5262ebc0,5f55a310,6a329376,be0d567d,a327988e,4e1560ac,ef069fd6,264ab8c6,b290c4be,6558cd27,2745d9d2,7ea22521,b79524e6,230a7c47), -S(39fb1a0a,924546aa,ee6b8f4c,65218a6e,56ee0e2c,3833a784,3858eaa2,f57f3399,e4bd9a53,8419ea44,30b041b9,e93186ee,d9ba4846,b6125f1e,c549f34d,ea5c2f87), -S(d255491b,62a9ffd3,5512555b,4c413eb3,b412ed6c,9b585baa,875c5643,70d9aa00,da4094ca,fff6616b,51ed389e,a5b9b3af,641f872a,7166427d,d24c5973,be24d067), -S(342d8017,5754c01f,504e6c0c,c4c6c8b4,a1079dcd,89de2927,a3227a1c,756de1f4,de8160ca,ad4a4f31,791fdbdd,4b9ab3c9,db9098f1,2db64ad9,d6f90ba4,a9b13a6c), -S(92e8a7d3,d4e8bbc8,4427ab1,a35e5a0e,c2d81c04,c98ff34a,325b4abc,2863fef8,e8bddcfe,876f7c55,86470c56,bcca444f,fee67417,8a592e0b,b9f5b1c3,b2a7e9f7), -S(eef2dd87,66dd8259,fd821f30,3771574d,4477283a,614e463,d81238b5,b08141eb,39a91138,ac12e0eb,da43724d,686d9207,1db46682,746d532d,55426a53,87b98023), -S(2efc16ec,974042f8,b1a91132,2ea4f521,71f76da0,196cba89,12faf48a,cbab65ce,97c0079a,3151c8a4,7dacf1ee,25bf3157,48a83cfa,1f3be2ce,1954731d,a2cd56ac), -S(3d2def4f,dcacdfb0,8dbb75e3,1627baf4,6deec0c3,6c4bb3cf,f96f13a1,2066ae14,41ab6cbe,eeae8634,2f95027f,e472834c,e626206b,3e1ce1a7,71b717a3,39e5827c), -S(ea23f622,95a65d24,162d88b7,6a577b64,1abca822,1c29d23f,56e4f929,a19dbe10,aaac26f5,c8b5bf21,38a9dd73,8ce69b01,6c6b4f82,4685fa39,c2de56ca,3c58b664), -S(f01557e5,ea723ed8,2d5e4e02,f4358ef5,5b0234b8,182bd4c6,e6310103,768eac09,8bd31626,7fb3e7e6,ae828401,fd00712c,9f4f4c7a,cee8f708,4eae9da3,38e12378), -S(1f645466,d562b0c,4618217c,4cef306d,7156a5e7,45327a55,40619bb8,2934a8e3,cf9dc7d8,e7c1c0cd,28d9bf5d,83a7b33d,e1060c01,eaf58d4d,10fde41c,495b954d), -S(6fa762,97a3cd7a,9799f3c1,95f56864,c5a8ad78,f4014c53,1dc83fea,244003f4,3bea377e,9183478f,89f94127,3bf5222b,148ebfd5,7125fe96,147243a0,d07c14c2), -S(71061b69,c5a32537,d40254c,fcc5f67d,cd4a8,40911295,8a8e3f3e,5f060a6d,a980fae6,eec78bd5,3c926649,96239cff,eaa10169,7580799d,5b38ff74,8f0f7a78), -S(518db918,8ed0bf54,75234c9a,7e9c0395,8796645c,89104797,5a8602cd,e7401e3a,10c50bd0,aa0fb6a0,62b964ff,65a5102c,d6bbb192,3dfaf2d7,edfbaecc,77cefbe1), -S(6f7fc8db,8d00e22e,6f30c093,573d9f5f,fa939796,6ddf5a59,6126f896,88e99dcc,e417e5fb,b55fc324,1a283315,3ff234e0,c9ac49c,13ae48f5,b84941b0,702a7c08), -S(1e09fb70,ea2c11c8,601fdaa7,7734b369,7e5efada,77b38869,8553d4ef,e1bde2ab,b8bf422e,c93c03ce,9d9ed0e,de058d20,e0fdf535,63ba16cc,494d6648,fac3a027), -S(54bd2f4d,961177c0,dfb4814e,bf5eee4e,21b12ca3,eaccea46,e70e117,76ad1fc4,358e0d73,79368299,f33ddb71,1722c2ec,8912877,c3891c8c,bc55e453,7c803962), -S(53ca166b,2eebb5cf,59a35287,5f6fd200,dda76f66,e3341ffb,1adb783f,4a1ce584,ded51d62,7769372e,42540e0f,20ff4a3b,2d912b4,6eaec7e,4e891ec4,18fcd0ed), -S(dd28eb5f,5fccf394,81467a6e,746461f0,3e4cdd04,6e7e6f36,534f6384,daad4ab5,8d702671,6e5e098b,648ae87b,6b782374,a2a3eebc,eb4e3835,470d4831,1f7dcaa8), -S(ce29f160,90fde1e6,13cc16cd,16cc7b8d,7e6e1203,cb1f1b5e,a724d65e,4d91aa28,d44c4dc7,90586159,ed9f9d18,dccfd95,e24bf6aa,c1bc3530,ec871473,330680fa), -S(6d25e798,ea08596,7cd9e0f2,da65b546,8e885d92,ed8cb0c0,8a266dc1,6b4e222,1d18fc8a,4010f407,aafcc995,8fe38f89,fa5f6260,e3288f8d,e4d98f94,377d624e), -S(6deeb20b,cdb46236,969035cf,58365ea8,224830a5,6cc187ef,6d938353,920ffb36,b19d7a95,b829c318,96d2833b,9277c9b8,7e28c6cb,c81c4c2b,d114afb4,c5266c55), -S(72c4d5e7,68866f63,b53a27c,74ef9b43,35e7fd11,2e13db1b,93654078,f625574,ed233d0a,1994d701,62869eb2,b7a2cd20,d82277d5,3109a9c3,e6e97f47,d727dd54), -S(79efc60b,64c060c1,a142efe0,5dd75ed0,a5b4ea0,85e5a10f,c6620db9,92525420,101b68f0,6ae4a3ce,2e33f003,1ecc3b1f,11dc24fa,d9f28a82,ebb2f5f8,380b3c8a), -S(a8cb5ee,ee7550e7,41f2150f,2e458dbe,f8d32b87,dcacf424,5cd089f9,7cb6c0ef,fefde564,3f885730,d60fa2ef,c85f4b16,d86d1690,3b2a8bb5,4b5c18b7,73085054), -S(dd8e43e6,828c9363,32793374,9d29a822,66bc8b1,4e320750,3d415831,bd7373e2,5b1321c4,744cd3ae,9348ed3b,5e4cbdb9,5e1d7256,e7ddf7c3,fa1fe9dc,494469a6), -S(8ad3b3e6,a237ed9e,8f94d669,2f5a7725,b0779bb7,ae06c57d,1c25e449,4c95479a,45b978b8,500757ba,51a05069,32f17d9a,bfaecbe2,2cc63c1,5a9b617d,98b071ab), -S(cb3497d0,7c72e534,75618cbc,29224ff2,17fb9659,9d51a6e4,1559f323,9c699c4b,72914c58,8daf6396,d4d9b70e,9476d967,aa60e574,b637ea1e,25c20fe0,1355509b), -S(fb77666b,b8c6cab,ca7ecb4f,e88f1e0c,199a81f1,319b6a6e,9cf2dfc7,e9128147,f122b377,84326ffe,21a707c,a3bfe74,2e433894,7c791814,855501ed,255a2ab4), -S(f2f16cf6,6a9943b6,19b321ac,76186ac5,6e65c2c7,aa9c87f0,15029f6,36749c74,aebb617c,88115519,58f90c87,5f021df4,e3c83e22,9f787275,db39eb05,9b3d9e82), -S(607cad82,2d0a117e,cf29dbbd,c7a5c6cd,d4b67f7f,6bf6271,c58de368,50692907,f2344d08,4e7db14f,70463f4f,20e9c379,538f0031,285d9c6d,1cd33d5,beec40f8), -S(efc8352e,dff912a1,936ca01c,18da7ba2,c9397f42,2cd58738,4ce321,4baac332,52006389,6229a8fa,e24e1686,4c5a643a,425e20ef,46febfdc,7d9c43d1,f767ca7b), -S(63d31f76,805cfe95,4db3470a,1d7215,505fa39a,cbc69048,58f801fd,eef99804,97cd5656,86da7de7,4d12cd9c,6e5b0c5a,c4f7f22d,3d44b372,a907c233,8f963e7c), -S(7e64f2b7,c2083661,8f2e2d21,e86ffa91,be646231,c61ac353,c32cdc25,953a01c0,c9222645,5b1ccb79,e00e905,2bf2c9db,91d41728,58e46f84,811bce9e,8b0713f7), -S(b5f29487,3a276b67,2d2de980,c6f74a23,d7bb465d,e9bd3362,45ca65ed,f942b85f,76459975,a0569a4,8b2b463f,375be7b4,f05e1cd3,3ee33a75,61ea8292,850d1089), -S(a0f6ba4c,b52187c8,9c4b1218,b7f57773,94551352,61582217,7e649893,dc3cbd8e,94d62e8,8f584baf,f0ff883c,1ebea341,d71f8bc3,59807c6c,eafd845d,361f09bb), -S(ef4130f9,88666de0,2aa37978,daaeb7e0,fbdddfba,d8953c5,6011f839,e974d0a7,322d77c3,dcfd1537,99043ed3,339a2b98,87538059,714a459c,1ddbc6dd,c9e720d7), -S(d6fb60f6,4b5409b1,7d10e23d,4f311d9c,4af5dde4,f1f07616,11e0eafe,13c2bae1,72f99e2b,bc790349,144b0ebb,67b35ba6,a62b94ec,b8bda4ea,c32de255,bb071651), -S(4f69ae06,8930b9aa,bc2bec95,8b3f28b4,5b488e34,c3ac0dcf,ee05368d,1f7d0b19,b72573b5,b86157ab,1e414c20,c0e073a2,e583f031,ddbd4141,1b3e26c3,e3447d57), -S(9fe97728,7de04cad,e939e6ca,d32afe4f,865b0423,9103850d,688fd06b,db10b2be,60cce398,c46ae002,a34a9ffd,d2ef6045,23f442cb,9f7ef392,ed292ce2,ce54256a), -S(b328b5a2,1adec912,66aca0c1,98084578,59036c5d,be3b6e8c,a9476b95,6954aff2,355076d6,a48803b5,fce76401,4e5b9e3a,d7f3a270,a7c50cdc,442fa9c7,71a3dcdf), -S(f8d16f5f,14885b0b,c5d556d0,8f6050ac,62ee00d7,c3e5ed7f,2ff6b8a3,54e54bad,dd483037,70d67a5d,32e7e58b,dd83dec7,b5c8e14c,a26ae5fd,58867401,837a332b), -S(422cc48e,415b2e68,7ff7896a,b32fc6d5,e3c433b4,ec2b511a,42178b6a,9ffe73ca,664821ae,781b98ab,c6f08fc6,ad11a76b,aed4429e,b7e879ff,134355c3,4b4528b9), -S(c8bb5046,1e4bd041,afd84d63,998dca63,de940192,7314d666,7c19db57,a8f629f2,1455fd5a,945165b7,2186e9de,ffe01764,108d6f03,bf4007c0,53ec7b8a,a6a7d07a), -S(7303bd5a,4e82fd3c,a94c94e,c2f4a06a,7d60c272,b2dda534,48eec8ec,ffdb80cb,7c593252,6a031a82,673eea15,263523c9,44f3ec0e,975203db,7cc302ca,83316c0d), -S(3455bd06,7de934dc,301f4a47,807106cc,24e3d8fc,9bdce088,4c1d01ec,2250dddb,d48aee56,e99cd267,d2cd8cc1,ee9fc3ac,88cd3d6a,2e58aa97,6586eaf6,e2052db7), -S(a419f5c3,a053b04a,a7137049,cc9452e7,268f43fe,528d7232,f0950270,b9d5c2c3,dee8994f,b9feefc9,d1f5f529,5444214e,2190de46,5a514282,5ade1a46,c439c1fe), -S(31602357,e187796,39867d23,89962d8c,3d5e9c35,7a2ace5e,83b6397a,585d5a73,21168419,4dcbe58b,95cf6e85,dc6040bf,d62894c4,bc5abfd3,e42603f6,ef86bae1), -S(3a0395c3,ccbc8006,a889e8b7,f6de9f70,44f2cebc,5c595f40,9d632166,c35831bc,25705a8a,213464ed,38fea19c,e1ed5ca5,2c0f8bbe,debd4388,bc8565a2,faffdbf5), -S(88067788,1627b285,336ff69,3ffd3728,6d0f154b,b743e273,2ff29598,178f5f17,c0980505,2fa7c70b,fd34ce6c,f27e5197,3414cc7f,1f57afb1,18385e9d,893963d0), -S(e1e1edd,146391e7,aff005c8,8f5d1347,5b393ef5,3a017b17,84a6dc4a,e29f5b18,e95592c1,5005cee1,f27c649b,2409c3f5,71870c85,c389861d,3e285e7e,7754a3aa), -S(113aebc3,2beb62a7,6e57a820,1c3602cf,d654ede4,d58e10bc,3545d84,cb406362,afc21a5b,5155c143,45bf5b47,50295ed3,db00ed7b,ae83205a,a0c504f7,fa5a2db4), -S(cdb6f34,7ba8177d,57e58fec,f22424b,fd3a276,96d386f4,9abaa40a,7f03bc2a,8959bea5,7d63b46,ae5d4d34,358a49ee,142b9b7d,137bb2dc,f4a937c,45338b08), -S(f9e9688,15a87cfc,85c00d90,2d7ce467,5086c566,49246f8a,bc655dbe,c1c82882,7152976c,19e3aa37,aa63d7c1,b9b45111,923b3b7a,df49dab,ae50226f,f39c1fb5), -S(7e7c0a6a,272ca295,c7ff3de7,906ce47b,9470e583,6afd4218,67143d5a,ea1d67b5,b66f3565,d68d55e3,b7542ed8,2b12e217,e4b47879,d9dda727,bec58094,da9d1886), -S(72995966,366251e4,57009324,5e29989f,f15670,af4acdb9,3eca8d47,3d1bab8b,9a8dc60c,3232eb18,9b454b51,d9db82b3,dcce9f54,e30e430e,26aae1b1,221594a0), -S(973afb4c,aa2688a5,b7e4f679,e68c2e4,df25ccb0,d56de80d,f6522000,6eb4dc1c,30055694,1c0eb266,906933dc,9c1758b,7a6181fe,8c400191,bbd978b,13f5f55f), -S(2d550e3a,f5b2d5f8,3cb4c695,431ed8e,62344236,66eb0eff,7759d4bb,39fa2dc1,5f6eba0c,e447bc92,70d35709,87eb9b17,89e7721,a7ef2ed8,8f749dc8,37dd7e71), -S(ed44931c,7d509be8,706150b0,3f24426a,571fde4c,e7b2d3ae,488a3576,37f6ec28,48e05525,e9b38639,6da1fdfc,40a134b8,1e05fc60,c7bccfee,8a8ac358,e9fd09f5), -S(6de88a88,b7b34f50,a8990a4a,742bc1d5,62d6b332,810451f,1c0081e9,18268975,5c435e32,379e62b7,46ed6518,b304ad1,65130b66,158cf41c,5418e490,edfc5535), -S(337611a2,907cdd12,c6c482a1,9b89fd74,1547fcf4,ed6ee721,cbcb66f9,b90967b4,1a438459,eac97f8b,53e45562,4a25ab67,f52cc6a7,fd3cea42,5ad08dfb,31d6bd2c), -S(aff600ef,329fc815,d36abbf1,3eb59530,58e74ddb,9df425e6,49662123,d8c429ca,ab8aa32,642dbcf9,994134f4,65a9e760,ce8cbf17,540d2f3c,fba6a31,9eab56f6), -S(4b15c510,47c6cc2,309c7eff,d3124f66,d56198a5,4da997f3,48f35fb2,7250504,5cc00333,f6399193,ff90ec0,54a726a,fcc492a6,bde386b6,57e481f3,18000cf3), -S(4683f46d,b9cda227,cbff9940,23995184,92c61151,a67508f8,5629945d,42a89345,cf1e8d43,b85cd621,2da2bed4,ce556ad3,ff0abd6a,1d40e445,629d727c,1e072e3a), -S(9ee0eea4,850864e5,c8239602,f84a9044,b966f84b,1aac7690,3fd096b8,fb09145d,c4c0698,e2611fc1,c7bd1c6f,f86e0fc2,19e3532e,defaf5c4,ae79410,db9e94ee), -S(ca4b7b7f,e02e953d,e622359a,f1834997,e5190c70,c149430e,d76aff1d,e166a0eb,e899496d,bca56f10,f2823c41,365400a2,723ea0ae,72f062ad,c36c0bb5,8e6ac820), -S(cf62993,f5be553f,a7492b3e,45934937,4536aada,f8db809c,cd01fa40,49364a2f,fda0bda9,d0f450a4,3c95a5a2,1526fff4,1b63c08,8a320b2,1ee9716c,cf2613d), -S(cc35c60b,288f8ce5,4120178a,dbac3e19,6e76ebac,159e45f,43afe82f,c034f459,8a6657e2,f8b99b03,3c6e29b6,f3bf373f,c117b6cc,f7ef935b,43b9a1d0,890d8bdc), -S(36a1bb7a,5f4ff871,b5ffe08f,90ecfca8,7c19eb0c,d110d770,20aff404,95b72e0c,1750a693,51de455b,1325e926,75dfe3e8,94de9f37,2d2697ca,954944f5,87d8706f), -S(a04c1bdc,7ec653a,fc549370,25d202d3,1bb7c21c,73de8160,160693df,ce42b5f8,4dd93af4,37e300a,8452a7db,af6824b0,e566a935,632c3487,f768988f,d874e74f), -S(484cd2a9,99cec03d,85872e48,84ee50f5,2172089f,8f1aef0b,d3ec6595,2a228a86,9a65d51b,bf64776d,53e40da3,85b84485,3c780342,6952446,35a78ed6,e1cefaa5), -S(398f027b,8ef951a4,2ad7c665,f5fdfce1,831ecd67,23f45154,62c636cd,db3b8a64,99577f76,a6a3b0bd,ac4d50a2,24c10250,727ce349,856f4e7d,eb1406bd,62d9b36b), -S(d62300fd,a6d242df,58be11b4,fb754306,62dcbde4,6e86b1c0,d1419da9,99beb256,cf11becc,84928784,d23a74b6,4dbd8ce6,37a1537a,3d9d0f43,17803da6,d1bf5e97), -S(4c41dc69,be8c1aba,9da4469e,2c1e3eb1,14b07fb2,db63785d,da03c53a,faf0f147,a83d7f0d,fd92a665,d73a2f8d,520f1a2e,ad6b2465,57ae2736,9618d10d,b114680f), -S(9a5086b0,1ba7ea1f,6cbd3be4,8acdf6de,29e8f733,b120aad,daa7e41b,3b1b2708,f4eedd2e,814d1f5c,33f44080,e4d50452,4deeba2b,4b2ca528,320bbfa9,cc3c65f3), -S(a457659e,51a7154,e5836fd8,4948cb3c,227986ad,f9fb8acc,89a3159f,d723b478,5c59c117,4e9962dd,94f3b084,8a544983,54ec4962,f0d666df,889c420d,78845ae2), -S(ea79c22f,13e6cdd8,e282defc,9cd6ed68,5d39b48b,c6c13c55,3bdc8aa5,8a90f78f,87223587,c3cde568,81217ec8,ef0dc431,89af8095,d7e9f82a,86142207,d8b5c356), -S(e19dd143,cd0a9f3e,8535edf4,a3dc7e7a,4c49a25e,1771f8f0,3fb5eba,1a9e10d6,d15a39c4,86b79714,89b2afb8,13b412b7,c1de54c5,c3fd2ff7,791bfb2e,d6a498c), -S(c7b277ed,9bada568,2f7a87cd,6435e0bc,948fcb1,2551ad92,e188b664,fb5f59ca,7d1e37cf,3093775a,1b0aec4,93b77c92,f6d6f32f,a1d8438a,b75add39,70b5eb00), -S(c1fb0836,5dd42214,2098c397,b11a63d6,43afc082,16c0686,d1540d4f,d39f2f85,438d6559,d07fe7e4,1e775a3c,66e79f30,a065a62d,fdecea46,e8ec0967,a5b5b8de), -S(1a5b6bd7,152c8c0e,6958cd5c,9344bc7c,5d7869f6,bd08d698,88e69e49,8ae62ed2,166a9f1d,b2b3a729,e374af09,40bad6ff,7646504d,36d40465,2c826ed7,98195f0f), -S(8e3f1e45,42438eb3,2635c65a,a817c325,3affb9b1,a1603d0a,d3fe06a5,83cf338b,e6b26e2d,9e310afc,e702dd5,4bcc2815,1dee0a86,1e31a16b,79fa0900,f94e320), -S(ed9ffd27,1fd7b569,fdb187d2,7d1d97b1,3a4b88bc,aa13639a,62a6b45b,cfd00dc1,5fb45391,d5a636d,1d757e5e,472865aa,556092e0,870f45af,a325e26d,40f755be), -S(873a3db9,be376cc5,f4516913,d8235555,624cea02,16c3231a,72750c44,12cf4992,3d5e2304,2b04870f,d3cb61bd,2f618b3e,4f1dbd3f,2b585026,fcebe608,7f0a5a03), -S(d3ef70a,eb5ed2ad,375ca185,69278cba,3d037dc7,b0f63ca2,442804f8,1840e686,f4bae13,fd55a2c5,ec93a87d,c2b4134c,aba2fead,39dbb555,29d70795,45a9488c), -S(d2127f38,8f3b4e7c,b0d24f80,27f27e55,fca1110,288a1c1f,da46441b,21327919,18f2b4b9,69df9a42,1a87cc43,47e2ab53,146d6b82,fe3c19ef,2df361bf,579cb3a0), -S(5e73dbe7,e8961e0e,32b9af6a,4443623c,cd3f992e,b024cd1a,59bfac9a,ad6c9f4f,4d8299bf,b505c0f4,5835cda0,b7fef2ac,640a5835,6a7e498c,b0f34480,34527405), -S(b9eae3f6,9af01cb5,48cd994,db6beee7,7e45fba3,782a9ba2,83b340e0,fa89bba1,b7ad76ae,189735b,f4ad8e8,dbeabe72,ed40b2ae,2c9351de,1beb1252,d4424b65)}, -{S(458f8dbf,9cef8cbc,5d2046c7,42ca6297,e8fc76a,ad22fd3,af4f9a8e,2173d857,57074c8f,14a36b5f,6924517,6e3dc7b6,4d12a08d,8d00565,e70e0ca1,56f29820), -S(68e7cdbe,47bb0fec,37fb7860,a71533f5,5eddfd2d,8ad7c9ef,cc266009,65c627a7,3bb96d5e,f0cf90ec,13614c2a,c46039e5,e6e30782,48f855ba,8f8bce36,f66b8a90), -S(c220e26b,6d3cdf7b,b1cf434,ec5fca6c,eaec952b,e61d213,16601ec,6e06b259,3fdfaceb,268183bb,9914c5ab,ae804206,a3711bc0,d649c407,82d3d2ce,93e350bd), -S(fc458625,75cc7343,312902d6,8e160a08,f82fdb0d,60df16e,575f893b,94592e52,e2236fb4,e6af3e39,4faaf83a,3c6b418,c560abf8,eca40f29,d3cb91e9,e13a8ab9), -S(7afc4446,f445a33a,64fcc04d,269529f4,1e16f567,550a8280,4027bf24,1d08e895,3ee4443d,2cb04a,3643f6ff,90c0b3da,a43c8333,82c62d6,5a024a68,e7e7f06d), -S(4cea2d22,d19a898e,fca4a7d7,499252bf,1957379d,a6004,df9c7df1,60dba4e0,c97fe09e,84024a28,ef88985,6fa1feaf,bee116db,a88962eb,36be946b,d2da76c2), -S(633cd50e,b00633ac,6d5b1bfc,89d97e24,abdd932a,ee9f265e,95dac73a,65627e0c,750ccac8,f09d9f86,7117781a,6b20ce6b,6a4bdcff,7ab04769,a8dcd1d2,c541bdcd), -S(20224a29,28ae9e78,87bf4242,67333b0f,fd59349a,2321b8b9,c28af552,c98fa7a4,94944b75,4b6a0ba4,7c647332,e9369b,dc57f98d,5a010925,4bf6d2a4,eeaf88e6), -S(29d9b1ac,7ad67ad5,ce2e965d,e7ddadeb,43bafd47,f0fef02b,2f553693,1f45029c,dfa93352,cf5dd7b8,3e5a9646,da2a3f3f,152372bf,285b75dd,1517e6f1,7859c03c), -S(54859abe,18867be1,dc85a087,4cc7237a,597bce13,866686d9,43e6bcac,ec4fe7f5,1d956ff9,31259641,1faa0b22,b2639487,d0392514,58c5eb8,7918fc2e,26916864), -S(9c3c1ee2,ad3fad0c,e5e6ad1b,9b1f5875,1ad30927,9aefb1d9,4e8f408,c3406d42,b31e5e91,18bbb027,f3ab9d42,ba1cf854,753dc66,641cb367,7e8db07a,4b7d4fa8), -S(c4e812d,5a640e68,70a42601,694341d3,5e964f04,fb52f1bb,819166a3,4fb8732d,f9494ed1,b776c04a,769308b7,4d312781,5f9c3d6d,c7ff4b17,cfa1fa31,87435938), -S(4f8fc5f6,cb4e73e2,e24b94dc,63aef340,b871abe9,2fb53525,ef0ac7c2,e04f571,d81880e1,b3d0c55c,8d28bb51,5f1a10cd,245fb5e3,70eca394,d80ba83,d7615512), -S(2223062d,f1572257,9330efcb,2c5a90f5,6d9c33f9,87ef9b9f,9c79db75,dfde7b49,8fbefa3f,37c855e3,ca3732f0,2d0c0c60,b73384a8,3458b05b,eb74da89,acd6c1f9), -S(cb3b77a1,defe7162,63ad33b3,5db0ffa2,e80d7,e00dae7a,91abeec0,17fb2a8f,29cafee4,8cda21fd,d692d241,2358b229,559d7b2a,c93e5eec,9e4e7386,728dcf62), -S(cb520a70,3b9abc62,9a039af8,ef7f8f50,fbaaa21d,721c1bf0,d2f680ac,56061581,58643940,fc79dda6,35b846c4,fdcab298,6a2969e0,16886e,93ba4532,cb03140e), -S(c1163c31,a922395c,7afb6fbf,19a848df,ff20dc1a,38f1c86d,89e6779,3c97473,8f4e7bff,a21a812b,ed0c00dc,55972ed,173bcd4c,36476bc6,70d5177d,73e539bf), -S(82a01624,64aca6ec,17abad94,4756cbb0,b27bbae7,120e3564,c1c83776,138a1e46,9eebe6a6,140227a3,15d7f23c,176cebcf,21f61112,86dcf337,21deffae,d701a856), -S(972acc1a,194b29c7,1d626053,34704ed,95201c9b,92e5bfa0,937b7369,dd389794,48ac34b,936ba87c,1a952b91,8a82f0f0,26ddf57c,2ea44cbe,d15f6ce0,da73a4c9), -S(11c28dfa,639403f9,f8283916,dd32194a,d116ec21,e56e6393,f743ccd1,1b1fa275,8a008459,24e50c2a,d3a713fd,53fe4998,86cfe86d,2f31b8a0,b2903a48,ec16b1ba), -S(d308b5fe,c8e87dea,6ff1917b,8b853701,7dd6a46f,97c268fe,7dd2a672,92ff3bad,83ccbd2e,82917e04,fe00fd3,cf837c0c,efc34a81,54c2f068,3fb079ac,3a1dcab4), -S(f4551b7f,aef3bda0,51ed6978,45d37d52,97a9ce9f,4b684334,fbac03ab,ad0ab7b5,7ac85f32,e5cc407c,5432ac50,ee015a7,e2fb3191,90d8855e,7c5ed488,ce5c6211), -S(23daae11,946de442,7934b351,a38df422,2f8f5424,b2dba51a,98548718,3c21d2ff,48dd1fc6,ef5ca525,88b21118,7c172792,ff9aba3,d18aab3a,19d9dc0a,d795763a), -S(1d225202,4bd2b32,87400ca3,e8de9bfc,366cea7d,c87007f0,e36d49ab,32f3d389,e711a6d0,692025ac,74755d2b,46c8ccf3,1824dac6,35a48cb1,af6fe2a,ba17f178), -S(b500c6e5,1111339,527ae172,11055236,912f7cfc,8e67c4ba,94dbf39b,3aa349f4,7a65e1ea,dda398f8,5da9f82,d5bff3df,41b92854,29994d8e,b9ad0fb8,ec9610bd), -S(135294b,236c6f34,478921c7,d463c14b,92da01b0,226b0bbf,bae7f392,fc1ab605,8f77291b,b39dda82,33e6e523,7d313f60,3bda29b3,4961a6d2,4e474397,2f6bc068), -S(1fc67f92,9f12d181,73e45951,eb64aa45,627d2fa6,61a2d35,25e818d4,3d4b2ebb,f4174ab5,dd5ccf0f,d6522310,20bca7dc,553fc88f,952007bb,b5012789,ae9d1bd1), -S(47ae7668,3654ec8,a3904f7b,dd02efb0,ae4c8489,7deffa8f,a71aab26,d82dbd52,1e20245,990a0f45,9368065f,edfc7d08,ffdde726,1c8f79eb,68adc042,de1bcd88), -S(750b52fd,7ded02cc,886c9105,8dc98545,67c8c62f,c7dcddcf,ba74e552,dd8343a8,2df52ef3,2d8f79f0,9423792,341ba29b,d78cbda3,252347bd,123fdf78,5ab9b8b9), -S(148870bc,fbdea326,62c20304,aa2d9edd,91de2474,433711f9,75e977e5,d3b9cf8d,a0848bf8,6cfe26d5,3c4a0960,97925a32,d296db69,d3348c7d,71f7d5df,223b3747), -S(ea916e64,4958c33b,1610c7c7,b865a315,eede0d2,4881b156,4bd234ee,e372be92,387af6d8,4e8beaa6,a4df0813,db45aab0,6612bc74,aaf4a292,5a838322,a18ff4dd), -S(1aa70a60,273c70ba,51ff5fdb,2037bc1f,5ff9e0ad,f2551fff,a2176bb9,757fb4f5,a578a726,53233bbe,fd34673e,4890e0b0,d2609bee,5fcae095,1fdd2711,b618954a), -S(a51395bb,6cf06cb9,b2898e7e,d39c1011,ea8e4539,cd3f5c17,4150ab6f,7b0f170f,50820591,ed76ec84,a0ea2b57,b11a10a3,d46f5b73,71a67016,f952c497,3cbdd83f), -S(c6d532c,a8745145,e005f8a0,82b57eea,a235d56c,4688d98e,5cd4a911,d0b381f8,fcd16c55,4a38f1a7,3f82ddef,a3dbfe97,7d554b37,e6b60727,4a37ca7d,28473b2), -S(c42dcb2e,169a5276,e0dd6195,3f7991d6,2d4e9459,5934dcd0,e4daa217,1f050bcf,9ea1f3bc,e274ba98,a38d76b8,1af87fb,4f760b1d,940a1ffa,fc6c8a32,59cbb197), -S(ae7ef14e,5f93dd3f,3ce400c6,c6944a2f,e14617ed,af42aa9e,dec2f269,fafa21b1,465a5540,e5a4349c,1ff0bb26,a660a935,373deb42,f16e900c,f66d638,38113dc4), -S(ffa64715,253ecee5,2ab8dd71,17100a64,936e7d19,3e8230c4,1d06c0f7,b516b91a,1bdb95d,631fa76d,1a8fe556,44c69cfa,b0997ab0,16b256c0,30a7ab5e,fb0de0fe), -S(def35473,ca162629,2f49c77c,2cba01fb,af7c94dd,8f9a21e1,9883901e,8305e3d8,68962e7a,aaceac89,1d5da447,40442b70,f2248b4a,b6b5bf03,f1e00a66,3b0378c), -S(52d2f036,925d466e,45b33be1,8d16ffd4,4b1d191e,10d0d72d,209ebc4a,3f8358c,88a7454f,260b9d74,28afdc59,1ebba74b,710c1b11,ecc755cd,ff482e0d,bd859719), -S(6ab19082,9a23767b,404d25f2,355fccb0,5625b6fe,88bfec66,409668a5,e5c0cf1d,85c26852,95550088,ac9ffd07,dfd972b,dc6f25e0,6509e9a7,92d59b2c,afe63ca3), -S(188dcd54,5c0859ae,6916c4c5,44f3ce1f,7f747007,a6a8d26f,5843f88a,8dbb6b79,9146ab39,c1ed37e4,557aa5aa,c557f874,bf47b4ed,2d2216c4,64b66572,50feffc4), -S(d6ede828,c35972b0,7105bfa,ce6396d4,12fdab87,19f93ad2,cde46a4,219b4faf,8316a8fb,2c30c3ae,88cf61fe,ab875c03,3254a2d2,e1c5eb70,24f83973,3db48b51), -S(a363f5dc,ab07afa1,bb0d93f3,df44f786,4f5f60aa,330afc5a,45368fe2,55df6097,a5839073,c4ebc180,50232a4,a6ce7e4e,b3ac6114,eebf3be5,b978e1fa,7218b660), -S(8ff6e368,f82040cb,9647c91f,7bbc75e1,7a163f0f,7c9295c3,e7901026,e4fcf2d5,fa8fc30e,8607708d,1e2fa7e2,6d4c13dc,3d560fef,c19cf1ed,5dabf5de,8ba890c8), -S(4dfb283f,fcc74939,60d239a4,d364d773,21f1426,b48f99a9,5572ee88,17ac59d2,a6561134,2c7559e8,8b180a59,a0708b97,9e9b381,a1541e0e,a7b6cfd5,b7aec1f0), -S(59c8a74b,ebcb88da,5b8cda4f,1af16c77,ce323f1b,1a9bea22,bbf8a38e,f5a8a6bb,9ec04d7b,e7d56114,f72c0fbd,b462332f,6f921765,93affd25,6a37ef5d,91eba83), -S(9b8dd571,edc71d3c,3337aafe,b3c33f8b,a1a35db9,fb071cd7,577fd5f6,f3a1d3f4,ce7249c1,e00c87db,1149e014,7c531efc,ad8bb3ff,75e51a52,318743bf,74bb84ee), -S(a410bd11,12ddb03,410eef03,ce8ea4ac,f1663660,c12c97de,bd4a2532,9ee2fced,4fa2da11,2c0f4a1f,5520ac16,7809d7e6,2faa8b9a,c442b84f,e2badf94,84368117), -S(6a78a5f8,eb495f28,dfec9329,6b026bcc,f88defff,ebdf4986,782cb546,332fc840,c90ada0f,24723e43,2a7aabc1,931954d4,cf60908d,38302255,a79231a7,93f02f86), -S(1126bde0,fdbf76fc,722bf379,43126763,a3a3fd6e,5f86e9c0,d5ed9eb3,7b9f29f0,d85252d9,ffd674ce,3d73ba20,49fb2b57,f1bb9073,daab3d2b,79bbeb,11bec42d), -S(ecd869b6,4057202,af53378f,a9e57c86,949b2b78,8034656f,912371f4,e5f122ae,cd94268e,b999b0f8,baa47cc7,d84b78c3,4817cfbf,43594655,2a138d8a,7c75b201), -S(deddc4ac,6aaf1649,b69dab89,7650fbd8,f4eda196,ec973025,7bd24cdc,7df2a94e,bd6d69b2,fb809b58,95812ad6,d1a4b029,f3861c52,4fde59f5,ab72a378,8bde28a), -S(4305fccf,95196da2,1aa49916,601b4f00,97e0b145,93e7a6ed,967768a5,836750c2,b997bcf,cc942007,c6b30a6f,a4f8ac41,52b92f52,fb9a3561,2015e846,4e4c4a8d), -S(c6235374,bcf2ad2c,6ec1e9a5,55080ab2,3765f1bb,892991fa,6df94a32,ac0ee35,e878dfc1,7a210fd2,ef572fb8,3ba9c4c7,b7d67dac,446a7066,ae0fac29,1b326401), -S(de7be4ea,50937662,a22a85ec,b2cb6f64,eff08302,13456045,e86d459c,1d36cfe7,b6beae42,d2d26eaa,20ea9941,e7ac5b88,d13e35a6,ac457f39,b80382e0,1c1fcbc1), -S(83faaa90,c129b256,736d231a,aaeb56c,851cd0b8,8a32066e,1587fe71,3d26e7c5,d5aa97c2,9eddce7b,58f9d96b,10a2fde7,4c1ec756,d30cd5d,bac03a2f,f4f5af16), -S(3ea3ac7f,976f5a3e,81cf5ea4,4325c73d,8fdfc7b2,57512f70,236abafe,925c1d94,edcbdef8,de65f541,9c5dfd7a,6b1e03ea,5b15803b,161a403c,8775e29b,7a64f3a1), -S(9a51b8a4,5bbce94d,8ce04cf5,dfe4bb76,cc8eb592,9aba8964,1ec58e,9d979461,661bbf31,86f36500,d45bc5b6,58071b27,9b3d327a,a86108ae,790f1065,dd45780d), -S(a3c3005b,5df20d43,411dbe7a,3daf352c,c43b8a87,564a9891,c237b7b6,2a485369,20603c49,2c90c32b,616fecf,286a13f5,213402a0,c0f8d64,e2a39b2b,bfa978df), -S(8685133d,3f0b48e3,fffc28f7,ece3b6f5,2789d948,68107d3a,4cd380ea,a00040f7,4b07a1a0,91f3fe2b,272d594,9336ff7f,d88d758e,d7c157eb,5e9efc65,4bc52c2), -S(f4512104,eba12a54,aa6d497f,59a256a0,ff1eac53,573c2ad,e480684a,99635bc8,538b015c,a96decb7,ba0ce9fd,b14393a6,7825205b,ff2c712,1f96d27a,3beb83ec), -S(709fd8b7,1795cc61,892ef282,10049b56,28f1b6ab,e5ba9a5f,285777f4,320d88c0,4a742056,abf637d7,e9b75e1f,938778fd,4117f87c,7699a67a,1c08e3ac,a2275622), -S(68a4a2c2,c222513d,b7aadee8,3d05a13c,9ae4c422,6d8ccffb,f6b6b88f,f59bce44,706c2374,afa7cb27,8a95d8bd,6aa98533,ea7fc003,33678c38,65153006,3589db2f), -S(38bfc02c,3430c92d,958b80fc,ba196f4d,9c4656c4,3f667cef,1ce0726f,d6be250f,a05c4f47,7b44a3ee,aa21107b,3a679db2,5aaa738,c474436a,c7dee4a2,228fd940), -S(c2e84b8e,f4380fe0,a674f5bf,3c55d3f9,3b060e08,6b207344,923f28c7,b7935fb7,bf1a2c1d,677595f2,33ae6530,d3bc151d,6b33294f,57d3ac23,78749450,6a0a189), -S(4425f7db,6cf56461,147ca518,732f101a,39c7f585,b5ff88f0,43ba3e3e,a47bb597,4ff5698b,88fa8489,b08c4094,3cda74ab,b5801911,d36232f5,9b358d12,193b3d9c), -S(98c57e63,521541b8,acbbd5c,f568b1f5,d3cd74bb,c30562c0,12518cf,96617e48,f49e42f0,8c236a61,e08d2d86,ec245822,64117ccf,6edb80df,403bf084,6e25aea9), -S(dbf6760b,351925ec,dc6976af,97a088cc,63115fa8,5fde9763,e1524c1e,ce901cc7,909d7429,73923501,e69d1bf9,ba1ad177,f99da741,560af1ab,9cd07e80,7b4f5f8a), -S(b42ef95c,79d167e0,6e29a6ce,ffb76ab5,c96f7455,21f128bd,faccb108,d7f2a609,6a3374a2,5edac6d3,744eb2d6,f39a94f5,44f852f4,779f2a98,6f1de5e3,fd729323), -S(a1034444,997dba07,20de1194,c355a1e5,ce182420,b19033c,ed68dc08,fcc2507e,b2cb95f5,d58044f2,36088bde,cf0d3af7,fe9b10d1,aef8f355,b688c68f,18829bcc), -S(47e80598,1a97f80,fd0f1a14,12d0d1e1,33d7e4fb,bda4c1b6,1dfea483,3589a59a,d33bdc2b,30d0c301,bf85e5c2,c364f1b6,f88b83c4,9e51c9a4,22229b82,10471443), -S(a355147f,281d4518,f36bc6ac,820478a1,6f0a1f50,bef72be6,aa53d420,3dff20df,627a5765,41031765,c3751c39,e9217493,f9da1927,b496eedd,8466709c,4a47a0a9), -S(b02ce0ed,6196748f,cbbc3809,7ec6e7d7,80186023,cf96239,e5a79834,4edcd3eb,f6cbeb1b,2b0b17b8,b620b799,14810a4c,8c47e404,89573b08,ccf826f8,7d8656a5), -S(87aca9d6,450aa411,8f56176b,49646304,dfd5d3dd,84f4508c,3a4617d1,92843418,82a93bd4,b6e4e426,27404ef1,7d837656,e0f876e9,1bb4b9b2,89e678d5,a430bbc6), -S(1dbe7199,bd248d19,5531ef66,260096a1,9614fb65,e90c2f5a,49ce3056,2cc60f29,ea49e29d,60082d51,7a807196,33c55ebf,f243a2d6,254ad322,8d614943,d19a5828), -S(a16909ba,d4fec20a,8b6ade2f,8ba3cfc1,d347812,f35b96b7,9b2910b9,de4e7ea0,496f1a32,3593a23d,ffb5f0c8,d9b599cc,18e101e4,215fe501,41147e07,6ce86a8c), -S(56e18008,832f45c5,30b819d4,a84416f6,db9b952f,84478dd9,243a293e,2d576867,16399c95,8ce72e9a,b2a3b2ed,becc8f5d,c220e632,60a1cc9c,57db3a4c,12e1943c), -S(d32b7ba3,d0af5b68,21d7d716,6f7d827d,f67c2f02,8510ab10,31e4ae6c,2beff031,8b1cadde,54e84e5e,5a0cfe29,a838865f,9dba3867,85016145,e9f81478,a6a20ddb), -S(55e603a3,8081a476,f37d73b7,645f3de3,9db27208,e0d1574d,99a7350e,95c76631,a9c50870,a3fe9f7b,da389eac,963e26f7,51a6f289,351025f1,b621d611,8b5872e5), -S(d8c1fd0b,a561bb0,3d44e9ca,33850198,3163f44a,5d6f3b71,118283e9,bc3c4feb,ef835785,9bee101b,dfbc2cad,7af7b10d,a777e78c,ee9277a0,ba29fba6,d9ee0568), -S(1bcec745,f89f938b,466bf429,3ccddd5c,c8566c9,2ccc25d3,a1cba363,b65bbb2f,b344f901,cd6317f,b4380012,d6fa9caf,64a5f75a,b4347f14,a227ea5d,bbbf2023), -S(8e9825f4,af70c5d8,15dbd92a,148cd259,30372bf5,f86d2a02,e700b156,812cc9ba,3290e56f,6876100f,6e20db9a,723bf99b,72a7be04,a3162d62,386abacb,ba377a80), -S(2581a86b,bd224745,a6518042,add5a63f,b640efad,191ecfa7,a582503,6c5797ad,4f08900b,e4e1abea,63c9fd36,c6939bb6,dc91f066,88ae9318,5049332c,be32e994), -S(d32004b3,48c65b67,80891f3d,7ef8c029,1cfba007,1cf03f18,c0b97cf9,bca71bfa,256a990,7442d77c,a1e3cfae,48a8230e,a03c0889,29c12275,994ab662,e9beb3d), -S(7b6724a5,a0090968,311ea2bd,d3ecb7e7,c7246bbf,b6a0793f,599a2146,faeab5ea,48a676,fe3a185b,cc6f7188,86bd7064,3ec7d20e,ff94b8a3,c1953b3e,a2f8db4a), -S(83d6737f,fee8bd73,eb4beda0,1916f875,85d9fc78,2f726243,f31a2289,456deee2,1d28e79c,c010e982,9a94adc8,35022da4,e9dc67aa,ae5751af,64c53f13,afed61e9), -S(472bd739,ece53ef4,12979f4a,89b6bb45,fad8b374,14478a14,afd13a57,3c315cf,27698c4d,861e5cca,831112cd,449980ec,1d81bef,6a396b6b,fa0da65e,ab164dcb), -S(8ea8e81b,22657ed,51bc721f,2f7956ff,fddab5b5,c703415f,ddeb524a,16123765,a301e8f8,67b1038e,56964048,2dfd39aa,9ba6cf7b,773df76e,eeb46882,2a229c7e), -S(1f931775,2da7d946,b6d9ed47,75ac74cd,6029531f,27487c1b,cfd2ab3b,faa7f6ff,37277158,e6b5c0de,5436191c,1ad8f944,7b316876,ae519306,f28a3606,ec8db8f7), -S(2a6aa0b1,106ddbf8,dceb8988,cfb33c82,4d55af5c,670d1e77,873f4a,ce74f4fc,889e4d41,b885fa99,21b66aed,83f46883,ec6cdddd,67a0ca45,dd12ed1e,ee6ad292), -S(9ff77e8,ce5259d8,58431c69,bf001dbf,fecfa5f0,bc356057,eed7543d,13486274,b8f0037c,c9c3b771,dd6b18e9,95be0ca1,23daf9ca,5bddbb35,a609811c,cd1ced95), -S(7a9b1d0b,a3f1414c,1ab3054e,f9c2fd5c,ebdc1931,ef670d1c,78db9549,6b1af514,a2407af2,ceaa367f,d6d4d733,49d77a2b,993062f3,d6ca8e0f,89d21eb,beab2b93), -S(37de2b08,4bcb4b22,e4643fb8,5f777b48,944a2351,88036c45,793d2d81,c984ee5a,c788ecf5,3900585a,a4226825,f89f9ef2,8cd25d37,565adb3c,a61e1c0c,ce4bf1ed), -S(6c3236dd,a08f2a08,9694f01,a4864dd5,d5ac105c,8c7cbc5f,7d2060fc,b4e8519b,2472d89,10106497,6ac425c0,43714ad7,d5ec4f66,fcd50af4,abcd690b,d219971c), -S(7c0038b9,2f2a96ca,115a853a,557be238,146eb196,8e7b8e88,4801a56a,fc8976d6,d68bd242,5586cc14,49fbe019,deab8a9,97a56dd5,f52b02c1,24e7b8b,141525f0), -S(24449d21,51eec6d2,49d6b613,d1b03e29,3b36185b,ecd95bf1,a52cdeed,890afc8d,3929bfa1,d9648c49,aa4144c9,584424df,895622c8,9a7a37a9,8462bddf,ecde7a2), -S(640d6b44,2c5e0388,7ea7c4ea,17ad3e5,977dfe97,907200a6,a43fb6f7,73848db9,db3d21e8,237ffa32,8d389e4,d93f33e3,cb75ab12,dea034c2,83b5a3a8,c7169b1a), -S(d2372e52,bc1d97b,8ccda950,37148f3c,1516d519,b171a9e3,6a3e87ca,619a52e2,21331dec,da625e2f,7330888,a31be425,9f69f49b,47e38e9f,85eba5b6,fdf4094b), -S(7143910b,fba2abd3,d2e7d7d8,f7c67344,581afa60,cd82827e,547de354,e5299a76,1965b472,4873bb50,c2b55cdd,dbefeb1c,e184d9cf,97ac9142,a49bbfdb,37e4669f), -S(275557d5,46e5acae,1ae98537,8d787b51,73b260a0,57e8b884,7bfbbe2,d15d5555,ca93b2ff,79544d54,8a784fcc,52fc30c0,49337a19,2b88533c,550432c2,6555e47b), -S(290231be,bf6b01e5,7904e066,5b1265d,ef4debb9,d14865b8,75341d98,de3ea5c9,acd3bcca,8ad8ca8c,b7a43edc,69fe9746,50d63593,71dc4d6b,a76e0c1b,bbf41cd), -S(93db5e11,7fe021e2,ca71621,29087cfe,93a2ecf2,560b6c0a,91044253,3dd4e351,11d18431,959d1dd4,8227844f,251a9c4a,134523a3,cc8c175c,f3f509d5,9da8d869), -S(8d346bf2,d4bae98e,ab44629d,720680bd,610f61b,32f6c109,9ef48434,6e3642cc,ab9975d6,3d4dc8e8,e90f2413,e93b2ad,e15f848e,7589451c,a7b735d9,c45f0a56), -S(6d7e8457,c1ac7255,c612d8c,99a1e850,d95d9058,113b852a,4ff0513e,e83e4f06,cade7182,8f92acab,a7d5ad5a,65fd84bc,15c57af4,499607b7,dcdd8c1b,20d75cc1), -S(23a703e2,540ba5d8,dfd5c7bd,183be8b8,a2ac028c,c51806ab,8ce1874c,5f66eaaa,5153dc37,e939eaba,35caeeee,ead1f666,ad62e15a,2f078b42,15cdc33,3372e839), -S(2ecada78,339caa89,a3baa456,15cd0040,9e7e7f4f,15fd5f02,665d5674,3ff48a7c,b2110739,2dea146c,2df5856c,aeed7577,a6bcced1,cddc56b,68462f0,f7999d5a), -S(2516768b,6d6ed0f8,9550c2a7,7167e0cd,34d10a24,7bc10f4,9c7ff55a,650bda2b,f363a634,be194643,68957ff8,2e329184,f2a6982e,51d4cc58,ec24cfbe,f0e6f95a), -S(c958904,ec9c6ddc,37f16d48,b56c74f8,64c547a1,c001e2a8,fadf0a3e,7069ea47,2dcfe201,8111bccb,29ef1f45,827d2b4a,753afd51,ed9927cc,395057df,7591bea), -S(c82c9164,9760ba4b,bed19bf6,a2323fa8,c61ca2d2,d27f70a3,b5798d10,c33eb5d2,531d2f00,be4f3c9a,1c08079b,b7aea0b,c78fd8e,30f5e2e9,27f465f,b814938a), -S(73d756a8,f79d7da7,362dd79c,5c0c3226,45e6d6f7,fe43234,1f6d7208,b9e9f5e2,2a80441e,c1b321e6,3ea1f341,838ff513,ec05a23f,e42b73e3,6dfb4a41,b96580a4), -S(78921b3b,ccd1d7b5,ac721e44,b5c6c8e8,371ae531,d36576b5,464b1fa6,6a3921d9,ade914f6,8802342d,93413c4f,8b67d343,d79252a6,d023f712,9e464e7,111e3044), -S(63ad2efc,c1e11521,139528c1,be3af253,ccbb4f8c,af95b00a,7a6467c4,d682f126,29b54282,c8718452,7ae954c0,1039c1f4,ac7953f0,5250b6be,47cc0b2f,69cbf28f), -S(448bd0fb,d7b22662,d6680a1d,57d81a21,a54256c9,d0a882d2,ed5c6f6a,e1e5cfb8,ce23a4b8,cbf12323,ccd55287,e5c68cf9,751ed0a9,1ad563fd,35688ee9,8c526d46), -S(ad41c647,5145c360,fbf6579,8a54ca90,7fbc9b70,a9323501,8ecc6a43,3ee564bb,c1830237,87a2872c,2884ebd1,f1ae7a1f,8e96ab7,99d1dcbe,eb39e68d,796a5659), -S(65b45a74,13b2e78d,20d1476f,c21ad4b3,2807b174,19eb89b3,fc799f92,7cae5a82,11aed89c,d5bfbc7a,9138885d,f64a38e4,d46a270b,ada85cc8,3a3ed7d7,65015331), -S(5e7db226,92f3d7f2,da0811a7,d0aa0d4f,6adb5651,3ac6a386,7c0cea91,ab212b01,d8250eaa,46275c9b,71f43f6e,cffb063,7b90a827,bc89f513,e769dc00,d5e28150), -S(37fb22a4,7feaec72,7db1d62e,390e7b8c,ed1d20e9,7f934137,1d5276bf,5c1110b0,9a537c0c,8da9c43a,6b7924e5,a6b29e9,17ae9e25,e8afa6fe,926ba053,f591c090), -S(4ec7c867,aff4fa7d,ade9777e,2d4a0793,fe1a1ecc,fa4765b5,aff9064d,98f16a50,433ec3e0,57138a6a,cf7ea45c,f2a91041,2e356c0c,751bb535,1856e37d,295143dd), -S(85b5685a,8e784360,dd1eb47a,9805165c,bf77dc81,56c93b68,54766ad3,87cfbcd5,b866861a,6da7efa1,fd3d5360,2b94daff,c0cbd09d,5707f3c2,b47d76e6,2f2037ec), -S(3a390af9,11caff4e,76bf870d,972465ee,f6f8da0d,c7232add,5ae9dd87,32be2269,f5052db7,7f43411f,ac6553c1,3d930945,a8833641,8af417e4,5033a8d1,a1a52c90), -S(44d40682,4608651c,4fb418ce,99391d55,6d93b631,d489f92e,fbbd56a9,c49736f2,1461465,fed84aa3,ebfc39b2,c1cbd1fd,b7472c43,5c9034e2,82d59c34,9dae7cd4), -S(9aa43d73,41ceef39,1b1bfb31,f620c39a,434e5235,2c14c28,8a50490b,9c62295,ad6272c5,19439e27,5a1c94c5,b3940b23,956d2656,d9870163,17e57d99,3d18b2), -S(1a5d114f,d0bda301,e76f3721,ff1e06ae,fb40cf85,b16c5dc8,a9bdce20,6ac8bb80,cd57ee40,1f4203f3,e1875926,199fab9d,9102a3fa,c851822b,a5bc489,6e1c7cc8), -S(711c1d24,299032bc,f2959c63,8139ae5b,b528b56f,e1a1b829,f7b8afbd,e2effc8c,98bdc11e,d2ec73b5,532332fc,478ab4ec,65626bdf,85287f8e,dbf1d8b0,5f163450), -S(3dc0955b,86e2d6d7,49bbc95f,2760978e,fda7483d,1f3b07c0,7d97ffb6,6961b0ed,f4af5628,d74d3fa1,daa5c072,9c1ad396,1b0792c1,b6fbd235,64debbf8,86d3051), -S(9cafea3,411e251a,8776e3b0,72f11229,8a23125a,5bd995a9,a4655031,9907df23,743b8ad7,ebcb4eb4,9469225a,7a2ee594,bd534c16,a8dd68d3,a58373ca,85f2b01c), -S(faddddfd,96d20fe,ec2b0c84,8ea7e6fb,f89dffa9,efadf475,6eedc815,b61a404c,ebc560c8,253927f5,a928584e,8e87b950,dfe26bd6,d37b739f,b0e9163d,c6312c8), -S(b539be0f,8ed02ba,f7787d73,df02e1bd,3210b88f,df1dfba7,a0138713,8a2d5a8d,e0271fef,2d0581fa,5ca30caa,8a101711,341d4221,b6b0a7ed,776ce399,e370561d), -S(5e3634d9,b7ff4279,3685022f,d3165c03,2ef8ed0b,c8a7d02b,685ab5ba,8557ac03,565b3913,355bb664,12225097,4e33e9ac,27cd38ed,a804824b,83985011,60f44200), -S(609ad796,d50d20e9,9cbe6ec,650eba26,ceee3c56,a6889917,44deafab,6a7a5904,54f9351d,9aa7d0db,822788be,bb1cc2eb,3300c144,1c7a4c01,230b47f3,7e67a9a8), -S(6ed020f1,fe8d7e4,73812756,3325e0c3,290b9a5e,d2723929,584f177d,4d9d429c,a1e48a25,b02ba024,eadde7e0,ea82c900,cb297d2e,b550c289,d664d4a4,b9b85edd), -S(5083663a,afe468d4,ec901e5a,14d2593c,b28c5948,1fdbca52,347d6aeb,4b7ce960,6aa5586,7467c6a5,dfc41278,c855727f,7a8b4168,98bdebd1,f9c6a918,a1d31aad), -S(e1c334c9,e355ae43,7e48335e,691a2aaa,64c3bf7a,16c77810,6bfff582,2a324df8,4603f15a,d7c85327,15502c35,cbe0ec58,e4ba8ac3,d038c4d3,ee3b4b77,74a13c07), -S(8c51fc03,ca1ed69b,4b627be3,3a7943fe,e1c15c47,ff7bc83,89961e40,6552907e,2a51ee78,7d48f8e2,53e82deb,a07083eb,b9513615,7f2a796b,c040b1d0,7582033), -S(4711e429,d9cd2b6,e539eb68,884d2a97,375c2cbf,fb30d6b4,1718eca8,9f3fa41c,ce826e2,711b6e6e,9a487a8,4ae72f80,a5308c21,1db0ecf5,706abe6,6b0565a1), -S(277440ea,ae6a1839,6f72ace2,c5cbc75a,41866c7c,c761bf3b,7bbcda07,ef5558a3,345f1584,9e4ef4b7,31964dbc,f9f899f1,def99279,ac2acbaf,3d1eeef1,bfd0685), -S(b9d1ebcb,91db7845,426accc3,578ec4d1,6df30fd2,9650b47,5c154d65,7a23bd5a,ea0ca814,399a76b9,5107501a,40ef0206,ddb1e9f,4933399e,35db6385,3dd2cb2e), -S(29c07ab6,e703dfe2,896985d,4d894d5e,5b793b6b,7ef2f5f6,dba00348,a8882fa3,7565e4e8,4b5485e1,661bb0ab,4b672cd2,5e9d58d6,48049ac6,8f2457e1,98b04a8f), -S(b9d17c46,9733963a,2f20626a,ef4f2184,6da791b,5e63194c,128432f5,58ccc682,5dcad0d8,7e08bfad,43e55633,3403f5b0,76482dae,d731e01e,3284c945,7c6eacee), -S(961e90a2,904e80f,1be65717,a0401722,6821876f,fecfa598,b216b04c,b4645c8e,5ab0efab,7112254f,722d021,a4da595c,99429a1a,5b242b1b,9243a8e2,54acd804), -S(40865cb6,f002104a,54a45d9d,da84e6a8,f98a3bd8,364275ba,4e14554e,2438f6f4,5b822fda,eb719e33,75309c75,b7c115af,351de484,98867a13,6b1fffb3,1e277d7b), -S(5efc3d76,307a2cbd,34e7d009,92263a44,c4e76e50,f1c213fe,b7fd6ed2,342f1a08,40bcc04b,cb227f3e,3cac4a7f,446bad6,6a304df5,a4128bd5,46f9f40d,a3e12f46), -S(13caf790,6a97e5ae,6f674956,c1586c67,57d3d56f,3d18d522,c4f365ed,97b54e87,156a85ca,74541ff2,9489b562,28324549,5cc42397,c54792e,2ba485b4,a86bb65b), -S(657e9dec,84a9120a,308a5235,6555c56d,6c1c98f1,cd946480,def7913,7e50f7fc,600ce754,7d74b757,c1e371c4,73401734,8fd6dbb3,72019f10,bcb4f4c0,bab1614b), -S(fec2b1d6,ab46c020,ed672687,7f2ec85c,214f36bf,149b2c1b,e75ae29c,54050071,3ec9964,20d9954e,edd8848b,c439fce5,740ddb41,c404c52b,f76865fb,26c48b8), -S(bafc595,37308fb3,c691f1e2,45908e92,776d76df,f6af7002,c581afff,320a4abd,2d8b8ef1,aab42751,27d0ba95,dedd27a0,29951664,e7ab9d54,b3a4a24c,faa3e386), -S(927cdbe3,2c1d78a1,89a4e3df,4ce6661f,149d7e16,d0cc7dbf,c287e492,891540c,e46911dd,cdcd70a9,f99f6892,18899fd,d3ff666,ae4533f6,dcfb441f,2b7da62d), -S(b443d061,1ea3a164,2e31195d,111bdb01,b6a3999b,e4377780,e19c3614,c0d7092c,e95b7ecb,e196c667,a19dbd2e,ff0115ff,9f0ce1a6,7f44d20a,a47d2990,e6b48c64), -S(e1836c7f,8b7dd235,f6af1b89,b7a13ad7,22dbad8a,78b1b37e,f6e5ff5,a6bc992a,57b02ceb,713319e6,9ebd7e6,844f374c,5871a792,e2109eae,d2cb5222,6c314e8d), -S(9f661b3b,c5829c51,2fc613a5,ad8aadb7,5c78edb9,9b84de7,683c6de9,d2a93f78,70e14e0e,558e94ac,aabb847d,3acde465,14c13177,45d45226,b6ca9911,f23ecd6d), -S(e835b453,6f13ae6e,7103137,bb695ed9,4d07507e,9fee8f9c,af661e9c,1525d3e4,192463e0,f1111a94,9f6236d3,1c0d6620,af9e0a3d,1f13f83e,7c4adaaa,76c81953), -S(a29fe97a,2ecbc4d4,f7156ae9,d6bfef6,ef601e26,4f92a115,48b5cd26,7cb26b3d,23b7d6a,15681341,6e1b8fb2,cebcbcb9,698d245f,b920f8eb,3d6b46d8,9cd25cbf), -S(396cf745,6127f3,31ca0fb4,95d98b32,7a738a69,260f7345,9eb79f0f,edc6a7b8,31b6ff3c,26879dde,6ebc9873,22a32b10,e283a256,1c1a65d1,928d3e02,de2505f8), -S(d1bd75ac,c37a3119,8f768b38,f665039,7d2f331a,32018a66,526058bc,aab440c5,5c17fcc5,b8e2500a,4edc3cef,ced52f2d,e20e7c41,bce4fead,8e12a880,aab8a185), -S(de72076,62274020,1791b51b,39fdf2e,297b7c2d,d358ac3c,375dae4a,494df54,d33d439,d4508520,6021c95b,cb1b22ba,b1595800,54056f86,82d73580,c50692e5), -S(958e9c41,4b096f8b,2d1ba41e,f5142a17,339cf57d,689d7d13,dcc22355,91418331,628b63d1,4e4cb154,a31d9752,9e50a1dc,f2684b40,47c27c39,bd54a0ff,dca06ed7), -S(38bae438,9a283e43,283d6a06,94e7ba16,b026dd59,3b505a09,6ee0f67f,eaaff536,9fb69e6c,73b27204,30968157,d5782423,cd4b7809,f09f280,93f5964e,6c06b170), -S(d620240,753af5bf,f1719165,f9d8116d,54c97a2b,5f99b7a8,97eea7c0,428dd1b5,66cd4f98,1b037f95,eeca433d,71d37fb8,b4a53f9e,853943a,ee0f5254,e42d89ec), -S(7de22847,c93ed32,6ff056f6,a002a7d7,e5d13361,e2580ef,d2cb682f,28e6ab96,c40be4d2,1273633a,e0ea9448,4bbf29e4,2b9bd775,b77802fd,31167d50,76a9b34e), -S(df0b50b6,679ed759,35883080,ac9196e9,ba5844b6,d9e541e2,bedb7693,c7af37c3,f09fe7aa,bb08fa37,aa5413f5,e17dc1e2,a07f83e7,4aaf160d,ad3ead56,1509e152), -S(578581fc,184af60f,80d648a6,97ab999d,f5ddec3e,b6046528,b9fc6233,7de81fc3,552be39,a8587bfb,d8de2f2f,6b923fde,20c7ee70,3a1c0c09,12ae85b7,56495ed4), -S(cca6a75a,131b5389,b2f8ae71,7d1a9f5,2258d3f0,4ed22b2,c836f7ce,3035def8,1787070,1bff0d8c,b74f5f95,1c6e011,f4e682f2,5d744f98,4c351b64,59669a4e), -S(6f81f602,b2054706,4a7c7b12,d5f13022,8657a77,e0bd1669,ed1541a4,b8eaf068,6ff959d0,1288bbb3,eb7a59b3,2eaa8945,8e4c6754,2a9bba0,668bf14a,ebb308ee), -S(90725203,94d2fb81,59e2ce17,5fb27da,7239f36f,61c70250,78a69c12,27fc0cd0,34a471f6,eb168b59,4a6a53ab,b93bad33,7da670e1,8bdd1eda,53b34849,94c21abf), -S(4e952fb8,b5e484b6,4ce1c1,c66e94de,3bb3a64f,26585c03,969e834b,291e597b,f7910643,47cbaa3a,e88dd796,ddac4794,c6500c76,147a26f9,c8f596b5,50da9961), -S(1985193,527e87ab,5b7dd218,718486f,1ed4b7f1,a444ee6f,21f273cb,901aa0f3,b067191e,df69ed50,b0771d24,2d99c8c7,22f1bfcc,bef31bb2,8d245f3f,b0acd3e5), -S(5dae1881,7a2bbb01,23561907,a22445,78e4dfa3,c6373f21,efe3f159,58abb5f8,7c6bd578,301ea8ab,f2b555c,66420c77,b84c6959,f96938af,eff54db5,4014d51a), -S(96a46ff6,e78bb2f0,4b299985,6d56310b,4df9702d,7306b30d,cdc7ca4e,68114e77,3f871bf5,d3a4ee91,17653bb8,5a98e599,d86ae580,17e8963b,9b18400c,979994d9), -S(31482d19,6ce07585,bc1268cc,a355df50,b9009f17,fa1e4f39,9876fe2b,51eb361d,50dfcba3,ce43896,1fc51f06,5ac4e58a,4757e75f,419a9525,5263830f,fb936e9d), -S(94c128e9,6d36f7f9,540da468,a2fd488c,ad615f6f,7920b201,27311941,db6e2405,595f29f0,f9622e32,b62e3ead,9f9ac21e,d07d7c07,7bba623,6c7e57cb,747da989), -S(a16882ec,b52def37,227e2990,3dc15e4,d4bf10ca,1b1adf31,c9cace43,348182bc,53f6d3d,6dd5603c,2f2bc7ab,677a6133,c138e26e,c030ee9e,705ce002,62e11f5c), -S(f0f5ef2f,f0f63cc6,fb7b3d99,6a5b14df,99a53a45,3a1fa425,3ff3ce71,4168cbe0,598b5ce,44e168c3,bef06c4b,c032924a,da454c75,b53d17cf,cdc2ea7d,93e3b883), -S(3aceda5f,190d83bf,f5111acc,d57d4d2c,5b7692bc,62f480b9,f5cd539a,b2ef0c1a,5b8f973a,16151dee,92930702,f3bc7f1b,93a096a5,ca4ff3e4,8a41bdcb,f78ba60c), -S(4e1eb580,b3e3bcd4,4b2905a0,d07d7334,befcca94,c7cbf639,1710948,cf2e66b3,c1d6ad62,c10bec2c,127446d5,34863682,196ce8f,4a966319,2be7764a,46e733d8), -S(322fa340,76bee9e1,697206c8,38cdbbd3,d54c3a30,82c22b3f,1ae17da9,a9047856,c4493e49,b5cb97d,eab7ccae,8f1547c5,98e286b,5e7301de,cd50656f,25dfc1ca), -S(4aaf3569,2b080f70,aafe6374,f0007570,d23fb620,cbb60a43,305f5e3f,29e9d189,1dc30c11,91f985c3,39bc8592,8390bc0a,c99d3efa,98f4bfd7,df2f86cf,7c297dca), -S(c18629a7,17d1b01e,e2f4bc72,2c86fc26,878884d9,a770b62e,d7167f83,631ff2b6,3438211e,bd80ab41,dcd4e76e,c742aa3c,1c859cb9,1fe0960f,eb0dc74e,d119a7e6), -S(239f97ee,44d77679,7a91a196,82c9064d,4552b4a5,33033377,6dd74ae2,fdef44db,dbf917e,c66d0b04,a0bd607d,6448a678,1821933d,26d51865,35d3d587,ea680a96), -S(c0fde604,387fa85e,5c5cba98,346042db,83a64e6f,103d7448,22b6298c,98bc7100,28ad14a8,30b7be30,58ce8e09,7fdbc87e,a3c60b3e,840ad9fa,a7cad01d,b83a15ac), -S(95ec759a,5526cd4e,eb9d00c6,9702dd89,3ae115fa,de3629c6,5fcf5134,2f389355,2f899643,711c5f72,8fb442aa,59139fa3,b1b0b4a8,ce75ba07,67aa958,eca943b1), -S(7da3bc4e,867885e8,febb8c6a,e5da50e4,55fa749c,adbc5800,1b70ebc6,96ee9b89,dd989b8,c4bc42e5,8b41fcac,bc1e1f17,bb77aefb,964bfe45,fbae0843,6dec8cc2), -S(120fc1d6,12db86b9,f352582c,e2761ad9,8a29444c,c438e2f3,5f523d83,e2bc3d,437828d4,5357a2cb,ffad57f,f991e91e,83466aef,584dd7b,a3b24d9,31eb6cb2), -S(50e42888,366a1fe2,83cb22d3,df324d3e,e52f58bd,26bdd4c9,67575f7a,5adc380b,2fdd99e8,427f9b30,1e132beb,3e0fbb43,8e6ffa8b,147c825b,e4453fbc,1318e015), -S(275dbcf6,ab238c94,740100b4,29356528,69de76a,9d84d7b4,9b88d526,9b8d5339,90e835b0,f20a7177,936c5717,fc18d0a0,28a31e65,53c32be2,699ae03f,6ef2807d), -S(59d174a2,bb918007,f3e044b2,7acf5e6,8264d529,cae342e3,fed00475,d95b86c8,dabbd87c,b49bd118,a663a848,2f7b1c51,9fcb0fcb,48f2f966,7a13ab2c,ab122860), -S(f8926a6d,5d824029,8f572847,6439f60f,528cded2,2849f182,e173f84c,cb75e1fc,8c641986,c4fb6a7,acea7627,e4f6872,26f86de0,a2160a63,1b2e1a26,9fa5f6b6), -S(d765faa2,b9cdc6c1,d9f070f5,4fe286c0,60351c66,c7a241bc,94d10e4c,7287e7ae,ff732ad8,fa7f0c3a,9ced3ffc,f5bec9e5,2d1600eb,4ce4d781,20481559,82c30ec4), -S(bc83f94c,7be686df,9caff340,35c6e393,1fc2a33d,7a09fe0,b5d09e64,a0610dc5,772d167,e762b3bc,df68c291,656a4259,cda67486,e430c7f5,492c66b4,b3e61fb1), -S(5a8b0422,21313e22,c5a2cb24,ec6199fc,a4e95da4,d5f59629,ca33f4e1,419d5626,2f609bb8,966ba692,84fb6854,5dff5b2d,f1463504,5bbfb145,4fbf40df,c9884fd8), -S(b106e89c,b4da505b,912da09c,44f42d11,a2de8836,28623cf5,7f27742c,a3852a97,90ed9bae,78ce94c5,5e4e971e,16013f9e,6902838a,f7f851fd,100c8e64,babdaba8), -S(c55445eb,439db24f,deaeb4a3,5a71ac1c,8915b051,350d4007,15cb9d70,2319b0da,98b517e0,32c9a963,f22e25d6,f3306f91,a4b604b9,6591729e,64b73794,55d0137c), -S(f05845b4,5f975462,e1051499,d8189cba,89bbd435,6ca3ba68,7b9994e,81dfefac,11511fa6,126f8d88,14c5de2b,dc92bd79,9a466940,3ec8a5f6,f445c59d,bcf779d7), -S(35620920,f58bace8,7dc7f750,876b59bd,980ad703,b3127c3,ba53c20d,56fb5755,759d3f68,60643a2f,d6c946ba,5bb70f61,fba28208,77dc47fa,a4d9ae14,9d6ac9ee), -S(f70c93ab,7145bcdc,2ba3a9c7,f423da0,26a39180,6dc3686c,fe32408a,f659f918,84f71fc6,818151bd,c620e79f,a2d380e0,eb37391a,4a56b919,eb14b2b,cabee697), -S(858916af,74216be7,beb2dc10,47f941b5,157d7f19,c9b60900,bc844703,79b4bd3f,77b78d3f,5fc4e872,3b7cec8d,8653ea2f,298a1057,88bb4cbc,18e4fc99,108620c), -S(4b690a4d,a3649304,96fbeef6,da701b8e,569e61c1,6456659e,4c229813,d7118d67,d64261b4,4f26a263,55e787f8,fe2fd5fa,55f44b29,5cfa9c2d,8cc90830,60ef8b69), -S(37542949,6cf4e6eb,36b733d4,ecf1533d,4ef38ed0,768ff1a5,58dd210,ef8d950,3fac2cbc,a4280d61,1e30efcd,cccd1392,374d351,ed9dc460,61041741,2d0efb97), -S(870a9ee9,e2a00f61,af0d1f0f,967971ad,c5afef39,b52a3d5b,de74802b,a39cec0,a4751ec2,989ad16f,460f3071,ebe3865f,3319bbee,7bc7c285,e8215ca7,831a81c0), -S(28c63e6e,99936241,73c0c5e5,7c74543f,dcbbb678,bc786746,809d3206,3c0bb3f3,f0c610d2,e268cc32,3dd39ec5,51723b9d,22cbb5f2,f59171b,14771bf3,a4ec7183), -S(1045176,321bf271,cf34eab,686d3ec1,26000d6c,b1e66d55,860cde39,e5b00885,2cdaf0,11879aa,10231e46,ac93baf1,7bc92067,24f97521,7e2fbde5,cd7dda17), -S(9872ed48,bfef1218,35ff27d9,168740f8,38c2628e,15dc1a17,d5c72ee8,df21aa5d,f744a757,b922361a,3976de72,7ed83300,885cfd50,5f6be5ee,2ef9bd5a,1823640), -S(12f16ba8,5a2833f7,1af7244a,36228deb,38075fe,222f4d6d,6c02744f,b5731a9d,5538557c,f3d2b832,77db6634,8119a3f2,9e272b9b,bad3dce8,df38c3f8,33dc9095), -S(96489f8b,407618ec,698cf6bb,1366664d,7f14cde2,3d3417d2,80f0a3e7,cec87c23,4e78ceda,5f034e7,8eeee63,bf263fd2,35b8d60e,93263fe2,fc2acc89,fabc7728), -S(5380517d,3a681527,cc2aa8ed,29075afe,9eb0660f,cd4d381e,803ca7fb,2bea7245,d37ef6e5,f3c824fa,75ef185a,22d6e6c8,d8ff865b,433388b1,a6e6cd7a,4bebcb1e), -S(2f33b34c,3b22eb72,5d27688f,96f94ed7,23c840f7,549063c1,386e447b,faaea56a,c86fc369,59426e76,8f005d41,5c7316be,bbf1bfb2,54add259,91ad2961,8e9f50aa), -S(cdcede30,e227f45,18d39336,204641e9,27a61c6f,801aa002,5f892be5,7b49e574,dc3b0562,5e5dc396,26c1ca3f,5f2fa1a4,dfc28dc0,18d6ca0a,b21966ba,5d1ece42), -S(a9642c56,2e284ef9,5cedc32c,94c55dc8,3768344,e7317ce7,730da1f3,c6ba501a,cb3bc00d,de25189c,b8894fa5,219eda80,934941a4,8dc8e140,9b0d467c,ffb1cd95), -S(32b67c85,f0f4219e,2ae8e63a,ac95b210,32674730,6a37317a,19a52235,73bb7641,d8bf9f41,e584dfc3,de237e70,79cc170e,96c2cc6d,62042157,ef60ee02,3d142213), -S(4d095001,ec45ad22,1c9cca7a,d588dbdf,91156878,688758ac,63514992,128e50f5,c66d7dd9,9206f339,e0b80e51,f6ee72d,619c77bc,4ef33b46,1c3b8617,7359fc62), -S(f51d320f,bd158ea2,71cdaf12,651e3eab,e7deff0b,434a8b06,b3b31f4d,f6d6547c,7233df17,a17de7d,3a87118,97006ca7,8c7cd5d4,7a86403e,24f050ef,dcf3bff4), -S(f0dfe901,237b4b5a,ba6deb8c,39c87cad,5bf4dd5f,6a5e55da,d7565ded,c4e50089,eab06c8d,6bc7801e,7aea2e6c,919db667,324f0377,ea58b070,2e87b10,7857130f), -S(2921d36c,4766c1f,775ec19,302f5690,3898a835,aa8dadad,6c8202ae,270e38bb,a79c8e4f,cb59c784,3f81b66d,57060d2f,7c7acecb,c2399191,b7f98ae6,771cf849), -S(99ad0478,e840c3ef,470a47d9,ff66a197,b62881a1,6189d9ae,13d8bea9,3c1c0994,3e9fc2f7,d37d580c,a16eda71,ff6d1995,47f18ce3,515adca9,c08ed241,d1607f82), -S(970f064d,32c1eadb,b42ca1a,8893dbcb,dad1b9c6,3b99a15,e772407b,3aa1489a,efc34e6e,38e29927,9ee73b0c,9970cefa,f471f130,9518b8c4,81e7f67f,ffd807ae), -S(8d995e26,e9ebcc56,d2f9637a,df1db60a,e1b51d12,9850edb7,ef020a2,7ace35b7,1ed723ca,17892eb0,63ee5164,ee8e7216,96a3c3ad,67a3d8a5,a0d87803,37c01176), -S(c650e8c8,f995291a,a1feb490,dd9ae957,7506f591,c308b423,6ca005d3,ced75866,505e36d9,2ab967e0,a1168424,60639c72,646b0569,d3651800,316126d8,810a9444), -S(aba9f9d5,ae231382,b3583971,c875f4fe,4c51007f,6d55e1da,79d7e369,c21964fc,e6a176c8,34fc11b1,6f270f69,f4f54f1a,fab4729a,20cf6348,9cdbd551,ae5d1fb5), -S(1068b9a4,19f849a1,5dcef7d3,9b3b55dc,2eefe04f,554f283,212b489b,79b79d69,20993e51,4344e2b7,28188465,340b28c6,5331a7f1,a6aeb6c9,7f09e9ee,701f3828), -S(598358f1,cd3aafb1,9328dbad,62b65232,4aacc23c,87b37271,e8604caf,d69fc3e7,4297b258,6c94df83,6fe6c528,fd1b8fd9,62969227,d854e09c,375f85ea,58cd78f), -S(d4a638b0,1ffac322,48dc1844,75e3d06b,3b6b9a4e,971c7153,da49fe20,f44853dc,e9e708a6,5bd3b39b,15ca6606,512933e7,97b4adba,e72cee79,c79605ed,cf601d6f), -S(38421e4e,fc54951,1560c7d0,dd947c84,652530e0,d5155ece,8795936b,83b5e115,cbd0d873,ef6c0d90,9890b820,e8c063a2,35d2071a,97cf73f5,74ef2ddf,83ddf168), -S(2cbc4bab,442eae5e,aca1cccb,4a589c6a,8822138d,c3a35885,132dbc52,7648712,174b4deb,3b28ddef,426aa586,314b7b62,4e9253c0,1fc2dd7,ee94ae0c,57d3f5a8), -S(202d232b,4244ee54,3fb77958,32c149ff,8ee9a4bd,86c02037,634f5254,9f2dedec,67d64143,1915831,bef7e85e,f057ad07,a6de2cd4,3578ba0,eeb5cc70,1d16a499), -S(4faee6e9,90601af2,3f204f8a,615506a,82288490,a14f692b,86c8585a,52b4c94d,b45c0547,98d18942,7349a87f,5abfe689,68d14f82,d5ea836f,131ad030,ad31c8a6), -S(976db42d,c73a4705,fd782bb,2a87f260,19f6d218,3da3ef97,e0e19304,87ef7b42,2e543c4c,721512f0,81c7a6ef,987776cb,11318c52,ae6e2883,7d52a160,d183c31d), -S(9dbbc369,218c5741,36a0dc48,a17055ba,2a8b1580,88932e85,9a0b8188,5cd11309,e93dccf8,4dfa1519,45f6f38,d634a21a,b431f21e,ed8fd004,e27ea99,4c9d648), -S(660a226e,48ce5825,14c0f49c,d27621b8,f52657b4,17b8c1a0,ac9ecd0b,b9e0cc16,6d2c4b6f,74432c0b,ca351ebc,27a72b6f,68ad7a1a,8c509d8,8308be90,d7f7454f), -S(2ccc9a2,5c61d492,5293f4da,cfcbd818,11bdc998,7aa58258,f161210,40773237,5abce831,b2b09a34,4d93a77f,b8bbe8e7,d6334cd3,be3fc86c,154c74be,c191e9a5), -S(dd9d0f81,6c41936c,fc90cf9,3cc8f14d,8494f853,2b3b72d5,95d94742,8a01a4b,f30ca0ba,3db463a8,2b82b1fe,3f310936,c58906e5,ca07e4bf,9f4482b8,360ce7ba), -S(1314cac1,d751b3bb,c867e592,9df56ff6,99f810dd,f76ea0d6,f68a3e7b,4d95051d,8d3631cb,226a854f,143c1d09,89dd1ce4,7d943432,43060f78,ed3af3e4,f0d8d41d), -S(b1abd6ee,fff64a72,83c26a60,be0d1cc,f5152df6,b85655d0,9495d405,f2ccffd1,549457e9,b4f2edec,63f81471,12957918,baf8deaf,7d8a4b1f,489c24a9,44f210fb), -S(5d8e23e,1212800b,56e7740a,2f20c402,6483ce0f,755e36bf,fc4ee667,3df1b32f,973cab61,da46c5a8,6d1633ee,1fa28892,6e1d814b,800762b4,e4599ec1,803c0af5), -S(ae0bfb9,b5567b95,34510cc4,ad8dde2c,50c1dc53,6c9ce5e9,ee97fc70,f8b4f562,a8d15459,7fa1a816,3eb33c40,6b78ff19,b4927a3a,fe48a8a8,1492884,46ced08f), -S(b2ed6275,b818b2d5,ccb807c5,262d5578,c83743b3,701217c1,8188ec52,bec10325,5281815a,b21491d1,62e0b3d5,1334fbca,54731fff,f5d44ac0,396f477e,ab566896), -S(5d5c034d,228aeed2,270dec13,deb5418,3205a996,509211a6,8884c2dc,42d7d7e2,316c32ad,36906509,2e0112ef,eef93269,e251f83a,9ea7781f,ad59122,ae2ad4b7), -S(3d94f70b,39605f40,23107882,b491cda5,6f1b9ffb,3fcc47,51e4309c,812c428e,b3de1921,d29a77fb,ae8c6460,c3ecf92,22b88c4c,3a96cacb,e4385416,7898d7b1), -S(5c0dc575,84732fe0,5098de0d,45926c0b,3f8075d9,2ece92eb,f910263f,3e0d6df0,34c7fbd3,171b85d6,65bdd9ae,30f671f6,688a55bc,cd68c0e5,1153348a,16b75a88), -S(15d25179,6b55cc34,5beb9bbb,f6ad1aa1,b11b60b7,5bcd80a3,2a44c180,879e3513,46632865,ce1e74e5,f3a89a58,35adfb01,eec8e0f0,34b84aad,a0d2d901,ee07fa81), -S(86e5faf9,dc091174,bad52eac,2c83f945,3bfd9f82,13505e10,323255ab,b9e8d0f5,3bf19876,8c8b5f39,ba25a9ff,5d112600,956072e2,7775af11,52bec5c9,7b2396ea), -S(308c0956,4ee3aa0f,792e8630,3ede1407,d3d3da3f,423408e8,7b0c5aa1,2d6aef57,7c39d220,975a21d6,5ce1e2ea,930bd585,203d9b45,bf5f2eba,ecc5b245,e95f0abb), -S(19f9d4ac,c7de487b,cccae45b,2515f727,196911db,d799c7f2,a68078b3,181099c6,645522a8,adeb841a,81e27714,ddc40585,81cb8b24,e7d9620f,c940590b,b14f14a4), -S(a05d82c2,4493370b,cb7f1639,16865c71,3e89d968,8c96919,ab99ad92,afe96a35,1576f727,6c65e32c,1dc1ad98,2f75749b,75589cd1,43ad60b6,2163a8e9,87cb35), -S(6453661d,303acf74,751bc7ae,e8226647,b17b5808,f3f8dd63,4c00a78,94e830b1,145993d6,ab6592bc,b6b242d4,432be395,de7d0014,479aba5c,88a48cf6,adaea7ab), -S(adb18972,9de87486,3207f954,4e3eeafe,fa255209,4a8c0170,44a952be,aac0485b,2c67657f,d6a2b08e,28463e9d,abf708f2,2c790aaf,907af16e,598f325d,f657211f), -S(8a6ea198,371f94e9,288943c0,5e387cbb,b2071935,3562fdd8,f9fbe899,ac31ce00,d5b817e2,4f5b3fb,e25212a1,fccb6e1f,1ba55211,ff2e0123,c71175b7,bb94597b), -S(9e18eaa9,621ea829,38505584,a5879eff,446303ce,9cf61bbc,eaa6c495,7f259778,3310042f,54b5ae46,1c996f45,abf27c3b,5df06779,3c931927,4689da07,46254968), -S(27ec08,dbc47af0,d3db2aa1,a3b4b22f,5cb42750,b4ad6680,9815ef21,ac44a8bd,292fd5ba,9371d8e8,d4126197,18bfb564,2ed1f537,3303754b,af6a77bd,271d660d), -S(4ab3436e,34fbe37a,aea7dfb3,70d93352,ff4a7c22,53f1ff2c,8453c5e8,cadec2c2,90221aff,faacaed6,760b1c91,50eb695c,a1117054,1ee068f3,8c684e6f,b005b406), -S(46d75d8e,b2b5ccda,2d6819f2,1338b125,61a9c872,1d8956d5,b9c73148,4d928895,8153db74,27f7c4e3,381567c6,e2629702,8db4a5ac,c8762ec8,181a5da9,b531b6aa), -S(469ff047,7ddcf32b,a0c71766,474b5730,3b687406,c22e51b8,9f5fcedb,d154e270,acf0fde8,b426233b,20ffe9d5,5d1bea51,5a19a9ca,dc642a02,6928c05a,e068f747), -S(1d0a4e9a,ff31f94a,456c974b,ccd5169d,594b7263,5e817f29,4ac1cc45,52d3c6d5,52d567e8,1316fa28,1c2dbe62,75e51bf1,32f2a573,77e0825d,eb024a1,8e637683), -S(d1f25e6f,5038f784,84ffb8cc,7b5b67ce,908b3050,371ac332,228c3f79,577e6e3f,6cc0b7b2,76a948ec,54b79662,6fe435f1,5c68abdc,9fdcf8ad,41485a7c,58291f77), -S(56e97220,8d42989e,2a0313ce,203dd87,e8bdd09e,38bcd097,6e3d047d,7b8eb385,c78f2ca5,93d563d9,6caf585b,25873cba,3f4d1f31,3e31fa32,df2e9e0b,7538cfa6), -S(61f040fc,eb4db17c,7675ce64,73721c47,785e30f2,217f03c2,5e1fd723,d40644a1,950c39d5,1994a902,e637cbba,e0afa218,50e5b191,ef5b5939,3257d67e,555a1d3e), -S(ceb5f3a4,e47483e0,a6137f38,1ea23678,81c3df5b,830f80f3,1a08a3e5,e5181f0d,6a31aeaa,7533fba6,7e79f63c,abeef7e4,f130f37e,1922f17f,af20a63b,51a1c485), -S(d9b195a2,dfb91ba5,814e54f0,3bce3f30,6b7f880f,594e8dff,684cdf8a,bcf63634,130e6034,3fba9959,898d4227,a8b4e79a,5a4055e1,a22cffa9,8b445c6,4684233)}, -{S(5e8cc841,c1b251c5,317faaa,89f6c9b2,107e793,4abe27d,adca6318,38a9ca72,9c1c881e,10e9f194,e00388e1,e2414f5,74946554,d2656ceb,392dd6c3,611eb982), -S(498fb0a5,c2a2a7fa,2e89a846,d7987897,b3e843f,8d664911,277c85cf,3ad0c128,c480af90,6f0aa1dc,8330d211,aa409649,3da0257c,8d09d5d,8b1aee13,f7e6f26d), -S(9060ce66,41a763c4,8d0948b7,670c1d71,1ac2a81a,431b979c,946eb25e,3c8ff8f2,567b9831,a2555c20,6dfc4c41,9ea75b99,d02a00fd,f3942ea7,e27c44c5,98df4d7a), -S(b528d336,1c7c3cd5,5480aba,4421c209,cdc234b,f948593f,98eb3c2,95a18396,1326dec0,490078f5,7c541200,9f131410,9fff1f92,eea82577,2fcb8834,c59f0c33), -S(5b0e61ef,8c9ca491,83508642,8cef89f6,75f49ee0,f33fc8a8,5783e6fc,3b4c59b7,bf1f0c2a,ebc45330,1d12e8f3,43b4d3fd,df0e40df,b78cf093,bff413da,923f913f), -S(22e892c2,258575c6,e6ba67f4,e0e36853,27771a2,28ff9ecf,a2efb43f,c9f1c7d9,2b20a268,bfc51047,a8b28952,795b91de,624a3487,9abe535,3cfd3a11,87a86493), -S(70bc895a,ad0c993c,25155e97,9d9276f4,8227b6b6,d7a31bb4,b64a969,8102e886,7c0be1e8,f268015e,987392b5,15f60d04,d1453e7f,fd5929b5,2176e24d,ac10da80), -S(1dd63c17,421bf994,3a85019f,777bd41c,fbea006d,d4e0b80,2effda5a,8591b87a,2fd392ce,2e25e393,9bad93d5,616c65d9,87718cd5,9b8cfe4d,e54473fa,49c86735), -S(7d3658a6,df58d88c,7ea92964,3dad19ce,12f295e7,b8b4e710,9b9297f8,ea83a088,6ce3e119,496fe842,f7e2fa75,b635c11b,bb4d00c3,843216bc,82c31cf6,46d9f715), -S(aa02cb68,5acd4d74,f2c547e9,43aa7360,6a960d80,72aac984,b44bb492,e61b1d94,1db77713,702ed407,655dc5df,55ae0329,a30aca7b,d5655ebd,91dec954,feb0e02c), -S(e015e1f2,10b7eefd,775369b7,64192078,edaf3118,9d7a5382,28a744e5,5ee7f068,dd69db3b,a82ab3a3,86e1f09,a6c3b8b1,37b48021,a560c0c0,a8c910c1,e315b721), -S(ec50fee6,402b79de,afec1f9e,25778b95,5b36273a,6974963e,3cddb748,1166bd4b,21b5136d,2a71804c,6c90a89a,70bc05f6,afa26558,ca1aab74,610cda3f,7adf0f03), -S(213d69ae,6ea3a73d,3566a2d0,10f6c42e,d0c3b60c,9f104706,153b48da,2b155415,198a8c8e,ab3c11e0,2b0d69ae,7ec09ff3,e69ebe21,8a849655,14c46aac,786954e), -S(5ace25ab,eeca3eef,3439dc5d,7313a07e,7cc94c45,5332d38f,5fd367a3,cc88b2a3,2ddb1c5a,168ebf76,6080304b,df44e644,d5b34ef2,3ac49fa6,3b19390,83fea9b), -S(fd0ab7dd,a0907d2d,7349f860,4cb4794d,db9d0a2,dab0e6e8,7fdd90e6,49a3ce19,6ab30bc8,fd9fa11c,835509f1,c4e9b0a2,faba9de0,4f2b8ba5,e3ca666e,cd1aed56), -S(a8af0736,a5e408ec,84b46f55,16e04fa3,bed5f733,f8b99e90,192bf2ec,ae1fbd4,aea37eb2,6f9b6ee7,90eac699,92a53732,91a68317,efd3e651,f27636a,878a531), -S(a4effed2,dd088a36,ad6902ba,db705a35,187f721,20e747b0,2011839d,76d68be5,5efc6581,210022b7,fd8d3dd3,f11c95ba,99a28e44,c316c8af,7510816c,256848a0), -S(290bfa2c,8971750f,90aa6762,aa1b2b9f,e9eb50b9,cff25ada,4a7239ae,3524a799,1e16aeb,1fe3c65b,395a06e6,49545ee1,95f0a6ae,9954f6f0,dfc1f528,ef7d0759), -S(25496b16,b62fbf6c,3e9c59b,de7df4f,6216256e,3b968588,e184bd6e,b9543eaf,6964be4f,d9fc2dbd,146774fb,1eb37f0f,a13a11e2,35b1c870,fde75c,ecf750d6), -S(8585f972,5efd5404,fbd73e8f,c78a4e10,8089f024,f6ddd66b,28d56031,b98f970e,4e61cd98,c9ed1efa,6dd112c,ca27383f,1614b0f4,728ce990,9251309d,13c2777b), -S(b4fabb0e,52f273b,9e5e245f,82a151a9,296d93ea,d690378a,2653eb7c,a68020a8,5a0d976f,2d34b780,34ccadd9,30371689,f1e3c5a,6ce774a0,db9da3e7,aaed0542), -S(4c902996,a5a7ddde,3bc42bf3,31fb1cb3,61ec471c,6b9d8e9c,249d9e74,693c9e8e,3d118fb8,4e8061f6,3c8c5f09,f60298ef,c7983887,d1522034,8c9aef13,9759347d), -S(8a1fb43e,3591b453,ea7353ed,f3414793,2cb2e5e4,33aa01cb,cde2a865,27954691,40982292,e5b49878,b7471564,a84606f3,6e128d08,3d542e57,ab04acfc,dc1f122b), -S(f93d9de4,43d93908,8529abc2,d27efc02,682e96f5,79133ea2,e65c44dd,4cf5e6bf,15c9e50,696af51b,64e3b7f0,19b3e27f,7dac74bb,d72a0007,18c4c3ed,10db4873), -S(8755c259,f333b12b,88917775,cd5c2536,431e77df,f80a59da,d2dd7a1a,a56c930a,d2d681f5,d6259780,8d5c4a4b,9169d9c4,181edf5a,cbf4b817,d27b4e2a,3adbe697), -S(30f44aa7,9d8a39da,3abc6085,b6d5f33d,bd96f266,e6f37382,c20e749b,efced3f0,8acdbec8,2461ef14,f4096274,cb08f3cf,149e0041,7c075595,ab24fe9c,5ec15b96), -S(691a190,7e98a004,98af8c72,3850acf,81f07e76,b70afd62,96174058,84bf4a26,df902e4d,3e7294dd,66952c08,4e562954,2e6cf93e,94cc0d9c,672d097b,38844483), -S(998d8727,55f5c048,1d738583,e3a80de7,c6abac0,249f01a4,1b890d98,2ce74471,cf9b4563,67eeb428,865a1416,ce7b7f60,ae953bab,ba7a67a8,15ca6a5a,bb4b7567), -S(21f95845,8adf4ff6,d500e082,56454d33,7893cda0,e02ee161,7368a2ff,1aa66dc5,d88c985c,3c40ad,219ad336,ced08e32,f328a0fa,f4cb8ea1,9cd17762,7b4b257f), -S(107b438f,8273931d,d14d9b3c,dc5a102d,41f24887,9342d3b4,539a9d76,a04cb362,a41365b1,4d0857fd,da9d15b3,76dee746,55d259ae,91b3e97,c61bb70b,4d0c3a87), -S(b8f40c64,3d17a3a5,5329f710,5a8c799,66ac1466,30d64264,1262824c,b276c705,81d88197,c24f85c4,88c96401,4a34bed,17067ad0,d640ecc6,8482a3df,b374647), -S(33ff357a,ebfbf690,b97644d5,af3b5766,7e564c25,5685458d,1d0dca97,f28b9cb9,59de095e,dbb83b14,1610f1d6,289c21d1,811e875b,dcaeeec9,40c6bd8,4ebed43d), -S(6f2c27e8,46c1b5e,b02c57e0,2f8b78bd,af6a6489,858ec5e8,e60c7e84,c92f8a42,a20f6853,3e180ab0,bab00ac1,d517c66b,9f81088f,f2ad751b,63fec4df,d2beb5e6), -S(510f00da,f51cbe28,7bb0eae,59abcca,f3dfd507,976b92a4,558de2bc,91761621,f268b1e0,549117a1,b2123754,ca50589f,283db3d3,95c1e081,bbe9d027,ac3a8561), -S(fcd2aa5e,5c3fd7ca,a1c9dddd,30feb5b5,c3abab65,924c1865,913ffa5e,5658d2d5,662318b7,2cc9a9e3,5fb122b1,d74cfd8d,55eeca4b,a0d6f998,aa9dd09,266bfb3f), -S(9292c47,e36ad0d9,957a90d2,8fc00580,745a52ab,f14f3d61,c9c02163,e43c41b8,80ea3a5c,16f68cb2,67837544,289d1ea4,48056da5,51b56bc3,e243d45f,51b770c), -S(30a07a32,2d6deb75,7c3fdf92,db896b78,25b4043,87e7120,eed7cc56,3fc1886b,b07239e3,68803d55,96f843ef,929529ce,96df7e47,36a2cb35,dbe30aeb,1ff5c3b), -S(4ace91fd,2db5f7c4,29e6fac3,ed7aaf6f,46217f3,e2a67ba4,74423f4f,5f2a47f8,18db8c0c,eacc55b9,fa98ad2e,da9634b9,c47aec7f,9cd8e89b,41913e20,ba2ad9cb), -S(63ed08cb,b10860a5,4b6c0428,8f345cf3,f6e0a48e,9935727d,9070bfe2,dc0ade69,f24eaabd,e3cb05e7,c74d3be6,d17bed4a,2d4257cb,e69b876b,c161f8c2,4b8ae792), -S(66e91d3d,e5f63aa4,8fd6d3d,9129f60a,c030cc88,a2ee10da,5c187832,ee309ac4,5d90f490,8f5f0269,cadec883,e4ac47d,7f0b8d2a,cdb979ba,78f1576e,7644aa74), -S(e6faaf1e,1b7eb6b,e1daa8a2,f7f3fad0,e0250e35,f59b4ad8,a80fb38,5c0ca6c,3ae02379,79d9c291,68a8f555,8469b4e0,98dba357,7ec85f01,8f4043b8,72e78ee3), -S(c1006c5f,f598f904,94edfaa6,2eab93eb,e11a44a8,5e3e1014,91218cb,13e7b497,b6d15bf4,28df9655,bf70336c,ff7b6d80,b7890d9c,82b0323f,20f45935,6635f4c3), -S(f9cf093a,f613d28c,695f146d,5790f6a6,379feb52,1a337d66,a5032f93,46a0c7a3,e017544d,56a9dba6,e9c248d7,9bdfca89,8b521ffe,b5e68a9a,26ad6f2e,46299bc5), -S(90d1d995,67f6afb,37806ce1,997c8917,e6ff7191,5b6bb4a5,cf1433b6,9ef433f1,44b0e285,e03ac5b9,5e4352e1,13775a20,66cdd3fd,fc4a90bb,9d39b6d5,a796864b), -S(5e48b3fb,eeeb724e,8442fb8d,1510770c,c0e879f,94ba1ae7,f67a853c,57a38996,20650a89,dc8e0869,5f6c2b16,d8620af6,b9de2333,e29ad5d5,56445f54,e4c19a56), -S(90ca5392,1fbc1d53,7402708b,82d3d4a9,366c39f2,4fe6bcea,8435b5c6,544a4090,ced1590c,b11bed19,8a14eec9,44f1a117,d51a26f6,df89f62d,d4c0ff2c,d38758e7), -S(7d4a162f,6d359758,9a9cc446,f111da83,4ac9540d,7dc3fde5,8fb8d3c0,fd63eb8a,445033ab,53a9ae3b,7ecd39fe,aff2b18e,8d308de8,dec4fd18,8243ec1a,caa5ce56), -S(3344eff3,c3a56453,f2d37f8,1970c94,5ee2bc68,b85f53cd,3f4baa3e,2784488c,4966989f,f6372f19,5eb32554,9642e3a0,954ffca3,b650fa01,a7246743,ffde881d), -S(dcaf9831,99beb377,18623330,197415fa,667848a7,634b4821,610bdd7e,453794af,44c24125,71252bc4,db15ade5,abe3813d,f8425f1c,8a1f3281,6d33077a,bff19bf1), -S(57fb24ce,887ef2fe,f02be42a,a09f6e24,1bcfc52f,a58c8bb7,fae08613,6431dbc8,c2044794,1200e77e,a1d18139,55f58a30,c9707f22,42529a16,c1bbab3f,dce4ca23), -S(bc4dc9f0,54afeea2,2bf06988,265d01c8,b3cd5d47,d745c75b,a234f6fd,9231b3b6,9dffd7a4,1627e744,a637017,eb54fc22,4d949bd4,1b1f868b,865765df,13508cb3), -S(299f90b3,ee45e1e4,3ee1dced,2b302caf,11094a75,9e1bb90f,6c751330,d13e1f6b,6bc5dffe,53dd7c39,51623cc6,a7f61314,7d1847e2,73d03369,836e39a1,e6da81b3), -S(5a239aed,c93efe47,3141523d,fea3af03,16aee518,8629e8c2,e279eff0,62b0717d,117ad8f4,ea8a387e,d9f01296,e00c5864,ac93a78d,1968ee4e,9c325402,63acc5c4), -S(609b6afd,77d8c8c4,3c14ea1b,e56dc2b6,beca0239,faa88f43,59f9e6e0,1ebb8839,a576ec45,1bb52bf,39e9981a,4079f3bc,8e417bda,36797411,5e95e384,74632481), -S(663283fc,3d0fcade,ef669583,180a8e1d,b297cdaf,672121b4,4c481533,1d06bc26,139c7dac,f30b9031,de97c069,76812e66,7cf59091,7f0ac6be,f606afd3,c4f30448), -S(eedf6685,d605ca2,e97b801,ebc72b5d,e135f782,df6c243f,140bf172,9b23f671,a6da00b7,3ac5edf,b83e8fc2,5d6603aa,72c2af47,62b7ba2a,4ad98aea,53c8f0a), -S(ed14e1a8,73f82d1f,4e211823,b0632e49,3ce198ff,ec6c19e2,b9467791,8164fad9,fda82b27,3517f8ac,2464cb9c,b0edf241,ef91ebc8,2bda29c6,de3f6602,736c97c1), -S(f7c21813,63a5efb5,9c57da8f,eaef4738,38b9d34,8d3b16c3,ac28bc0e,b11c773a,9bd65899,bc4d15f8,875ceaf5,936ae25e,b4e9f,ce5963a,dc6095ac,5b867c17), -S(d407ed6d,b840bfc0,75c392a1,bd446340,9fb8f35d,80d9d4ae,95ea7bda,bb35e1ed,9f2af608,93692dc8,11330ac,35e317a1,fa856984,cc635354,43846545,5a9953d2), -S(32d706e,fa5382d3,ceaf0543,8e77971a,19e0e491,275d0381,ed705326,86f52376,66f4e0e7,1529c73f,aaffd9ac,a6846e3d,e2e8386a,939d02b0,7f64baa7,1d6c0f04), -S(ebe33ee5,f6baef23,ebfda782,e9ef55a6,d1b94e84,b76e7784,6d2827a7,82484a2c,27137340,2fcf2cf2,8ed164cd,7fedb8cc,178dc3f1,f02be690,ecb64938,cd942487), -S(5359d4ad,617f0a27,70392201,a2a1dbc7,fc5479c7,93be1cce,23b905e3,2751dd8,cbffabdc,ce183e6a,acbb21ea,86cd4fd8,97dd22c2,582f49b0,9f51e846,db2e8b2a), -S(92f718f3,8d2c428d,cb9dcf3c,847375e8,7f53d165,45a89dfd,629516c7,e5efa5bd,ca140596,6d82382a,453a5a4a,98ac315c,4351a4d8,5518af2b,996a0b3c,55edb05b), -S(70ec6cac,37a78311,8394e3a7,5a0756c2,117b8eb2,bf330440,ff6cd5fd,854df5ea,a1c909da,7c0cb4d4,141334f4,2a819c39,30af0877,8b4ea63e,601e3356,5d0bd54d), -S(72a4c06d,21fc5b6e,978addb3,95c1da3d,7c6390f,98f0abf9,26770ea6,d33c24cf,e811ff7f,ccf7f961,3c16b50,f74ce397,ec1c3e4a,877dd71b,b15cda1,c3027159), -S(ca5a0a96,e40e0530,344b532c,be4fcc47,2d243192,4c19019c,c602a6a4,45148259,b3274b9e,f30bc965,eb518686,3bdea539,130657,8199d2b0,4c56558c,a1bc19a2), -S(50e52b93,574a12e5,1f8c562c,2d335c54,4aa6edd,b3a83c4f,95ae5509,80b76261,dc5c4d8e,ac4d34c2,71af7d5b,abd714b5,194441d,72fefa4e,d1b4ac42,6e44d477), -S(e5ca0666,86f060f7,7c1d869a,94f02407,962cb101,1bdbb6cd,dad786fa,15761a6e,4ee18b3,7b15138b,61618a3,a7632c68,4f31cea,4d0c59f8,a6ce82a5,2c5480fb), -S(73560753,377906d5,9ac8c104,57742dc6,2d37b454,658d90ff,a4cfcbe8,f0e311d2,35ece58c,a5c7e200,47f80080,28fcacd8,2c8254fd,99fb392,f8e3b96e,31f40e4b), -S(a419a2e1,362adc6a,6fa18354,dcdd0cdb,37a4f8f9,bd1347b6,8763276f,b7acea19,c10fd807,3afc6f05,a2775e52,5d880417,f1c684e8,6dae0e35,9e600cf,9a6fd02f), -S(64a26b02,59fdc9f8,86ce26ac,cd826316,95eaaa3e,d95f9504,93c00505,ab149aa2,b03fca02,6b90848,965de8c4,6adadb8a,ff41f633,6c4af3b8,2a064880,f455b07b), -S(a8db77bb,4528572b,1630adce,107c8cd2,a296783a,acfbd84b,8cce742b,2c519e56,fa81ec4,7565b607,39dc4769,39624240,725afb64,df8ad9e2,70291dc6,acd1b19c), -S(95d43497,c9e2f1ae,4ecf2a6e,7839ed5f,135ca565,909fae2a,9590ffd4,2137e772,7977da8c,7d6d8880,d5c6a7ac,56b1ab4a,12d101f4,a26bc594,3c1ec394,5e085b7d), -S(184ad7a,9d1f54be,ae9bacd0,30707699,16e4158f,f1c7a9a3,e7303f38,53011793,7731244,6ceed0fa,3a832731,b477db26,743ccf3c,f3d8c09c,242c3327,6c67e3e7), -S(2f0ae3fe,5aa29a17,3a2718a1,91171d8a,7d33d2ee,6cc201de,4afbb00b,62db95e2,90f37a42,efb5787,6ed382cc,3a243179,4860ffaa,848b6299,52c6ace3,7dce5f28), -S(aa487bf7,fd746413,60e46513,4dec0aee,84287354,a74600d,65d02102,8deec2e3,d5de9cff,94ba3830,ece6a020,e9bda5aa,d999e97,a0ab4a0f,27fec770,ac2231ce), -S(54551633,398a72f2,66754798,5d2cab2b,6a107d84,72f8c06f,a34ed482,3a2a133e,4c33cc27,c462a5f1,e02bde02,aabb69ea,7a6c258d,55c6ee2c,a7b573f2,a7d970bc), -S(3b28883a,7df3010c,90b8613f,1b7639f0,7d766ebf,e3c1a02d,3bb20c14,156747aa,a3b1af7b,b133f94d,d2f720d0,aae669e8,b0a1b6c6,c2e14b66,72383cad,c28dbc71), -S(b3910ffe,6c153fe7,59ac3097,fd1a3b12,181deaac,f2cc3310,c036ac54,ccaab3d7,e242b0f8,de758d5e,ffb5e824,9cda6202,3686bbfe,439bed7e,eeec0c88,5b7efada), -S(679c5fd0,ddb09e92,77bd7c4e,651c862b,4fc18991,3892a31,6d0ed64c,1b66a0bd,f3cf0bd5,7e4085ab,7dce51b1,479e4ebc,63efb364,d11902a1,5d84b89,5599eaa4), -S(978d478b,3ad85f55,4b19a2f9,22f57cde,3d235bc1,92511422,fee2ad13,82a79f9d,fe0acd64,df69cdd1,985021ee,135050ec,879ffc35,b14deaf6,ade2734f,91781de7), -S(7e683666,eefc660c,e4326801,2690fac,4b0e3812,7de197a2,ca46270b,cba20572,250becb5,eda33bbb,cfc594bd,3675a82e,d5eeb642,bf755d2a,9e137ae2,1bd218ba), -S(8b90f968,26c56532,990cc0e6,8aa007d7,4555d566,7be7f23a,306788d6,cad77664,bc021a57,8e37d617,4a8320e8,e7bf68,4841096f,e191588b,79219fc0,d2559f6b), -S(b4e60f20,b7c71a14,80710413,fe81fcc3,88e83167,2183c36b,71185522,112f854f,d12ced59,7834d01,70a69bef,fb516ae3,4c67fea9,573bbe48,b3c2cc7d,edfbf0ad), -S(47d28ba0,3be64972,b30e7cb2,d4193440,bd4efc5,17194eca,2ef59cd1,78c6429d,304390c2,7a550fe6,23c9d6d1,465241d9,5827362d,ddaff80d,26ab1bf,9e32cc43), -S(2441a57c,1b9cea4e,28076f12,7fac389a,1068247b,56a1a4d7,7a2d5c1c,5945dad5,ff976ebd,3df8763d,aae65b64,c579408d,96b51a6e,9b3a85b4,401c25d8,fc9263fb), -S(3d69b290,d22112aa,ac7e2e7a,ded5cd9d,80754cd3,20831381,6e3840ae,d986ba78,bf7a0570,53ea3a3a,f27a866a,f0920ab,47f72d5a,f9859c31,6239aebb,d8d4ebf4), -S(2ec76c7e,3d684284,902f1725,54eb3dd2,b0c4304,4807a25b,472febf6,e9e6d1b4,97112d42,6850ee23,e57ae095,2565ee23,66c04ac1,6a388a44,14264767,20e38ac4), -S(972cb83c,80859ff8,96b0a318,a3a25386,3b6c99a0,49faca99,d36d5150,36da0e60,9668359c,953d20b6,e1873041,f0aea3c4,8e5a1d43,e4abab48,c0eaa391,8f7d8e98), -S(dfa2ccc6,9cb6c27f,6c072fc8,bc875c5b,e716c701,81b451f7,a85735ba,29363243,6342e27b,f9dff0e1,48fce3b0,1f9e569f,6af4a97f,b434725f,feff488c,501a7b4c), -S(3ee11d8d,8a46cdb3,8af24cd,f5f23f6d,2f18bc60,9f89fe14,ca0326a6,2a75c4f6,41ec4c72,ae99670f,2c5a4d8e,f0b2b211,fd3ea5fd,33b9158e,383c3ac2,d5c759cc), -S(bdc7399e,a6415348,77c66ce9,c62c1a96,7dfb72ec,6ef61c,e50dc71c,cdb3df96,90bddf9d,21aa5a98,8737c202,f89213d5,dd43c352,90a5cc96,40653be2,813f3f26), -S(d170eb03,dfad39f5,2e72298b,881e7c40,df9c4ee0,94cf092,25ef7b25,4250ac25,c9b3b36,937a83dc,c0592f27,202db5ae,9868f917,e6155e55,c9e0b3dd,8daa9085), -S(7153994,4971899a,8eff44c9,f38d4dba,e9315f,abff6106,a74231d9,97d4c66d,a95c07cc,e5d41397,7bdec5d3,bcbeb106,9dd90aea,ec57b911,3c6e3a69,baba78b6), -S(516ebb6c,f30e37d3,25bd8a77,f99e32eb,f2a84716,45bdc04b,a39b514d,268e9927,72504ee6,53710799,f5295c69,c022854f,b6ea6ff1,576c667,ab936d66,e651d103), -S(9de88063,6bcab6db,c7967dca,ce14949b,75529de1,73b46fc0,37a8c450,d5686d29,399f8480,c0f68bde,64ccd187,f247e09,30cc258,69e4779b,868d0af6,1e2dd1d5), -S(3a59c31f,dfae0e1b,a9b83db5,6f1fc0f6,51a0f9ca,8dc49c15,6e8d4ba4,a3ecd58b,a0513e83,600b57ce,3f87c762,6c0092d8,f88e0b4d,4b45a291,61abcd83,d2e93bc), -S(f533472b,fed40d17,566587fe,6f9e3c7e,3a657962,acb80e5b,319003c8,9b0b16f2,2fcf2b72,102dcb28,b36d8014,ee850bf5,9700d4d4,ae07769a,61bc0730,6a92304), -S(31b9170a,cefb23e2,330495da,dcc8729e,ce63a807,7406c4f4,de3d118d,1b759abc,111324ec,fdd8522c,64c0ba5b,a73cb848,9f1e77e8,d19c9731,dcfc59d2,26a88f41), -S(17ea4c86,6e3293d6,6cb535f2,db4ec265,331a4881,a9eb9941,2064ee60,38c3f8fe,a88536de,8cbec45,3d6fdcf4,3e3b5771,25ab4791,e2f318f2,c7572b19,7f3f02de), -S(f7a2f7a4,9462978,6f82557a,ec27a021,21995935,d5ac4adf,804b28bb,36ae5086,8a7ed1fa,60125463,96e3a50a,5616c515,3c5b6676,92bae5ea,f418bb57,8c4f42cc), -S(4a6b83ac,11a8d30f,c2bc4ccb,71b312ac,9ce05d77,3ca4a971,2f45f16c,c4a36099,c198732c,fbdaf72b,2c0471ab,5b4e2ac1,16d62e15,c5cf3bdd,c7fc2377,1db156ef), -S(d61e0f2b,757b2147,36f69e8,80f7882,26796f21,34c8ac39,7f023f60,9a222df6,dc369e3b,a99264d8,1041e2f5,decb93d8,7f3ddc5d,ebdad99a,1993e432,f92326ab), -S(ffc48a38,3faa0772,995f2074,4329141,1ded8a68,69f54f9a,53e14426,8d2d7788,edf446f2,660f6fe9,95129656,fafb76f,c1ef96fb,7227c4ac,8660cf16,867aec57), -S(986f203c,c3400685,610c83b4,fcf7a0da,636d92c4,f6f0bdb9,99b01321,ba47b952,7e152eec,4ea0a4d4,8f594801,40e5bfed,6539ddff,60646b86,ab463f9c,1c1cd72a), -S(e078d96e,97b33ea7,bf1a118d,8e45104b,18da1b7a,f799b5c2,2fc95db0,869a4b56,500aea63,487620e2,1c89ac2e,187eb32b,5567f715,2a090d9e,8e493190,c0b904c4), -S(a0b76ce8,3dfbfa5b,9ffbed50,736a676a,8e3e58df,aa3684b,68943ba3,f89d0ee5,5087ed66,33d4eafa,d7f962ee,11844da6,6e152831,8d780d83,5a9e7341,77c2551), -S(e6137a2e,1c22146a,81b622c8,947ebd54,5ee49505,e7343d6b,434ae440,f74deccf,b9598911,43813abd,14323cf8,fd880dbc,bb4ac611,e961c461,94d0f78a,1118b35), -S(bc966ce,8e2d896d,454cf19f,8126bd2,fd21f912,9e0c5b56,3afc6483,d5a8de1a,d7391926,bbf51367,c0d84d14,9fda784d,4f5e4db1,a4a71868,e8dc9968,ad27cd7a), -S(4fed3ecb,7303d658,48260222,6bb94148,b56a753b,902c3655,47db1db9,9b355624,87d3c83b,c4336625,4ddddcc1,a380b9a6,a7796f7e,6da00426,5c067f85,7c446b5f), -S(53151e3e,793f7ef9,a75180c4,ec3106ab,af3452f5,1a8c5301,1607ef98,3fb208b2,ba84da4a,dd761991,f375cfe5,146ba47e,d79e8983,8ab1e71b,737ea419,7aad93c), -S(f1ea6a7a,1595f99f,187287e1,2ca4cebd,8268da53,17c9deda,31c9c828,c91ba210,77d27512,38290ab7,4a75d9e1,63238537,555b51be,c0644f11,9409c1c1,7895c2ca), -S(4ce24395,80fa27b7,3a3bbed7,379b19d9,4c59e23b,1d482237,3de48d84,1e7650e8,258ae955,11a0890e,5912f651,f7705920,1971d6,82ea9abc,92d34888,f134aede), -S(20f5aca6,c33e91e5,97b66f07,30a7eaa9,4badf23a,b6f7653a,69f7a638,8ca20808,58642a87,964fd398,259037fc,c0c3e028,392eb7ff,15646480,1656cad8,7b6165f3), -S(5a84a300,9a7cb6a9,e86447b3,9d449bd8,3ce4e8a3,88395cc8,b851d961,df2bdca4,a724823c,bfa39a73,c02e8509,78d661d9,fc8dc8a1,e3a98c21,45448b2d,2c0d8d26), -S(4cc4b57,2e4cf18f,212315c4,65ed2464,b7850846,d64872ae,7b98d316,73853a6b,72594713,74be90df,fdccec2f,3a84b30f,74d6cbbf,fe966fd8,77de5b51,f9eeb409), -S(84aa8352,80aff2fc,b747f2d8,6e6d3f7b,5828ee7b,c0024d9,9b9a4998,fb809d48,a33e80be,b6131f8a,6ede3e5e,2bd265e8,5773a903,5912ac45,83cebc02,e0f70585), -S(4354311,ff6b6381,92ffa63f,a7a52fc6,cadcdd05,9adaafcb,7695686b,478dccdc,fa6b68e5,9d7f3aea,8d90d21a,ff26041b,68f68660,745bfee4,179d9e3a,2683f06e), -S(5be8ea1c,c7412e23,fe4a505f,aa15006c,ed823cb6,1853dde8,2e7af0a0,f06cc196,a2c76a9c,959b6b5e,d71dc83b,7a81e43c,a22a019b,8ecc54b0,eddfce5e,af9cbb45), -S(a69f7034,b680b802,189c6e8c,9cccd352,ce9ce14b,a50f9d41,a5991af3,e1822a07,df0cb8d6,86a38785,77235cd0,edf76b1c,9e902d2a,aac44b99,c916c3b5,848755b1), -S(f278be9f,11ce9c4d,2fc94317,98f3f552,b3f73bca,7da23757,93ea99ab,8aa0418d,8ec2cd50,6f3cadfe,2eea65a8,7cd8be99,a29d57c6,69482737,44e48289,d5eb283f), -S(28cf2333,17cd2dad,a4c83715,d0af39c2,cbdf7d98,7c90e1df,8709bdb8,929caf1e,a7905953,6c19b52a,459803cd,3a2ffb3d,d5597e5b,656c05bd,86d8e3ed,a9b7dc51), -S(45071195,99d6f85d,1e585fb8,2d4bf807,1b8ba01a,5487ef8a,b80d0508,2edc7b45,4951b428,1340ae42,1586824a,24933dcd,31a954,880d3c0,cc49864,72b6bfd0), -S(6df50945,4355e918,36a945ff,fdd68626,1b20f362,b1a7f601,9041506a,7cbade3f,38301bfc,e21d32db,83951120,954e9d56,179bf6d2,7fa3d5ab,7c37ef40,5245a031), -S(4db57458,b29c47ff,6f8b8ee5,12d897d6,36226380,4be13a48,6837f8e7,ebe147c5,e51039eb,7f9c8b93,3ad3c932,1b254cc9,f6221e35,13cba26b,a7c3e6ea,44f93ae6), -S(ad0ab782,d9a93270,b7083a32,b1913b7e,b0fb1947,9c8d8be5,ea74d0b,2590e087,50ecbadb,d801fdb6,5d40e84b,1511522b,3e603d06,5bf3a6a4,2b864558,c72c3fa4), -S(acab606b,aa8bc48,c452487c,700ddbc,daa04799,e9f57811,c47587c3,18d3900b,5be0eb5f,3f78292f,c248b704,f6cb2df1,891a05c7,822d9b47,35efd687,35b2e6c0), -S(16168437,b019abc,49fcab11,f7c0f2cd,14c2f784,dbfaeb40,f3790404,c4348d51,c68bc496,f40d5e97,4fdbaa51,dcf54ea,fb50abd,5ecb9f87,99bb3533,262ce86d), -S(5f03f4,a6cc9ad2,475d0f90,2090888c,31ae6eca,b08f7e4f,da8db504,876c8915,c918b3fa,1104d382,1d862299,17e0c5d5,cfbbf924,f69c24c9,d97b7091,157d7ed), -S(6da6938d,ef8b701,fcb228a3,c9066555,b4f7f0a3,297de3af,39d42897,5f0a27d0,f3ca7083,79910a1a,cdb94e7,9a7c8eab,e2c1b779,b749ad6a,fb4579b8,a3c56b6), -S(6b25cffd,587c71a9,3a736f8f,f5daeea0,26734350,fd158415,727fe6fc,6d309f86,dbf00735,d0c10049,27d582d3,8e61257a,770067fd,f9418dc6,73cf132a,c33f7b74), -S(7c48e557,27b1bed3,604cc3f6,7e47e24,b6f9b8a,7cd56cb9,f531ea5d,ef793f12,4d251353,73636962,126782f2,170cec17,e08483b,5b651f78,f0723da0,d6d4369f), -S(6769e622,cfbfe289,337de46f,4b6e1843,97fdc046,4560255d,9fc74c06,b00fc7a,523669ca,56e3e24f,b2490db3,6ea0bc33,6851041,d9146dac,1aace8c7,3a55e92b), -S(f83e990d,87486667,11214f8b,6a4643e1,901251c6,118d4d2b,a9087678,5313984b,b9decf7f,44c2cb00,d3d8858a,164a1,7ccbb6f9,5bbfa72d,6792ced0,4786a12a), -S(f3034416,5db59472,d7753efc,b55203b4,44b3a5f0,88825c4b,145d982b,38d369f3,3b765eb4,fae61edf,4a4c3b11,c71c5359,d8920eb,5cca2896,226e85ba,5932458c), -S(b2051f1c,5e6b22e7,d565ce94,bdd27c14,885322d0,e7bd3db9,eb13cdde,b26fd66a,b3245d05,2e93fc5,362d7e0a,4a4eebd9,ef8fd1d6,15c8a343,e308ef26,b9e331b6), -S(443958e8,fc9271a2,5215abbc,ad1bbcd1,887286ff,53d0d6e3,7803df80,f26094c7,3ae3f492,f51f287e,3f881bae,b16f4ca5,60583593,108053c9,352a48aa,95ceb545), -S(e8c5c31d,8e814515,b992ef4f,28bed3e3,ba6b2ffb,373a62d1,45976712,da8f5ad2,9d9e9d26,83c6b623,3d867d0e,727d00d7,fb5b7312,74d58bc3,b036b74f,8c22f676), -S(8b997cb4,8291df62,82ab7ac8,f6a917ec,330e76ee,4d21147e,ac15d3,2a9900ef,ba8e7e28,9bd40fc2,ee71f32e,48b1ab1f,1daf8c1e,6147cca2,a11befd7,e93b6920), -S(18ce6b3,126fd15d,29377619,4ad888c1,9355c739,7099d851,60111cd8,55199865,2f4ec4ea,4d215ec1,e102f7c9,ba9137da,5e75e00c,52b4d740,57bd37fa,61bcf038), -S(5b28c60f,a6c84a2b,dad6febd,f7cfc5c8,9fcf0e8f,d5cc8882,9540330b,8eaccc7,4d1c0d1,bb90266a,219592ae,ee619a4f,7b07c3a5,430ae20d,945f2121,2a652cdc), -S(5d4bf89d,fc3e8ac6,50f7c29f,6d878ce9,a1ba9cd9,d5970a58,ba7975ee,16496844,ee920d1d,8d7ee256,7f556433,90d0cf8,48458f75,f81b9f36,5c48dcdf,d60a96ab), -S(1fc5cd84,8a5680cd,76deb83c,f8ec6d99,db0e2fa3,7d7ac5bf,feb07fc0,ce0f0d9f,239f7252,18017a1c,d8419aa7,229eee96,37251ba3,a4a1eff4,9e42a29e,4f61eeb5), -S(e5a33510,603428c9,10cb5bd7,1da8bbca,3b50e97,46475a49,9d69b7df,badf601a,ee53e84a,a7e18842,a6879ba,ab59998f,62b6eac5,499230de,55a5c681,5d287a65), -S(c5ff6446,39c1772b,efe07d3,aad6dad0,5ba3074d,588d362a,6b5de6db,9d26707b,f11fe8bc,7f449e9,ecb22301,f131c6e9,7f4cbc52,af8fa880,6272705e,527a8e5f), -S(8246573e,b3ebc64a,c2118bce,9a275eef,6df0a34,61057e4c,a8836187,620041d0,fbe4a4c9,3bf019d3,2c2beaaa,ace3e4af,6c924195,8af4e387,d4ab3ef1,5146491c), -S(e9e9fd34,83b18055,cbbc8e33,cc6f3fc4,c507bb8a,84a09254,4822b44b,3d6a2910,45a4b02e,18da3327,80ab1f5c,37545bef,551c9a1,98616099,14bad711,1b4efd0d), -S(c3e53eb3,7d3a9fdb,bc2ab9c4,83656ff8,375bf18b,34aac991,ab5a6584,19d5f2a5,f95cb1ef,a793934a,2c1b0dc2,a0746974,75a29040,7f4413e7,449cb71a,af96225), -S(f54901b,fceceb3e,5beab5de,e9a93344,f354d956,5a989fd2,21cc8442,51944dab,57c0cb7d,8a79b236,608d7971,c1590672,8b5039ac,32db50f4,f50ca4fa,eabf3014), -S(d5cad259,e0716691,b5a1f8c5,970b4bf6,c7329aae,e4ab647f,daed2388,85b4fc55,4d944544,63cdfbd2,d769628e,bc60f501,ebf1d1ba,a1e4d68e,4a50e57,7afd7fa0), -S(fdfe1cc6,51fda605,d30582ae,d6d3e74e,855c278f,4151145,312f22e,ac142bbd,42f5dcb9,5772bf4d,4451614f,854f5ac5,e753533b,4d16e8a7,ee2a1adb,64df9029), -S(4db28db1,f69d04e3,27a438f6,199a5f98,292a6380,5e8b7edd,b36d341d,28d2e790,fafccf3c,394ad72d,40e938e2,5eb64079,f8617499,313241a4,99a840f8,733786dd), -S(1dffedf6,a430c31c,9875ea06,227583b,5e5160d0,b2d975b3,452a99ec,dea4d3d7,67bc0a31,ec97cb9b,fe191614,ded30a63,f77025cb,5cd7acc1,2e3d84fe,24b590b6), -S(41239a63,857928c3,e4d51a41,f77129a4,d60c7d44,9b6028d5,3b183efc,2452403a,8ac22f58,288c4a53,b6703f49,cff08a9e,39c16516,126b2803,9a0759f8,776ac785), -S(f2ecdfa9,adab5e32,eb7740b2,4eeb0fa2,649baced,1a69b03f,d47434a7,3d0c28e0,133952e0,ec187463,6d5f15f8,d2ab385d,aa58bade,36b9984c,ab94a591,70f2beb4), -S(7e74762d,c7c312a2,2fb7a48a,b9b393bb,7f540f7c,279eff83,c2170f2f,27132da3,9c7e6962,f6fd9cfb,a83a7b7a,85062f9d,add8a558,cc4cba51,d6079072,b7775daa), -S(613df89e,dc48052a,b497e0f9,571703f5,78e0ffcf,b116c162,277319b6,df774ffd,9cfa93b4,61200eef,c2e7855d,898a4198,52921aab,a30412f6,218095c9,4827d672), -S(caa6c1f6,c176e31c,a2baaf8f,39a1b5e0,c1c28443,ac8503d6,f4a55759,8e8180e,556a1519,73ece75,8e68d10b,151039a3,ed0521ca,c19281e0,255ec99b,10c21a26), -S(267f26da,2393ffe2,18f5c574,ad4fb6de,634ee94d,ee5ff952,10dd72b,1c550f5f,234fdc5,fd8e9412,650512c7,a510dd4d,f5ae9c88,83ecb1c2,edd2a3ec,d4bc3824), -S(8a26bd9a,b45c1aa0,772d794e,b088a941,2414b48c,82e2a118,23e869e8,3dea895,68ec5163,a955ab1,7c338a15,d2b66d36,5734f015,4e21e750,1387e978,452d9902), -S(29593a26,f0b9a728,c0248f06,4471e56e,4fc8d38,9823f7da,aff9e46d,81b9eae,710860e0,a9c98dd4,b1086e7d,2364be88,8741253c,9b8a7772,7b4ac275,53cf9b72), -S(5676cbf9,a0a41fb7,cbe1f3c0,a202bf7c,4458e938,964d903a,65325526,27454bd2,96cf5b8,1aa71fbf,f1f60e7a,2e4d28ee,ef7d0288,1b63d8fa,da9a10e7,8fdf7723), -S(6db9282,fe0ff035,b279a832,6f1c4f63,839a6c67,788e2e5,af7a4492,ecbcd9bc,4788671b,aae2f709,a2377b86,2c30af5c,49c721ee,fb2e3f91,20d49eac,821bbede), -S(db46b01b,c6047a92,e9e5c8b6,24f6aeab,16b213e7,91fdaade,8f045c55,d8de4275,9bd83ff8,31737782,21f161ef,ea079ea5,1e459023,445d8255,8e5f318e,949b52bb), -S(fa91fa0c,c71a2f21,38c61aeb,f451b435,1ae6a432,53a242e9,249727c,7c649ada,7c518caa,bf9fc9e2,c88a9ddb,712f32c,d8d04d7f,54dae53e,7dcc154d,e8826b33), -S(9752d6d9,e7dcc767,8bbce21a,5a7a3ea7,66d70518,fb59f435,eb6cd1a3,40f84dd8,9d1c48aa,2965ccfd,c03f5bfe,41a073b3,da6948b8,457e6e0d,c8a13de0,149a00f1), -S(ac9c0ed2,2e66bb0c,83ccb76f,62ee840b,5f2d6f5,568697e9,b0223009,63cf3c2e,37532994,58f79d71,df7d1b04,91523c98,9d30578b,706e3665,6c897fb1,1746c948), -S(71a9d71f,1f44b087,e02f7f28,5c47c947,f143d9d5,95e59dc9,64233226,d51c15f3,998119d9,7ad626e5,28e971bf,6ce85176,e3b9a095,1426f6d5,6ce8eaa2,81d6401d), -S(fbb85fdd,c4c25602,13ec981c,a40e69d5,6f3c6132,d1ffa38a,87b25c1e,87e40ecf,85882651,1c142a57,6bcf5f9b,1fbb0786,38511629,4c1c82a7,21e24bbd,16551bfb), -S(ad1fbec6,59b15b66,d34190c0,cc9165de,e48221d,eb1666e9,4d18042c,26db21e5,b579467e,d7d83215,c260dd2c,f089b2ce,513aa5ca,c9ac705e,e5841a65,8a583e18), -S(2af71297,ce1d4633,4ab66dee,42d005eb,845b927a,e6ae91ca,2fc8d414,58ceeb68,7477917c,5a456710,266815f4,39135116,69654290,36968cf8,e6983ee4,c508e605), -S(c0ae4daa,d71b2fce,d9c9b40,76be40e,a0cae11a,3d86ebe2,282f52d5,b86f39ec,61343833,f5d4ebf7,4445c133,37fef065,13fa3e0f,66cc7937,698b0cb6,9225fc9c), -S(93178803,9a374b99,df4135a3,50e1be5a,efd2e73,fa9c050a,d0b48812,a654c529,1bc01acf,3bf8b64f,6ac15664,c163ebfa,4a1a6ce1,4f9d3a9f,6e5ccd45,beaba2ce), -S(25458ec3,e24ae756,51f84ef1,a2bf49f,c19e86c7,99022de6,b7b58933,82a0050b,eeb2e93a,e357cf8a,9afbb9b7,fc0e97de,d80876cd,f08ee79b,ac07324b,cd41463c), -S(136e031b,1ab7a45e,6b8c3b53,7a615fc3,9e89d81d,a822e60f,aca2a496,e651e974,4cf2e215,8bc5c677,60e7d9bd,e9a476d5,d44a1c98,804e2697,a28dd17b,d4f5fa10), -S(5fefc4b1,2a3caf6f,3d025f3c,3510085e,ecc1ed97,46ccc265,1167cb0f,7fcd1af2,5cf8288,30eb25ff,1ad53354,acc72f49,5eb558f4,776b219d,bdec8ae9,24b1f125), -S(807a0f68,dd6026b7,2116e606,90a39596,e8558ce1,d11ffc9b,dbf2c574,40b82c38,12a2f38d,c84c41e8,2526fe56,2b877aae,10f575de,7edfb5ce,25f6a93b,158535e7), -S(8579c776,ad8f4fa3,65bd4efe,cf0b66be,3cf33cd2,61efc2cb,387c9a13,13947c34,7d888de6,9403e15d,3489748f,5d85bf7e,fd8213b0,673403fc,28a3d7e5,c3559198), -S(7374f757,46d03189,46386205,bc5d222e,243034a,3e0d4566,48777a3e,9239dce0,396af260,b295933d,2b6ae205,6fe53231,7ffec745,c4c95621,c1588d68,c3fd3f75), -S(a076997a,d9c613d4,adad3eee,9cb00a08,dd747840,4fe33fa7,34dcf3b7,58e8670f,8eef221,804526da,bc1b88eb,4320ea86,8d36ba82,775d059a,dcc4017b,6356f60e), -S(88494285,1a2626c7,f52abe1f,b31f124d,6fe0563d,c962c35b,ac690b96,27fbc604,e0a56299,86cb2c2d,a790688b,c63542ab,7362969d,d40d9ce8,5ec09e87,672cfe35), -S(682bb535,2da425c,87a541b1,35925e63,a161a84c,30beff50,b1c34193,fce7a6d,cea25359,481132c9,e9792a9c,4beedca3,4d16c3f9,f46349b4,e9d6cda3,e55f9b6d), -S(f80aa12,f4fd2631,26e01c2a,2cb0f86e,4293d3b8,87fc954d,daeab57,cbbe18fd,f6a2f24e,458214d4,c07d9191,23f8b6e0,af62d656,6657ff2d,c9894fc6,11917100), -S(f077e470,ca971bfa,9c762c61,132f5dd5,53eba38c,9629a8a4,9fae5b00,a23334ba,8bebf838,df798f83,88200f99,cdbcac9,8495681a,e4debeec,3f5ea4a2,b07bd87c), -S(1cffbe02,6cd70d89,f27a9db5,284a94ce,c9705d06,72b64bda,89b3a23f,c8b4a098,ea668c0d,61b0307a,15a303c9,cdab0ace,2ce5f1ef,8772dfdc,85d936e2,57bfe49), -S(7694c9e6,c10ece3c,f7ca1bc5,aac059a8,32f541df,da8342b3,ae31ea66,35d3c5e2,98054fd,39bf818,91b0d50a,ebf214a1,23010078,e75b20dc,c6c6c768,493899ff), -S(54f25d1e,1de2c437,39bcd34c,8a7e7d9e,d322a6ef,bc025143,de17b95f,e5cbae3b,a0a13012,cdff3d30,6bd3e863,9b1156d1,17c1f74f,8be3d8c6,a3d7a77d,e20c3d30), -S(ec3ab50,419649d4,78592017,c539f924,122d8aa5,4104309f,fc213499,8b608cd3,9f147580,8523383c,83f75c37,4b802589,fb1b0f60,99f20cc6,3497979c,4e558b4d), -S(21db4eeb,7f414ad,d9d951f2,ea33b9dc,8ac6f752,5549c982,174a4742,7dc99145,b4cb3a0e,a408bb1d,31e946b1,f0a99344,b0f2fae0,183088a9,543bef43,61950b22), -S(9e76ef4d,aa872a56,514bf43b,767a4bec,59dd96ad,9c436e39,807a4e5b,ff7b96a,7245b4cc,a609a698,bb3c6ab3,78d5236d,aaa3d8a4,c8502f5f,83432d62,b46685b8), -S(ef1c1a18,9fff9518,b1b40bf8,1edf4505,6a46bd92,1bd93c3b,1291597c,1d50bf29,ccfa479e,cb5e2217,ee9d2af4,42cd873f,953ff640,4127f760,2cd465d1,6590f309), -S(2fc501dc,d994ee04,81f1603,78a056b4,44b211cc,85e23459,f9969f57,626b05f6,29385f01,6b4180a6,93533c57,63e33818,ffc4f63e,72f78174,91532bf6,89d3b847), -S(52fc0f14,ce831d5,85e242e0,8421d021,cb58ec34,1d3d718a,34764966,48017b80,ee55bc21,120709fa,67251940,2531b231,e9713263,b28f52c9,a294b32a,cd7b2a07), -S(86932072,532e1a89,80b5ea8d,896deb75,6ceb8a11,87affd5f,c5eac0a,8ab374e6,efa4d9fe,3cb01ae9,b685e938,1a7ed4ae,b673d6cf,3fd8b47a,d55b2b22,cfe771c0), -S(d5001bc,4888eb3a,28ff21c5,52fdcfb9,f64be472,d677500c,2c6ad71c,854731cd,20a40358,579069a6,b246ea31,3e58b5ec,6569ae72,ddc20a0a,5ad7bc14,70aac129), -S(197d8ed,db431380,ac8419bc,a9a415d0,c19ff38e,84145635,a50eb5f4,fc026731,137d9984,ec510a78,130587a,59a3091a,24581fe8,40f49bb4,aebbfa3,9367ccb6), -S(f0efe141,83441eb,acd172a9,5496b85b,648deef6,9dcbb653,be2993fc,ab70eae0,1df1c523,4433bc9,7050c858,f477652d,636edbe9,8b3f51ef,b1a2ec17,6a0ad6b7), -S(7657e05b,c0659f26,2f2e86c7,73dd6dde,1e650064,5fad0165,4b52803d,c1c06599,26407f2f,a1c5c820,b729b9be,4a3c7c6e,b5c0ca46,f9c07d52,654bbd67,2a2d5f35), -S(6d037db3,bd776672,ab096fd6,e048768b,3acb7e5b,14cb4a77,ad8fa2cf,b67f7605,81d83989,87d95d38,5412e93d,43cd82e1,1060bfac,72d689c6,4d0572,7356db5), -S(16243eb9,d4eeb5ad,a68617e9,1dd8fd82,87db58ba,f7b65a40,db756936,54653ea5,fb3d260d,abd9a44d,e8795df0,cf9959d6,b94bbe4e,caf9c715,c4612c2a,4cea9615), -S(a59b5c4c,f732c9ef,f10b7ce,6e918562,d6082906,8509eef2,17c539a7,7601a48d,ae27b1d7,77021234,d703c423,cc7052b5,7f23388f,371d2a07,e0188630,ddbe4cb4), -S(33da8d1b,ba39bbc9,fdf39d17,1b8256f8,853da773,184d62e1,6d0d6ead,198b3cf,50bb1787,a917a656,622be1c6,1948adcb,1992153e,9b7725df,b93007db,7865719a), -S(4e5b40ec,c1dec23e,ffd4d2ed,4b3be8c1,b2a37ae9,e7d17d02,a00c046d,6173c48e,a68713c,3cefb9aa,559caa17,ff33b2e,476cee33,27dd5026,157ae77d,98bced0b), -S(86c5fb99,352060fd,2125290f,cc4625ca,2aabeda9,5470c14d,91afbe64,36511ae2,aa638940,d79a2237,c1cbc174,14ccee68,aa6dee00,c411dc3c,caf3b4e6,a24d5a24), -S(f3082a0,934921a7,6dc3d0fe,45d4badf,c0bb26d2,8b597a4b,bc7bb719,e43c5e7d,2f7a82ad,fd0099ee,3afbe9ca,a279ebbc,55841101,e1d2361c,1b7b4e81,98d78a90), -S(9eed2803,f83079db,90d50731,3fd889db,adf10be7,625a6455,709690fe,318df86d,1eba34d9,e0eb25b0,2494e3d4,14bbb963,69b6b6b0,f1ac8936,58170039,4ae254bb), -S(5045129,bafa3288,6d6678f8,eb0fa73,c182dc1c,ea039839,9e7eaf01,13d10432,f9290714,bb6972df,99d58a5a,50bab590,8c274310,1455d479,db9851a9,242c658b), -S(5083cdc1,1249ae24,4d1891a9,d74ee53b,90bb57e9,25fe26ac,32c364ee,99544031,ad385238,f304b7ec,6726ce24,9477326,15ec400c,c60069ef,cba2ffd1,c33ae39b), -S(6c1f547f,41bd9771,aa16cc9a,e19e5787,52e06b06,3d1aa740,dd219bd4,b8413ded,4e42a565,5169be0f,a65a471c,fd3fedac,58dea3aa,7cfc31b0,39902c6f,9938341), -S(bd455ad6,2c32f8e1,98f92a6e,ad5f8d1d,4ce6ab3b,57de4c76,d4a2557c,9d0cc2ca,ee672a2f,e514b76c,ad8af99e,20840aa0,231c423d,450451c2,66130160,a51db589), -S(3ef7949a,2f73d9eb,29390e2f,621cc651,54a31770,d49664bf,6602f8a5,3107df1d,faacb2a3,7050f0e7,d3d5e0be,edf3f658,ba30da79,df8fbc81,167bfee9,aece4f69), -S(8f45c59e,dbdd7f48,cdbb0fad,c2058ca1,b7007ba7,4ed1a121,4c6b562,7bcf6acf,357a629d,1e9800d5,c1f83981,81a39afd,56b1fdc8,9eec847d,a72fdb26,8d7fbcad), -S(3f7d488d,82c85663,b618af77,30a1b987,f662238d,9ce02ed7,f5160677,99ded34,c61323a6,bd1d8c43,506e24b7,e0635d72,e8eff076,db783b56,5f9424c6,8a1b53b4), -S(3700e5de,478887df,4f0819f0,86a2199a,a12d5925,f8e5c32b,c40738d2,edb329f8,8218c49a,3f40c04f,2a9ebf98,cdbb2d5e,1e9f2b51,5dbecc94,76f6e54f,26711232), -S(47ac5d4e,e3147cce,3d3e0c66,fb0c3a8e,a1d9c0fc,92dde919,7153ef9a,b4de1642,37b484b,4f0b4016,341a8b02,8136228b,6744ad3a,a871971c,6fb07a93,d16dbef5), -S(40cd13b1,6b0d24c6,d730c135,6ee2ba56,cfe6bcaa,d38ada27,230441ec,b50d5f81,31ed93d9,a98b6945,58c0130,b57c8c27,5caf386e,690cb1c,96b530ff,7a3ca4e2), -S(d491b581,10b6e137,57d20933,b356a977,51d3d03b,327354e9,aa1aee11,c8dfa15,85bcff81,4b5601dd,2eb27e1c,ff7d1489,93a98cea,9ec0553b,d14f108c,beabad07), -S(eabf656c,8b8e7de,a4a4ad70,d9a17911,d56891ef,7f6c32a,22078713,84f0b3f2,2ff10143,49e265ff,16619e7b,c7528fb9,9b3dbfce,e0c1e6b1,c30ec1be,47cf4e5b), -S(ed8abca4,ac4d7946,1ab4e3a5,5c05cea3,834381c,c7ec940e,c1b390c8,cce350d0,6b54dc69,86bc76fd,fef49c22,4b536795,2961b8f6,5ac6f552,73c4052b,dc8285da), -S(150968f6,3a67fde4,b4b404eb,866fd66b,50b822e,43f4e684,230cd720,e2e8e6d0,93e824ec,28bc5a84,f21b7717,d08ce64f,f5ede647,81538f4,a6f84332,4704c6e0), -S(83cab683,9ce8d260,7398446b,9c8f63d2,e4e1471a,f183f482,b22dc360,c59403f2,8f570cf4,391133d0,e31c363,84cf5195,f160ceea,b96e44,ba79893c,ddfaaa0d), -S(b3f062b0,189836e0,e9cc7acd,5c3c7810,bd287bdb,c0d64b4a,27202ea,f3a05b41,730f1110,ad1e7dc7,f6e1b84e,9a332c86,2003ec5c,f9e75835,97c07530,dcf9feb1), -S(7c226926,b567438e,cacc7662,2fa3f806,2888db46,f3e41649,d2bd5142,1a90f83e,563b94de,fa1719a2,b7f09c8e,5b31476d,8b8ee80e,9dfae6f6,aa0f6a6,45ecc33d), -S(b9416bdc,9862a2c2,cf1a50ce,132d07d2,8862f6dc,19e36f03,ad3100c9,659fcb99,5ee3e16a,5be0ad7,9c908fc5,f61c7024,678d2c93,47dd1c95,45734edf,e52fc618), -S(ece2cc3d,10edaa0d,4fe86a0f,b2d682c,aaf4d50,2913d942,8d704590,c2b3147e,5e79ac71,109cdd4d,12ff674e,b512cde,3a8004df,f2746165,e55233b6,2ea6fa07), -S(1dd18b36,369ddbc6,5a8d84a4,69262341,e6dc55dc,6362e7c3,5be5d5e6,ae72c0d5,4f7679d,e9ef807e,be2c1d39,163b7b17,1cfd22e2,6e4fb466,d8af03b7,1539ec98), -S(beefd37,fa712452,695bc66b,4fee98af,bd772c13,e63d0ca5,d62a7b0c,a8a2a3bc,caafe844,5be9307a,e872d297,991a9e42,7364ab4c,257168e5,660c5297,8a623aba), -S(d7f42137,7048d65e,39bb5032,ca991d91,184a98f5,4c35b3a3,73c118cc,d276d3cb,64e78d01,8e179101,41685830,dce8ab9,3285ebd3,ceb9817d,76edf7bc,524716d), -S(737fee9,6a6e5ae1,98bab025,2554e3f6,12517cf9,2614a503,4ab7b882,d97555bc,ac29b0c1,fb66bdac,a3ca5f19,3ac71997,87573d85,8353b9ac,c30ab147,bdf379bb), -S(784f4c1d,6a815b8c,6e429596,183e6e17,e846a50a,c65f0c0b,abd1d943,e115a307,ac5124ea,29517daf,782c5698,e5318d0a,fa0a05ca,d7a9d395,bd17c3c7,9c3a9972), -S(982794d0,a4430900,e6254f33,40924116,ec055a4c,8c0715f6,72af4cdd,e1bfeae0,90b9959c,3ad2170e,9bb70c1c,676ab6d2,584b97c3,855d9ec6,93307407,e57a3c7d), -S(7532737,c45039c,768b4cfb,71aed614,c8c8f977,70c94bb,1c8d5bd3,cd092d2a,b495750c,b0e5fd38,7f7f08cf,b5d2cf40,5f5c9a07,8184fdaa,5af78135,895be55d), -S(2900819a,badaa25b,5e79c9d5,7d35a079,4e587f3d,f75ca042,736969e6,a4db24ce,e7489b71,d1e8492d,66a1c6b0,dd23a453,12095649,b902f68,9789eac8,eec97435), -S(7c615aa5,b7134559,82fccde3,8c90d0ba,2d3a09f4,6bdbab02,4dd7b6a5,cc9fc205,4189a5c,d5830638,53569ebd,77855a63,f70229bc,f9322b2,2546df2e,e687cf50), -S(13749da6,79887b0a,d7e4f461,ae125385,c5126eb3,63d88327,6f0a4773,ee00193c,c2ee7f13,49def3cc,5d7963d9,2bee09d2,c36128ce,a5a0fbb6,964a0c14,a7644e92), -S(4ed1478a,b92b688e,aa491c7e,e3134ca9,7cc71cbc,3cb32ed4,a69c5b13,4e73b526,16f25a92,fb8e8042,ce2105de,e9133b82,3be2277e,66dfaa9b,368a2c5b,6b980a28), -S(f1efd577,6955489b,57759ad6,3c5cd042,383c1cf4,a1ea3719,8b1ad624,8d2649ed,909afd94,20027b64,aaeea435,25c77989,674411c9,14bcfbfb,7edc1055,e0b0ba6), -S(eec2b3d1,446835e2,ed2b9c32,80f320d5,296fae6a,fee19e4a,e38da171,6d0e35c7,a9f0beef,738d4ff8,f56bcb57,8bb509ba,8ef9e07e,3abe009a,9f0e1a7f,9d1609e7), -S(1d45c89f,fddd05a5,5043c44d,b8d0211a,f49f3aba,31e3ac62,5687413,4ecaa89,ab2abf54,db899f51,6c19848d,f0fb6e8e,9b43de72,3c74c33,9ac74611,7a64592c), -S(61531e01,5b2f0ca3,e36a20e6,b6d7f2ba,e2a1e245,340afb7,f134c3c8,799374ae,fae6274c,1e646987,2aa0b680,8a7fda0b,f3d495a1,24e859c0,2ac50be2,72dd4596), -S(a1b129b7,c1803643,6136bc8e,f7b99895,c5551ae4,71b2c0cc,ee48c266,bcdf2808,b9f97676,9623c4b0,bf10a738,6081cb23,f68693cd,626abaa6,b3874be2,5af886c8), -S(27e38dcd,d63bab65,c77eedfa,7e1f4b46,203ff350,20c86fb0,4ce2ffb8,af8d7056,81f30a56,7340be31,52ce5c6b,877f2c67,a7db7acc,7f24e13b,bf836660,9d61f04e), -S(64919bfc,50072a00,8769f559,3ad0e5b7,72ed6575,81ecf37c,8c759a3d,51149fc4,5759727c,20ae86e,b38aa3f,5e53b848,8ecd2b,477dca0a,ffb83903,65e70900), -S(d392e5cf,3c2d4a0a,20779b28,f4957800,ec7148aa,63b2bcb2,348afe9b,d28ad57d,54062719,a0ee0869,b1a99d9a,e4716487,70386747,9ead4774,66df29e1,78c87c6b), -S(6b9fe223,333b0802,34fb49d4,85218d11,9123c430,94e4ffba,38f33bb2,dbe7d9e2,5ea16bea,b5101109,4d34ec62,e6a63a71,c78de1f1,fcb7ce23,4ba2f51e,e4eb2ef1), -S(b1a505c,eb85f130,ef6e4a49,e429b0c5,51a87831,f850ed83,6bc8649d,6097ce12,a887e16a,805c0708,45589bff,2b22fc6f,4187cc06,cecef137,9130becb,5d5d149f), -S(8bd25993,c653b1e3,6f477988,61743aba,a5ffdaf,fd0890c3,caeb2963,736cbb44,341aef51,13b0d08d,90e90ffa,56570d57,5777260f,e85a15c2,2b5b3139,4f0a8c20), -S(2da121de,147507bd,b8836321,40394006,afc65465,7c6d4399,97cf6c88,ce0c4016,3ec87a24,eb19c502,848ff433,7ac3f48b,9a56ca56,3d0bffe8,eaa98e97,49f04aaa), -S(147541,9e9e9ff8,5b93f56,2832e74f,6c8c311a,676a759e,7dc62c63,5faa0b07,40fb95e4,810607ce,7ed10d9d,61404078,10ddbc55,261badc0,5e07bd1a,579ca271), -S(7c48371b,7eb5655f,b9d95bc3,5660d783,b1884573,d2934346,c5a5342b,a0949cb0,8b8cfb2,4cab96fa,1ee1e5d7,7dade5bd,23fa7868,445d9ad4,723529db,38110dae), -S(6ac2912f,d959d41c,19ff8ac4,bc136e85,91944b79,470d633f,b9fe65f0,f72541f4,63351f35,d4a7787a,31ef0bd6,f28aedd7,864ec5ab,7d841f11,9163e351,e070fcba), -S(db08e4fd,63e16bf6,abc05d78,be6bccc7,c9b8e15e,334ad697,9205a2e9,c2100e15,eeb0ba62,e1a5ee98,c2e2cc5a,8d9cbf11,d265019c,9eea8f50,4aa1e50,a422d4e), -S(4160dad,5255da89,12f69754,77b445a7,26fb7b8f,6ae8e2bb,d6276ae7,2a31afb8,ab0817bc,7a9b6907,9f6db9f3,c9a77718,23a1d79d,9f2739b2,cbeca18f,e5b8fbf8), -S(3794fc72,f432c983,2f9ba8dd,b46b1c64,d979e899,78b3c14f,2f903ec4,75af091e,a898cdf,7cdaf6c0,3715e38a,4bea1081,fda150b3,7faa4a11,ddbdc350,c7e0bb05), -S(244b87a4,fcecef37,76c16c5c,24c7785,be3b3c13,46595363,b8c066ec,45bfe561,9642f5fd,e0ec25ed,bd2129ca,6c023ec1,a2eadac7,f6ec5b7d,2b7fe894,41e5aa11), -S(9de52b81,157165cc,aef44485,4c2b3535,a599a79,80d024de,5334b385,ecbb2e91,74fca165,26fe2f87,a41ce510,4dd5634,5cf98c11,803c0392,3eb4b8b7,60240c02)} +const secp256k1_ge_storage secp256k1_ecmult_gen_prec_table[COMB_BLOCKS][COMB_POINTS] = { +#if 0 +#elif (COMB_BLOCKS == 2) && (COMB_TEETH == 5) && (COMB_SPACING == 26) +{S(7081b567,8cb87d01,99c9c76e,d1e0a5e0,1d784be9,27f6b135,161e0fd0,3f39b473,ad5222ac,f062cb39,21b234a7,15b626ae,f780b307,9b5122d1,53210f42,d9369242), +S(228af17e,df90d1cc,a40173e9,478fa445,9780dacd,c3f15b90,fda5d00e,1faa1b51,8ff47c4d,a4ba636a,f656da9,12a81f79,6252496d,1e519886,b2c2b073,25be2b4a), +S(b515ebe0,f48fb34e,9e01824c,d90553af,db116579,96667847,5ebaa700,242fd722,4cf08191,510fbf0,51f9e19a,198f11f6,ea31268c,2a6d384c,60557250,f0553c50), +S(c37581f1,35446ff3,e80cde04,ec987f08,5af3af9f,71d87494,99b03ba,dcb8f78c,9e46324a,8d8754fe,fbda7c34,2446cf72,b7472708,25cfb92f,a22a4e73,4f1e9bc7), +S(768392e3,b2ccbbc,21792f2d,6f43c63d,efcc249,bcd549cb,96abd8ef,4ae59e90,5d061a40,ac3f93d1,82f0f7a9,914fff5d,90bbacb9,1965882c,591e89bf,c49da994), +S(a9db5de9,2d96c715,8ce5ee00,3d186cf1,976f6a76,f1be0714,726594fb,6c1ba564,743df2a8,ee73fb4a,47b3d0f,2f2b8cab,5af5227,f232946a,82676e4e,8bb70c8b), +S(58921d8d,3712f640,657e762a,737ccd0a,cece1459,a2ba8323,20b43903,d4953f93,78c26959,7e422c02,c01fcbef,484a9d44,9f635c82,849bc2a3,2a9bf6ef,3e6f1e7e), +S(bae41760,ade541bb,60028015,f6906b78,aa41515a,d995dc40,afa091da,77ae8b9a,716ff74d,ad6dc24c,77ebe31f,abe19792,41d18b0f,43ff7598,c6ea04c6,6899219f), +S(e836ff6c,6f9e02e2,4e6f6bcc,2f2460b4,9de88730,6d69241f,b22fa574,7e100f80,77c41df1,4d87b6d3,de74deca,ad426635,f85daca0,ab966a4,5a26a972,32105c5), +S(c7f17d19,fbbf28e2,543fceb2,4268ff6f,1b85e189,79b09991,7457fca0,9ba1b5a4,23a6d4aa,83ee15bf,f1655575,3e4162c5,8acedadb,4c4abfc2,54b7018,f477514b), +S(79c337ad,8835046e,572eea35,df76276b,84e99172,7bbc68a6,8c0b743,28619a,af6cf2b3,9c6b51c9,f1f92e42,6598dcbe,39da6196,2abae0da,d5fc8d0a,aa16a875), +S(1e77739b,12d20887,2bfe200b,d202972a,544804f5,2b0969c5,c22fbe1c,b8b23837,880c7490,c0455322,a0f1e67d,34b3fd1e,33c1e7da,83b9b047,5aef7bc1,332ccee5), +S(b1d314c1,74d493f6,c36a893a,830d90b,f1e86d0c,6deceee0,edb77ff4,31e9607f,8a4ba010,ec3e47cb,29d8f056,e056eb73,3b6b35f6,4c742d06,9ab832f4,68bcd3be), +S(2498aea6,471f748a,f14e50e6,bc17e0a3,ee09514d,fccbd174,f8a21d02,dd0fae48,55a3949f,2e4188e2,b3d344ce,6f0276b5,99b121bc,358e8fe6,bc4f03f5,a8219d08), +S(42d0778e,27e87710,dd19285e,d531af1e,7064386d,11b1b3c9,fb788bf2,b0c112dc,37888909,d943825a,9610e37a,362549f,547b7c7d,ae64a27e,c34290f0,b4fc5fcc), +S(af09a9f8,3a21b2fd,69ce14c5,495c680e,df18e426,c1ca5a1c,af56246f,d6ea5bbd,8eae43ca,8e591017,62c4cb02,9e5cacd2,58f0fdb1,ddbef7e2,c5765208,107c96af)}, +{S(4a7f72ed,ebd8df1f,13db15be,3ab296a8,d67edee4,37965f03,eb501205,3518ddea,1f8c4dc1,2d0e59e7,7d30a326,fd4ecbf8,aacd5fb6,7dc7169,898a9708,ac46b972), +S(c4d4f8d4,949d1ff6,559925db,f4d34972,af16062b,d59493b8,b1e0d546,c2870874,cd7f93e6,c0ee3fdc,4267625a,a6620540,4f6d80c3,d0f7210a,ce6b52e,c350706e), +S(773627f7,dcc56184,7eabafa3,42fffade,325b8ee2,a96f2f77,cbe675a6,2942277d,fb0ad731,9bff4c9c,270d93d1,89a4c380,218ec9df,1f564228,641ab35c,46526bd6), +S(ff443101,befd0bd9,e1914864,3eceea06,b9cf711b,1405e3d5,3883a29f,906063ed,aa1b7d9f,59cbddf7,bc1ad03c,44c4295e,efb406ca,7960c683,eca508d1,b2a9a2dd), +S(cbfb6813,a6874b65,9234e866,c2875f70,e45f9f76,3d634752,3f86040c,880a2e56,ed85d1a,6620c1a4,85ba3038,d2ee6590,4e27206b,eaa531ec,1eb5b886,8232cbca), +S(4e85c77b,27788563,aaeba139,975f7125,f3c933b4,8d67ba6a,2e964243,bdd7bb51,200a9d9b,3400c87b,1fb98422,3200aeb8,e6a5af1d,58c061f0,d059c0b8,d431c08a), +S(d58178ed,f0ce32e3,39a524f7,ad389f7d,8817f41f,ed782612,45218816,2a67d4f0,4840df81,5dab9596,93f9284c,54bdee72,f4861d39,3944c648,ecd76ec5,6dd3225e), +S(670f8f7,9b66496d,13692558,d56d4cd7,a1eeb0d6,9e5133ab,4f0a064b,7152fce4,1a72206,6f530586,927c2e39,370d11f3,e251bd9e,eee10303,406b7592,716333d6), +S(10b41abd,ed4de2fe,b7a40050,e61e5982,89a8cf3,6eaa608c,f2a82c63,5788f1d0,532d168d,680e9c74,4d5111da,6aab902a,9a0f5283,7836b9d9,585dbc8b,1a407de4), +S(76abd21b,103aea9a,f04b4040,297894ce,a501474d,9d38d30,8ed02cc7,137bc7c9,b5a432ad,9e92935f,7040897e,3b04152f,693c5f2,cc1e1d53,2c33f70d,185318e1), +S(4335e10d,5e4f02e6,f1b58a0d,ffb473ec,15f735a3,bf96c140,50bae78c,37061db2,1301143b,1f29f122,afcd0230,d46b6b38,b154e589,92b7eeb4,16088968,a7d57485), +S(2b3966f0,7e37e771,ac4c68ad,b8eef3c0,977cb895,2f47676b,e658aa86,76057f67,5382a6c5,bcdd1a01,6d79d817,80faf650,c0a486bc,ea8fb592,1cd3492c,42c91c3e), +S(f7738800,b7fdf237,dc7f03fc,43724011,8b53aea4,4d7953d4,276f3b4d,bf5c0ff8,c1de7924,ef8dfeed,c4fb409,f1a15d4c,5e8ab42c,90ea9c92,867b5b5c,f2921605), +S(5cb07874,ac4ffb86,2da619be,4c8fa38b,e8b261ec,3ec73a12,cd4cf8fc,4f8d5dae,549d1896,4931dabf,ba4553a2,461f2660,87733454,ea8eec6b,f671e3de,60c70340), +S(5cc85d41,7b2ae9ac,dedb1b44,ce78d8a7,8f56b878,1a4b3af6,635a55c1,fead3be7,66a48c79,301e57d4,54cc8644,d2e778a8,45d85762,2c10eb98,d77eb873,e58bbeca), +S(f27211c9,a067b01c,7fe7fbf7,7b5d9b0,eb0f2475,9d541457,6eb24ba4,19fd3db8,e26d28eb,89f7b518,e9ae0b88,fadbfb9b,641d3a44,c59c6f93,ec28a541,486e041e)} +#elif (COMB_BLOCKS == 11) && (COMB_TEETH == 6) && (COMB_SPACING == 4) +{S(629bee58,a391595f,eb20c534,4933937a,cdb2eba1,86d49f8b,845c1b5f,4ca87182,8dae4162,73c6c068,2e2aede4,76efa86b,7612c07e,f72070d0,dc4486f1,47e95085), +S(6fd5e13c,a94b874b,28cd574b,726efdbf,143ab108,1089b846,7b5b2ebe,6c6a3c8f,4a4db306,52c9772a,868b2859,57c5a005,d83f6afa,6e65d87c,700da998,ce651396), +S(609b6576,191514f4,83f5b428,500cfbaf,96871b8b,3348fe5c,1a131768,bb266b6f,90abb9c1,1bf184d2,8dbc424a,bbf74eb8,de4e0582,2ea5dd93,7d1e8b30,e5f695e7), +S(b5ec0263,27cfd922,23a46abf,a755e6fc,547806ea,333666cf,a43865a3,f4ae647,143353c,cc733d02,617f7764,7dc29c65,67a2e245,aed27120,e5fc11b3,95ffb9c9), +S(ac1fff6,cd869ed5,ca920544,1ceb990c,ce304998,10e27587,6536dcd8,1d4cd15,67a7a012,3e5ea292,85dedf0a,9f138b80,58a1d23c,2a233c5d,783bec39,b6482126), +S(c1807552,644130a3,f9b8aea0,29fdccdd,59e03e27,ff2cb1f9,9d13cf0d,42da7b13,85e99587,f77a25b0,bc64b882,bd279fa3,5be0262e,c2f5253c,70a43261,bd1fe361), +S(42919187,2b3c6877,c3b91266,79266e49,9fa37a8d,74d094a8,8c4a3638,89c2717c,1e4bd2df,a9757d42,285cca1d,856b49b0,ad481ad,828d826e,8921f744,7e04d6ad), +S(d4b10124,283afe03,4b278e5a,91daf61b,be608417,fc845e1f,9b9f52a5,43659f2,fd070859,75e2bad6,b34e0396,47b81a87,cab9fb,fdba802f,6ae3cc8b,67cc98cb), +S(ec4c2c4c,722a54ae,edc37acd,cb6ac490,3077bdf6,3f2c145c,7eb25e74,87c046aa,327bfe37,d745283b,a385dfd0,8e30b61e,2b4e5499,4432be41,fd3f0d31,c00e9ed7), +S(559e40a7,e151eeeb,46442b86,aaf4922c,12030adf,7279bb2,2bca24c6,67566a05,5483756f,60d26b97,82033592,cec21681,c5b5496a,c47f600,2013e5e5,f2ea82df), +S(c1d2e92,19c0138a,9f0a34fd,acc92f4,eafe13cf,1c004b6a,3175133d,6cc7bf12,8fa653f2,a20c1262,be59c7db,20f12579,b2adb1ff,54d84ebc,e5ad4116,3d2ebc23), +S(1becc6c0,e4861825,576624e4,fa622c01,139d9cb0,50c12062,9b87ae6b,9622245,d8516472,656ea10f,5b23839d,43f64e,85fc727b,faafcb6c,fc9c6e89,bf9c038d), +S(c483c2b3,8ceefd35,a9fa9e7a,da242c,d618cd6c,8b3bcb62,e39d68e,c1effab2,71964aca,9101863a,d7c865f2,41e814ef,3c20face,f46246b6,4a742026,471b2495), +S(3487162e,40c7efa6,92bc827f,9af9121e,af5ac549,b4ab6585,6353d699,a94a3783,f5b29042,28833bd6,e3ce0deb,dc0396ca,42701752,f930f437,d042cab2,8f135c1a), +S(eb3b21fa,f733f15a,b94ee0e4,3378e9b6,47571aff,d69292ad,a1b107c8,ad511d5f,cd95b4ad,b8768858,cb750cbb,4fa64523,6b6fde59,ceb71dd4,73a7fe48,9e5a2304), +S(21c8dd7c,34d3f333,758d1d1b,72748fe0,8695af46,3d0bd9ad,e4a6498d,1d01e9df,634d8671,7b885f36,a54b6691,35c3c026,667f3cb6,f2577701,beb0d3bb,84f07940), +S(608e33b8,14998177,5d78e286,d5c6436f,99623417,4e887da0,a95274a0,d120b57d,5d094ca1,181f8dca,87d1e043,f798bfaa,f1004edf,a470fce0,7ff8b124,328397a5), +S(f77710b4,dbc5f7fb,ac6b015e,956ed26a,6bbfb540,6a931a30,d4215aed,de610c7,7508a762,a7333ca8,ac244d6,47e47647,c62c82d,387d8df6,175fb563,1de83d54), +S(f37040aa,b0347fe,976d5980,cbd83db5,4d8cb90e,7f2d2118,85159911,af769d61,df228dd7,67fa0d5c,d44c3f6d,b09e662b,99faa5c6,688b088d,949ddab1,6f11e42), +S(7bf929f3,25374a1b,a0cbaa50,db47fea2,a5d1e3f9,3c34bddc,ea5c2250,d8252071,8fe2d2bf,b23a6755,50f16760,a6511ae8,4e4d316c,45d7cd62,4411ad3f,c72805c), +S(261bc0f3,a69d636a,b82248,6132bf91,2ab7ca95,e9a4925,b3f68bb4,745ee63a,68f52f7,df1ec349,77856c74,7b280907,cb3d456f,988ff7a7,225c4ace,8457a804), +S(60ef138d,e7086d09,711defff,68dad211,88d7f878,d616efb6,dbd3d498,5b730243,ca7c3297,3c56b178,b0cfb8a,da98748a,c3d06cc0,7fe050d7,3a6a9695,52500f8e), +S(8bfef3d6,4be90cac,8b83bf20,906b4277,75a6d982,23d5141f,b74e3851,50bc5eec,ea8b6b4c,c7c8d9ba,809ca811,3621c72c,b82006d7,81ff5f25,32010fc9,57858324), +S(9ca85f3d,4ba47ab0,e9fc0a28,74cd10a4,a8ba9aeb,ff319405,6140fea9,6e395ff3,41182ce8,96554f45,93768fc3,a656981e,69719f05,5469f9e4,ba79de22,bcfe8a8e), +S(38cd0c79,437b1299,9567999a,f54d4f8e,82a6354c,8a93a5ef,56ca2ff5,8a1ce180,c96f5ed,d78de5,9f560716,82b60b13,f06de5f9,49206258,80544bfc,73dfa76a), +S(be37e05b,9369b159,6b390290,3eb8fa0f,f221f599,1270c5f0,47edf62e,a1d0e6e2,4fc860a7,1fa69a27,fbefd8c0,906fc68f,4713fa2a,b37aaa2a,7edd3c8c,d100963c), +S(aa640e99,b091512f,85faed73,a3ac8ede,ee120513,b661f812,9a046a74,d624aaaf,dfb48ad1,a01fd508,e5652406,b681cc9e,13d0d600,68411dae,72d68061,6f6b94ff), +S(d08bb931,f008a1a7,38a16200,9fbf1ab3,d3d455dd,47f45cd6,617e81,8b8e0245,18d92218,21c9a2ed,bcaa5d26,2b7aba18,1f7f1e,7f2007a9,ec6f7d18,f038d723), +S(4e6ed1f6,c39c894f,eaa53e1c,e115fda,75fecf8a,55794628,d9a2202a,9dd5c719,1bb97d73,2e0e137c,e9c94d4c,763f9a6d,e1496548,904460d,df1c3a2f,73b66c1e), +S(867e83ae,610a24bf,401119d,8e1af6dd,414a7161,52b2ffdc,50f71f77,2fa8409c,d5d21ad5,ef365994,b3ad0533,92df82a5,6f677cb3,8500781b,a769dd50,1f6d235), +S(6031361c,6dffc505,dc7e1887,bc75c1d9,5a9db023,8b7240e4,c254f855,b35686fa,b9a9a979,c6b8c576,11eeb783,8b4ac2ae,66506bb0,a203fdf6,3efa9b59,98c7643d), +S(8502d0f,34684503,68784822,f4510c5c,562ad30f,be29a792,f0667e83,b6f95773,cd0e6511,763674b5,57fac9f1,bb62f9e2,3163a0a4,cf08cd52,a6d10064,d8b02ade)}, +{S(840e41bf,13203a96,f41ea041,1ec034fd,db0dac3d,53b6bbc9,4f8a3a78,d0371235,71b51550,a79af319,56c9b3de,fcb167d0,c3e318eb,a852eedc,78490dc5,fdaaca85), +S(5678a034,a24a1607,d78036b2,23eaa3c3,845c9f9e,7293f656,7390354,2f714d5f,57f624be,ff5d1774,c6962dd4,d14cc565,acae170c,7aaf8c6d,b0552daf,e3bdf48c), +S(722012a5,57ed9c9f,9d737a87,39954469,ca12ab29,9dedbaca,507c1259,7a27c6f1,6c28881e,a0e62453,80d73a7f,499f05a4,d9a9c04f,c2ba11e6,9fdd0b6,7c5d5ee4), +S(70c638d9,3eeab892,8bccf1e4,82368eac,a03ca8f1,b30f7b2d,34258539,8c95c014,f8635082,3dc2a200,67dfb293,891929cf,18a810f2,5c85c169,159a4b44,b190a029), +S(2ce4a530,b5f6c77d,c0c4d891,6e89b24b,c25c04c2,723842d4,29300f82,5e260458,6f306154,4d1195ea,98b972e,91a962e2,95a2a4eb,9be03949,a789b01c,f61dd705), +S(89e71182,851bb441,c0af4e31,cad89dc7,3947369b,fef12eb6,b1dfa71a,72498c51,20b7ffd5,878718c2,2b5bfdc,ac422794,63aac0da,4bcdec2a,8f3b538e,3a9f574d), +S(f01f06b8,da0ba34c,e1045e83,adb95fbe,b76f134b,35235539,6b07f8de,9dd25869,afa0fb5b,45ad1f24,73460f17,5ff4bfd8,f162262,65c423fd,ebd92bc1,72f3aa7b), +S(f0c217c8,1dda2201,1f46648a,e096906d,71fba006,1b4dfdb9,85dfe59c,9d8f1894,d5ddd6b7,bdf2a6f6,cba166ae,4c01c60,b012c9ee,ad954a46,6f631f9f,928b3fc), +S(bd9acff2,87cc2a2b,396aef61,b0937a49,c43a2366,a2c3c461,c1283987,a7b6f53,828de0ad,b9067b2d,8f8fefe6,ce3a5c94,e7d63ea1,7c891d2c,5f266e8c,a5fac116), +S(ee314d97,2b9c10a4,fec9f8d,ccab0015,d4923e52,d915eae8,b319911c,7a8fe379,82057aef,ff05c496,ba8b4753,c4e57832,aba9a724,adf70a9f,1b3765ef,952ab52), +S(d39fa7b,9b87ee2a,aa32454a,13470406,c8024c39,cf387143,3364de62,cb94c103,5cf1309,530f9e09,c9b38ad9,3a778ec5,533f60f6,4a42e31,1cd97c2f,c984b9cc), +S(5ab1a07e,5f6aff68,16780e5a,23c9faff,b29cd7d7,5bfb8984,4834fb6b,c6b34a14,deac47fd,6567023e,b5ec7a94,a0133bbf,158c0425,c0a6d288,23558986,314d54bd), +S(b1a4ecc6,94bb5212,98e80464,cffacd32,331ebc7c,4d545141,a129b522,a4818830,9772044f,3722ec57,d76a049b,2afce2b6,319f0bbc,b17c7f06,175a288f,3ce3534d), +S(56015e42,81aed744,a0859e29,eb913a7c,b44ebd39,2ed8c0b7,1eb42f9c,9c93c8ba,8f973650,45f7d8a9,24a276ac,20056895,fb2b0aaa,4b35468a,a51f41f,722b9d33), +S(7d99a5c5,21543229,c8f9c7b,50dbaa64,b200bf86,47c71b35,a0105dde,2b3a8e0c,eae09ef,3ffdec8b,9a30291c,244c0a72,6466c26d,fe2c8d30,174f57fd,ec6aba60), +S(ab7d21f9,1e7dac68,afd6e4e4,794551d5,55a9f42,59825109,5b25652e,946ebdae,8805a806,710ed7b0,fb99ff30,130c074c,6a0be3d2,abe6e155,f9c07496,f8b92454), +S(b31a5f85,d65e5200,8f5261cd,fd6d36f6,4b2a1f3a,6f08d7b8,defc7e84,21d0f7db,2e6d46c3,3733b3b5,597a133f,7459ee2b,570ba333,4d1e7648,1980dda,1aa8d2d3), +S(30af789e,850c8ef8,9eeb226b,27786679,442a9a0c,35cb7337,98345400,29220fc5,f6651170,c83e24e1,eb6e8da,ffa0b0bb,a6c53676,72558d44,c5b77176,3d9b5d7f), +S(8d87f808,98fb8007,ffd5093a,bc6bad2d,23e09e90,e6967031,48d5418,4c60e0ae,3d14332c,21df527f,a2e98243,d3ed4bd0,6634d799,9f62efd,e8d6c919,8ed716a3), +S(a961c219,eb9ea127,205af30d,909ef732,8cc599a,b2080966,f615796e,1126dd98,3e235ae0,37b10074,32e5cee5,56778856,1d552e3e,bf40bb82,5b527cac,8e1e5b9c), +S(b9c2de21,40cea728,2aec5293,bb77dc7b,550a72c8,84389c05,310651bc,7570f2ea,74171cd9,4a5683b7,5bc7c5d9,b4c8fc10,1fecc3b1,b7349ce,840b6ca4,877fed21), +S(cd041ff2,e8191946,8fd7ef0,c33021d2,9533cd75,64772252,c686f718,7e33166b,3f54a9af,e8597bb,faccbbd2,9280e60,93d31bc5,b366aff2,2c95e21b,fbca6041), +S(adfce0b5,8a9cef85,e690b84a,c7ccc6,8f5aa4de,ada5e265,3720412b,e1f19ae,8ae2dcdb,c6ce83be,825593d6,87f9afbe,a88af079,564c60d5,c9b88898,897515ea), +S(833a50c2,cb5507c6,60bd450e,cde341c9,64f2809a,e400215,c52dfaa0,9825df96,de85e216,493cdb4c,4541f720,201f4c67,1472b6a,d61cf8ea,3cf54ccd,a4584b77), +S(3475027a,628ea423,2d689d70,d45e975d,39d62303,282b16b,1f94a427,3d7ea746,97c3052d,9270df78,6efbd2e7,beaa58cd,f864e28,905e3ab5,507cb9aa,e3c69160), +S(cbda2707,e61d9e40,124668ef,7ed83973,dd293dfd,221396a8,d27e7aa1,392edcb3,fd5023a8,af8eff08,f0e3c8b9,b6a22a99,b3ec3aeb,7e0104dc,1f8409cc,d83d8a02), +S(963722ec,aced2105,2bf447fe,619a8532,dc78816e,2e17a111,3ffc601d,9bec0381,f31feba,259f7d0e,3c326c69,53aae60c,1e0479da,5ca839ea,77c6f1a4,9419172c), +S(fc531e1d,49d2a984,83c861b2,b299b8fd,b26831e0,3bced6da,5c4449b0,18363be7,9f9cc9b0,8d72ced1,998c6329,a17695d9,c94cfc76,ba9f6943,1c5dab83,60f2942), +S(dab255f5,b47d96d8,ec5272b,5cde4ca4,33070920,84aa4866,d53b674a,330aea2,feeda13b,a544f090,b790514a,42064cea,509bb3f3,9dbd4567,6bd75414,37579d7c), +S(ac5b161c,fcc42998,71b49d1f,8cf35bd4,dd6bf98e,5f84f2f6,420bc363,b9cac257,4511d4d3,1fa26d7f,e56f671d,7467bbd0,41358b36,b60775f8,65f7d491,3d17b685), +S(b62fbfcc,2aca0706,b0fe67f4,ed5d96b,4a65b048,f73e8f4c,9782e1ee,36189e31,6549e8c2,f77bc824,4e1a90b4,e42ca64a,5ade1768,a0996d69,8d7b047,7bfbf862), +S(56938443,5e509000,5cf3dd18,ea629078,e15097e9,da7bb5c5,737cfa0a,a40e8818,f86a1815,4f379054,11016994,9b2eba6b,477c32b8,b68091a4,4b14990a,5e8eaf92)}, +{S(7c028bd1,75367939,74871a6b,cc957d95,3813331c,87ae606c,17aecbdf,a704ebb4,4fea040b,a0ef0319,91ff9b8b,7829c0c3,93895439,d506c5c3,1a1a3fd9,e32e7e59), +S(24e966d0,bf1227ca,11eb8fd7,8dc5369d,2bb9b681,927990b6,dd02b948,fc18a169,72b7fa7c,f929a6b1,c556a372,4149a279,8d57f504,4b50a1a7,922cfddc,17308ca7), +S(a2b7db3a,265b30aa,94823577,6d5ea839,c4fe564b,97a5e3da,313f7fc4,5de617c5,5e895546,a2778162,4a91ea4e,c104c911,85f3e954,f8378fc2,bea41a3,f1cc9e15), +S(e365c695,449c9976,cb67ede3,325d9229,ee526349,e6b255f7,f4e72184,6722580b,eff99cdf,a0920505,ac37e46,b812d47b,31a29113,e491208,a19e3edb,557ac2e), +S(c3d90905,297c3a65,2c6c3d5d,915cd9c2,d741f472,4a47c8cf,35e5cf3,cac9dd11,8e9ebbd,34a7dd02,24fa6e33,193cdd72,4906dc81,a5aa41ee,4a34d3d0,4b2ee5b3), +S(6e4e23cd,ee4388d6,e8b61f8a,af7678d1,a62b3e1a,3385d278,895a02a,de4c9f00,f69b843b,ae39cf41,11fe9b99,a0287057,5695421e,e1ea690e,2e76d937,e7e32c01), +S(92eb38a6,3743088a,39b58cad,4eb4a27e,a8b08c27,444d704,6d2aa5f4,89713217,22af8d6c,d3567a6d,cf7403ef,e0afea02,48ea4266,1577005a,9afb5f2a,19611864), +S(b3c84323,e2d022fd,d2a80d07,203f4a26,f5d32dae,62842072,9663a994,3a829d08,9a899de,82329d94,83b88e1e,1bce53ed,8714cad4,c68cd491,1b71bc0a,e3839821), +S(daae5199,57a6002,8958b22e,6dbbee20,c4bbd8e1,7ed589e,b8528f35,7a4dbb40,afec8a03,321586ec,ac38e941,7fa8e342,f0542193,59decf5e,56479a39,c32f92af), +S(7afb9a56,89fd1344,cdbc5c72,62dff7b,718c2e47,a6e19ec,665af795,86ed0161,d1c2c9cb,60a191a9,a3db7e20,2ebc2eff,444bbaa8,d81ba086,6f8825f3,8c765f53), +S(8d0c4a2a,e72b54c6,236d997d,61a2a24f,ddbd39c7,ee16f1e7,d7c45b22,b4bfdac8,15a58f4f,fdad9e3f,b4d33c7e,170747cc,6a5abfdd,bfbe5814,ef0c3611,6a0a9e91), +S(24d8c0ca,53400126,347e67f3,72f19298,595b6d33,76ba2f19,2fba6dd1,7b57bda1,7c01404f,bd316814,f10734a1,559049ca,d6f20e90,d6b13ed5,f9542630,db77f9ec), +S(4c2b7a58,87a49df4,f98cfc72,22fdd832,362b8cc4,c5f4fff4,d0a20674,c9749bde,c2a1cfcd,e8636288,31a5c450,fb5cf552,c76e581f,9274e5d9,888a3a68,c37ca349), +S(2028e381,f42cc2f7,a8829308,bb72881e,94e5b54e,3331d848,898ccabc,bf971cb,16debea0,203f0709,d9b55b0d,2b8651b5,cb085d8c,8f56708d,c1fe4d33,a616dfab), +S(d11e0753,f72b7c4e,641ed50f,84dfa24d,a0baea77,98fcf062,8b2696ba,a7ec2529,55af37fe,88324646,777387e5,a9b18059,ace20e9,becd7488,5e43fee5,fa6809e2), +S(72309865,b8a1a6f3,9d6d561f,43ddf5b7,f2d022ed,95df130b,2563eaff,9008a95,f3fca0be,3ce7d9eb,e1648964,58eba87e,934d000b,a535f223,868dae11,dd5230e), +S(adca4785,cbf38a0f,28de7b36,daccc761,89b8b918,f3fafa7b,abbbd9b1,4ed5485f,880d76a6,fbcce864,657edb9b,349f124d,1b22c7af,2b0ff833,40d7a0c4,84b49de0), +S(bb43e0c0,93d58c6f,3946e58e,4727d7e2,d223c84d,513c4e2,222406bc,aafb03c2,c00f7dc8,fcbd55b3,6a95f2f4,a3a07b7f,9599736f,af099a69,e2fc2630,a2aef1d5), +S(179eb588,d1c7aa5a,24e51f5e,6d86e4ed,2e6f0f98,bf956b71,ec1caca1,b7f775cf,42f461c8,a784f643,d5a8682a,6ec9b470,455f0ab9,f269140,b1ad2376,95f64afd), +S(9144fc75,b00f8608,714f027,16b30575,be19dc01,d3689e8d,2665d967,6a077d11,b168c324,7dc6c31e,8302b6df,a2e7c053,dd849538,f9d45b87,14d889ec,cc789704), +S(d6cd2a7a,b7253b86,34231eb3,2793f062,bdf103b2,4fade912,6206e745,a3b429a7,9903e507,dc5e3a61,d73fc83c,5c4ba476,6ae92655,9b208369,bee55948,4bfe444a), +S(264845ed,623bd3f3,808ca51e,517def45,1fbc237b,e47e3ded,70c3769b,391a9f83,cb5022fe,3d535f4d,192e73d8,5d9ede23,78e0824c,e560a97,d53aabdd,f8717377), +S(2df9621c,cf3e67da,54c47ddf,81e3ba7e,7b50e713,cc7d08ac,d64f47e9,85c4f334,8058f6e8,139d8e87,cce4a389,c470e3d8,45da3537,ccead4f3,abbccf42,a5fcc49f), +S(ccfd6c4,c5966144,32d2efc4,1ccfa0eb,3e0b44ed,a4558128,c3e4d68d,949a5cac,bc77b87b,5f50d3a9,6b28d5cf,fb371b4a,36cc1360,15c548b3,f98d661a,beda8acf), +S(4e2e6052,cd35d585,6531fcf1,73bf124d,3c569bf6,6cc54ed6,9a520d42,cb836296,6381d100,e5d9ae50,f1821122,b8e91a5e,f365edee,556fee1c,2fdb6d17,3fd29c65), +S(6603d715,ed0f8725,7d9c3f29,cf86ad4c,aa0500ca,fa16a708,3168e265,b87d0255,9d2eda4a,6195e2c4,a4576e4d,5d02383,a3a01b2c,f94ab8fd,fef2f338,15807d31), +S(f09ef30d,fade81df,2fcafe31,387ed34,5a8029cb,e93fec3b,eaaeb8ac,8adc9803,f9f3039e,5b73c7cc,cf841eb8,1c15203f,ba192e,9eb39aeb,36f56c29,44b286bb), +S(ebf4611f,cb3a44a9,f9d5b00a,c559dbb5,394840c8,41a06496,bbd2011a,2508cc34,1e183324,9a610584,5d62ef4b,685152e5,c75c7525,c703f81,51bdd87c,6fda0d43), +S(31fc3226,c19aea7b,4845ff2a,ddeca6a9,36505a49,92102cb3,499d66f8,a6e1a3b5,49babd41,b1e8a6c,a728f971,d8d8cb76,47cdb94b,89767a67,fd975ac6,93f144d1), +S(be1e37d9,dadc4b4b,7a5ba74d,fb7eb55c,2b0a4fdd,81564f8d,51038afe,f716e3d2,de6f0c3d,b6efc974,975a7d6d,3c6e9d44,a712879e,4e95c612,164273bc,5de1f4b), +S(f8034e14,2425cdce,31e82b49,cde33ba8,3630d1ae,283b8b47,73960539,c67f1652,a302e3b1,860252a5,e7114568,748746ad,1e02c2e4,280bc913,dd4b4d2f,92a561af), +S(21e709bf,369cdb2d,b7f51b10,f0ff56c1,2c1938d6,18419d00,34e57d94,7b83d5e2,d7e09ab1,2e7d04f5,aab3a75f,8cf75876,ddc3cf0d,cb4b9526,ea7f755a,dfe1e495)}, +{S(638b6618,c1498946,75a1a943,8755a68,30d7dd3c,9d8a9f20,d65a7161,9c8b477f,e4e66035,e947c73a,c34a48b,b43a3762,d1038e6,893dee23,cf658a12,190d2a56), +S(4b6ce93a,acd4954e,cf0febd1,fc9a965e,ae7fbc1e,e24a12d3,a4b86573,62eb255d,8cea4838,1bdf4e5d,79e25ed0,1aab94b3,5f00267b,3ec7eeb6,63833507,583407b3), +S(e2a42110,3e8e2a80,a6451f71,b348434d,7d508023,beeed16a,d87417b8,5c7b7913,5fc15b62,124014e7,fa8f95cf,78ce8415,d46a1f97,d88be55a,76431786,8de3d605), +S(6949956,91582c2c,2e14576f,5ec0dd37,65133237,a4e43369,633edf69,933d1f75,5ca8c2a6,329882f5,2daf48e2,e291c48d,febbbd29,9ccc9ff,3ad54ed,33ccef43), +S(55d836af,2dd4b8a5,7f20eb57,6886790e,a3ccfcf9,2a2940b3,646f263d,685f62cd,7cc1ffe6,37781c72,d3cc26dd,9d4147c2,183c8e0a,95b87742,52ac47ac,19db266), +S(442a3090,46bbf3ef,503a138,b60ddfa0,ea4a5901,ae801003,f3f18ad9,9703a44e,129d9913,eff78c49,16e67c4c,cb658784,fa47da35,92ea1c98,4054b371,a275639b), +S(76981efa,29944c2d,9463fc94,67a92e1f,9403c287,dd595292,4860aee4,b78626ca,c87cb5c9,ce93ff3c,23189404,cabf8e09,996c4cde,e67935d5,874c705d,6a7f95ae), +S(42ad08fc,2a1eafc3,d793f04e,304831e,c1bae89,c7d00b24,7785d870,904bef5c,c3913fd3,6b8c08c2,553b9c48,5b90221e,ecdc8d02,6d558bc2,5fdd6ba3,df78ed63), +S(4d70ffbe,efc6254d,cee74a89,70244bd3,384b3af5,8510ca61,258fcbf8,f0c82575,ba3e19d,b022a75b,c75cbaea,84ff912b,867124d,a20e0d28,a007fb74,9a9d1c7b), +S(4ec8dca8,7079487c,adfd516,da2df139,5477b524,df4aa6d6,4db5e206,cfb14b9f,e88e5bad,c8654d60,fe1f8f6a,73328209,63bb10cd,31aae381,ea1b4d9c,eaf9cb27), +S(2e5a47c9,a47cbbb5,ef701784,34798a6c,48244df9,dab1e5d8,83c7f732,b89c7d79,7c8202dd,cf7fb6ec,471856d5,830d59e6,99c04377,c553d835,f64cb333,cc405c35), +S(3ca98150,bc5f116a,e7034a07,628d698f,67cbb8d3,74869ab1,534464f5,5e8ed24f,fad702ec,c6b738de,5b653f78,f51c98d2,1e4bad57,4db97730,58324d1e,12b89f9), +S(f414495d,9093ad22,11e001f8,b07b38bd,f5430a11,72899bcc,2c553b55,a9d4a225,bc130e93,998db229,6aef128a,5b8e5b9,9cf67eb7,713aa7d9,9fc4c902,af660f4b), +S(44e794c9,5a28ee80,f9b64193,9c626a78,4a851a4f,84f28887,9eaec508,1b60e508,b219e000,1b07a275,f63dfb3b,e977a40a,f505be1e,d3eb8194,b919b9ea,70d7198a), +S(35024622,bc17bec1,9c352280,297ddf7f,41654c08,61c3744b,13c74ed5,6673b98,64aece4c,3ec0b19c,cdbc06b7,4eb15704,50ff689e,6c5bafb7,6ae99396,12f4cca0), +S(45c4f36c,ac4c4738,ab216363,e12b2475,50b8ef09,7a986ce1,60b0462f,f8725a58,fb944806,dee59834,7d256885,3761e3a,9ae666b,9b0ee095,fea33ec7,bbce9a5f), +S(20a0b4f7,cfb58bd8,d09d008d,70e7f807,b4fa61ff,65f2e15,f00bddeb,55df1124,7961d1de,e98ca40f,4d09e5fc,52ae4916,cafdd6e,2bdb9f9d,2776239c,a3480157), +S(fa10af8c,eb2de4c9,3c0c2cb0,95f95911,755b19d9,90f17e33,69930d6,6002fcd3,68a3bfb4,533bb5f0,54fbf91c,b771b08e,e388a61a,9727bb7f,a3a1f67e,60b2eba7), +S(d417d7dd,30ebe9f1,7d52edd6,c82d91f9,25d5987f,a6f53b0e,d769a34f,e557c11e,ea89c810,619e32f2,369258ae,8ad8a456,cc36d87e,b45a42d3,83956039,62e437c8), +S(349b002d,ecee0e4,1788a3c0,cabb9ff7,c17848e2,78ef8905,63924c55,52d59853,47583a2e,7ff61b9,6fa168b5,1191b363,efa3e0a1,ce825a3c,5bb04e5b,e403b4b0), +S(4b8efc8d,7eeb3554,b5128e8d,ce20c29,697f79cb,29f61b4e,a2f7ac28,57910bb,e3cef657,7b5c0d2f,dee52c96,b6353073,b099fc9c,65688969,24cd744b,981c5ff0), +S(f356e8cf,5785b05e,e99a2b4,d202b64,2b1e98c2,57741e60,7241fb9f,d3f5ea2f,9079fd65,59d5a93f,91370d16,20ba487a,a8c6ad3d,e67f2c83,a1c335,fb5398a2), +S(bfb74aa2,15e5ce36,97cb6156,c2666ef7,1b579a50,56ff60ba,d3d5e10a,7eb2d31f,3def8a80,ddc3f407,e30d11fb,232f0e31,191bba1,d51a7eaf,b86d7f97,45d78dce), +S(658748bc,bbc75ba,30c969fa,371fc1d7,76c32a5c,7e632201,264deb36,b296ad2a,c173fe4b,14ead07c,2c6574c,8887500b,53f6c02e,dbd4048b,e69aab41,9267ef9f), +S(f51a5ca6,fd6dde25,447fa46f,c0984d26,66004c02,8d402624,8886d0d4,604f6ad8,fd4290e1,7b2928aa,f2e03b98,97252b82,d481c4c5,ad4edda6,16dc1cd8,e7ee83b2), +S(20ef1ab3,491b8d0d,a1565e2,8dd92dff,efcb88f,e88c6c2f,6b100b30,b58249b6,6814d32,7b5b94c4,12fb770e,2fc4077f,fa9a336c,9e7db2a4,bc7dffa4,286eee0), +S(d98785a,82dfe5de,343bea0,d91cd8c4,93344b86,7fffe1e6,efd7758a,90cdd899,37ad7f7c,5783d262,5204bac3,4405c207,972b7fb4,cccc3585,ee152f0a,48ee16c4), +S(3885e910,18a66e64,2d3f0c76,bca6dc82,a6916cb,1e46a858,7aff5ea2,d9390689,20765590,83ba89c2,14be9178,46e40553,ea195c49,de203c9,d175296e,a4430819), +S(c88cf650,3b50f5eb,7bac15fe,2097ff76,9c57b983,1b5d05c9,fbd8dc58,d4a9a746,b6443b76,64984192,e7056478,e9f372cb,21a0c7c0,cfcb0e84,850443a0,25ff42b6), +S(2831fddb,2ba2d301,2dedd58,a3f47434,3450985e,80e4e4c1,646745cb,1abc69d4,1b04e1b7,db84b6c4,882f264c,7bba91d5,2256dc97,fdd22e58,483dec32,5020a257), +S(5e492bf,c9d19dcb,c3bcb9a8,b7bec84c,23c359de,a78aa0a1,e0522232,df037abc,614fe5b7,cffedd76,35d371b5,2d89baf0,55af687d,e6c12d80,b221d0b3,9d03d0ac), +S(bbc64d06,681957e9,685c9864,c5f9bfda,34b4dd02,6b749399,a12bd8de,87f311e7,3c525096,dd6b7d11,26c6ca50,5064da63,f7f6a203,87594f4f,e4ae0403,fb4d66b6)}, +{S(2b00c7db,16887372,753ab219,17092563,8c603992,f501b07c,9d8442b3,721addf9,8e7c5f66,4c2493ec,77cc74ef,d9221235,f26bd3bd,6f505347,39f0fe19,c41b9fad), +S(56b9a3eb,d9360224,56267f52,21ade9f9,674863ee,4bacb7c9,ef0155ca,b36b336e,2e2b1a4d,f6c150c8,6dcfe9d2,e2836579,f82ac4d4,2f8fa4d5,d814b952,e92da69e), +S(ff52bbc2,83bd15ad,523e6d08,873a8896,9449a1c1,c5ec8570,ed532000,5a92aa3f,dd9c534b,e59d3845,a1943435,1a20513d,1a829424,e65ed8ad,60342b38,6578b21), +S(84f79356,86b0d45a,13a1ce22,7e7c925e,d80be5d9,9fd7e671,270c4c35,7254e9ce,3dfe2058,1e91dc25,12c16951,c667fbe6,83192bf3,3fc0bdec,c760dff6,730f82be), +S(db14da0a,86bcd275,71cb9348,36268bb,85c306c8,9ee1b78b,83c247a1,71c7355d,66ba535e,81e877b4,71b0b75a,6545970d,6e33cbe0,ff011e3f,d653d026,f4fff395), +S(28bfbd9e,44554371,74a4c24a,cc65ef45,5fd4d39e,b466e94,358cef4b,b0eeaa5,5f5ce6de,2925acc9,e503d731,d46601aa,7e668001,669819cf,fa54b3e3,dbb98f32), +S(a7b21a3f,a07b4049,7f9f5087,c763b431,d5f04cd0,e7b7e0dc,f9c6c664,df7c6ac7,daf23f35,b903ecc,af4f50cf,459deac9,85d0d008,3b5afa73,7131a61d,8591bf9c), +S(12fac42a,40935aa,e881894d,245b9691,cd1f6ad0,e0481e1f,444e0ccb,6ee88781,c519e0b9,e3c19fc8,f67c07e4,f357f43d,589ec23c,7714f7a0,4347be96,4ca572fb), +S(5c2e28bc,94f8639e,50133dba,9b6c8a35,348eefdd,2fdbc18f,2abb792,eb8807dd,c546b3c2,5f2809e2,7977a8e2,3a1c3ddf,36229f31,434c90e9,1386ee84,b64e8fdb), +S(e8e73382,fbe8b94e,58bef90b,aeb28305,d27ea48d,9c5f6e08,ef47e4dd,5fad6b78,d3529a2e,86240f06,a63ba03b,ce419c05,24d22622,fab9107d,aaf3016c,6ff7fe3e), +S(26b93629,ebe68d1e,878e94b7,5babd663,6fe1f6f8,659b155a,e10801eb,c2cc51d9,f4630056,b3e532f7,32238911,555c0ffd,f4951c9a,b2f45119,cb12e774,aaa2666), +S(57b3b642,431f793f,24862328,dbd271ae,19d343eb,c3b0ca7c,affe4fcb,319d8d94,1d7ed35a,5abc7e39,1858a9fd,b90f907e,6a065648,c00f94a7,75f06d2b,1cacef1a), +S(c2123794,d98f0311,c1327522,1767236a,6f45cb14,8fcd65d7,e0be8d13,2a650953,d5a382f,fcc2ffba,3917763d,ebe0549d,66f358b,d727c281,288551f8,4ecd193b), +S(16789662,9208b510,7528efd1,36036980,994d6c3e,5b34c69f,ef3b86a4,3db9e8f2,217105f8,39b0ae0e,932b5207,e8e7c190,3ea463c5,40c043aa,e4f8b106,97ccc84b), +S(3a0b8ffc,83a1702e,214adfc3,79bec5a9,753274ef,9e3271ca,8ec5b067,a5f3b6cf,2c3de01b,f27dd574,4496c2a4,75a07e60,71ee60ef,7eaf1c94,c257418b,744d1338), +S(482e5ac2,6477feb7,6c848d58,40173d87,1687c5b7,3b2970ec,b8dd69e9,3393f923,dfb3995a,ca5b54a3,b48e1dc,107023d4,dbd7a918,6adf2af0,61f92160,76e7f78c), +S(3869373d,638a30cb,63177204,bfb194f0,2c6ff503,3cb4ef1f,b146741a,f3b495ed,f2ac9f3a,ca159c7,c2ce9f48,e895c543,d3f19066,74f335b9,efdc4b47,4ccc23c3), +S(98c16ec8,54b34ea2,f08aa4fd,3ce1877d,4a36f2a6,4e673191,17f74e5d,86e57f4e,3448646f,c9aaab0f,4d9ec298,8f7c07ef,448888e7,6318e0ac,552d7cc,b59820a3), +S(1b3a4ebc,8ad1c200,2847e182,de7c9eba,f0f7a408,e2aa172d,484bb9d3,ab897b73,b93decef,69cf2da4,5c3a2373,ac2abd77,311fc1f9,21e7df8,5f5b3504,a5ecbdb4), +S(57b5b2d2,87bec103,e4aa7b96,16129718,64780441,fb5ef847,19f16d,a1c909fe,2c2d983c,d8c37a7d,653716e6,15756121,9e5ad5ab,25664967,67a0fbd8,e8180c71), +S(cd7e277b,ae1498a1,8e7bc00c,2c299a49,69f6862b,bf96e6d9,f5143db8,7b582115,f9548ddf,c27108bb,38f80025,6ffdc25e,28621c17,c370a40e,5009b968,d40660bc), +S(80615f12,82ed7a8f,bdd70890,77c24f18,c03fa395,3cbea7bd,32a26c7c,260102e7,8d54a3a2,83383d6c,a633d17d,e2f4f756,3bcc3826,10cc1012,3f2f192b,e654c2cb), +S(9b16f5dd,c8c8c8d,53786b49,e2d025a6,838f6322,700fe105,7de6d78e,92281a9e,a36aa3c2,f2034285,76f5c570,63bb1bd7,e6e0410,2e1cd2dd,f100a54e,431ca08f), +S(f1d04075,35ffd40f,2a0b59f9,14ecf368,67700c5,b33e15c5,153fa9b1,c724d36c,22a8b48e,4db1d3d1,28cc735f,99db74d9,ba7457cc,67b8fb39,7b38fcbb,153f7c0a), +S(c252ae6b,cb711704,659c37a6,f425b215,1ac8a4c6,63420eba,899127e8,1d8df3b7,8e9a75ab,c5a2cd8c,d44331ea,b07e5d97,a30c6619,8e382261,642c0e10,8f6d46b3), +S(59f6fadb,4a8a3389,999b93d4,cdf1f8f0,4735b397,9fa5397e,64df420b,85876ed5,c6e8baae,fdeb7019,23a68b71,9c88596f,60742a38,db04d7e5,76bd1b8d,1ae25a6b), +S(3c2e03c9,3f610ffd,db519c7,80c201ce,b58ffed8,ee10e21f,d1610e99,33fd08c7,d339d979,38e1c5de,7492e7d2,d64fe34d,ed889d48,54670345,1c51432f,ec6c829), +S(59d16070,f9147ce5,5bac599e,aaace0ef,24c02ea6,85249cc6,ccfbeecb,a4bba83f,8105bf41,47f22f7b,18c73941,3a85ef06,40bf6805,51c68a10,e16be920,193977f), +S(3aca1182,3f31b2b,a12e628b,604b1010,62c45fce,22e15dd0,8b9b5ef9,a53dc02,bdca8ab2,d2dcab6e,3a98e7f8,7e192c19,cae60952,fc6f54bb,d46acb49,60d51c0a), +S(261e9b93,3648c7d8,d5255219,fd0634eb,112e1dd3,fcce0a04,135b2784,e67b5e32,e0eb5ec4,30b1f9ef,2bd10916,b21f4fe1,4cfc80c,2bc179e0,fceb8678,ff933068), +S(75918e0c,a0f03b34,40cd6239,c108bb72,f293a881,a1f2e9a,73c604b8,8c451c39,7f02a925,80e50aa2,5b786d10,422f1d80,2c42cb37,27f09ff1,1f5e0dd9,bf6a6c1c), +S(42025e76,3c05c64c,311a275d,d6f1fb3f,2da2108a,39ed24be,3de83123,b1c1d1e9,dba2eec,7405b67c,a1915b13,45702062,7bfeebb8,6b90dbd4,87849e5a,756921c6)}, +{S(ef2c5fa8,b23285e3,50d7f05d,bd8c96bc,6e662824,5b10e1cb,4b659bc5,ded5836f,1b37679e,1177b653,8975790a,4d5d2abe,3626d636,1d863e0e,1db5881e,8e0c54a8), +S(a1d5a92c,93df3c75,a06f9c2b,a604789d,fd487513,62d957be,68c033e8,3e202fe7,64c1c00a,3964fd5,b35fb52,b423b285,77c8d269,bb1ffd16,325c5e0f,7be08bdb), +S(ef13ec66,d46813ce,68038fcd,541e5e8,bdbc970d,337d7b5b,9099d0e4,3fa4288,7ad7f4f0,c8345229,96341248,b1455ebb,89aaeb6e,1ae9db25,1b86930c,9f779fd9), +S(aea7cf4c,afc1079e,e61396b6,2df9bac3,bf334745,54af4678,8621e337,4c7486c7,c0538605,5911c893,459b98b0,4be449f1,2e9f98cf,ef4cc292,9975d42a,f460d65), +S(8f082b3b,6476b4e9,ffb317e6,1fec0cbe,8e389041,1fdc87d6,8d4d26f5,44c2e6e3,eafc2bd0,d6570a7a,cf8bb5d1,6cdc1020,456473c9,e7fec1b7,fc6217cd,89d0a2a1), +S(e0d6310d,e5e664b3,164faddf,39c93676,4ddd3f0d,f5e007ef,5293ee35,980ae0cc,de093cfa,ca1033bf,47e88723,4978758a,74b93cc5,2cef48a3,daf4dda9,adc79ccb), +S(2518110d,5d064422,5ead0e2a,5ac8b8b6,b1fb7fe1,55e351c5,1d39673d,dab0f6a7,84f0d6e4,b497043a,95b6af9d,e72cd502,a7b6a68d,ecaa01b0,9e0d8ff9,9d8a16c9), +S(6dc820b8,5db42353,c97453eb,d7d768cc,af9732d7,c261bc6f,8399caab,34cf5b93,30b168c0,2509e2f7,2035f60,8be8b89d,577b6e72,540f521,934fe980,7412459c), +S(bddc1c75,5bca9911,3c9ae05d,c14441e,2c707fe5,8a329f8d,feaa36ff,12771376,8c0087ca,b7688dcf,5a3cf1a3,3c27c7b9,cee36007,3aeb9b9f,d7088623,af20f62a), +S(b6e5ef5a,a84c6d2c,a209d50e,8fa8e1d7,93c61ed9,bfbc22d5,2ecf293c,9489ac13,f76e3adc,a89cb983,b6b670f9,5a7e774a,c015de5,1ba56417,40ac1f68,e3df377a), +S(26699dfe,93788eb8,d91cb601,cae628e5,75e8468e,73f6cefe,588755b8,c396071c,e5f9e00f,bcf6f1cc,cd39ab13,41cd06b0,ef2e789a,17d761f6,6a7a83b1,c036791f), +S(72f7e16f,77f0a4f7,92db2cd0,354382af,34282dc0,7b8cb290,a89a5d60,894e8090,54d32ecc,2cd022c6,c03f1379,657450b0,db9f08e9,6e2be5ab,5233dd84,62733cf), +S(f84ae7f8,a03b60,af9cc359,36f0ae78,96935b2c,534f852,8ad159bb,6c0b44e7,68f4dfc6,20a354d9,d6904bae,67792622,337e3180,ab340828,80bf04fd,f47cc23b), +S(5dea33b1,b5207880,6debbcbf,83ca17db,4617488c,ac5c6997,ad4092a9,8a7bff7b,99976fe5,ae88d36f,597e16bc,6dbbd4b4,547f4dcd,7e85786c,d10af30e,1d81bbaa), +S(31be76bd,4f946e41,7de73037,ceaa0dd7,c6eccedd,74399e14,2ae6fb2f,d2b59def,54ad8748,ef129085,dc3172aa,904cc376,e203fa69,38783007,2af33889,52cc6549), +S(b6124d0b,f603a00a,22662897,8dd0da87,fcaca5c4,fb04ebaa,81a7d13b,39f2e307,34ce08c7,4463b06c,afb03c02,583288eb,7bfa6f2d,3eedfed4,91e31781,dcff10da), +S(6aa4bd60,90bee70a,295c451c,c8af72bd,3665680f,545f46c0,bf5af990,aab5f43d,9c2364d8,25406b76,94ec9db,a0ea2f9d,bb36fb2c,5bda62a2,bec941c6,874e68f7), +S(f72faef0,e268a7b0,a9b00a57,3674d846,c1f0dcab,c9a586da,be318b1c,d2874d8b,16b3cfda,65db0f3d,1b5274cd,20b1329e,61ea0404,1f702e71,cd98708e,28c9307), +S(1d26df15,98a6b9a8,7c0a6171,767539e1,86d51d1d,cef130da,1001226f,87872c5c,f227cd82,becf5493,e2fc7635,6a37bb48,3e681a19,ab4d9dc7,92edb114,3a7b072e), +S(28690cb1,db697840,13e9eec4,d9388723,4c28451c,cf9dd51a,746d1274,b13b4610,d9bc39ef,19228981,a1ead1f8,94deb254,162fed5d,cbb58a76,6d361e04,3d8f62ea), +S(4b0b5258,22dbc31b,1966b004,4d39c5de,f2e16d5,1e032045,f9973b1e,fe83ca12,2db33ff4,3631fdc3,b3608b40,7dd494f6,ae730212,9619ae35,f6ea08eb,51aded12), +S(a5b4e205,462ae419,8fffc1e7,393d366f,c5a9eea4,e98c67ee,1684d63f,cc09aa64,d3c11017,de4ad175,17cd076f,cf6c0ce0,4d3108ed,60eabdf0,935499f9,4226078b), +S(d4f1af69,2a3e9fee,1f92d892,b14eef6a,a0ec1f4e,d4d455f3,c70bcb19,52fa9837,115c7ee,73b90adf,f142191b,eca0be01,7d5a651f,93e2e90,5a36646e,21790294), +S(c275c715,9d6e9757,d2adef47,2ee53856,dcf067db,bd4f380e,892c9832,708d46b6,70da1cdd,853a0dc8,a6a9043,3c319371,25590c9,5807284c,ae168f65,62e4465e), +S(d2e38b27,83156e2a,a8e4eac0,149bf2bd,bc2918af,1cfa2a23,d1c7136e,15dca7b,738a0fe,751ecfa3,459e005f,72b7461f,a4b5e1ed,736420d2,22c5428e,2ec1348c), +S(f8f5b3d,b3659174,e0149fc6,fa747c22,9607c434,8f9eab60,900bfe92,b23f9a4d,d89eff33,94a093fb,549fece1,4e11028a,614cdce2,21d5ac26,1bc25f32,dca3919c), +S(5e266403,e49fb860,e6ed0928,45bc0811,a214a0e,dcd6174b,290ecca9,3539d862,ab300acf,5d8b8a14,2fc9e93f,ea995d2c,d7a2bdb8,6a146f65,2b8bd49c,4e8dac1e), +S(8ff869a7,60230ba6,aa5adf91,1ba61702,17cbfdc,5ffa4018,b8a09b9e,4088d634,db5a5aae,bdb946db,80e4c207,22ce38c9,4921bf41,47eea510,70e5aac5,c592f32a), +S(f3d39b65,95bd5ab9,aeedc43f,f49bdb20,73a211f4,5ec2c1b7,72226a97,a31c059b,ea41abf,9322d733,bb5971ac,194da6a0,a6d41c6c,a0d0acaf,a53e17bd,dabcdc68), +S(18ba0c34,10169914,7f7589f9,179b94f9,daed92c9,287f3468,d283bdcc,d71cc637,b3512d25,c199d2a4,c115bd11,eb53d6a1,6ef16c3d,97be6291,5ff76b76,890ba675), +S(2cf3354d,7f96c58f,3c6336a0,6fa30c83,8da767af,48f89fc5,5ced5b40,e0b86cee,403ac306,f6c3ad55,be1ee5bc,29cdd46e,2e3d83ac,71050909,5f117d21,7ef015cf), +S(5d31d140,f754d6c,5943deb7,6aa4d867,cac81abd,9911618b,82327795,da8d085f,c25f99d0,5bc5d583,a3a72b41,4e5eac5f,c14ced01,98247ded,79ba482c,882bec49)}, +{S(e0ad91c6,6ca95326,d440f44,df91c1cd,cd3ec344,e906d0ef,51fd4a48,31ce293d,3559f3c,e349f7b3,cf66c17b,2c3fe7e6,8ba3804e,438c0816,b68ecfe2,30da18d), +S(d8b8c50c,ae9f285f,d6d9282c,373607d8,5fda59dc,71ba0066,148b378b,37440076,ef83dd08,ddc115cc,24948009,f9eb4afe,dcd65c64,b6ef2194,bb4ddd0f,ece180e6), +S(881fbbf1,a9627bd,369abbc2,edda8026,a61b10f,4161e442,530a5e36,447a0290,6a63cb8f,7e5094d3,c8beba5a,2a1d7b54,bc33005c,efdd5a1b,20d51f74,d00c2fcc), +S(36bc0df,fd1441be,1a4efd6a,43ab9d83,243d44bc,a6e108dc,fa9a79fe,23106f0e,eeec58b7,dc37eedb,4432dcff,4de7f88b,2a0e0721,da2c0a72,eadac4dd,71037ed9), +S(7652c155,c2ca8a23,7680f015,a62c7c31,31682752,a99c4329,77ccfb9d,cb58b03e,5339a51b,36ad4548,197d3018,4bde4428,b38ed983,d624bd18,a5f8c4e7,21871c5), +S(904774bb,fb8b0c12,e2b3f91a,e5a2a0c1,a92971f9,86e29fda,9edc609e,e85b222d,ee843f1,8039e251,9c7b23b3,725ca099,114b4f0,26970111,35ded92b,94445e2d), +S(1c7c82cb,fc14b9b2,cdb3c12c,32df33b6,a08e7af9,df62f310,79fa0710,f28f5f95,93471b5a,17c84eea,a45948df,80c0f56,d8684f35,1aa2ce73,ab84b3c,1b8250a4), +S(bb060f5d,971ce062,427a5630,8f114532,40ec54fe,6479d5e7,9ce81444,27f07927,fcbeaa69,8278eff3,d4dad904,836c0233,40a866b2,d8f66774,70d1159e,201501dd), +S(287c5b8b,8dc168ea,197200ea,97c4f63d,db0b620c,7f30d623,7934f856,a558438a,260630e6,ce310eb0,366acd78,bb58f4ef,27fe4836,edc8ff0f,5d5ff987,b659bd20), +S(7d4c5c6a,d6bb0f0a,47b45a35,1264f4e6,a81ee0b1,65a7e665,4b226c95,feb59dbb,e89691f3,ceb4c57f,5aabc1b7,4acd9aef,41531851,b41ec1c6,608f16a2,2243ab5e), +S(ff806f2b,9eaea4f6,47d85077,d8aa5052,9d4b96d2,1e0b31e0,7c86b14b,73b7ab4f,9acc2f77,a994997c,7a2b1aa0,79c0b5d4,c84f6715,e4a50e33,628b871f,8885ef9), +S(3ce795ba,1d91a9bc,b0260654,3450ced8,c94184dc,8a41ac5,e1b84856,e88927de,3492e696,cd1ab2dd,587d4707,ae34fd67,3ab7902c,d0c0972f,ef419795,1ad88a1), +S(299ad528,afa3f36b,c80a757f,f081a8d,c4a6ddc2,d2b57fbe,1e3d361b,ee5a5d8c,9fe823da,74eda2f,266a8e9b,331d511b,623dcd32,ef9ab7a7,f1d1cb4a,7e6fa65c), +S(bc4b0549,16177aa9,b52b29b7,cb91673c,9ffce4c,7d0066b,e4249383,4467e3b9,55bc6436,7db68687,e699cf6c,f2db9dd8,c2b9a438,8202fef5,11acdce0,ab06f969), +S(a8e8b02c,ff5de02a,9e6652cc,6fbe41cf,6e87ae0a,abb14ac5,a178b3d9,e697d0a1,285d4af9,405b03da,c57c993e,4b40df8e,82c6979,f8de57ce,4543b7ef,3381e0a8), +S(e50aa8b6,d7dcc055,4f406959,b056dac5,21a7842c,ffaf09a1,ac24a3d9,8aef5228,46656395,ee84d061,a9f5788a,cb05975d,5ffa5fae,edced564,1f81b5cd,2491c23f), +S(cb516899,98a214c3,c31e4f2,692cd7d,fad6f1aa,eb8afd1f,b29c23ce,429c224b,2292b8a4,5a89eb80,167238ef,2027f975,98a2aea9,a4460c5,3646d088,82403c63), +S(ded04c06,74c6eb16,557b5bed,4b6703d2,cc37c6aa,bae466e,ee7b5665,6693c3c9,4f3ea70f,8e75b02b,76934cc3,645d2af,eee8e9d0,8d100117,40e8a16c,dbf01113), +S(f3d0a253,edb74436,897e6cc6,621c74e1,30457b41,e0690b6f,7b2a203e,8ccf8ac8,89cb07e0,97495bdf,403490fa,d58eefe3,e79ffa33,1deb5cfd,2c548ec0,8771be67), +S(d4c66267,aa73ed55,bd68fee3,2a166a4a,4ec660fc,4cb13e18,fb6ab0fb,19a5f330,7c2efa2e,4509b221,97589483,40b6c74a,8ee2b5b6,5fbb794,7f838c47,ee03e2f0), +S(dbe9a638,f262f9a4,b3a8955f,22293feb,50ef4b32,20df0184,f363a373,d7110981,4c563e83,5e957756,5e6a8996,97510c67,9561972e,5601c1cb,2f2f789a,c1e0b5dc), +S(70c7c07,1b1e6fd0,a97b55cc,5ee34297,166f4d02,417a796b,eadcfd43,96e1b338,b5c49a6e,2ab03e55,f4755f37,e5211d4b,e23339d9,d464fd28,6781bb29,56db23bb), +S(aabc501c,6d52961a,a613fe66,96f0bacf,fad74fcf,8386cbf8,b18704bc,a1392ffc,cb72ba86,70bc3f7c,85a00d3d,76b11596,6cfa0fc7,44b31e01,9129da9,a5b04b77), +S(47f72ec6,e7820788,f0f7814f,aefd6e2e,af5d90f3,f877677d,ae72569f,c6a2e8f5,6709731b,ef2dd880,4696a6,a0661d13,fe579704,5e0a9bc0,e5fdc0af,789c5830), +S(20026251,d9413e42,47a5884c,209b144c,98e36f7d,8ef3f56a,68efd475,8a2ba8c6,9c5531b6,94ba0d24,a943d0c0,94bb623,75c798ca,c9716181,a9d659af,2acb978c), +S(8dfc6293,9b300c9b,fb617d23,6885f652,424b4f12,d04f8bf1,151d1ccf,935e445d,9a519433,18e94107,5472aa9d,6ec3390,59bd3bcb,bbbf6937,c9290e48,9da25f8f), +S(afef3520,3b558495,6fde0eff,5cfab48d,8fb08806,3c1d7cbe,d7e352c2,9d49176f,a764e6e7,bd0c8fa0,8a6f7f30,aa38d7de,fe71773,fb7ea484,68b3fd9a,8adfd650), +S(354c0a98,1628dfff,8be8ede,ed809db4,bc39c686,39a26828,ff28dd47,90801c46,8ff40299,d607036b,acd7c0ab,66a102ab,38f8d3a8,a271e2a5,20b43cbb,687cce6e), +S(da2e7eb1,1a1e66d9,5001ec4,f7b66c1e,d9f7d0ba,ea3bb326,672b9069,5cf4bebb,cbc1c7da,b9bf7e0c,dea9297c,5f45ad0b,9c4fb093,318b55f6,1e4a8951,726c4021), +S(6f780994,d0662667,8fa74156,4232bafb,b3a7f54b,a5b66507,9df32545,c192c3fb,5f11f0f3,af1a763e,4c9fdcb1,1e5e57a5,6dfe0d0f,f27535b4,4343a312,90e375e3), +S(8e28948c,729c1438,5bd09316,31ed3eb8,7acfc5f4,2a9eb4f8,afa50362,33591cec,2c09fa1c,bf0044eb,a78ae81f,bdbd4271,2a89ffdc,f7d476af,881d29fa,2627f250), +S(4011cf05,a85ef14f,1875cf3f,4f78a51,a52a89bd,a8930a4b,8e13802d,b85f319f,35045b10,45c4f71c,c762fa78,5b8d4daf,aa2a1c07,ba37d82d,ee0592ae,ad807810)}, +{S(9089bcb7,1c1559bf,e17f6c0b,91fc098,c63785fa,18a42d69,798b063f,a0930175,de229175,5e4ebf17,1047f79a,37d81b9f,9004a7cf,df747589,7365e174,ae367969), +S(4d1caeb3,41f25459,3b06f715,9e9418df,e29ee076,76c26e6a,51d8add2,5c70a5d1,bf773e4e,4151d17,650aa7ed,1d6a5505,2d622264,75c50f31,3261aea2,cf68dc37), +S(b0760330,517c0d66,2571cfae,830da7fc,a7e0d86c,1ca7f75f,5150f625,db50ad2,d8d10ef3,9c84bc13,32c2cc01,4d4df0fb,45e5c546,1849fb1b,81b7fdd0,7484d35b), +S(3db731e4,273e5b20,2de984c9,74b4112a,d0feebe3,7bb0d2c7,db38c7a,21bd8c67,b425c1d3,46b6a61f,2893a3aa,a243d60f,5563cba2,40018cca,3f80925f,71f4f1b1), +S(3a74a50d,cfbf2ff2,5c99c4d0,1a13a917,9f510c2d,eca1d5a,7ac8fb69,7eb9795,d2b468b6,714681f4,57bc586f,40585c01,e1dc14a1,a42ce887,9ce044d9,ddb92d82), +S(b9139ad5,4f44fed8,4917ad55,c49c23c7,8d62aadc,e83c9ebd,9efde865,cb1eb298,18068856,c80abc3e,2a02a441,bb7a7609,aae8d2d7,8abf4e2e,378fa3d0,a27aa900), +S(bcf5cf94,5887f183,e58a0128,4ed9a4f9,fcf918dd,4e68d70c,5a54eeff,166cb44c,8235f63b,bb06a1a6,d9ad2ae8,47aeb2b3,4838c962,9608943a,93294c6d,e21a3ab9), +S(4b598ce3,a77680c4,c5f66e90,1b76627a,27f35301,9641520f,53ea3894,dcbbd187,357af043,f77cb9fe,c04ce1f4,dd9b610f,9151d15b,3b7383e4,ecc5384a,8ff7c5cd), +S(b588aec9,2dc045e9,a95abd7e,da929837,28b5a7dc,d637001,ce7f0917,1283b16e,e682f53b,5e94fd84,914b7bed,5afc28a,30ae6f53,e12d948b,3c0d88fd,adc5d0e6), +S(eb8f5080,218ac5c3,cd792042,b59e80ed,e3857a75,a81d67e0,7c2221de,d3b7a677,c5f272cc,3734e0f4,6a5cf40,626973ae,1aa76839,1953f211,eb52693d,254a7fc3), +S(87d119ee,65a60dd9,aac3e784,22049cfb,4123d262,ac9e7473,4c9cc418,fb7ce4f0,5185ac,7bcaee8f,f1334eeb,cdf2c39e,83b8b665,1ef9d8f5,48a029c6,464242da), +S(cfd0438b,186d0f5,c64b5f38,a190baf7,35b67512,a439f486,fb79d501,90294683,985edeea,243e9c6b,d9c57cb5,c7372202,7492156f,e10bd2e5,67edd14,8603daf6), +S(52abfb67,5fa8b12f,1b0cf0d,8e85f402,47696662,64c7252f,69562590,839ce4f8,8483ab43,2d4851d7,4f432c0a,8e3863b9,783cff58,3d4c390a,9865d7f7,d1aed67f), +S(52926df,cf12eebd,3008459d,3c91dc1,73532f1d,ce3c5d0a,874ea4c,67331787,18b48fe6,1bd74ac6,4b34f2d0,e7de8920,2c875625,bcad84bd,cb3c81dc,cc86dd87), +S(695e09db,8c4479cf,4c305005,b5737ca0,63f89d02,aced2010,5600d65f,58e26401,32123a91,8bb23fd8,79715cc7,488184b7,53e0eb00,6dbbc95a,ef9d815f,3833c08d), +S(97c35716,e5aac70c,45dcdd45,a5ca0155,5962f09a,cc22c16b,c79ec272,ce1c12d3,93869464,6470f8e3,c0db18b6,2e4378e6,5caa7203,c4d6a079,a10c8182,b8eaec3a), +S(35197cbb,8da9188a,fc60faf9,71cf08fe,73372e15,f857b93b,6afd77e6,bf4db7ed,4e0efeb5,2db601dc,a539c777,14f4aede,c5ff121d,77dbdeee,7f16fb0c,4cfc19af), +S(afb2f842,e0818237,46c294b5,9ae8afd2,279e834f,100f7d1a,58a9551a,98408d49,5bf5ac43,a3609b4f,f058d6dc,6ae09fec,19a19864,6d12096b,6bd3e06d,95d15ae8), +S(a37f6113,882459,b1dc6335,26253a8d,287c9285,b7862721,f9bee74a,d2c4c09b,9ed3252a,303c6d,e01c9985,c5b3edce,1074d478,db56b961,d91fdaf5,1b1d07cd), +S(4579a503,cb12a345,182b28f6,9a3fb98c,4a80579b,2ff592d1,ab18b32d,212098d8,8c61c503,df79dcf2,6083f15b,c3ee1f99,9e1e0960,8bf6af9f,b3175699,cb0e32d5), +S(545031f7,883a2c8e,bd56a405,52719096,4aa1d40d,b22a1730,242f3064,530ce326,ecb024e8,e762b456,f62072e,5f471180,bbc817e7,54e830ee,7757ed7b,df5c9300), +S(b127fb32,bb3e193c,99d232e,d50dcad0,3b45c072,e0d521dd,de72daa9,e20e97b4,b198428,12a344b9,2e8a8d26,f7964c66,82cb3652,66ab3e28,2ba56197,a159f1a), +S(28cb3582,d312cfcc,75ab637d,66c646f7,5157dc74,7a464e9b,933c0820,2326b6cd,a87042b8,510ef9b3,ecf918d,916128e5,f946f43,6f18fd5f,ad62c46c,5882a23c), +S(8a46cb3,27efbeb6,850e3861,c4845ab1,21414f12,9fb27387,4560826d,c9116886,ab09eda1,9156f1f7,194b7b17,fce15268,ba041c96,24765ce,fd964ede,d1f05b3e), +S(b73af914,10ad56f7,d490dc37,1a2584bb,633de0f5,3f00cd0f,6b8a6019,53c7ef16,3dbf4e52,753e5d33,3fd23cc1,c839f278,38eacb3d,5980cba5,bf1be426,b27641a4), +S(b38c1896,427a0108,3f24a917,2a64314c,d9dc1759,60971135,1b2db6f7,d66ab745,d3a71a74,f80d6919,b65629f9,80c7757a,cc49c2aa,78dc67d3,d6f76d06,91a90d85), +S(6f6ac108,aa819a27,6dae862e,276b3ebd,8ed5a3ad,9b0296e0,4f8b65a7,f6a5ac1a,e3048583,7aa2140e,de381363,788d6d95,25a7ee33,9e3a3ed1,2518619b,30d9f71), +S(72f5809c,7c282ab3,4dd81851,33070d85,53999a6f,14fd753f,2ed8deec,ed7adc5b,112bf5fc,8cfd71e1,84ca1967,d05da765,801f12b4,c852768f,60afa7f1,e9576534), +S(4c348833,10f7dd6f,b385ce25,e2d6eef9,8556a59b,5e79a084,ec83425b,37150085,9c4c97e1,be47b073,5209ecf1,5f05cd8a,58ece74c,1b35a92d,96a70287,11d95add), +S(f16e4513,2291b577,ab360b42,c1babcdd,ac61e623,da85819,e9c4c73d,463204b2,5556d7d3,a2d45955,28781d15,16b59aad,941ea356,1b5c88ec,94d09314,555ea64b), +S(3580d3f7,896fb70e,d48d40f8,1b31a72b,51405574,2c2b4369,e3e7dcb,aca4ca22,e38da3af,f409e459,82098305,87aa0eb3,b2339959,75af2e33,501115ce,648360ee), +S(407e63d2,c0cd6d37,84c27734,f7e517fb,4bdf7847,296dc7c,a8714fab,16199828,2dbe5da7,4b29bcc,fe9adabb,69157830,987ac51f,389c6001,2577f298,710025f1)}, +{S(f61f644b,e2414c07,66c6caf7,5d32683d,efafb133,cb4d341d,7eb565e8,9f6e4158,2848548f,15a6e7d7,2b2eefc1,1b76e318,15ebb4b2,1e3bb938,e0c2e9d4,5ad4f7d1), +S(5b891f8,ec902550,429a5ea8,33fc29c0,bfdddf6b,a6f62c19,87a14050,a9689a9e,77901539,1ef92985,6d3e3b35,4e4ba2db,3bad967c,dedf331a,c0bff08e,f25f2e99), +S(d8c5a617,62655ffa,c943ba35,3b595b46,88012282,af068e52,d918bbec,46bec87b,9263db7f,6f74aa,df0dbdaa,7e7ccd76,cb3a498b,44de2bd5,f9b23029,2ebc6009), +S(2e940645,cd189edd,2d6cc2f4,f9b49e4d,305cfe8a,46f2a596,fbb55200,89fa5b21,4c197028,e89ef8a5,b5b6cbb1,3733e90,408877fe,7425d58,1f4bd063,ce286fb2), +S(396c3bd0,9c6af07d,123a8441,c9f79ab3,a783b8f3,fdd69dba,ba61c7ec,f65e3098,534c8657,aeb8cdc6,ea34b372,68f1c70,70881797,46b8e335,477c8525,cd17aa8b), +S(c34e6be,b079f3e8,d1355754,4246d2b7,a82d551b,740b4b59,b9220bbb,768796fe,57806a7,653ff7f9,3d7cb6,b3acf68e,aed049c5,75988fa5,f03b1ab5,1103aee8), +S(5d2d6aa5,252fc9b2,55d89773,e920891e,7021f233,5f7d0ff8,c6bde5eb,b65c5149,1fdbd2c5,6b8bd095,2d16c304,8d9c588b,2a26379a,17f748d,f1345695,1c5959c4), +S(dec812f5,745fcbed,fc36c635,76874bc5,96dde8ef,68a8724c,201b6af3,be7c6e2c,1715328a,f75f9661,d58c667e,5c5514d4,c99dc881,8cfbe702,e0c3c8cf,662e6906), +S(32499061,83487250,f65684b9,9434489d,3a83ec93,61531dfe,48086b2e,b2bd18fa,53217af1,2a25fc6f,45555d93,98fe46df,4247d38d,7b162e34,945f8928,bfe148ba), +S(d3e9381d,83f31116,ee161490,c9b5d1e5,7e086c6c,1552160,2c913315,af033ddb,97ae863d,34271b26,a4d6577a,32028c12,f092a54,8a18ae1b,a83de384,3b8fb84), +S(1347dca6,d097faa5,7c6583c1,c292c6b3,ed87b31e,9f7afe8f,d0d151ee,50ebdeb0,570a9be,e4806ee3,e30696c9,71b5d905,65d09ee6,8b4fa8e2,8acc54c0,7fabb492), +S(691f9995,af2bccbb,f556f624,b28a1da0,67854c15,4f014e92,a56a8cdd,9a43c25c,81babe0,ae44984c,bfdfa958,4dc5c677,881d1b0f,63993075,a3fc462d,e986866a), +S(cbfb62c0,b91cedb2,5a9d4b3,ada43cac,7839dd18,33174711,24688ca5,5f162cb,77c12161,e8199410,b040dd57,4d90c39c,2f1b499e,6b7c17c7,fb21438d,aff4e674), +S(53627516,8de62d6,2c792f64,f87996af,3ed8ec88,653532a8,ad60942e,cae4a339,d8449a0c,c6ae32ff,45a11652,97b3d3a0,57e67c64,42d3bdb1,ea2cbcbc,cf0655cc), +S(2a81679,7505601c,763e6f6d,f7ed5c0c,14ee7fbf,d75b8755,7bd57f3b,e2d3c7c,99f26af2,10540397,b8423da2,c4809942,63734d99,f0d642d8,96b5f216,767b759e), +S(54b2c03b,7a7ea964,220a255b,bb688767,99ff1b83,f0934e4f,fd03c2bb,51490e22,b3cc56a9,ada9240a,a3730828,26733090,ace3d7e3,91200d08,2cbfacfc,bcdb9c08), +S(aac88c8b,7c96e629,6f023e5e,8f260324,9f4e645,bd701705,8f38e9f3,a034eb57,da03ca87,b98ab6fb,e4869756,7c2db04b,7f9948d9,ea65d93f,d222d52f,6d48c552), +S(bfdd8394,fb49f93d,630f6b8d,469da38b,105529d6,70b9a1ab,e3196816,d2a13978,39a97919,4249f78e,c336b00e,475722e8,7ca734d4,3d1e97d4,d2aed074,abfacbe9), +S(5b5dc3d8,66ba3647,d2aab2ac,3338abbe,4d1ca08c,6cc6fb26,4335f40d,4dfb2331,3432ba31,46a0f15a,beca45e4,1ded8729,e6a0a49e,70315745,bfcb3388,4e1b9e64), +S(77057b28,a1d139a1,91e05ad,a8d72f3a,c7bbd198,7647070a,b6a21355,7bc0c73c,46f32321,4519afd2,f830cf7d,567aacc9,47ae6b8f,8c841adf,988e39ad,e7b9757b), +S(f6c8d1da,e28a3d23,2a388998,1b638b23,f381618f,18dc81ed,67bfa696,4cf1626f,2ad8c92d,43378941,8d298dc8,2cbf288e,86d21467,ac73c0e3,383ef3e0,a03142fe), +S(b75b5cc3,77a55310,a3b97067,34f1929,fc0db732,3265e6da,71405f37,729d5a90,be077940,4dc94ea3,3cff505c,e1aef457,bc120359,521eae05,1de1963d,b1948053), +S(a66d54d4,4b4d06ea,f141307e,27e1c225,41274eef,5c0b1743,e6398b22,fbaa4068,51b6b8a8,48e1c27f,107f82cd,d0554643,b9e16611,fa93b789,a2199b3e,3bdce296), +S(56b2f9,ab707dde,3479d0ea,baeb62a7,6cb9bf03,66278eed,559e027e,a1ea6b3b,27c47e9d,646684dd,2a54db0f,c245fcdd,721416f7,22ed568b,736e3e1b,f195b379), +S(a9642a49,83b19c3f,f5f63ea2,9e76afbf,a25dd0c0,221b32b7,6e67373,36e7f5db,8ada3766,9207c6b6,a6b6006b,5240a4d6,cdb8b807,c0c16a56,91289b7d,62b3a051), +S(18eef8d,f9e64c1c,548db40,ad77d92b,11f3ac43,60c63792,5f7d598d,7d8d5155,806db24,eefc3a64,c84da338,937811e1,20c6d0e6,9cde79ee,9957a4fe,c53d0e12), +S(d11359fe,61861a36,8b3809cc,c727320e,42905036,774d0e83,98453ac0,68d404b9,d4182ce7,2500637c,8e14b977,34fcad09,f061838d,57c555fa,420fbd50,9abf6b81), +S(7ea072e8,f60ff273,9cad1d8f,c560f208,b54149a2,5748900b,50830e3f,738b2db2,af09e54b,d44feb44,b39956af,fdca6894,91c7c6fd,f029e71b,e780f8f6,77a48a0f), +S(f53406ab,9fb1317,b038dc28,f0165abc,115b37fa,77d23bc9,e51993a7,8a15ba00,a293f429,f7fb281,9cb60b53,b2e6f07,afb6537a,39a18be,a5ad4cfa,55aea13a), +S(b1674e5f,9f194a16,94fd12d1,4b64ac8,bba69432,241aefd9,9a1c49d,23287635,83cb0060,1f5c33be,9436d946,22c3b3ce,68d20733,ee1e2392,8c3d6c14,a7cde085), +S(22b72e08,66b96344,ee53b898,ea725f7a,b5832c12,7c0881ce,862ea945,5eafee85,b886e8e9,cba29b15,be5c22d6,ada99b02,1098be69,d1c500fe,6fd2ef8b,f1ecae25), +S(9b7151af,698a85d,2246c88e,8ffb14a0,c762c2e2,64ab70b7,e30e2434,9b8370b7,fd9c3d89,46ee9d90,e7fb6d26,796062eb,4cb6c160,76df4834,eecd2748,c8a7bb4b)}, +{S(5ba26c2d,53b04b63,d260c6cf,392786d9,41a1a7c,b88331c1,149cd3b9,9c207f5c,9c7f6303,bd72850e,d4da618,3427e7f3,eee078,6f67cf9,85d483ef,79c2eab7), +S(f7d26944,6d29f81e,39a44a88,49f12184,b9f42eef,16c5d88f,60c96a28,cf0c3e48,e7ec965e,d0a966a7,45087e09,a058421b,852c8a7c,3790a3ef,7abc6ccc,e17c6084), +S(98590b7d,36bd2ef9,37ce788b,22cab951,d921724b,87c3ad83,8263416f,b5a67dc9,b711c21e,5af72a36,5cc1b220,7ed09ebe,be918555,55e9239a,e9b03d75,c0261d5c), +S(92e1cc4e,5f57514e,9ed13535,5f3e2cda,b0b22f8,8f56a972,a657dba4,7263463d,14d296bd,452f2faa,7d6f42e1,550fe35b,3c47eb2e,fe7636c6,2eef90b2,e7822da8), +S(33de9b1b,e153bdd6,efaf9d1a,30aa9b3d,faf26a32,4486b6aa,ecb1f958,f11c4673,7ef29223,4d3a565b,c0f0e295,deffa3c9,a86a6bf1,933a084f,9334b790,51eb0270), +S(f9fad0b7,e1dfd4b2,47cd2cbe,bd863e1,95b3be25,6cf7a707,5d422b9b,f5631ca6,fd5262f9,e6ca0cee,e1c7e531,83d9f3c0,7ac518b,c024681b,56c06a1d,1826f5ef), +S(455ec5ea,f34c02c6,961469ed,27bc7883,c07c9a18,663e22ca,83830a66,569b2b36,4dbf1b57,a7de2fdd,7c0380c2,b38fa5d3,697a5995,8ca0c0f7,6405244d,bff4c9), +S(940fa05,d96fb400,bac8fa39,e696c536,71a490d7,c98b3851,ef76ed35,c62bac19,b6de17b4,1a045978,5755497f,1c2a953f,17554b4,20f2ccaa,9fcfedf3,5afb9b46), +S(16012402,4ded6478,72374af4,6daf9c2d,a9000841,9a7d4672,98b627c2,420981b,7c2607e0,a4b86f7a,d5df7371,60987d21,35d2ce2d,bc422ab9,b643d080,26f84323), +S(caf887e3,339046ff,42c629ff,c954873,2c629ecf,319c44be,6701a9f7,c81bf842,d253a688,3b3d51c5,a914ffb7,46e7ab68,70c2b1ab,5b7e46c1,7a5119e8,4ab6c878), +S(41a5b720,595bfc66,18406547,d59ec09b,4efba0ec,5bbd3191,9e9256ce,f40a7afb,87ee1be5,2233ba8c,82dc06a3,6fd0a1b,4ee8d7d3,ce89cb56,1dc96c19,dad79613), +S(8bdcbe80,fe8533a,174045a8,3cf9d89a,ca438ef0,8f6393cf,6e24d923,edb02586,8d21379f,c053e8dc,c628f0cb,83a7782c,b4e946e3,ca88d467,36232762,fc6f8fdf), +S(409a4482,6b6f0ff6,36178d65,aedd64cd,2d28b39f,3e9cd93d,a0afe712,b75fcd19,25a3bec4,74216dae,d686825b,bee6aac,487a6d07,606e5aed,7c3032df,f4911eba), +S(b7f414a8,4c0af927,64ed5b52,e96dad38,6995771c,2cd90af1,1986bdc3,cbeb61c0,702b0a68,4e93f0a6,26b807d8,8049db6a,3e65001a,d75a476c,e4be230,89574e8e), +S(58b0cdd7,bed4f327,bcecd493,d835c0f0,e45f6fa4,3687d1d2,f19de285,5bcb5c11,21b0a478,2c1d14db,9c67817d,7b23db21,a96e456e,62a85c3f,2a02c76d,78dcad10), +S(c75cbf00,893447ba,5b3f8462,9d6897ff,64be841a,9a6bb714,54adb849,8df03900,15f68903,ae20ae4b,9b3fc7c4,f8135936,c09de15,18317dde,bcf66190,2db79f72), +S(e6258fd4,b63be23f,38361a16,cf3f81cf,f2d7343e,515b2d0c,ea0bfe38,6d4400a9,aedca212,9b73e49b,9757cd7d,a39a1e92,f885b267,a188521b,32089ae7,6d351eb0), +S(7c61b66d,d76f759f,be92708,8b075147,2ba10db2,eee4f0a4,2eac1ad0,d2dac3a6,c2b79de,70372e1a,6c9449af,2612e34a,8e101cc2,81ef378b,97cd77aa,bff004af), +S(29c71194,bbe41f4e,b2f58bf5,799616c3,7b247283,c993bce4,630929d7,55f7c8c4,c0fb083f,d68f63d3,599c2da,9d0c1f03,b6903545,a47581ff,3caecbf4,359e0235), +S(f1cd983,5bd3eb61,f8207495,48da075b,ff4191ff,d5b1521a,a1f4413f,2173a68e,beac8102,13b643a9,4658cdbc,71713894,39b72abc,f8644697,2fe6310b,4ff0233f), +S(94f2137a,ae170855,3af3dd45,8f8fc9d3,c1bf07e4,35a62798,25d5b93a,37380144,e952d6af,b27f9b2b,80ccbe89,59fb8b15,5fe1b2db,f3ffbf14,cf9c1fe9,b8e8209d), +S(f4f0cd2,e28cb8a1,9b469b18,90033912,4a40a39e,67ae1642,a3a677b9,fa1a9a3c,75412f04,5c41770d,73d7cd77,bce0da96,1e6fc69,cfc6cb9,8f691d43,dce1e548), +S(15ba2fd,b652ea98,f2b326ee,e5e1629b,ec8f8e7a,36078d7,cb8a80c8,c943e98a,db416844,cf757376,cfcd5a9a,9a318b51,184f8c89,fcda3d97,e735c120,43d47c35), +S(5754903c,ffa8cb6a,3ffe3488,e484c498,69163b77,7c07183e,8d2da037,78b8da34,508312e,6c2fd008,fac12bd,afdf8e50,1940a81b,d05efd38,5277a85c,ccf125da), +S(3bc76f6b,8abc155a,dbba76a1,9c0fef85,373bb1bc,9775f431,1b3ccb12,9c7fb29c,48036702,aea467ec,daa8b809,97c41c07,9e38c414,f798bdc3,a531b08b,fb4ae303), +S(2992c410,306d3d40,313ef69c,a2e3383,88f592d4,a9c2bd36,ebd9f51e,883aa33,cdecc5df,41cd193a,ecb26700,baa42486,a0506372,d56de3e2,2fa09156,7b525519), +S(baa7d83d,6d70a528,e6392adb,b2af797c,72772b92,ace96a25,90d65c37,b0ff1bc,9943b555,4e44b480,28815d8b,e50189d3,6617e9b6,c8f07393,8309e04c,9978fad7), +S(935488ea,4c88c2e3,cda6c0ab,5b42d519,e7fabe09,fdd3e36a,7c78c9bd,730612fe,705c8f8b,228be0c5,539eae13,1f4f4bdc,2fecf6ce,6cc567c4,dc692af9,7c1d506d), +S(8edeb68d,e63c35e2,5e36bc8,61445a63,8b0637ab,d14557bc,f0b0648b,db43f86a,d20bd0ec,14ef4f35,68954130,6577ef85,baeeeed1,c1004130,80687a5a,94a9e9a3), +S(9a39617a,27c2ff2d,9869acff,b22fad1e,a7d04271,be154547,43234f54,7f21924b,917bf9f3,fe0563a9,8daacf90,dfdcd8eb,e657f023,3fb15711,79bc5ce6,e6f5dd56), +S(41dcb02d,21137ea3,a179b469,199f9ed7,9b831923,68719a4e,5c727ce0,d42e95d,4669d53,82147266,8327cd6b,31c21b80,d3394bf7,fa29a43c,2ed7441,d866f5e1), +S(d4e3e3cc,387e0364,6688a62d,9390d585,a69ff43e,1060811,431dea8,d868355e,3309af2c,b3d7ca6,55334f2e,c53de6aa,debf5d57,1618ecc2,9dc9830f,ec46144a)}, +{S(90edfd0,61871350,b7f1f029,c4114190,b050065b,2030a400,9a8a7a6f,4b92aae8,872d4f07,5f60ae2d,dcec2f12,98a22da2,53d54de4,fde85560,690dde89,1628db56), +S(27e3ce53,b4258f97,a499f408,ecab24f0,60aabae1,dafe992e,5a34952d,5e6e486,d393fad2,9be684f4,7ecec306,332ad969,75b79d29,b5863d98,5f959c4c,b8ffb442), +S(420f1078,27c75c95,d5bc657b,a46cbe2b,415a7d42,ad62cdf1,6c84ee89,22215379,8b257a28,e0b15fcc,ae0b555a,cdadf4a,be93bbb3,a208ee45,77710a9e,d58da7fa), +S(28859abc,b60a95e6,b26c0996,566bf798,60c1a194,2d3342f7,9655f286,32f9d5df,2a770426,5eeca5d8,87840cab,3923d868,aa7b7b18,f9d19941,738ca006,54ccba6b), +S(c33c317b,490e2266,2649a021,e87f6596,3897633c,90be208a,193f1d52,28614059,af850be0,d18708bf,d0e1f523,c1a4fda8,9a6c156a,55f82518,2bd99bb9,b999a358), +S(2333793d,b961d3d6,740fc725,6cf9d833,81b5dc92,85b6d83c,5c343aa8,5baea83b,accc199a,ced3012f,b6db99c4,7a36c30a,f88e7eee,b62c2ed4,1352b488,ba0167bd), +S(4834aa89,caa9c25,a99ee4da,e4a64c15,25a5d74f,9ce573ab,ff44b63f,c3a578aa,fb189539,448a265b,eb87a268,b71a18db,f12fe8ac,e502720,c83ca156,c1cc7a39), +S(432cc05f,c78b0d56,e605391f,e4708bda,a1ff3edc,96a729ca,aad3cb0,300c4d4d,6675d8ee,ece8c078,e1bad373,247ce383,d4c65519,4a6aed20,a7ca5eca,34a89c30), +S(874fda6c,b284ca2d,a216bbda,28249388,88da3968,7f615ab,52c8e61f,b72a1fd,2d7199e2,b0b88f45,18e6eeb1,240b2ffd,a9bfcee4,6f754a4a,3db7959,dfe857e6), +S(7fe21a0f,3ef67d60,1de05f67,2b163285,a5577948,ee78274b,19fc35cf,2d2f6801,62fb2ade,5e2fffe1,28542038,91a6ea73,aabfa35b,1f7fb000,95190adc,de6663f6), +S(cd0540e9,efe497b6,2beb2227,a2da819,a1ac3bed,8eae24c2,6e2991c0,a707dd69,446c3218,7d0c9229,d65dad2,1392e4a1,66445386,4a5c1620,bf768fad,20a45c06), +S(a533c295,74e78024,52218573,66c30001,6159d772,f5bedcff,28d7f7cc,3051457,b61a106e,e0166d54,5e1b945a,f3e4e285,31a34cb8,56a34dd0,cd21184a,9555eeee), +S(5e144f44,ed88845a,c089331c,eb58811e,4c164e02,5d1758ee,51a7a522,c66deb30,ff95cab7,597cf62f,e1aa8df8,a2cd3844,d71ab4dd,4eb02a9e,6175077d,261e2540), +S(97487a40,9562ee2,7620fc2b,c5bd55ac,6509d487,8ab41257,53884b97,7c5a84be,e52a282,1430c540,5f1143d0,62b69faa,16592f02,cb9b8602,d52c9fc3,70769091), +S(906f9ac1,d3db4690,d74771b7,f1940679,b0de7731,a68d7d35,89caae34,c3760eea,6f2be7,2275dd5,1e77a066,b8d3c303,f565cb97,b8fb0dd3,14445d18,876665a6), +S(4c355a31,d17617f3,5d4066c7,a125b2bf,1d6f77e6,27b585ba,2d271a29,a88c81b1,6a686e69,237b75a1,a1ecb86f,b715e858,35aa0686,e2ef10bb,38b762ca,5646e9db), +S(15aac1a8,9b6b7629,57375d4e,aad87c9d,e1fc2617,89e57d29,731fe96c,1380140c,2968c0b2,2c3dd83f,3286d37a,639bcc14,3d89e75f,cac1da56,7e07799a,62af1008), +S(4642f29b,37b87118,65767998,d00b41b9,fca6718d,bfc55785,1c459efc,2ea15037,a1ded31c,be33cc1,425df851,998ddd11,1518ed13,f84756c1,c7cc46cf,3f5e9a72), +S(9554abe,9e092bd2,c4ff46a0,abd0b7c7,fb73d85f,1c01fd96,83146559,306ea727,89e2c07d,db1fe6b0,9872ce91,66ce9ca8,1124986c,c7e48e09,f80aa3cd,70987711), +S(1c0977a,a773c56,2e36dd15,58b95fff,d35b4dea,ac464011,ad7b79cd,26227238,e04ce4c5,b0b165e9,87dfef97,d32094ea,3e86e6dc,33a4c96f,c9470336,34b0db68), +S(71d44171,60361c39,6295e5cf,b1540ef2,1ca046b5,98645a23,e8c9772,ac21be4f,7122d5b,32a654a0,1476a47f,d3317a25,ed51536,4a21253,f4068dc8,14660c55), +S(d906f59b,4d56bc12,f26d60e6,6fc31733,e5450707,89025ea3,8a6193c8,520ddbc7,cd7f414b,c6cc79aa,4c65b943,ff914234,a9d85cf1,9853be59,2a71fe1d,dbb20163), +S(11b7dfb3,17dd5c23,6b8084d4,f3cc157f,c25c0e70,8248b472,240963dd,9a3fbca7,dd2c8caa,2a2d14d7,fbec267c,9fe87ab2,8b1ddd92,dd100449,f75ef1da,97d4e5e), +S(3ef8274a,fca8fbb3,1894d7a2,d1ad59a9,4951b21,328b1e84,ecaa6df9,cc1ef473,2e4f0c04,f5da671d,4a2b641,46ae749,27bc35b5,98a54190,3883469b,3e7874de), +S(a861fc27,f5e6300d,ec0fbf6c,3315d053,98f90b84,2422992,bdfba11b,1c1c7e34,75a7458,5d98bca4,e3517897,afef848,8e524168,a586d8da,18834171,4b51846b), +S(9537019f,57d7869,2a358758,47e885bd,1594a426,4412c595,62eea9ba,4ab34de8,21bfd84e,a66650dd,79cc8c13,7217a351,57b9c046,938f20b7,246362c8,6637d5f4), +S(71c80c38,b1889d4f,507132a1,87af0c91,79994b84,1b816c8a,6d130a,df1b500f,8de1f76c,100e75b5,1572da6,d08c76b2,10cdc447,cf903e0e,2b00e002,5dee0ce2), +S(2fa9ce2f,59865d10,17880d74,d31cd446,5c28ff56,50f29e6b,d74a810,977ef9ec,6c5a2073,55c0dd3a,b994778a,6bd02b87,80ba8e1a,899330ee,cd8781b7,6e15cddc), +S(96ca6bb4,bf74c748,75703386,ae02dc29,13329d9e,a5395892,df1c6f57,4a84fa4a,fcb510b6,dcfe8da5,690f8fc9,4dea8ac0,e42af209,35c33347,b088cc79,52e98b1d), +S(36a066ae,694f2645,25cba884,956ebd46,ae568acf,11664965,63cee00d,a32f2199,5d1e975a,856ebd1a,cb1fe254,101e89ab,ea089e8a,b38bbd0f,1100e914,709fd965), +S(4922879f,800234c9,63f4b572,d236843,4c4da5c8,ff741982,c3d1e341,841d1309,9b259470,24b5f4cb,97c68d18,f7f8dfca,1e57f7de,63208765,2ce15770,98f35494), +S(ee27e2b,acf95f6d,dbb5ebae,bbf181bb,43322a3d,6db87e78,14e57a3d,41b581e0,3d6a18a,daf69ae4,88ecc9d8,7d6b1bf2,c8d65544,3f4b45b4,c5a0ac51,7b1dc3ca)} +#elif (COMB_BLOCKS == 43) && (COMB_TEETH == 6) && (COMB_SPACING == 1) +{S(e3adcb1a,fe947e6e,7cc4f5a2,df78310a,b235e2c3,bcd75eba,1904de80,c8814c50,e0b27ead,c4bbb9d2,37dad580,6e366674,4a9f9c3d,e024f2bd,1edb11d2,fafc0a22), +S(612c2ec6,f0e9c4ec,c2200d23,ddca77eb,d003be35,61e52b1,890bf846,3bb53ea5,9e944d7b,dfc7a952,c1c5ee15,485d7199,dda19551,2d729628,c215a9e0,285f656a), +S(42053dc0,9f90a7f7,86feca60,d68a5c3c,789e44d2,3479aa13,2d1a427c,621373a3,b338f891,f3930ec7,738669bb,3a29ae2d,637be08a,954f2a8c,acb661af,a660bd22), +S(4d227ea1,5194ed57,10f8ea4d,a639be04,fa68ecb4,f3d2d9c9,43ec32f2,80f74051,28a94075,bda4c195,40c20493,b5391df7,166b1264,b957fef9,683cfbec,4c6e6875), +S(8ec4abf4,d4db3b0,2b0712dc,ef54a405,54b6cac9,3f88fa9d,d8cad4c0,9b94eb1e,4e37e159,517346ee,17e948c4,a17912b0,b29c303e,497cfb38,16796752,99aaf9e8), +S(ab186398,117fb83d,db8b9392,cc888fe2,50d2f604,5a0c3f89,92d8a82c,382175c0,79437224,b3b1604c,fae64902,e3030448,51ef17b8,9af02d7c,54a92c34,7fa2abda), +S(2bd09ae7,1e8d85a2,ba550bf2,9c1787a2,3d2c8985,e2ed07bd,1d39e7b9,8ef8135,ddaebb19,195bfd6c,a44ce82f,b7f3c65a,8af935ae,52e2d2fb,33cc231d,c4b16082), +S(e6da6560,c8265e7c,8f62edca,78dc739b,74bd6543,44a939cd,bac0f489,12b920af,147f5ce4,a98377cb,981dfaf0,1a1e4740,238f1c5d,ee69cfff,a54f3aeb,e53980eb), +S(7df5abfa,d6b46a37,30bd5892,69edb6fa,b70a0d31,936c0787,407d5d6,96506263,bc5cbafd,1f5fee67,1aa449ff,bacefc67,cf7c529f,86100d7c,a8160e4c,376c76d4), +S(ad672823,cfe3ac01,50038d30,81a1a109,d8629b4a,a4e26779,373ee0db,44a466d9,c288397c,f91157e6,770c401e,dc84b328,87b22534,d11e11c,c8415a4b,743fef9b), +S(72032cac,3177c280,ceb3076d,7f510405,2413706c,956ecf38,acf410ad,a12473a6,8bbaf50b,95797824,2994e6d0,a4bf6d07,149792bf,f2a74847,1095f845,bb332036), +S(36a1f78c,3bebf8c7,1fae5e29,cf08485d,d9debdae,348a20,ad84ba5d,4308fec9,842f57e2,e900d07b,eefda7e5,9dc40139,c5deefcf,11c07c42,4629c59d,593e01af), +S(5f418454,72e80d51,1c1b8bc2,b6b89224,9119ed43,5b915809,f7b26d01,8427f579,dfc29fdc,f3c65221,a6615262,cebd9a14,acba91ba,cca22ec5,d84303cc,1fe0085e), +S(5577ced2,f6bf41f9,503aa4a7,c0060fae,6d33cda6,e3c8ec55,1eaec315,bb91fedb,858ded64,6c3d6231,87c0967a,84ee5253,2b21c4e5,b329bdbb,76f6a6d4,93cdcb4b), +S(bc74b56a,c94ef36f,2b356bc5,dfd11d2e,7a371087,653ad607,dbfcfeb8,27abc502,d57d74e7,39e758ee,96a422e2,f1fa61f7,4f6308f5,71e6dca6,3b0b0103,e83cf1f3), +S(727ed91f,be4c5086,50a0d365,b28ae4aa,c9434c0,735fce3c,7b3ebb42,f4be911a,8c595547,5e627c22,6bfa855a,22ebbc56,d3d0b331,9120d8e9,13bed868,7d3bf331), +S(6286bb90,71f8887b,c4fbb3f0,a9ecb19e,fcdd2cf1,5e286da7,1bb60c9b,5ff5e644,73731ec5,ea3e537c,c6060ac5,dde716b7,2aef4117,ba747b12,1c26fc9,eddbda74), +S(3905682b,72282a78,2b8d8dba,72cf147a,de0025dc,a21521e1,ea989040,c248852b,5da3bf52,dceaa14a,a3534068,c05bb015,2cf9c722,cc80c56,cf828ace,d96fc390), +S(561a2ccd,ca12b67f,dad28ee2,c3cee78a,cf811766,9e4a2543,c81b1ca6,eb4bd16e,3b386a9d,553c2746,893477f5,17a05e99,bbc8ddf0,896249e3,85e406d6,a57b9ed9), +S(75bdfa06,6a1a42a7,50f283e8,3ec91cc0,a5b68829,6e6aa24a,28a61e33,65f378e5,c73224ec,797d6736,c1a541ab,34523d91,e1ec3754,fe7fed44,474f9cba,29f305e5), +S(e881a840,847aa2e2,2417cd3d,3e798c56,1e630290,5dff6bf7,754d9419,98d401e3,8816d775,f1555452,f624e45,710a240e,90fc5e23,7536d217,cf555349,b5e31bac), +S(1fb527e9,4e9c70e8,657de745,8b81ef9e,e3c2b4e0,128a675b,f7e28980,e18b201e,bab00a09,1145407e,693d5353,7818bd30,49e1f364,757d228,58b8aac5,416e3e78), +S(1c2bd878,b94169da,722a9de0,c4e317ce,a8802aa9,60458301,11a89d1d,9de4270c,95b7d99,bc3df31e,f0dbf17a,a09ef148,71ae6c5d,870ebe75,1f52aaad,a48dfcc5), +S(41f7fa0a,9a59513a,e221e3b8,4b91995f,c9d40eb5,d120a6d8,e663452a,d92099c8,813dbbe,92ec4b62,25d1cc5e,5820ebb7,dbdc2964,d5dd1ab3,deabceb9,5e793d32), +S(e5cbd627,89c6a843,25a24407,89b88dbb,1dc55afb,9e8296e6,bb8af7de,57a50e60,2cf01cea,ae4f4fed,46c4efd7,86ca5e4d,ef5af524,e9393d74,e9dd224c,604b9408), +S(eb3bc68c,623b1f46,ab905412,c7f2d588,fa25abb7,7a7bd782,ba9bb3aa,c05a70ae,df9f46e0,5dc1d126,2f72ef3e,8db01fbc,11915af6,4aee0c51,da1cfa,b4d15ef0), +S(5702fb8a,2602f41f,52699f68,8d4b005a,128762e1,1dfd13fd,22ea751c,cbedb2ef,a77105b3,7af534e6,46f58c3,b02543fd,9e0666c1,58051952,a61f8389,73f5847), +S(66954eca,5434263,4036fc7,fc0fe33,81f5195e,88433bc3,2c5a8a60,341e2859,d8b1b14,40e9f123,f39c8658,f9d64e7d,fe4071f0,ada879ea,42eebad6,4d37f4fc), +S(592152c3,98d6c719,636a03a6,dad64246,a5a6814a,a62c156b,ce5332f,6759b031,8d22d1e2,d93dcccc,889f3b6e,dd5e2098,2f5586d4,bac06842,d689a37b,4b845c12), +S(5699b93f,c6e1bd29,e09a328d,657a607b,4155b61a,6b5fcbed,d7c12df7,c67df8f5,c147ee87,14325497,6b2e534c,e6902748,2a5c33dc,867732a5,8338f05,73368388), +S(c62c910e,502cb615,a27c5851,2b6cc2c9,4f5742f7,6cb3d12e,c993400a,3695d413,e80c2522,898d8a22,2c4dc0b9,8dc9ce88,740fe252,5144656a,c30f978d,dba83c1f), +S(0,0,3b,78ce563f,89a0ed94,14f5aa28,ad0d96d6,795f9c63,3f3979bf,72ae8202,983dc989,aec7f2ff,2ed91bdd,69ce02fc,700ca10,e59ddf3)}, +{S(efbbec14,ff6d7e18,a8015d68,ba3ceb19,d4cbfbb8,a1bbc09c,ce755a23,e9d4b3f4,a76faa08,2b02b8a4,405573c9,5ac067f3,ab936127,24bfc14e,a27f923d,3adf0133), +S(f02f6744,a0ee7b0c,7bf0abb3,c7ec0a5a,3275d109,92be2893,7e9ef649,23fa932d,955f3630,c5621787,13e6d8f,39efee26,d91a0947,8da36db9,4ab4a89f,aaf9019a), +S(1c6f9f0f,d6ecbca1,fbcfbe9d,1f3d2476,dbd3b6ca,ac8e18a5,949b993d,8c0063e5,e3e3770e,33081dc9,5125d69d,c631450e,5494d21b,2ddf48f1,fbc3169f,3cc1eb91), +S(2062725b,739b793d,c9798397,dfc7b1a7,24ebe8f7,5e5654df,536adff1,25970841,22f3e3e5,c0201265,5e6d8e58,b8ba633d,9a9216b5,445a7f78,a2605688,4a5b6092), +S(57ffda66,e0c29448,7a1570f7,e2f5dc58,ecf9b906,5f374046,5bd1734,841785df,22ae8728,a8800436,1264c380,3beddb65,a9dee575,6f0cfa97,c01dc047,3c806def), +S(4b49fa7d,463cbb43,b14928c6,7b3a85a6,8132ad9c,427d3cc3,bba76d1a,7c9a69dc,7e7e3133,3782b30,5c7c3bd6,94e3c306,b3f9829f,86f76f08,d44b1a76,a207f2c5), +S(411a3b18,c9b638fa,38a0e811,ee370f34,5c9476db,61df1843,863d6d7f,4e803ccf,bb306f97,e97e492d,e74afcd0,a771570a,8210b51,9e61df78,4e6e97e0,ac23e109), +S(c8227510,49de1572,37afdf55,d175196d,5d315001,3670b478,a0255a4c,ebe95075,16be5950,a3f12be9,5905fb52,8d5bd93,23eb5908,211d2e8c,26204b32,556c5c45), +S(e46bdb74,8692d0fa,e6fc9f50,6685487,31d61f8a,5717fb88,4e1f7a41,70e4997e,35398e06,48bea42,cc48fa4f,2805efbe,6bead663,c054eb08,2c15ad46,c0611052), +S(d18293cb,d0902dab,e4c014e1,22969601,84aedbbf,a01526a8,6978e144,88ca794f,3a5b423e,32c1d2f4,bf754f42,9da3c9b6,84bb798c,ea73f637,1777ba77,1aae6086), +S(7b9cbbfa,a53923fd,e9f50845,3130101,3b17548a,8097433,79d3a526,d1c90c31,3fd7b71,5b6801cf,30fe22a9,8b7895d8,1b483f6e,9fdefe7e,6c59fec8,fb9786b4), +S(ab6e185c,be9ee393,5ad6278c,167396fa,aa4d936,80524d16,27ca8e93,48fce67c,7154007d,3f96ce60,d09499a5,1262c7bc,3ab5e9aa,929e0594,994a9671,8f912987), +S(56ffb418,8b9c9c13,4a110c03,8df8636a,71141ff9,8448cb79,eb6dece8,a28b65b4,1d728ed5,23ab821,ac0c40e2,b9348e27,191536c6,79a73835,8bd9b3c,b43dcafe), +S(bdba1eff,bf6af786,dca1da26,cc226102,1f95d56f,245298c0,b87a40e1,fa9a0cbc,fa18673b,41f765b8,25d13f2d,7963f1c6,b3308a14,b033fecd,e1d0d597,583440b2), +S(d9a4a7f5,5b3af93b,1c49ffa7,4f8154e8,23aa1477,16b16441,39fbc86b,2d9346ef,19ca90e7,538ac3d8,a28e1aad,5d8b1dcc,756f8a84,240e5769,a0f561d,f53289b), +S(ee5c17b2,74c78b87,9eda9341,256b1506,25582835,60a0bdcc,c8eba320,32d58638,d7d02f4a,b81215b1,7843e3c6,abb63755,c7e05d20,6c61a4f6,bb08d1b0,256409ee), +S(6953ae81,7ec599fa,5f739bef,dc4cd8b,4670eac6,912bd03a,a3fbe91a,5122ba0b,61bca3fe,36245ced,31cae918,fab6d463,50856947,f64a3be,d0eb62d6,f9f16059), +S(3bd721f7,59f7c3a9,93474472,4ffd3e34,503cbe45,fa7fa5ef,40a5a173,b8bebcea,bd7cbfbb,797034c2,d293aa64,1bf175dc,74a44dba,84b8d99b,8182d2be,6512ef2), +S(ab6e36ae,f5b7ff2f,fd2f42f5,8c408b7f,3ac84253,e1d8a43a,55cac222,678dd38e,ff0dc59e,51e504b2,9a0ba824,3ef26eb1,2446f628,78293da2,d924028c,21f57342), +S(bf1a1f6d,7f73b09d,3efbd73,eb9ea2c6,23e17911,9063489b,42fb1303,7b53fce4,236566ae,5371fc97,b5449b9c,2db32175,90e02412,b44539d3,bda7a814,3cd4a634), +S(fa0c6aa3,4c4825de,304cfece,37a20bbb,f72044e3,94cad202,c9e1edc3,b288ed57,df8e64ba,5f5e8381,4b6891b6,14dd4753,fed5f566,956a6dd,95540bdd,25c73995), +S(d2ea634d,ab56961f,52e39ba8,ebc5c150,ba9eeb1c,6178aef9,64fa97d5,e80581c6,2928f71e,a09a35b9,6fc1976c,f6cd3c1c,7d1fcea0,2142eb80,9666917d,c9a0621b), +S(827d6a36,697cb2f1,cf19e27a,ac30c06d,20d818c9,fe869309,6435f1f2,171c9b75,53237d41,3781a1df,d0d977c2,9690d488,b051dc2a,841ba226,c552cc28,12ae7caf), +S(59dafec5,4df05695,e123004d,38d9aa12,6a06c399,e5215245,5392e5e3,f1a47dd6,ff7d173d,ceda39ec,ca8d2c95,ab1658a8,6ad99618,e3fdb7cb,b07b03c5,2f96a86b), +S(5c4f5b9,2acb30ee,8c7ec4b0,ec577f41,a9502af9,a5a384dd,3386f230,3e62a830,8aea5f7,145de3a3,679c86ce,72e8b36,f3d6ac81,bb1d2043,9d719c32,ca2f8b30), +S(38add3d6,209080c8,efb65551,3d9420aa,457f06ac,d3ec84e8,db84e208,a0664ba9,ad95a891,c60f01a1,5fcddf2c,923790e2,d5596334,4d83a21c,dfe5f6bc,4c2b32b3), +S(9038876f,21c3bc14,111d5f6a,4749d07,34e40a53,7d398c68,809355f,764cf1ba,da030216,5e661aff,53367578,4a4d3447,707f14af,cf0d771a,53e8e687,b9dc29e5), +S(b07d3e8,dbbe686e,5e163725,8402cac3,e1e4f29,fdf154f7,bf008c5f,9969da10,c8b668e0,56bf8173,2d9778e2,eaa069d0,cdfbf826,47f615c3,6d0b311a,b2e14922), +S(8bc89c2,f919ed15,8885c356,844d49,890905c7,9b357322,609c4570,6ce6b514,2cec0c32,283233e9,21889013,c4a76d3e,e8d2cfa9,eed8890f,909c0b30,5736aad8), +S(308913a2,7a52d922,2bc77683,8f73f576,a4d04712,2a9b184b,5ec32ad,51b03f6c,b5a4f6a,bc0141a0,6e1cace0,993fc8a2,57ccc015,7d42e0ed,9f54a102,1701afc8), +S(3f0e80e5,74456d8f,8fa64e04,4b2eb72e,a22eb53f,e1efe3a4,43933aca,7f8cb0e3,34992828,d693436e,16f463f7,b7a2fe4c,6afedac5,59a4ac5b,34fd761c,15a0bbe0), +S(d30199d7,4fb5a22d,47b6e054,e2f378ce,dacffcb8,9904a61d,75d0dbd4,7143e65,6afc7262,f51c2a3c,4c292136,167c7f9a,e089f33c,9b127e69,fa4c00df,dbef9176)}, +{S(983e1ca0,5dd64afe,8d39e15e,43c1cf9f,6badf550,12cdea89,5fd85021,b49f173b,18200e81,d75a745,c1ecfe5a,3ead988e,4327693b,7e3c0e04,329b0c80,3d9934ba), +S(4e1200fe,d3e5048f,f6c9fe53,cdff8ef7,5d78e601,4df471fe,369f3d1e,80e46674,a62aca58,4ecf32bd,cc297b38,c1951c71,a66966f,b9ceb2ad,de411da7,d175df94), +S(82f5f27b,83d49042,63e69f48,b676c9a9,2446955,cbc18ec7,fd4346fe,37e0b0a1,e523d039,d0b8ccae,737bfc11,9b83dfd3,d6878403,862618bd,40ddfc89,9a688557), +S(a8c0fd4e,ab1f0e3a,cab37da6,58fbab3d,949ad9a4,31d6461,b2648308,35762d19,950200a9,63c3dc2e,6d2771e2,eff401d1,f9ce037e,75782943,3fd3c560,a169713a), +S(25c1b464,33068900,bff89a4,ee973937,b03c11a,5b33d16c,4f672fd4,bfaa11f9,471f1f8c,df18e73a,e12cae35,43506cf2,c57894a8,f633ad4c,e1c5330f,eae42b43), +S(497e56ce,8793bfec,4dc6f972,dbaf4a72,aa5d8412,3bcac5d4,2aa9baf8,ccfd6723,1d3d028e,b70105b6,eae66785,5dfe7e0b,7c0a6b3a,b069a475,bd913aa9,c29cf426), +S(68a285b0,d30c2dbb,b543e480,f66824b1,69aa339f,7e2282c1,5dc60f50,8e3f2fa6,87529a0e,1d53588d,21064447,99a8fee8,ffc791a7,cacc9e26,f7a7d94b,25e74cdf), +S(721c92ae,931712f6,15f4d7c,498dda23,e1029dbc,944cea16,9442b22e,d755a100,7ef052e6,a0d2646c,a5dff39f,3b2a1019,de43e3b2,5e51913f,d636281d,cee74a85), +S(aae8418f,1b124d79,ad15f773,1bdcea1b,453493ad,4cb0cd6b,ee5c9a8e,34335ba3,c2558bb1,4a7addab,62d1f308,1a9e6fd5,92a06976,3be877d2,af9ae1e8,b510d98c), +S(b6a06052,b492d74,c68640de,8bd3251d,fbaaeb0,ce1eb997,f2127ead,4bd0b81,7bb4269c,4a9ece8b,e8ea2f0f,d663a193,2a571249,2814eb73,4ae1493a,6a97b39a), +S(42fbe048,38761203,11e43178,6af555ed,d7bea551,d4d5aa18,afaa4c05,2c6d0c19,9ba562c0,a4cdc664,87caf55c,291d8246,65c29f32,2a56360e,90138b06,f109d83b), +S(9d6dcb88,b378e7bd,233464e0,25e97bf9,97768e29,6e4aac31,301fa1c8,bfbcc27b,f434ea54,3f7269cb,1ae1279d,4178dd25,bbc337ad,2f0d5141,610dc061,80daa8c0), +S(fa6fa5c8,1e6713d8,90cd6f29,cc8b7d03,c5f8f2d5,88963652,7c199f6e,8f98e060,726194a,2a5da1b5,85eba1a5,5e06ce36,5aebb89d,ba5f7971,db3c1571,c848c5f9), +S(809167d6,85e432c7,372dc111,8573e620,d9ce7e9b,c3ebc15b,ea7e866a,3a8addf4,bf0cb694,f00fd1b4,b62119b3,9dd6c88a,22ef1fed,a94ac0a0,9cf33225,9298b968), +S(99d28ee0,962c1bd2,fa63109d,f5485653,964059df,bd514206,24117eb4,e582ad46,8cbdbb66,4ee209b3,419c0b80,36affa24,85cdfbc6,e6644429,33908490,f6f6353e), +S(559d0617,e0860cd1,87f1c68,e9a9951b,fef7dba,3a67594a,eade6e25,e2df593f,194595af,721e3b26,786fc25a,cf5b2d77,1fe00649,b0cc4938,7168a9ea,1fd2947e), +S(ab9a7228,f0d533a3,4a95af3a,51021b55,bb324229,8d101a66,eb362c97,eac48b02,80a6d111,e451eb09,cbebdd5,a3ce4fdb,42b3665,f8974df8,912221b0,fc7db6af), +S(42c6680d,18b0f528,274c2eb5,422e4731,560ea862,adcc4419,68bb5f3a,5bbfcf16,c8961934,e5bd6e7d,d64d4b1d,f7867c7b,978d182e,48315ae4,3fe2e082,a9455792), +S(e8bc0f9a,c3687bb,69627de1,df71fb34,21e0252a,e33d15da,3039a200,43ec3374,15de9e9e,2ac74839,5116ef76,1267300d,78c2e583,9286e6b6,366c8a6a,540036cf), +S(604ee928,4ea1c8a9,a0a75bf7,be3a5c02,8f52d71,b5fb6340,53401e8d,8f5d3d6,43bc16af,5875b25d,8e2427b3,3913f6e0,bda886a7,52a3b812,f8f191cf,f7bee54b), +S(7f589067,5b771ce,ac754412,a9984352,4f2a4a6b,a5cecae8,5106bb81,f7e4d9dd,a74f2eee,584696c6,88157a3f,fc27085c,6445c7eb,e363c6ed,7a1f5902,63de2024), +S(80aa63b3,1fdd0d2d,ef602bab,dd88a15,71abd052,270988a4,63abe269,fc489fcb,9a145d0f,6dcf0edb,a4873287,a2f221dc,4be613df,f70f7755,f28879a,6e7d9978), +S(ca9793bd,796ae0c1,d778f3,6445bb8b,aa50d859,4be28fe0,ea1e2d16,30972503,7304af4,4c56106e,f0064436,c09b411b,926c4c56,cd82577f,f8c01ab9,9f7c4c6), +S(4cca305c,baf6615e,8cdc8a58,f3a9e52e,97ee20f3,ef080793,ce105a03,a1f1d3d2,637ea84c,9578321b,b5dcc239,7f6206bd,abdfff2a,128d3645,47d474f4,8a8ae493), +S(cb7813b1,a7227a24,cc53b458,1985592a,a9077113,28fb2a05,1d4972a2,3127a913,208b7263,f8f8193b,76dbfb1a,6c4f9264,dd12f63f,e852aa8f,8375fd00,eef83482), +S(d61676be,a11dd1a5,79164cfb,b2488e54,555d7d55,23ddc8a5,454c49e,4a86d8ea,1875b5d5,6db950bc,60b1eeb8,17a94af6,5a19f690,d48aacb0,e483ad52,61995cd9), +S(7142872,6f59c2c8,b398b22f,2ab5c3ca,e803a34c,ab580947,9b7b4d83,1f8e8c0d,3702510e,324c0911,b3154c61,e064ba23,68eff5fe,6f05353a,34980ec1,87ab9ad), +S(72a73d15,9cf7f79b,950971b7,1c66f362,54d13783,c5ef67b8,4da61dcd,4cf432aa,77d711e5,c1793c36,eabf9b86,bf3a692d,234f02db,e4d5854f,5deef926,b9818d2f), +S(ab3b2de,c0a8f23a,a7d3b9d2,88870969,2e45ef47,37a792a5,d65af92b,e58f6347,ac4e4ac9,1bbb57cc,1437e612,e4d4ce37,3d4f0286,5905b621,56826d80,895cb48f), +S(fe5efdb4,32715fed,f9bbb16f,d65ddf6,4ce9bb13,14a491c3,3bfedeba,cb4704ef,e5dc36f5,5fac6974,eaf9d8e4,232a22c3,8aacc6b9,1225a97c,2e695940,ec795c21), +S(5f94851c,a4149e75,e44a0d8,17e81c75,132eb242,c96ae41f,53f30ab9,c8c828a,d9473c47,505e0117,1a0f8682,777d0ca1,7399208a,b03974fb,4014f5bf,c8cbaeaf), +S(5d1bdb4e,a172fa79,fce4cc29,83d8f8d9,fc318b85,f423de0d,edcb6306,9b920471,d7bc7d98,86c861d1,86b4466b,c75dd9a9,8614e166,693a9184,8fccf998,847cb2c)}, +{S(8cf1437b,d87e7faf,550fcbe8,81b0741c,ae0b48e6,e0b3c3d9,9b1b1924,2a925a26,17b40146,c313b1c5,3bdf52e0,efebda45,80d86783,910996fb,8b2d0acf,9bd253a8), +S(fedc65f0,d622743c,53fa6172,e68d983c,2c9b8fbc,58943f48,ad06a852,c98403e1,ca5dcf28,1a2f20d1,5fed06db,89dfd290,8c9d32a,cf40fe6,817e861f,7f168ea9), +S(846c6a48,e771b90,4ae1e8d9,d3daf1ff,d1cb4c88,bbd1de98,454bc817,954654f0,5a4947a5,8a0ab994,3cd0a90,6c1d1f0c,3fb73d2a,49b9c0d1,a9bd35b2,99475dd7), +S(4998795e,a7d80937,e4abee13,6c14585b,40b2dbbb,3fd3c80f,c8c61b45,cd1d59e8,8c817eab,e210398b,59b31660,267c099,baf29e4c,894e09d9,a50894b4,ebbe97f6), +S(76c29921,eb3f3d12,5c11b906,3d1ac276,a205804b,b3e7484b,72ae0483,e4b3c517,48d8a8a5,fe658e1a,4d736bd1,8f07b5ad,28cbb775,d9388e7c,4fecd837,c8eb964e), +S(78de8fb2,b15ff39a,487135a2,636bdcea,57bb3a14,efc329f5,a06bcefa,7ffeaf09,a55c9e98,5e1f529b,ba7ccb6d,3a5c00ce,28cb14f3,e9012d5f,9f66d8cd,5e45113d), +S(71fb3464,b0600c08,7fe70906,2792a676,27830e50,a0bfb473,ec909530,30799282,fe036726,cb928a8a,8affed30,38977377,2a016e7b,1dbde8f3,6db810d7,cd423f36), +S(f1f23de6,bf779cfc,d864dbc7,b46009cd,d2306b1d,cd0de2c3,65f3006e,565d9e21,84f5a011,74ff8e7c,c9a98f52,3f2980eb,4b013695,f6239016,9cc5a1d2,acd8193), +S(f18909a5,a5db0daa,ece22ac7,12ae04ee,53484793,6fd8355f,9ff5ffcc,ab6ca78d,6306f08d,13ce2b0c,b60b3b8a,b0bd5f46,b3ef2a83,7edce51f,2cb5ce41,79f46344), +S(7598d96b,189f476c,bcb1992d,9a38adcf,9d1b6ce9,6c87058e,24584514,a0df4770,7f288be1,b82da02c,a37f655b,d23643ba,bf3d5cff,3b6c2726,9ece7409,ed78bcd6), +S(1e44193e,8223b57d,8fc68641,924cded8,3a04d806,cf9dc18b,7af06010,4e6216eb,45ea3ada,fd726fbe,2b1d6fd1,858ccc2d,57b237bb,bc2965ca,ebcd1b63,53c2f2e1), +S(80954b78,4872286,8fe38891,2d76dfba,d676b4e7,7901e559,dd5983e4,e908f13b,6fe564cd,a0966639,e0237f29,46e92d29,4aee124f,cb33da53,974e8882,b0acf22f), +S(6dd8a9a9,ad7196c1,3c36464a,5cb9fb41,aad8b0cc,423b99fa,a281c5d5,a6ce6ead,79a51469,8767adcf,ed287aa4,914eedc5,8382af71,5485c2aa,c3a77c4,efe2aafe), +S(1895cc13,f99534a1,187a3d65,d1480669,f0d0c0bf,b42b2a9f,1a6392d8,7e1d2c6e,b7905afa,c0eb9b66,51de3583,2cfb9ac7,ae8d2355,1e334d59,32909de9,ed400a0c), +S(f1efcb8a,86f94997,65b38fa5,8edced68,7737b8e9,49dc05f2,190b359d,9ed2c0a9,79b2c874,22de216b,904572b7,a39f320d,f53e392,8dd8e533,a1a28d93,fdd4945e), +S(2944af80,c207d107,ce89fb90,ea6daa2a,c65c1360,503c36c5,ad798333,90432ce4,44b53d27,fd6730f2,33b8c29,f1256136,c637740,86e001a7,60bc1ff0,f8b6211a), +S(938a1dff,117540c8,f6ee7df6,2d3c2cf3,31b38593,131527c3,9804c6d9,874752fb,4683d049,f096bc21,2e0dc20,a8600b8a,a02133d5,d0ae8d6c,b26e4694,ed6f2aa9), +S(b1b3b2c9,54d1fb6e,98fcf939,efc18803,2f693989,81f19c32,f5e55b30,1f59eb16,423a6754,1a29bb01,95adfe15,c1df1c9d,81394e96,2bd1926c,cc789f5b,eef9ec29), +S(52e23f2b,19048d43,b1725695,e3bdfc7a,f4ebd2bf,594f013b,b80d6d0c,ec10632f,258a6236,67090b8a,73881e39,746906f8,eabb6683,4bc3473e,1c6fa8b6,54641cdc), +S(5799a463,cc817bfa,26bcc543,efe0e00b,ca9d2320,1989e854,620fc9b1,ffc14afe,645238d1,8c69338f,9c9395fa,5ef7c9b0,f62b7dc9,c4c6b9e,c545c850,95b6b7ad), +S(1c493b52,3f5a4467,6268220a,58246228,608a603d,f6edb1c9,1a90b060,70b16069,8d311a45,5af92640,e9fe08f0,2981db57,3b22bf4,8fd5e76f,31c175be,23e24fd4), +S(84f5a9c9,cda291c0,71aa9f8d,d7af5a8b,f2ee0dda,fb9139ed,fee08f0f,3f9cec2,df381327,16527be1,d86991a9,bc28966a,c3c6c081,4fc0def8,85e5d160,f59f4458), +S(712c18a0,ae87e7e,87856c8b,ff6e3f6d,996ae157,970e754f,bba80bee,421fcde7,b2788ba,e69d34ba,eb5dfd62,830396df,3b8934a9,551c6070,ae8203c,ccc50ac9), +S(a5104184,ee996a34,7122a460,cd2eba5a,11d04aaa,a47d2ede,25ea13fa,41ee01f4,f4b5f2b3,f7ec9061,7ab5f3cb,763233d0,afc8d4bf,fc535076,5dc5fd41,cc547ffc), +S(79383075,a46a8eb,559ac95e,7dbeb9ee,51b6e906,27e55b9b,922473fd,5f2eb63a,243f56e9,84fd2673,58754a67,2bac56a7,9ae71a5d,68150740,8eaf8c2d,b55ef1a0), +S(2b22635f,b83ab0d4,9b82edfa,a54d6234,8d3bee6f,edbe3315,9470b18a,96f97821,41d9f3a9,52f17182,ccf02725,b58ebd7a,1f37235,1fbb8f2c,15403890,e8b25b82), +S(272fdefe,148ef7e6,957fb8a1,4a07f0ad,b17c27ea,49532547,5114c1f4,76170a0,789b8eb,5846e50b,d489bf66,cebd873f,7cf05619,3674e7d7,147ea691,6a9b8451), +S(2c2da4c0,8a6e73c0,2efd6e7d,13006135,f09990a1,4c0a0eac,1f286108,f4a2a0e0,8011a521,d7fa0ab2,75765bcf,50dba163,9e89c9,300e8a25,31942cc3,fdade63d), +S(19a9e5f,1c4cae30,797a98db,a24051a4,38ea755c,7b062094,a34ed6e8,8a8ff2cf,e199e398,157a50a1,56f9d6d,afed48cf,f3181411,77b792ca,c5881898,24f1b8dd), +S(f7a4be3d,fc6579fb,43c5a960,890893a,f4026165,ed9e3ab2,e6929378,b63968b6,29221093,17dc39ea,de2d6fcf,c735ad2d,668fd047,2eefefa1,b6b225cc,2f3cb3ad), +S(e5380fe8,575f26ad,b7924ae0,d58138d2,68112776,b11bd34b,3eb5e196,33f0e9aa,4680278c,6f784be2,a496ec9c,6db371fe,9046b1a2,b97ce71,3b45bec8,bf7d8a20), +S(4c1b9866,ed9a7e9b,553973c6,c93b02bf,b62fb01,2edfb59d,d2712a5c,af92c541,3e086d2c,df4175f0,804348ac,31a91963,39ad1528,1bc14e52,8d3b0c01,39701c0f)}, +{S(5a13b9b2,5aa6944,1b0b5fb7,f7665dda,95aff48,e3250b4e,34cf8e28,87406c1c,245f250d,78fd66ef,24745e09,f067f16d,d400c387,66d2a1a9,af51e84f,733d0ba2), +S(617b41c6,8534072f,2302290a,4956171e,902634bb,4356bd27,ab83a377,13d8ef6,c867779b,97383817,dfd0971f,64c09c71,7c468a5d,e1bb8ed0,feb98f5a,305d8e6a), +S(ac118ae,ed46b08b,488202f6,96d9469a,e9af3cc7,ddc8eb71,44903a3c,ee43c654,f992fcea,8268ca6b,79f5ce69,c87dcfa8,42ea0345,d7c85a5e,a1b89f1c,9d0217aa), +S(741dc47d,2e0d1424,3f2bd96d,9033d8c2,9008c1e3,66bfb5a1,1434f1cb,3d85310f,c3135d44,e86f574c,266f97d0,f0279dc7,52aee0ab,8e3ed78b,ee0fc646,c133000e), +S(2e973138,f6cea9c0,5adfbb5f,49a7b928,5ae0c15d,120a8b1f,2d0c76ea,1fdcc7e,a05bc93e,68bc82da,7a7c7e38,95a647d8,7f724f20,c5b312b,738c6dee,90de771a), +S(9d938d6a,cf56104b,5522351a,3c424e01,e4d21c33,771ca94c,f55357fc,fe51f91e,881d05fd,4658b08b,edf87396,be3fbb95,ec9f371d,79ff4586,6ddc803b,65ae763f), +S(37a8ed2b,4085961b,84645ad9,8f2c901d,fe9a9a8b,4de8fc89,2cfbca5,c8909835,b1bdacde,94fdc3a8,78cd0eac,f8865d64,77e2cff5,efef834,97b93835,5b7b401a), +S(da1ba954,899cb05,dae6fea2,dc8ddd7c,5ef9e91c,3455838c,a49d2858,ec217d66,14051c3a,12332d70,f8ad8ffa,567765fb,def69640,4291b81e,d3978bf4,51f788a0), +S(92d2ef44,5a10dbc6,73f8c1e6,af093596,13bd1e3,c1b24705,bad2b3de,e8f11b81,adfed916,800d3e94,91a42c59,dd72e3ea,57d47081,b9afe668,f853cec2,c72cbab7), +S(e62208bd,52620df8,91b3ddbf,e6cf0641,6059ce50,be3b00ce,14e7a53,6d1acb07,1fb71455,53b2f4c,431fd86f,c72d51af,5e2edb41,dd3f69a1,9a971371,d9679dc5), +S(191fec47,a48ee268,35ed37ff,6758a80a,532f7011,ab099048,b024efbf,cde1d0ab,47b6389,b3f5534d,a632924d,5b65918d,f65c9c2a,2904ee95,4f24aeb8,c6a02557), +S(60c822fe,a74d52b7,d5203720,b2c2a361,b7628aea,d2a683bd,80655636,bed15714,5d9a9c0,120211b2,e8285b77,8f8d4bc0,b06240d9,22944248,e1cfce73,826bb67d), +S(f602da1c,788ea65b,cc339a38,c353bc08,1c43c2f2,6e05ea6d,ab52648f,890c9101,21468929,89348f8c,67cfdeda,31ef3429,23b5a450,9fbe9a49,f011d42e,57f998e6), +S(756240c0,5274101b,3059d23c,76d9ecdf,33e1312b,7a36af,ea21e6a6,c52cdbb5,ab24e853,900c7ff1,3e4f813d,a2acdd5f,53ce1710,b785ffbd,e74494ab,43e583ee), +S(8e815b45,7adf482e,e30e475a,4949e5ae,c7ff494a,a918f07f,c39441e2,360d112c,a966f04,2dd9edb9,436b0005,7473aa66,dd19b4d2,cbb3bd95,932ba98e,f1a1f406), +S(216d5970,36c661f2,cf6122c0,a136cc33,9660306f,1c190ee5,5f3bf438,e7189261,5bd23797,c6753eee,6fb934bf,dc897ec1,25b31c9b,9e797ef1,56d8cdda,2ec1d128), +S(a30ed06e,ce34d29,a92fdeef,6954b5ed,4065d592,3af09be4,f0ad4a73,e7c24346,f6aea418,6b38c188,b84fb6f4,2b6559be,f52dc13e,b7ddeccb,6e85a76a,8d4efeaa), +S(aa42d20d,8acf7c47,fe40ac15,3fcaf1ac,6c4ecc37,dfa39c39,fe5c7657,c78444d5,bc3becdf,464ce930,e42a05b2,c52d3589,fd45ff37,c7d1767e,f8462811,89634059), +S(7585f8cb,4812e306,de02393c,c06e9871,1953133c,bcb67ec5,c6a79228,69124ff5,c242853d,1a2c1c9,a1cd1b5b,364888fd,28bb23c1,2b0e169,67961b3,e7c8b95b), +S(b096a1aa,fb969483,185ba1fb,a5fa3f3a,d1da87dc,a10344a4,d74ef471,45cc45ce,edbc9490,23801861,44ee39a5,7bdec0a,230df57a,72649e04,c4c99883,a147f0f), +S(7034d8cf,df226df1,6b310628,35dc02c9,f3e3f91a,635ad93c,46be292d,56c0ec2d,f783b6e8,29447cf2,32769a13,7ff33f82,f9fb166a,aec8c3ad,1679c48,c1a913a0), +S(9f88b01b,b936defd,f61156a,b55ca290,cf282a2f,3718b0cc,2d32dd3c,49248b4f,c24ebc35,27052f77,41087cb0,e772ce12,1035042e,603f1301,e19cee0d,30029230), +S(14443190,51f05d23,343367e9,6add133d,fcb63209,2f218847,59ad81ba,c65e7445,745216d2,d11f2556,7e3b224b,6dce478c,bb988b96,a1240093,964e4ba6,f3b15554), +S(54aa2e02,3038fd83,f17a633f,d9ab441f,e039dd0c,57f9368,3da013f1,751c6813,f4d163ac,a9af3e08,c009b44c,b358ebaf,31aacc5e,e0bdb917,d1b4df5,420d2d34), +S(fd44e742,b04ca4df,693e3109,3ec52ad6,1f67264e,100618e5,88d638d6,d96efa41,7ac09cb1,2134a246,b17ce054,b38f3bb7,7d794f9b,2fca3786,a0ba665d,3eb0f14e), +S(f662f214,10cf6e6b,7f79fca8,7ea3925,6760d83,17478419,ff4671f0,2bd2ab6c,be4ad0b7,a56c87a4,8fbc166b,da8473ba,6518385d,bd004b5d,c85126bf,7b9309bb), +S(520e2755,1cd804d2,67f9b4ca,b3986952,612bb099,cbd3f3be,a54f505e,bba4db64,e3c75cd2,c831c539,b095ac18,3bb13a72,ba7cb152,5b9c214c,288509a3,98a9cc3b), +S(4d16fa3,2d74de13,111b3f22,c4133ea5,377921ba,e54af1d,666d6e9f,b01e117d,a63bdf75,78d73f03,75aed657,fbb8675,67230c3f,868f2cf7,b7275ec8,b02ac46f), +S(ab928c61,ad1c2f68,905b9e95,3c2629ad,9bb7c8cf,ad9f5a4b,35b35fad,69a92568,bf39ec2f,6c1ae222,ff383375,6bd83882,c05be6ae,692539a4,5124b972,e72159ee), +S(8731aaa4,93580732,66b96577,7bc24a46,17fb8363,51c5ad8f,c8bc053e,802dd07d,36957f16,1020430f,69a3b1c3,1a6df993,d9ca8e2a,8f487b7f,b2ccd44c,7f528ce9), +S(3514d41e,8b9388e4,33d1155c,c777c398,22ab36c6,3c2aaad7,ce674831,21231d11,7657cdaf,e9fe8147,10bb2ee1,a97c6100,6c7b0ce2,f5086141,ac2904be,1c7a9e3a), +S(9bb8a13,2dcad2f2,c8731a0b,37cbcafd,b3b2dd82,4f23cd3e,7f64eae,9ad1b1f7,6ba44d4d,50111c46,490622d7,b079c17a,f0ab57bf,b8ad2ac,9becf9d7,3c7edfaf)}, +{S(e60e88f1,dc24f079,f835b687,778307af,83446e,71809086,e6dac0db,9f191de4,25a0b86e,ff05c849,d79a176,1a634d82,29d2a759,fbd003c,b6ca4147,85726362), +S(55a5e6cd,c9e11103,749d469,dae84a88,9e744dd5,d9309762,15050a83,fef66fe,31278ace,a971a41,e2f9fb16,8e80ec03,37009cd5,b0a49938,c28c902c,a7c71fd2), +S(5f25326d,e99a7c5a,d81bf2ea,61a9195d,48832bfa,8caa9777,53e483f2,b5a62580,40b69a1b,baa2d0d1,5cb78a3d,3d184c08,5b4c16d2,90751ec9,bf3eb3c1,d3ec2ab5), +S(1a32cc7a,f88976b6,cbc89865,89e685ac,49381a29,1579bd2a,13f9488,c0333d19,4667a3e2,2048f781,11f009ae,5d7b1b97,850a3a5b,86f77880,b128c8c6,a9720acc), +S(1d78e74c,66247be9,352c9797,5fbc1299,743f9c74,68c64d1,f2d8affd,1b098769,37adf553,fa2a11e2,6913ab02,e59c4f2a,48133fe7,d9aa3c24,a76e9af9,48a29d8f), +S(8bb6f83f,6be5c2e2,b2bb265a,9bb3c931,bd5cce6a,48efccdf,daa040da,535dbc86,eb96a982,23278b81,6284fee7,b5b8a121,7350cdba,d56b6078,89602bba,bc003481), +S(a9f19ca8,1d2ebafc,4bb5d881,76bce19a,d2d2564e,185f905b,8f9eeca5,d6b12d6b,ab23a468,3279a9f8,e2e8f880,e0accbba,844bd4e9,4d3e4b43,74db2b55,d998771e), +S(19680305,c887467a,c3bfe44a,dbe65431,7323d8e5,62271e25,1a794b78,618befcc,48e9303a,3d6371f7,cf0a904c,cf16f606,b0007583,87ae0952,c6119521,dde25532), +S(18b3bd03,ed4696c4,7c3f896e,5df7481d,6f19a5ef,53d62ff8,2948f1b2,154175c,85fb04fd,6573a19f,2c136753,a1ca2585,d39dd64e,6e6e3fa5,fba362b4,ae9dad36), +S(38e3bee1,3cc3e18,a57aef97,4ffee58a,a392c311,14ac8baa,1376b56d,f8ac017e,8596c7f9,8abf3e44,4ab5491b,fe659619,f6defb58,f48e2b7b,57842193,cd48fb5c), +S(dba5da08,8cd17c33,3e892bcc,46261694,d2ff3a22,2a26f92c,17c5e1e2,797b235f,ebc15bfc,5729e986,85a19afb,d7f9a219,e60d2784,e9b283cd,3697f782,630fe222), +S(60456426,caea7fc4,48970eea,fab9c632,3e66fcee,50f92630,7b130937,25b85ee8,dd22df89,c5dae339,49459593,1433f2f6,5f719379,68e56f92,a38d1290,17881924), +S(f1ceac82,15670212,279f36e,f0c8ce28,3a192f66,460e4875,d90b2f51,a38f5712,ec11f026,c76c271e,fabd7d55,c8488d99,3298f6ff,c05ad4a1,26be9447,7d878b9e), +S(2c2fb5de,5dea249a,7bf6b196,8bdec8d6,1838da2c,12147045,18d6494,f09e50e,6c0d020a,d6bfd730,5ee73634,e939ac89,ca2b7d4f,dcbe760c,2d14ade2,659a5b8c), +S(2858ea8c,d40ce264,3c9a305,c0e2c758,af5b0b4d,5c57ed21,60cf7ec4,154ffdc2,33586bf,a61a3cde,4f402bea,123c69e2,2410c0e,590a71d8,9a1e8130,85cbb579), +S(2749a250,4e7cefa3,a3647088,6bec22fa,339fec0d,ec63c02,19e6af39,7fdec3e0,d3415104,a9070af8,b61acdf0,77954d37,57fcf742,a006129a,5c0d3529,3aa95407), +S(8edf3ad8,39e661b5,f7f16a85,dce3caf5,d571acf4,d0c6195c,53b618e,5311ac65,fca0efba,35a14d3a,9944367e,db4ac982,7dcb7aa0,12438c5b,aa5627c4,c4a15ed1), +S(dbb92358,8b083294,5d6d3b62,9cced57d,7085d3e2,d0890bde,95d80400,98c22745,42816661,5515429a,aa023737,5fb77804,624546f2,1f0a34ac,1ed4e4ee,dceddccd), +S(aaca9896,6196ce2,e13df3c7,d058a5e5,10566df0,5fefc04e,51f9dd,85a4349d,be389d02,789548e0,aaf67c57,3b91b389,c7e6ed80,ca3e637a,2a147262,80cd5620), +S(104804ab,e621b098,61fc540f,f4d6be9a,750e3cfb,706170db,e34c06ed,e0a431ea,14b700ed,a465915a,eff84ab9,fa568535,f63e4f44,1387ab4b,d841072d,97739071), +S(b2215070,a8ea71f9,b71f1a73,d6ce366,c322b8ac,4d135b3d,ccea68e5,a51f1c0f,9e415cce,3bcc4e62,6f3c8caf,fd632eea,862a046e,bb45e8bc,84fc05a7,a4b87e00), +S(600c6e28,be5ebd28,d83e6c86,bbbd9b0b,aca22006,42234634,6124133f,3348e6f7,822b1816,79e253db,a47ddd76,c0023991,5c0c0206,8f422415,94ac38b8,ff7994fc), +S(f8b9b45f,c6298dc7,13355bf1,3ee33ca9,c4c1aace,c09776e2,56b3746d,ccae0dc,bf4b7f96,1844aa2c,6ed8c8a5,6626386d,174e77fb,98c0c23e,e2b6de90,3f1f79cd), +S(63987b18,67fe5a17,333eef28,5385a0a6,576163e,2c74cd00,ba87b6fc,96a57faa,23ce6655,51d48ca3,c702a5be,87a05d98,b5aa1097,dd5877e8,11e32d76,4873e6cc), +S(2eb06c4f,5ea9ad2b,124a1202,cb13c1ae,aec4394f,4af7c96,d6a9ecba,540ee04d,b96173dc,77b46ef0,6f4141ec,96ce8d1,4adfcfde,f0bd7ea2,479ba6d7,522d037f), +S(5db39904,153002b3,1498bb01,16efd0b5,838e3495,62d9428c,912987f1,3aae5ae,2115b896,479d0d0f,75ffcb54,ff9e3f73,d1356ff1,4b14292c,6bfe8d54,e9e08861), +S(c0f14110,7f324ffc,f3d3e6c,78d5a628,6000d57d,7e85bc7c,fda15f75,79cef3ed,6eb03650,c8142b12,b330b96b,81214a4d,d01b068a,74827611,53d2c52e,e1315ce5), +S(7e3d1510,ed767345,bbb3515b,6f9819bf,33ed9dea,fab35d01,a7284cc2,371b0e66,4c6b3aca,5159023b,d43ec0b2,57e77e87,e5a6b745,178bb017,9960c89,361fd97), +S(f98b5dbc,3e54c227,b002f458,94850ff4,3b15b2d6,1607851c,50d1e4d1,8b20907d,1d2af742,b0b5ec05,bd6c648f,94563361,be03261f,da56f1ca,7caece63,a336d580), +S(188ef3bf,ab103784,37e1859a,7d53e899,6124c395,ca422c05,d6b21b3c,efc76ac1,19036685,fad04566,2ffa04e7,30c671c7,1b299217,c389c78a,cae9fcd4,ad70fb73), +S(b89070ae,96ead4dc,49be16f6,a1a30bc2,41b4e98b,c18d0227,4c9d9d87,dcbf00eb,90db373d,375d2770,b8dd6b1b,3e3b5899,34f274f9,49469598,e480e431,e4f195e1), +S(381c4ad7,a7a97bfd,a61c6031,c118495f,c4ea4bc0,8f6766d6,76bee908,47d297fd,6c950ac4,dc71111b,70c1a058,f66ea133,fbaefcd,246c63ff,6c531ce6,82b6bc6a)}, +{S(704a26e5,19071bb0,24eb2a16,48b66a6e,157b07a5,52fc4258,381f7d02,e8fd9b9e,d169ea55,8650aa3b,ce52c645,278422a3,69326e74,46039381,920f5857,fa3492fa), +S(705063f5,e481735,60afe9dd,5b2beeda,d6e46391,75ad7fb6,f73350df,51edf53c,32290956,61cacec9,472dd014,bda52364,3399d7cd,9ce2bb31,a5b23590,22c6ee5c), +S(972e7585,f8b1725f,4a7d18e7,77939aa6,3600a7b,a07c4d94,5da9511e,889473f5,aae4382a,49b4c97a,bc3edb7d,26ba7bad,16752047,dc99b434,f306c673,2851310b), +S(260530bb,e338f4a9,71930b12,4f18c82d,e33f22d7,32de9375,81e2b0d5,15e59d97,77c66c36,d6b09205,8ade9c0c,a311b60,a705c8c8,73fd2d4,8e6327cb,71eefd4a), +S(15464351,d21d2513,f792ee32,aca3eca7,a52cdaaf,9862172a,e7224a03,804581dd,d9ee19f4,502f1c44,f656ad4e,add6adbb,d8a04f5e,5344b554,894721eb,8e3e2285), +S(4fcc68a3,caf3ff91,dcce9770,11ad5157,6c844132,321791ca,a652593f,6cafcd04,e8db3aea,a35371bf,9700a9bf,b85e90b3,93cc088,9cd655e3,fb18635b,49fb59eb), +S(301c65ad,567952dc,6b39134e,c361030b,3f5203ed,da89784b,225548ec,45c75eee,95e2c0bc,7b4a7cde,8ce3dace,a691bafb,f78fb03f,3170b347,ee807f42,6b947560), +S(96ca5edd,8047ec6f,b5f8c37c,a734533d,13f0e6e7,f55d28,b8b10b5,121f4abe,1a21f1ba,f6a2e336,247f6ee0,88cca9ff,816b0667,3badc241,d9ed00fc,d2070f1f), +S(c94633f5,783c4e68,12143fc4,6e670978,8e8a526,819afea9,404dfa00,df1bd839,874f8760,33dba9,de463f86,b597219a,c1ea37f3,970bdadf,97c96c48,feec4ec5), +S(963146d4,5bdaa05a,b5115ac2,3ee862a0,2305ba9c,75003f4e,ab838f7,e9adcdfa,d75766de,299e5cf3,c8796234,5db9866c,cf011c5c,f108a794,5642a6b9,dd33eb0f), +S(dde8c870,ec4e9890,2a820a7b,c5784034,19ac261e,de5afd0b,82b8c5a0,7c2863df,e7833936,50d4af7,427158e4,6c753ac1,a5143c9b,c09de97b,3b27065,6f622b82), +S(546c6b00,c5e34a8c,4cc7255c,2edea33,d9f77e7a,c67ee629,bbdf1879,4622265e,5ae149da,f65aba8d,e214fa63,be9bbf11,3dd3c220,12d206bd,d56026e7,4a019897), +S(4340c850,d91b63fd,bdaf41bc,f8d8c010,d3f30eb5,79eeefc9,e67c127a,33324071,dd66033e,eb5ae8b3,3c47a940,2482bcdd,4db5c8e,dda3b422,35627434,dc3bad1f), +S(f796431f,679d9cb5,77bce62d,236d1fe9,b5042a83,fdd1cf94,1a2e00c0,5a261d11,718fffe7,68aa2591,d3fb1fd6,1a00537,3b529f9d,f9c27f79,31ad0df9,9aa74859), +S(f3d17ae9,d5b4cf41,27423894,916318bc,adfb5a9a,6c2ca219,1b918e43,eb5ed129,9da6d033,49c64d79,7ad09a33,bf71cf87,8e0ae6a7,9fa7bc3f,1451126,18415960), +S(23899a73,a4b52d27,29ab52a8,370ceef8,4c7684c,cd535f4a,ec360eab,cfa5a787,f1bcde3c,5c4740c7,37b066b3,8a1a88fa,c43357f7,f3fa23a7,b00815a3,85336320), +S(5805914f,5418971b,106305cf,c397dc12,f63a3b2d,8b451e5d,c1b60c2e,3d9e9208,616e2764,67a5f1b6,46279ee9,6e8645f3,76a80192,31e17a5,c92e26ec,1b76e62b), +S(85ffc326,1991848b,5e918c4a,53f291a8,31796b52,d56a5c38,8bebe625,d78cd07e,95fd6f12,7b155e6f,806c089f,3f5abe95,344e9014,e2c72fdb,e720bb8a,93d864a6), +S(6f1a57d0,6566bf81,f4b16329,19f477ef,aab4f829,e29dda4b,27627b96,1cbfe3eb,de1e8359,7ff20c63,3d28b909,caef273a,a57898f1,a797fd91,e00e2e7,da1872f4), +S(3d28eba0,4d0ae2f6,208adc71,cd6af3b0,e208860c,722903ab,e106feb0,af3185e9,cf8bad18,40d3d2b4,abfb5b28,b50702dc,512527d9,5bcd403d,9713ec7b,ef1dda13), +S(46511979,2b845113,1b32663e,baa14c4,20a5408c,1f53afb2,43cd496e,c4b18118,40bd602b,d740096e,842b40fd,8304ee73,842b074e,415d5ac,c5e2243,28b241f9), +S(393a8bb8,7ffe4265,51678524,8ac940c6,4aa70e71,512ebbc2,3485596c,a6d9da5,25773032,d2c1f80b,3954715a,6e4132a1,74b4468e,658f6cc,4d5f5d63,d458980b), +S(aeb37eed,35274696,2b85a21c,86b9fe34,60433606,9ae4ce6e,3a8235a5,e43c48ad,d94165e1,5372330a,7b5507f0,377a966a,541b6fcb,949398c8,dd6d6f52,2411d86d), +S(b0bbb4d3,100ce417,dec58f46,95ed8b30,4306f21f,ee11f899,585fb37e,a9905c59,89141fcc,9344e617,7742e31c,42c565d0,45c7ccb8,6f88df7c,5c36d23e,45e51d75), +S(49694de7,330b4c3,1431d452,f3e9e562,eddfe029,1cce58c,73b69cdc,b89e0f49,4715ea3,b6fdccf8,e224b93a,ffdfd1ac,ad8baf44,c5bce735,e7c9b4ef,3faa2656), +S(9a7720b3,ff0363dd,7263e1ad,83c32526,67b67d3b,72c2c14c,95f0804a,dd20f7a8,815a769c,494824a,a819ea,54b560ed,e1df9bca,d7df2d63,aae69c4,a02f9f20), +S(b89c399f,cdb3aacf,99796fd0,95c17cc9,786d79b4,9a1a255d,5c9ee510,38d3620e,ee3c4936,d4f9d1f9,d2642043,d25b21a1,aa32fa3e,ef44f409,73db47a,96965cdc), +S(add68bac,d7180ac1,4e9bbc5d,1e0c3911,f2202d90,1f9ba649,46b06507,b86ed5e9,fcffc13e,a9be67be,8d090a77,9fd9107b,f62bc785,3f98e97a,c0358b3b,7719944d), +S(9bf62cdc,cdabe928,c1ab44ce,38cd0611,135971ed,81ce6c6f,dfc5eb5b,d9c3996f,885b2381,e0e785d3,cc3f78c7,f9fd54b,ecdd9d9f,c2979e23,f97e9bd2,a4f10d3c), +S(bb223cee,f11450d5,c5e0b75d,20eb44be,9d44dcff,28574117,12fc5875,3b839339,8bb29985,87eb6f5c,c8cb615,285d9e69,71db8e31,8d81fd5d,6318909b,8311a00b), +S(9ed73f09,2263e84c,d022388e,da82361b,445f573d,b646cc62,fa0bf5c5,1d33fd27,49ce7698,144e1115,118a4b0c,bdb98dab,6b57dc1a,4d1bb6cb,a68d4d20,d8e937d7), +S(e747333f,d75d5175,5a0cc9f0,a7287084,65a02c58,7737a7b8,b8fa1b8b,4bb2629a,d5001fe,baf8f3ee,b33bc9fc,7fb3da7e,377c8955,91e56965,607269e4,96b90559)}, +{S(516ea742,3f956765,a15f856,182f1e7c,18d3e548,b9fdca94,ea46024a,1a8fcbc0,cfddd98f,be500604,28beb901,92c01282,aaf9ed93,76f0e26b,e912ac42,a378d542), +S(8ed072cb,13eb90c9,e5c107f6,ba576a87,ac75a431,53025e6a,86addb95,bba7862f,eece8a5a,f28d356b,f1a84c14,2549ae7f,894f7c07,305194f3,18e30e0c,873fb5b0), +S(3e0e488b,1c8acc24,f81bfa1a,f6761afd,b4fa5f5e,6317ba72,bfba2f07,6c2ff593,2c4ec39b,2f37b948,fdbc9e3b,a3fa82c0,dcfde2e2,57830a04,4c178759,ef5bbc8b), +S(f6b3f19f,cd7eac5a,13630ad1,bbf331b9,5608b7a0,ceaa67e2,4a1e830b,5eed9825,a2a64078,19ba0f7e,7a890df9,523c6736,50ad08d5,c2557cd1,53c6ee65,ef493ce5), +S(e2de599a,879285ad,398b1031,8e1a8387,21a5c4f7,1105469e,affc8e37,189548a,dd977e62,3dc05cd6,3155a71d,d87d91d1,d74d6e31,5f73434b,679b605d,9db264df), +S(bc52359,683840a8,59fc2c8e,22d72ec5,da2493a4,bb5073a7,f658517a,de83f867,76a13651,712ff42e,a0c10f09,45c4ce41,2cc8c4f2,ac3ae446,7cb383c8,656d3186), +S(d87e2b08,154e38c0,13847a5a,2f84c276,dc088b6f,c19a9bf3,90a8a433,fa937fda,d91447f,7c9042e4,6f64a9c6,40a5c294,1a6f08f5,d3eed464,b09b2a1,1c402c0c), +S(4359ac5c,5dd70bf1,d4f24f00,1301b9f6,17d9c69b,63350dad,9a8cd192,655ea801,c9e14f94,d8ec39aa,46092657,5d770426,350794a4,b1ef2410,a9b0118c,ac5d55c1), +S(3ab3f503,29e22bf6,8fe9882b,3b4dc989,36dfd840,be6af588,ab6d61de,48094b9e,4a40c435,9f4dd21b,11664095,4b55e6b9,f0308786,eec32fca,6bcdd5d5,8d055ac6), +S(a0f1ac27,d046d987,b9a98bf3,f770205,931fce93,59b75944,6494d221,dc2752b2,bf1bfdc6,47a15997,97b5b6cf,2d8a2a44,e9c36b9a,20b53abe,58ce9e0a,395fab70), +S(a9aa63ed,3b0260d2,b35b030c,7a5511c8,679b6170,b8a4f386,fae0bfa8,92735905,2f654620,4dba9b31,99bd648c,cb1605f7,62f312d1,67123d98,ed66f02e,4d794e90), +S(e51da157,5e566ef3,bad3fa66,e55432e1,29be6c36,32e390c0,f4d76719,bae34b7b,55930b79,2ffc91de,674820b1,eec290d7,74ecd79d,1ca07d6f,5ea2f817,4759984e), +S(8b69a891,b417ea65,7ba52bae,58920eb7,f101bb92,e150dc1b,c961c37e,73cd18b7,5b824edb,f4a68988,39de0d70,ec16ee1c,a01a4692,f29263e1,1069aec8,6b149214), +S(ee5c1186,77462649,6d37fba,e48e797,dc69f31c,d6ad22cc,937c7224,ef7ce8db,13f7987c,f2cc4551,e058d410,3d5c24d5,13c2d602,ddccadae,fddcab82,d14d5310), +S(b961cb45,5de8b5b6,c4c5c2d5,75303c81,35b5d278,503a15d2,371b0551,5b236b,3ed18486,5ca969ba,31c734a,19055129,1cd664be,576925a3,2a142769,4fc40df2), +S(83effa4,c127b5ad,7a0c53df,5be5596b,d4a42987,2eafd8f1,5498a6d2,47b87314,efa99759,c9360b14,7643de2d,64ad07ea,39cfabe0,2bc94e00,dc9b2e70,c2e2c217), +S(f253fc52,4fb0254e,e772f50e,5d6c16d8,48692455,c855d4be,15ea9f9e,9a5411dc,59bd1f8,2cece609,8a63fa1d,48e4166a,d79174ec,5f8216c3,16c48c1f,e5c9a0d7), +S(6b61024e,e6451d97,1446b55,1476c3ec,eb6b19ec,16155acd,317bc2be,11086411,8de5c6e,37b562da,ca5a203e,ea028b76,e6befaff,e54b49d2,6605f169,592242cd), +S(1691a90b,9cf72621,3680a72d,af59ef24,985448ff,5f35372a,ab6e2aef,df8b33e5,83d2032b,6ca761d1,286c1348,31250054,5a230558,cba391e6,f0db9c9f,97c2d618), +S(42a078dd,cf749f25,aec7a1f2,8e976f79,e268c36,a7b5b0cd,6aaee3e0,925746ea,c60f1846,6f025987,e0ea6ca0,3eb98df6,99389753,b57abbf4,f5739509,bfd09d1e), +S(21bfc1a7,16b09543,5142c31e,5038d4ea,4643d9c3,2fd4728d,1374dba8,1ca1f07a,a991d491,2601ca23,8e289e71,e9d743da,4385aed6,c732f808,6dc21406,74540acb), +S(e75223e8,fe247a98,5220cbfe,52151978,c98d1460,746f8de2,8696d235,71f3336b,dbbb8075,ab489582,52472982,c7b0c3bb,d82a0762,36c07c05,44417ff3,883f6f18), +S(7a756a,72fee88c,7a2758a5,3294da85,6b06129c,1978e217,2bc7952c,92b05265,c4ad3a0d,be72fd27,bfa475d0,fbd16a92,5e939362,bc0748c,c39ba9f0,3ad84133), +S(2bc697fa,d947fd62,63bb2841,1a274520,f5d582f6,7f039114,293438fc,9aad7c82,543109b9,82097efc,cb44d854,11fc5230,6c7a219f,2f58b37e,3dd354a8,2ffb28ad), +S(3862db95,1ed8994b,a8cc0178,f6dc97ef,db6e1380,c18719ab,cd24a88c,87039744,af1e8ac9,2b195d3,6fe1b1be,a68e9215,a453e638,67e65d88,64a8baf3,ff5c1267), +S(7b648cfa,40ce7274,59a6fae2,2836ea1d,b18ada4,9b18a61d,748127f7,7ceee771,f2a30c56,42887135,30124a69,da2c0355,8688bac3,dae6d95f,a252855,a85a9b4f), +S(f803d7c6,1820f980,ebe0b297,87aa688c,ddadefca,229b99b3,a6bde5e9,922f94d2,a5f8b450,34dc7de1,461dfb74,e7ed9c49,80407bf0,4b0d9159,af703a9e,1e0f9c61), +S(2247f630,9be2f3aa,e30c5907,c29095d4,b9198d25,1a17bb34,7cf5cb35,a2ecb1f1,82685964,20d87b07,1c5a4044,b79b069f,7fa6ecf2,cfc0f839,b2161475,5728c2f1), +S(1d770ace,ceb2183,fea7c924,a8fba197,579df37a,908992be,d42c8e80,8bd98ee1,d87077fa,b910a21,8769cfc7,49aad579,c809e35b,f1c2a813,6047e85,e2c6fc65), +S(5d134e5c,5da47f7b,a495f216,b4994d90,4a79057a,3d0076be,34f09013,99f1f366,fc4e10b2,c1f7bafb,d241d5b5,1c57d48c,30fd29e9,df5774c6,1d4f2c15,3b66ed03), +S(a49ed10e,aaab9323,3a5f485d,4bd18c06,28ab2629,f0b8c3db,4d05956d,6c953fa9,338d476b,99f0ac67,1fcb893f,5f202204,a5178acb,6971e7e4,984d42dc,b904afbd), +S(4d000b62,1adb87e1,c53261af,9db2e179,141ecae0,b331a187,aa4040a,ee752b08,95f2a470,e71f2daa,34927daa,7d268d33,34820a0e,e638d6c5,c18d7adf,b7cfcf45)}, +{S(44d42980,eb92b3e3,b16816f5,56858355,e031b88c,99117385,def6599e,f274e56f,6e3de5ba,4f693fdc,747caacd,b2cf0107,f29fa7c,9c6a1a09,a527cd16,4c2c1484), +S(9812d508,d6da303,6f08fa7b,54cae319,232f925d,6af91d71,fe6c2fb3,bc86be5,735081a0,35fc17f6,7547b9b8,f0f91ac7,f0ddb965,19f6f398,dea745a9,81441e2c), +S(5a022ba,a90ddc87,42246783,4f692ecf,dd2c2dcf,b054308f,4afeb17a,7ff6ddcf,6fc2a9a5,4c7a130d,fd26ca48,82406fb9,f67db0ab,7e6a6d95,1675fef,2e2d4256), +S(c181ffeb,a8ea7d69,c524cd42,18af3030,1cac8e97,69eaf6f6,ba73027d,30fb7bd6,e88959e5,b07b7d3e,693756a,f94590bf,997763b,afa7d850,a80dd9fb,88e6e904), +S(e29375b8,21c056c,30954b81,4f9ce795,c1493dfb,ebf06f6f,f32c92c8,c74839f1,a9040ad0,95c9d45b,1527c624,bac86841,a1f28b7,ccf8dd37,b7e950b4,858e6e18), +S(69445948,ebec5ae3,9fcb505d,7efb7902,6bc1e8fd,5d3024ac,2b772439,72142d80,5b6c2694,abac3938,db899396,62635c21,e64fe2aa,40d18678,9c246e9,fe3f4be6), +S(a86f3aad,85d0bbb3,8270956f,58c2fd65,f5425428,27d7a658,da1b111f,64c02c36,dec740b0,ee35208c,dbec5b7f,69bb94f0,7fccd075,7868a37,6ecec7b6,dcbe20e0), +S(ba2bf65f,aac92da5,6c252b50,8dd74e3e,99ace1bc,42b9d2db,9d0ead3d,b6820306,37bcd01a,75027b42,eb0d7b85,564bedf9,67153930,6fc97106,ab6623e9,90b031ba), +S(78419e61,4e8b5eb9,d09e0c09,79ce4eaa,26271696,fcc68269,4cddf1d9,6a4c7fa,a32dbb3b,46f9b6b4,9adf4dde,f1986af9,72662a6,2ed6b6a2,f8b920b6,82b32363), +S(71163271,204207c8,a84b5993,88beb505,640898ab,b24c4c10,42195dd8,15d77985,aab43609,9370f246,7035ddc2,e71d73f3,c0f1aa13,148303bd,840459da,ae307e8d), +S(473f52a1,fb7c3920,f09ba6e0,a3c891c3,3f4a13cd,9dbf51f0,f3d39ef2,d6bc07d0,b2c403d2,4aef71eb,1b834df2,8bc08b67,5130897f,a6d9855a,eb21ccf2,780444cc), +S(581e93b2,99b8c50e,e6338c0f,f426502a,d8699563,f17935dd,abe08a73,6932b71f,46e7c7c5,1e076fd8,9b8aa98c,f0b3933b,8ca82cc4,d21783a4,d74ae1b6,ca9896e6), +S(e65d9e24,e7340122,875a9d86,d6071a48,691ed5e5,a94b315c,76f169f7,f3d69c48,73575103,a70b7a59,90d9b880,8698b651,271c8c0c,ac93122a,66873bf1,fa3c6fab), +S(cceab216,41d0597,f9c7ab64,7f99154c,b22d4827,70395d6f,ddd6db5a,dc752825,4084c57d,5aafc328,e7a250d0,a7c3c0a9,627ddd70,c77c2be7,e5a1af34,359b9b86), +S(4222ee66,5baff421,17f47df5,c1c1df5a,dbafb790,d5c75bb7,2646cf85,7ae85923,43088d6c,a029903f,f5a789f8,16730345,5a5cd0af,cab57e15,12781396,fcc9b6da), +S(391c5d0b,17a8c11,3440cd30,83434841,969b0833,71758b30,27e38a25,e778da6a,69f3d295,be55f859,4bbb2fb4,116de5d0,b24b5a80,ed62c1e2,8fca9b8,3f6d7439), +S(803b7149,f87e86c0,13599898,b0c9050c,d4a6e030,e07e8d7c,a49c46a3,8a6ea6a1,6b367fcc,6d5916e,72f670a6,5ada9c39,54800e90,a8830fad,c9ea17c0,494cd9aa), +S(f7aa1c64,f8f92f20,1319f316,353d89bb,eaa4d65a,e148b01f,ab66aff6,c9deb179,e9b407d9,4c2b385a,74f22eba,93dc35e9,bebca7d5,17401b7b,576b7d2b,e13ff0c0), +S(f1c34d52,2b7493ec,cefd49da,99732e00,85ace2c9,fd14e9b0,69b67dcd,5acd5e23,29460fc7,dd77494e,a5a7764c,7ca6db5d,5d7a5e3f,65e865b9,e5f85d58,e77713e9), +S(db19a1f6,38ef7034,5340e3df,8d384944,7500640d,cdbc3be4,df3b191c,edb9db87,baac873,a76e0b91,c4847770,9dbe88e9,6195e9c4,ac4d7749,71ca204d,4a5e748b), +S(4ad12e00,f384c7f6,ea669c71,3649da6,55e0abec,67551a58,224b9f9d,de6bdaf9,2e0314a,8e3f32da,33a22ecf,ccac4965,1f1f6f5,20baeddf,39a02bd8,423cd40c), +S(c9130b88,cd451d4f,6eafffc8,357ba391,ae920c27,69e7c48b,49881070,fd088ad5,aac7c2f,4f2f8b90,bea9267,897e0079,7d6515e1,937fa4fb,1043111,6b5e1de), +S(88260ca,df81b391,be79bde7,b54f8a98,428aeacf,970cd843,d683e6e9,50686db9,3b9b187a,b998a22b,56b2933c,fcd09333,9c23889d,1180e365,10dc086,9869cf2c), +S(3984fce2,ab73c70f,a5538206,c2a61e60,2f160b1d,2eb61980,fe174cbe,fe464dac,b7e65c1a,46b50c72,621e3fc8,4f4c7cf3,6860567f,abf00743,5fd1b13f,7400326a), +S(e6b48495,c8277598,23b73f35,762c55fd,8cd20420,fe5be6ad,f27f12b0,68bdd63c,ccbb7124,3b0300fd,993dc9d3,4b55534a,12515243,e07ab78a,8d8fd528,46e5a69b), +S(6af5144f,342f492f,3f506ee7,fc515d3d,d3c93d02,27ba841d,74bc6548,97d4830e,b195d9e0,8113eeaf,fab92a2,81ddeaa0,95356053,a51cf84a,b5d60fec,5368f98), +S(14439b7f,e40ca407,374da12e,217edd9a,86c84397,e2fcf6fc,965023,ba984a1f,112ad656,47c47c30,f19ae62,e0c06b35,effd49bf,d5e604d,6d621471,9f088fee), +S(d4a7e4b3,863fece9,660baefc,ee57d09f,6f60cd25,f4aa178c,cb6f8a17,5fda9d4f,4985a973,ab0e8627,f6de7ef4,470de4c7,1adecaf9,f3766197,a86f4e40,14ea474c), +S(facc2a9b,9d3ad0e8,9fa479e0,ba777a0c,90a0c229,59d4b719,a9304df5,f1e96ff0,6e12c914,70c78733,3e5a65b9,8c01d342,827810aa,be3e4e33,cba0b7bf,eb283b91), +S(3d1b3f54,2809a7d7,79ca2416,a7b7d007,4a728599,e4f30cc9,14bbbba8,3daa091f,dccd0d01,e56c7e6b,90829ec1,f0fc733c,8f1cbcb8,79916982,3b466448,cc21674e), +S(a8c1ec56,3cf9596,d761e41a,bd6bc960,562eeaf5,b54eb83e,3d7e7259,f69671d5,a03c9fae,e160ba53,8aaf38cd,96ebe3a6,db59a04c,ce7074e7,dc3757f1,ccc244e9), +S(219b4f9c,ef6c6000,7659c79c,45b0533b,3cc9d916,ce29dbff,133b40ca,a2e96db8,db2639fa,26a61015,a5bbe7f,3fc8d591,c6b0753a,c16fa89a,d820fe57,72c49068)}, +{S(b445babc,55be50ee,bedb8c27,dfc6c37b,492649ef,8a65de02,111b9f74,29b8c3af,6f74c5b9,f9a022b1,8d3a706c,5c608b31,9f7ce25d,8424d893,4cbd2f90,84b78bcb), +S(dbed76fb,7e46e1d4,1b507edd,8994fefc,f94bd651,a9720d9f,8d62dc3e,9f329104,c047fc1a,41689ba6,9855f063,c563bfe8,49bd8b5d,37b3836b,d8bc57ca,fd02ef64), +S(844426e0,860ff2db,f012ed29,ad2919d6,f46eb102,68073862,c1792e99,f1b2b33c,243512c9,c6ca739f,fb181482,a901ecc6,a41893f1,371d6b12,31d5427b,fb486394), +S(1df697b5,9a2f9c91,b2c5d4a7,8035ea2a,351dc000,4e1c3bd5,5973020c,24836aa1,e89f949c,f6af652e,d7e79758,74a994ff,46475df5,4f7b17f2,a5c29cd9,7f722831), +S(cf4ffa86,87d9a39,7b4727ba,a033cd02,7d8a5377,46903db3,34c35f1d,855999a1,d1316b65,e027ed02,b4be11bc,4c21c1a8,585bb247,45cdfa67,5fb9cccc,faf0c546), +S(e3eed1d6,1813e3ec,d1b9fcfe,3e8bd700,bf3412ff,78a0a9b9,724d4dde,ddfd98b,dcb09803,b70d4c34,ee2bd7ae,6444724e,9ab27c20,5c3c736b,172af37f,cc673105), +S(3a202c1d,94a94eef,18fa396e,5cb8a867,8c3ae45a,e4ee64b0,822d207e,6c814fe7,147992e5,ab565bc2,ad1b1355,60f37dc6,b5cbee74,fef8e5ca,4e4f418f,811a0482), +S(6ce8f558,a853dacf,205db4a5,80c4cbab,8ef477a6,47bca6cc,9e676cb6,5f3f696a,e88e3934,b2857ec,6edb911f,acd132fa,f0078971,2805aa59,9afb3d80,942dc23c), +S(7fef9aa5,b2df37ac,99ca488a,ba598b4d,eb222149,55e1cb4d,c3ef1e7e,7bd38945,d4b7cb4a,8f9edfd2,3a0efd1,9882baf,98312b6f,7b5775ca,65e9dbf1,f2c32870), +S(6ec1ce91,d1eff7ed,9beba2b8,2f4a526f,736e717d,6442dd29,b55ae2e5,3371e0a2,28240ee,12e2b1ed,b40698e,ba6f087a,145eb772,caece880,b3e94b97,700dbd58), +S(645b9fba,2cb739ee,9b148b29,8fbe9884,f284893d,968c21d9,50696d2f,efbbf0bd,b06977a1,2d19836f,add50b7,b73399bc,698729fb,fd182026,d918a267,eab4b7c6), +S(7b930561,3a4a7cc5,ce1e7f5f,29314e1b,40bc8b93,40604f81,76578c18,69abf6c5,55a7e3e3,3f19805e,b5056d15,deaaa4f7,aea07a46,f9dc6a09,6ce15392,e146fb3c), +S(bbcc74ca,3697ef46,e7415ec6,b31a0808,1e6ade01,c7e2264c,f9d4d94d,d849ccaf,27bf64e,e1005f13,989639a0,8772c42c,b4249ba6,9d90cae,3f542ee1,78929f26), +S(4a45fd82,af96af67,9e640bbf,561cb385,2585a8e6,1b57df7a,e028ed33,a017c680,4ba76ea1,19a0267a,f019b3b9,89cde9ce,7b1c0b6e,da3c773d,ca31e44,61e048ed), +S(c3efb1ce,ddc6a749,a5db9daf,48032a6f,3f1a848b,aef9e44c,ebd76127,a9c90d0e,3de258cf,e593b489,8f92e8ac,50be894c,3636019b,a9f31f70,28468eac,687b8f89), +S(ec71a2a4,6f24acb2,8fda6bbd,ab9326e9,6590a96f,b9b9a4ef,405949a5,e3d2858d,31a91fa1,71207da3,1b0acc25,cace1e7c,5126ca2b,4c8d9733,4c50a7f5,29bc61d2), +S(65dc268e,cfd191fa,f07421f0,dcb16701,f979ad24,81ac5ddb,1f77d3ab,41a773e0,f8c9ac90,255d6460,15ddd1d3,57b92522,53bb55c7,e2f5d843,d7d9a025,2766d2c0), +S(62152eaf,df564900,4379891,4b53ddd7,3b91fb60,f16f2d18,941caa96,18d8ffd3,3a185ef0,a8d8a35d,112f678a,6a04a654,df565a8f,87e99abd,95fb4977,1b278ce1), +S(f68e6fcd,b2c49661,ae59bff1,f24e97e6,fffe7cfd,f185d0b8,133d58e3,bec1c89b,223dee27,5e9cc518,af12be21,ee7ef3a9,ab39c7d4,4f950fdd,9ce5c78e,b50514a2), +S(5d02e9c4,108860e8,2b1ae04a,4afbe1e2,9e0a8444,89876776,7e5b60d9,3fe5c753,25fdcc35,5f1970c1,43dae96c,a1ef0a7c,f95853e4,102548f3,d869d3d5,8bcf962d), +S(f6217e4d,4e6d06d1,27668a01,8225f88f,a1e0fcd8,e8654fd,ab26c8a5,4c6d4751,65a6acbc,19bb2835,13eea5d2,5fae521d,aeed63ca,50f9aed8,edb74dd9,c43d066b), +S(c18bb768,bae77077,35b4d3d0,e82cac24,fe3d7ee8,dcba20b6,a320ba6b,4695a406,b7a7ded3,a589153f,8ee504cf,fb5b45eb,b2d8e121,40f2f475,186153df,1fcf84d6), +S(36fc443c,1350b40b,881e41c4,d3c15952,31f8da9f,cdcac4be,f1d0c5da,ceb9844b,9843bb7b,fd0ebca1,762785cd,55669233,16c36aa2,d2c37b3f,2b196f78,bfa5830a), +S(ba7b8c09,d5293e6b,a2548e6f,ff3c939b,80d2ac54,34903039,dfb8b661,29e19cfc,54fe2a,9353fc1d,a0d34e07,b6d34d1f,f3a1f67d,f4aafa7e,57919142,95c2a5e3), +S(50a8ddf1,17a91c92,37a48fe8,f1a00e72,a5dff682,7398a4c5,d2f78b4d,d49ee339,f91d9b20,da28e51b,99fa102f,13f5e451,ab22e139,80052384,6b9c66bf,b7da1578), +S(642ece53,832d1859,c6543147,56b618f9,520a5888,2549277f,6b27f16,e08e3d1f,d9963beb,2c6da204,339a49c5,f253498c,48cc3e99,b715ea8f,a5eb00cb,1d6cffbb), +S(a68c0d3c,13d764d0,7b513390,5842c9,a7171e4f,755a9737,609db06e,1a44e5e0,a2c3fdd7,b7938a87,86f3756d,dbc66b29,72469e79,839a1448,b367db5a,2bc52c15), +S(5b33d730,288fde53,b123fdee,177758b1,ec113adf,74e79eac,513eadd4,cef377ac,1bbc10e,9d45cb00,db58fceb,bc4bcf4,a0e2bcd2,a7d3ec12,7d87beb7,a134a20b), +S(aa6dc4d3,ce531af3,e68590fc,acbe7816,c8293af0,d77914a3,c7119e23,e50ce56e,14386670,5dbe1ad6,91e09123,a19a199c,3ee67b25,708ef57,4620c5ca,821224f6), +S(180a4ece,d74ceaab,e0f7db3b,b038034e,5e659c61,3c66a534,8d962d14,efa32402,b675b2a8,b845281d,524403d0,db01417a,59fd3a6c,80232e74,cdfc87f1,3b76b0e1), +S(3a55690d,abb5e00d,c2d0d8a4,96d16c44,76ee767c,a9d0d1d3,694c856e,e5b7ad0d,3c1d71e6,8a5f9a84,4de0453,6810660c,fe353475,353cede7,2936786e,4d173828), +S(33b35baa,195e729d,c350f319,996950df,3bc15b8d,3d0389e7,77d2808b,f13f0351,5a75fe7a,9bf54078,6b9bfc9,db72ad43,559a9f10,4377648f,d43afc32,34728817)}, +{S(52f79560,fdfadd45,6165a204,6bf61bbb,726cd726,3a3ed2d2,45f07631,5b0b6ae8,e6c46e55,5b4a0410,bf38965e,5a7ba381,fd259482,2280482f,877a7ec5,84d14012), +S(29eeb07c,7b27f82a,1b031881,11d324a9,4df77713,a8cadb36,2ce4012f,52cafb19,b7538574,28faf258,f240d4a9,f464797c,dffd0a68,f9f978fc,476f9bf0,1a0a2df5), +S(2191ebbd,a95c29f8,e7062f21,a70cb368,ac67ed59,dc44b167,66e52120,cfe8e742,2812f1fe,557496f8,f21b1f11,2df7bd19,db6aad90,59494ad4,eaed4d77,49f66a4c), +S(3c29d849,e25364d7,576779ec,78755ff1,8aa64e2a,65140a2,bbcf22e3,da33a4f3,3658d9ff,e2e283c,f8973cc0,ede5af6b,69ac4970,3c6b1370,f6a2ba4a,78a28a97), +S(37230e16,e11db299,f54ca0f9,f5423ac6,5f05840a,e166175a,ff0732be,c72ba88d,2a26ac2c,e8f9ebdd,20f1f5f0,f628d3d,d0e02745,6132cbf8,78b614b4,51db28f2), +S(8fbb3be7,98e16bfd,b738a512,ceeea92c,1be8eeb8,5374702b,e927c614,ab1f1baa,8280f387,64a48061,26392be0,c95f0c58,3607343f,d0b24b98,afe3605b,8f7e79f4), +S(fb639ee6,29dd1f03,8e12330c,bf40ec7e,129d7da7,655c1c21,86452fe4,9589c89e,171adbae,2efe213c,8d01e273,ed9c5d47,c4e85503,de3849b4,d909823a,bb1da898), +S(2399064b,876b7584,8c977bf8,e35d6b32,2e45d1a0,c4243fe1,2a31a581,d1d5d826,79c1ef29,c1af9497,f3b3db13,17432d42,86fa014e,17e5d780,a0d39df,b61369c1), +S(dd5663da,63acee49,eb7fde29,6ac1215a,772512ee,6a080f3b,1266c7ef,51da5dd2,d19c7348,3754112e,9cb3a4ce,8986f748,3eba26ab,c415abdc,5effc956,27efb7dc), +S(30862c58,43b161ba,c127bea6,7b23d3cc,46b6c42f,8faaa281,6ae47092,8ae47993,44ea1101,26a7c448,dfed4995,46a0fc8a,3658e540,d7d0c2b4,18f8cba0,accf9537), +S(df7ebbdd,4e416e4d,6b1e67aa,34915da2,cc15bf8f,f6d79ebf,273b63a8,32d6610a,d05fddd7,e9618753,21f473b1,bfb5ff48,65b3c4f7,5cf4ae26,549989a9,e13056d8), +S(13adba8d,2485bda5,1ac7994b,c45a7e4a,1b21aa9e,8188e631,59b217a,29d4237c,6256a795,3f24b25a,c1f59384,aac3eabb,4458e504,af3b99c1,99ae614f,8def4ff4), +S(c160f7ac,9a453a1f,8811d031,9849be43,22d8bbe4,89cad7a9,cb815927,d4b54720,7958b41c,751ef3a1,fb985ea9,c7cc85f6,c16282a4,c374fed,5999d8d6,3227b720), +S(c66af931,82a7a9d6,588e9c7b,3eda3b49,40fdcb99,346aa55e,e6549d4f,f9382228,ffe4d0df,43f00af4,fe885b10,92ae38fb,97d21a8d,26aa5f69,9751d52c,a9ccea4b), +S(d3a4f4d7,d208b43e,c4c2fd00,798d882d,922f302d,a199b707,76a70f36,5ff404aa,8df220d9,63faa827,1c4ee360,67a536ab,25813239,82252483,311616d0,1458e1b), +S(47bdd428,d57ed451,cd8754ea,817c5f5f,9658274c,ef6757b8,70527b4e,96f372f9,fbcf0ee,9fb14de6,3c288dbd,b1888fcf,72f0265d,3fe2209e,12c85841,2c375b53), +S(6e6deb95,7f2eea30,5d625288,3cb311c7,f0365a42,480fb807,36315c4c,62495438,ba0fdd63,9b8678f2,ab0fe3e9,a16512e,ffd9ec23,e691cd4f,86146969,534978aa), +S(dcd2775,7cd691e8,28e21987,d6eb6b54,e8def24d,27238cd5,dfb36a3d,d0f05caf,40bf37e7,bd776a62,ab420209,c71df7df,74d185c,f0d6b038,dea9c8e0,c1dad163), +S(eda569f9,9bccdc21,580da94f,92d89312,cef87d13,f08d8ad5,f1574e12,30a64ce6,4e1da1ac,dd274e3,f9d7def7,746f0652,678e549,ad5476d1,410adbbf,aa3c1e42), +S(5d3d4a29,734fb7ad,2846ae12,4c803364,ea3d57bf,e8d77d9e,6a3b3f8c,9cff26b6,d3e598a7,1a469323,a357df08,319dcd1a,d7337a32,c9894b80,6a30c575,b19756b0), +S(10161fa4,61e87595,f269da7a,ae3ccf01,40e910fa,891276c2,df1bd91a,95e4d046,b36eb5f4,b8291a01,18691f1e,50235d8b,f66e14a7,f0641dd6,18ad7ddd,ea150196), +S(7ba1b276,3df207f3,cfd1d58d,5190eb91,99cf82f4,9d2d0927,f5f260f7,2ea0f178,cb9fcac,4be96ef5,3134f513,5509c178,99af24c6,4eabd650,afc599d8,3927969d), +S(4bd6edd3,aaa1802a,b0f46e05,418ada37,e75728e8,6ea4b293,6619c92f,57674dc3,c9e962d3,de71eafc,7fc9a329,3bfd721f,305e876e,a2a4755a,f9567dca,21aa3c0b), +S(95fa0b32,40b24ba,29a484d7,f8f022eb,b3f30349,9d8abc1,9a69b690,3e885b68,dfe6b88e,56d7b923,dcf8bac6,2241d663,3ac2ae55,c3a01fcb,9f966d62,8f3acadd), +S(d0fd4d10,18c37114,2d5f8a86,617c250e,b6c3d5,210ca465,6ec84e87,d0ae42b3,4e3bf443,290404a9,3af38e72,a54fa06c,3b2d6a81,161fc8de,554edd9b,f3399587), +S(992e1183,d4e7afde,166c45e1,37c71c88,d4039709,4262163,b4ae38e,538293f1,c29534fb,55e47a08,ecee311c,8f0ba4c0,39096edf,b2d7ed63,21a2810,32e85900), +S(9c124ecd,4e6ce167,f60dcf38,25976f33,64cc30ff,61f7dde,966f8c23,4c13a4d9,7ad73bdb,e0afe3c2,c89d9135,d445ba4c,796066eb,1909349,9e6ec14a,f74f664c), +S(b09cdc9b,d102f89f,bcca0ed5,888519b,7c5c02b1,64ccbfa0,3d0fe42,b1b113e4,f409865f,6ab4371d,f52790eb,88df67d,84b3b74,f17edbc1,29b802cb,d5e49a59), +S(6b4f628e,beb6d619,1d616e87,3233ae37,ca4cc3f2,ac881e59,9c2c8e3d,295ccdc0,1140b988,60f4ac7b,659eb012,6fdfb796,c0baa652,2202cce0,bf54b3a4,865f171b), +S(a728c830,10169439,3af3f780,b1ceae3a,6ca08ea,4bdc7554,2ae84564,f542c28b,7b68fde9,8c97db32,eb3cdbd7,15816e51,9aa58458,259dc74f,5d722dc,f48f1933), +S(21ce4401,4ce959de,f16b3912,e88ff48b,d44ef79f,5fed2d35,bdd2dc78,de8f7605,cdc598fd,c5d30508,a2690299,e0e25b91,b1ccb69,97b99fd3,eca1baed,76aae6d0), +S(89912259,11b9132d,28f5c6bc,763ceab7,d18c3706,e8bd1d7,ed44db75,60788c1e,2574b267,83365364,d84789ca,a64ec905,c969637b,21061ee,9ca3bddc,7170ed3e)}, +{S(5914f66e,28c1a0a3,47f461d8,1d7f2c55,845e35eb,3dc39945,584b5efa,8d71a215,cd2ac885,3f681e4d,884e308e,ed3ca185,b47e2d63,3fdfff6e,efb6dc67,4d7de056), +S(519834c0,d16c807a,7867b8fe,c99dc93c,3b9ed218,87a9ca17,9343729d,3ba9e294,b867d57e,fe2dd7c7,8586303,152f02fd,f67b5648,78a7727a,190d304e,64f97203), +S(959eda70,cbabcb05,fa8fae96,7227b6be,876db942,ae38bfea,a9c3d359,977e1c52,86373396,9338053b,b00d206c,5d67abd,f95d35e6,992ad69d,8d8a3322,7370fdc), +S(a40279c8,48dc042b,a3ee929c,2910e326,eded6051,9d9eb1a4,98fdd7e1,fc88a6bd,f2c962a9,f2950d2c,acbfcf29,35bad39e,2709c0e7,36378968,fa04d957,1dadc4ee), +S(650b8181,edcfe46c,eea03ec9,f8ee5af2,c288e618,7d634961,6c95554e,25957334,ce140ddc,c2e2b07,a57e5627,62da3eb5,ca1acba5,463e97,fff7eae3,55b954c0), +S(eb04688d,5f4c8d2e,4ccd509a,3d003b30,8c5539b2,dd160a45,cbe71efe,36fd9005,37d80690,2062bde0,b96fc8ba,7a7f751f,9461f774,a1d6f3e8,8999c676,a2ae76b), +S(f79206b6,7813cd64,9f946313,3bac4aca,3762975e,954e0ef5,a876b78e,4b5a5d24,6033d4ee,936e956a,af117dca,6086eb1f,6466ab18,d503503d,4b011315,365242d8), +S(539c99d7,728cf662,13e024c0,9f1226f5,ca5d09cf,67bac12d,47814b2b,b1e7d611,87efd14e,e58fbff,5491bf85,aafd48ae,6680f37,e0d928f0,13fb6cec,6f417f76), +S(2308281d,e761f602,66fb8228,45eec88b,e32f8fdd,4a06b8b9,3dfad9c3,75d64a8e,933f4071,e4f2a9ae,95f4a299,f4267098,94b661de,c96443c5,f03f6cb,f3be87ed), +S(a93d05ae,fa31c0c1,54c02f68,9184c1ff,344c670b,e13eb304,2de517f2,1f6124ed,b7549c5,4651fa60,61f4103e,27d316a5,db531e3e,d7396a46,e360341e,f53ed274), +S(35717dcb,4feada90,b039aa79,10cf064a,c8c998b5,fcbb037c,22bf9e92,eba560d8,b6ff9371,d98bf532,f82d7fdb,24fffa69,2afeb0e6,59ba30da,602b3399,2bbe5a5), +S(941d37ef,1671d5f5,675be9d0,d5cb1f0a,ab6dffdd,2bd342c5,c5b62be9,88d5a0aa,4834d5ee,a8f9ae8e,ba5cc8b,2fb52260,33e35767,d55b6aa6,d204e0e1,a38b42ed), +S(c22cecb,aff78c61,f6e34c9d,9367c4f4,1acc9c35,29e9d894,7989a874,1d70bccf,38a37fb0,5fd9036e,762e2f0c,fef8fcbd,c04a92a5,4cb72ee2,ba08213c,4b58f1e1), +S(7863ac2f,1704fd,5015f0ed,30edf5d4,33c5ea2c,e150833b,a15c1db8,a5e4d2f4,7468fa15,eeab5653,c9f982b4,ad9e4c99,2f44083f,a7a93e9a,25ff70e5,b8742b4d), +S(f702cfa6,f0cfd275,a2c7af50,b53d0c94,bb965063,c433f4f2,cfd13d99,800da48d,3da4a4e1,bc5f2c6d,2f8daec4,599a9704,7c1b930a,b37d6b2c,f8a586cd,ef7dce1), +S(c3a1da3c,6e6b8f2c,2a8eb81a,1875f2b9,1e9cd286,414862d6,57626b47,a413d7dd,983d0892,5983d42e,bdbce2d8,df116bc2,f5cf8c87,aeb833da,e5e7e9ca,f9699798), +S(df0a4106,d61fc3c6,b2a14ecf,ebea3dcf,7e38069b,8faac576,a0b8a1b,7c8e7b5e,dd97a06b,840d64db,1798cee4,9334b033,e8d3f4a,79da565d,c6130da,f0bea75b), +S(ee9901fd,9312a21c,879d4e1b,24d5a299,b8200a15,6e65e147,4a2055c8,a2363423,1bb2933c,8b10f8e8,ab93ecee,16f861ff,a86781ea,59b891b7,740fdc2d,f6c206d), +S(52890b99,c8dc48c4,b6b1e4ae,5b823fca,ad9495b9,8217fa4a,b4f8e960,77cdaf9,6ca2ba73,72606e82,9c3395fb,dd2e4b74,8c771231,e86fade,5e2d728f,e5e7391e), +S(a372b545,bf56b58,b7c4628d,aca9bc14,e8bc634d,d79d139d,8eb7a2d4,13465c3e,afde23df,fad41c68,df94abdf,90a642b,31d62f84,c6254c4b,4cad2934,376372f2), +S(89d02f41,f88b1f7c,90b01078,d7599a70,a1eb9c23,1059e856,4237b0a3,2c18010a,7e8e810b,b063d75b,c224f41,a842972d,6fe065c2,aa6b16e5,7bf224fe,e44b2275), +S(7ef367d7,23fedacf,86425861,f67c5ba2,2deaf04,69e31988,7a3a3a12,2f39576a,4b81e743,e00bfbc,1d98cbc2,5c98c516,55e574,fc7fa1f5,86f15d9b,1b5b7ac1), +S(2eec37a1,5fdd1caf,b4c0855f,e86c5534,1a78cdc,b3944798,311b1cf4,7df768ac,1c18cf5c,1a98fe9,70d1e635,ab133668,4e0d964b,4df0b16d,7c51ea01,c9a63), +S(72208b8c,fd9840d,76dfa6e0,f36cf57e,502f285b,422f0ba1,9b119500,6b2ddd11,fa09196e,a89ce6a,888415ec,a8eb92f4,149bb39a,50174a85,8a29bf63,65b4e577), +S(9f46479a,69411d57,c3c7ea6a,dfa833f9,1fb2109a,fd30c790,2ce323ae,4b14be0c,6cd6d7e0,8494cb95,9e67c258,1be426f6,4eee4514,83e9a9a1,278b073d,758487c3), +S(a9aaf56b,5016db58,5b8116dd,cbad1169,4b16de8d,9db5ea5a,279ccf4d,91b1d7a,218fed41,389a4abc,44fb2a83,7016eb50,99c40e86,bb419265,7f57714e,194a5900), +S(5f950f20,b610c06b,76949dab,52fc6149,97d254be,a1330a0,493f1ea2,1d608864,d9098481,823b3ff9,d1c0b7d0,bce90856,186b45ec,6f20da26,9b158283,8a4c96df), +S(ed621f77,98add722,b0dc5e52,9c6fec6b,dff60827,b0b12c85,18d798dc,761f1075,a8973e79,a9caf1fc,e3165145,df08b7db,6b7187a5,28b12712,6c62bb5d,4f0c46d7), +S(15b8390d,652d7338,e18ee091,97e0e176,74f8c4ba,fa2e7b85,8f5badc9,9c89240f,87930df3,710172f7,c5422833,385a6066,4cfc9854,a3e5ccca,d1d06106,1cd90be5), +S(ac2acb9b,21999a70,540708ab,68338266,aef650ee,d81c5b30,da1e87d8,a8a923b7,897bbd7a,ee3e8db2,e36505f2,ec2614c,9f4f2f40,ed2d85b0,5d23edb4,2832db89), +S(17c072d5,6bdd1382,a782481b,8aa4d223,2db79438,5870bcad,c3063330,a5cd5379,26fe420b,d7c25f9b,1883edb8,50e2fcb0,76a65389,d9a452f2,8351fad,4ef72f0a), +S(8d262002,50cebdae,120ef31b,4c80cd5,d4cddc8,eadbcf29,fc696d32,c0ade462,1412c44b,8ea40bc8,2ce090d2,3c11c945,e2b504b1,8d9874c5,271f5745,f0d9b523)}, +{S(ad9144f1,bdcc3673,26d51685,a047ea9c,3c4feb3c,da4b9b83,80e1ada6,300ba487,68003744,ab5b2c8a,cca5bcfd,e1c4262e,88ffbc0f,b0ad4206,2d57dcf8,62c93c47), +S(f3b90a0d,7a8cbf1d,9b994b19,7ce215f9,b8ed861d,d526228,59fe1811,68727bab,95f48e8b,c05a7bf1,e47fdc86,87513ae,5a56472a,44f384f6,1153a954,2db68b81), +S(24af6d7a,99122466,45b07a1d,29b4bb1,a68b5b0e,f9422065,b5bb0050,61d43cdb,f9dc7725,f628cc4e,d4e5554e,f0166b22,566d59e0,4d55c28,a4d0e975,8306c31a), +S(f704aa4c,2bf19c9b,128311c7,1bab5f8a,f2a3865b,728f4838,b8ccc7d7,82574cdf,ae7c46ce,c44d54a7,2e3f758a,e855710,dee6b189,1223d120,9e059620,38d12453), +S(f701adf5,a1bd988d,d7e1fadd,9903c453,e6798760,252579c8,b90cdce2,a046d9a7,db39a987,48aa20d0,5d8b8538,fc4b7d77,95e2810b,160198c7,ad98305,96407c31), +S(bfe36081,c492ed7e,3b91059d,bb1af376,47dca509,69be6665,50f94903,d948ca7c,a1fc9468,2c3dc954,764ee858,822b8c1a,5d0184e0,93f12bbe,21e9931,18911f03), +S(e707057a,297a3d7d,904a615d,ac1b8e81,78f52481,32fa166e,afb621e3,af3f4f34,9161a930,bfd583c0,bfd3b121,acf574a3,6eb534ab,5198aa84,ef38253d,9ca19bc1), +S(27a6c7a7,970a9e3a,7cd42b6b,4478be62,31f53ff8,481791c,4394e78a,968fdddb,e4bf1b16,6bd56269,9e2c341b,b1a51c8a,c2ac7d28,807899e1,3ab1f726,90f44108), +S(e65f799a,8fb3b6c,ad088351,614db5c3,d64660ef,8c977ec1,2bbe58fa,a53314d6,5897f680,253a948e,fc260fa2,8ac39377,4e6a445d,d2bde00e,4e01ff03,b4398e2), +S(8406a84c,e9e63204,761dd406,9651f20d,6fc3efe3,f98951d0,d0a2db9b,cf86e0a4,ef81aeb3,eac17e5,676f4455,b4372ccc,e405b786,f11a871b,d781e54c,6307d1f2), +S(c012cad9,4742fd49,8daaedfe,5b847f34,7a45c792,53c8a645,2192e905,e256c7a1,c4866f98,48f31660,8a81da9f,da112a71,34232f9c,75e388,7ff987b6,8404cd42), +S(73795313,e9de1efe,3d91ae5,15c620c4,4f9c6bb3,a21e3097,c8794710,b2032683,548ce754,93817f22,cb96c674,5d67708d,c7b9b133,c71cba5f,fede1316,c55245f7), +S(352b89f4,78a47e86,b5575fbe,ee1373bc,e93ca316,1f594564,9efaf048,a60bfebe,d784e6cd,88d7862a,d82747d9,b23340cd,b50235c7,65f30be2,ab5d313b,edb0624d), +S(8a0b3d0a,80d41abc,4b8a028c,6c523923,7b040445,525dc345,d2d8a319,c4708316,7b7a427a,f0e1f902,dd1b9bb4,65b6b376,ee68b9a3,f495cffa,c52fcb9c,705443e9), +S(b4bf6756,61462829,53f9a44a,ee3b5427,2485b45,951013a2,8d59346d,62f65894,85d0c26d,2987dbd9,e26c9673,71ca86af,3b8cfb4f,cbf97404,c99ef900,5379a1c6), +S(bff69744,3ac23a6e,574bd1ac,d0fea305,2f05ea65,14814f1c,65e86e9d,5b46a2a5,36961462,5b998565,9324f5f,c8714d9d,57ff314b,5d5c2cc6,99a4ab39,69add4f4), +S(ecb09f5d,122adf91,e68e98ea,d39e5790,27e7c4ca,405bcaf2,e086d4a3,e68242ed,aa214cca,8a601fa0,a92633cd,a353ca02,7a7dee71,cf335af8,fc75de56,a3405f60), +S(310d957f,10fb34ef,ca3a2a0b,35c901f5,35c0862c,68310134,10982d7d,e74af8ae,289cda3f,29a489a8,86121f4b,4e75a90d,2bc4ff20,e95aa103,4044ea80,cff56378), +S(3a5f1ad7,c59ee6cf,e090f210,7040b419,4ca15fa7,dc8e9f69,20825fc4,e012ac2e,8ac8986b,48d7bd1f,5ae99535,2505b0ad,78f855e,d8411b03,15725571,dc99c920), +S(725f136d,1b426894,c24f8782,43fdc1d3,79636a23,d682f389,dbaf71de,d4672067,db0ffaac,ec5ffadd,f32396be,3f01fe2f,45bb0cbe,eb0d98bc,2390f3ca,c3dfec84), +S(b28e523e,6fc68192,445180d9,5da3e411,2fe0db1a,5b3bd5e8,e00a1090,39c69d53,7c172a4b,31339fb3,47db74a6,beedf59d,c24e6aea,c71e2a0c,434714b4,d61a2f70), +S(b808db0c,e34b5607,8166b308,1dd4b2ca,cf9d2d51,3079648f,fc3c617b,8e45ba09,d69c4ab2,fc7e490f,6887f2c2,49e0b71a,746e3e2b,97a7415f,34475bd6,f6dee79), +S(5e0b091f,3144d7bd,c7e40dbc,98c716cf,d7e64eda,ee9c1fa4,6838bcd9,e0c6878f,1586cf7c,da66b005,8b2d0d49,f588d444,65eecf42,1d94c004,a078dbd,47e0bd20), +S(1c3e88b3,ba46410d,8e08f9fd,5db8b53f,8dff33c6,4f5314f5,e005442d,10cef1f8,ba365020,5f85aa9f,71a42c0,392345b7,4a17a5ab,9ff91109,4d81252c,d8c8f72f), +S(b4926018,fb0e9c,e80c5614,37c3f22c,cc223412,384321e3,6f408e4c,ec0d81ac,55544f6e,cea3575d,e81649b8,4950f225,8a94e78f,13325ffb,16debe1a,8387173d), +S(f4bfac1c,b0834e1a,e332b7b7,1ab84500,b1c8460d,c8c2efad,6a5efbb8,ae78cd1d,5faab691,59ce9d3f,6bdb1818,676684b1,cc2309af,1401b5d5,137e1c61,5fbe287), +S(220ed3d1,fe028d87,b96e8ad9,37ede03e,ed8f262,ce877c0a,42718ab9,cb2ddfb6,5ee2d60d,f96a1b8b,e11c9139,7abf9b4f,a0671966,34bf37a2,8d26864,31933fb6), +S(dca5fad2,d045526,b6a4c309,de1d95b5,23f9a7db,e669b558,edd75ca9,40c85878,f350337e,877c9c61,98fc912b,5d53876c,78ea94cb,bbf3744b,62a52fa5,f5ae4399), +S(486ba509,3272eb1d,16ece443,861eae7b,2d8604f3,37014bc5,11267485,9872642,688d4585,9fa732c4,f582d65c,45930567,8c27dc6e,5525d47c,3908daff,f0a534fe), +S(96bc1bd3,b4840354,14aa92eb,6db81f5,403e2858,c0552d5a,6b21d33e,c468f31a,83027873,f4066b5e,ba6f413d,6a7d4d18,d57f4a62,25cc9289,b514f153,91ede3b9), +S(9f131ffa,b53e20b4,e9cd9e33,793f4614,922c03df,7d11222c,7fffec33,42fddec6,c4deffeb,3f4cd90b,102cb6b,3f713728,2c5cdcab,bc6e7153,91ea890d,76207bdd), +S(c15c8c23,d90c8e35,c1a214dd,e2d4383c,735ae45,bef61f10,aa1a1c25,5984cf74,d456ab27,d7adddca,372390ba,1da02845,b84088d2,af4fea5d,3b5b7326,c6334c2f)}, +{S(e24b71ae,8fdea24b,2d42a2c6,5cb022a8,2aa9e03a,3067a889,e778caf8,34903fa,f87d5757,cae83263,1233b840,296d6066,52cd1ddc,e8334629,25c992db,7e0ee14a), +S(886a7626,6203c559,807acbf6,7e1631ae,1f6bcacf,3fde277b,ddcd795b,292c38f6,b1f590a1,52d3ecc3,2b699c23,a89b2601,de78be2d,fa11b20a,1ef1235d,93ed9e99), +S(3079f709,3d5270f2,95fee75e,a6c5cd3a,5638ee37,aef535b6,523604d2,eed0d57e,492dd2cf,d76705d7,42187f38,f38982d1,85efa30a,fd1639cb,984a8772,3e912a91), +S(7773469e,c557e3e9,4097bd55,33a87583,a79e3eb4,2e421cd6,592363c2,76641966,f827b0dd,46f4b5fb,4a656731,d827cf21,df1ec610,f36dc2d1,215f33fa,20a08020), +S(ebeec367,eb032a6f,7c421ae6,f8fb56f9,3fcdaa68,f6741e46,1992d019,7567336d,6e78af43,e10c742c,35467149,3323f8c4,a6cff91e,7b1f1c2c,65b21fa1,e63f3a6f), +S(b41658a,3683b512,c751d817,f5d92f8e,5d158632,1f2eb836,b446aebf,d276030,9396ba60,ca61b35e,4e52e879,a457ce5b,fee9121a,b2673c19,15e78236,483e069a), +S(2e2ed965,a926700a,1428af7b,68b7dbf7,61d1bf53,6eb9f75e,d56afa0b,63852cd6,8d77656e,d5f11224,3a94e462,3dcfbbdc,61749930,dfcca6cd,c4303cc4,617e9133), +S(4b54bd22,e5604384,9ff2268e,88c695d6,4766e0c8,4f598f5b,634e1dac,d03063ba,176c68e4,a1f25683,37c14fee,dcf9a64b,17cba4f7,283428c,1514990c,98d29d71), +S(b6cf7c38,2d4c63cf,78557116,55b5de99,1fd32da6,8b8d2dd4,cfcd6f5c,59c45251,c4c190ac,2870142f,2a13d7bd,5d6768b8,fb5ccdfa,b99d0e3f,6bda805f,7741ff52), +S(857b6db4,79177eca,82a6c801,bd763647,c1a49021,e5b4f405,ad02e6ec,7ccc3629,586cde8e,cbf7907f,704a6610,f7a8a910,16599e9a,93bc6a6b,1b70d59e,39c0db4b), +S(a18a23b7,6643d92a,9e1bd2c7,7bfee61d,c5171b33,12f64d7f,821fbe05,6a771ee2,321f460b,b9525303,c159fe3a,6762dd97,60432307,919a2f1d,6120c946,47cd8568), +S(19b91028,cc2e5434,b162cee8,c77351d9,d38d9eb6,8ff9b09b,f26cb25f,4b88510e,cbcf2e52,3335ee5c,56ee2a06,7c565627,a5c60f16,808ea8e9,94250c15,e427c883), +S(657e2f30,b1e0241,82c0e57d,996cccf4,7bdf8eec,5a4da875,1638b3f4,9bcdbd2e,8e0a3117,12da36b2,2d0cd048,a9a99b26,5faadec2,14162083,5210f1bc,bb79fe3), +S(576879e4,f4a8e697,45014bee,36ba4267,cf72038a,f5997d38,cf512f08,f0ccf6b0,3f313f,388c011c,18ba0938,51b0e7e,84627277,2e9da999,b839b58,92ede5c0), +S(ed72d681,6516c2f2,7a9e97c7,1a7c99f2,faeb8e31,a5f29260,faa0bbf8,6475117f,331fb25b,e71c24fe,f4d2133b,f1591f3f,e5f8830b,15615134,36fc47fc,522ad4b), +S(e4ed422d,9152f00b,96bce64b,bc3ddaee,6089e1a4,1ffbb58a,109c688e,ba44699f,6dae6420,2dc6cec2,e4a49203,6b16c9f5,9c517436,bf3b9d9b,7e8f458f,7fcba8e9), +S(fc3b8afc,fe39404c,29622db5,b06c989a,8d7a0c4d,85018796,d006bd5e,43dec087,7b77feef,2211c1a5,724af5e9,a841e09c,d7940bc5,43d70c7e,51676689,7682ef15), +S(9c2421ee,e2e7e66b,decbd152,a8839f1e,4cf03808,649399bd,ba55cfbd,9dda6360,8d9477c1,c66a532b,967895ae,66c7585e,608e9653,4f870bd2,c97d7398,74a84700), +S(22040517,334bb5cd,2252d1b9,8a9da91f,a0bd32b5,562c8218,4d991e01,d94e8f13,167d3dd5,738a467e,f8e03064,d6482c2d,64503892,b4f5b9d3,c4b04684,fe2f15c0), +S(b648a617,3c728243,f3c0c7ec,2aadcb13,dfab92fd,77da9aca,1602d47a,80022dd4,7199a3cf,89c596e0,d607d05e,de95c8db,ad763ac0,76fa7ee8,ba7ae6e1,4c14308a), +S(a7d7ab3,6722b9d7,940b2a15,c94bb9fb,41a139d4,26215286,bfff84ec,57386dae,25ea853a,c3e772b6,f400d850,a7cf5760,ed568add,a145ea75,6f20b77a,c32d9f28), +S(9787a21d,ea3dab74,366214b4,933a702c,7a07c4ab,696eddb7,3a84cb5f,80f2ba41,8663b959,2214a018,e373e360,a9e035be,f68d9e01,f6fff1ab,f8ad9b8d,3f6f324), +S(1d2ebbd0,65bd4f50,8dd697db,9c8bafff,b548edef,856fa4e,39f893cd,349ff205,85d0716b,109ab208,a96367e3,bd0a2314,ad2c8586,169096ef,9521d780,61df01a4), +S(d0a506ce,14e88414,46c08a61,98ea0aaf,75b9dfc2,c4d2cc58,1238a597,154981b4,dc8c863c,7c4611a1,85744975,34c8c02d,7cb7504b,dffa91f5,96765a25,98d1f506), +S(b6c4d103,a57d0af,27e93627,f55a34b7,75b2ef48,47d7612a,5fac0748,b41afee9,dc9440a1,596cbfd9,ff87fade,8b426091,4799dad1,ce0f7b60,d032e94b,bbaf53f9), +S(5b5d965c,f2f37462,86f088e8,b58887ab,2182f874,484686dd,43a245e3,dcbc55c7,6718ba28,cf43ba30,eeba6e49,a7234ec8,7f01762,e915ff12,41fb461b,6d87a875), +S(bc85aec9,55e6e99a,c5fa7738,c7972354,57b3935b,bb69e8e1,ddc69d01,d34a47f5,59dd49e8,cb3100a0,9c48ceaa,20cbde82,5072e13a,7af0a44e,601044a,361dd971), +S(66b7ffeb,a34d8cbc,e00b4d1b,a0558741,5123d8b2,89ebdba0,47587d66,b260bc99,43bafb96,c88a5917,c6333dd9,b4a546b5,1c37ab48,3f3873a3,6932ab97,efd79712), +S(3cf9208a,b230b73d,68470411,bf3d4899,e0f19675,f829e32f,cd148d,3c07d7c8,21fc39b3,ea5079a2,ae131935,9a3e98df,62b97b37,2a473a63,f3b56e24,25b30e27), +S(66e3fcef,b7b24cf7,af0f8de2,8e53c2df,2bd1dfb2,c0289b10,31239da0,948e129e,df4074b0,488f3f09,a674a40c,b3207f34,a0282661,2e5ac4ae,8d443c9e,d1184045), +S(28df781d,4ec05680,590f4658,713c8a91,fef23763,87ddb6dd,674a35c8,b0e74459,eb66159,95ecf0e8,34f24e87,6f0dd86b,5c86a45a,fe5190f5,721f833e,10a196c0), +S(85d8da47,48ad1a73,dec8409b,e84f1a13,16e65c51,96aad27e,766746f,3d477c2d,a76b74ac,99a3996f,a794ac9a,ce103843,6b4f5fdf,cc3b2a59,df867e8f,382e1ebf)}, +{S(39ca1e6b,9fd848fb,ac24c444,5a9f398b,8639fa6f,c0c2f2b0,8058d84e,6c0caf1a,8797227c,f956ba7e,5228a452,91cdd51f,8958ab7f,43f6c8b5,e06176b0,dc9048e4), +S(4c87e538,c9eac9ba,d5a2a81e,43a6f1e5,f8403c01,68ad5020,4adef77d,5e3aecde,6ee8b74d,dd0b9bb7,c8b7ed7a,728dd99d,a9fab941,f0132d0e,998e65b9,ffbcb9a), +S(1226617,9f5dabe4,6d963b7,e96247e1,e29f2440,f831c8be,578d628a,78561987,2d3552bf,ddb5ec6e,a7758830,9badce7b,41d71926,857962d3,c3bb28cd,5d68ce7f), +S(866c0a90,893b6b3d,807a96fe,3c67b928,67c1d95,e05146fb,40038476,26981201,8d8f3188,da86e510,b7a7642a,97778201,3926dae6,4ce80663,335bc448,d204413d), +S(8eeb2e94,9a66824,26a6f474,9e7578d3,1b356aa8,d1b42049,5fb83e5f,5d08f723,e439d710,c45063c6,d23aad9e,ac0cae8e,36552ab,ca6f2c02,6eeb03ff,6162a052), +S(ffc93fcd,85fd9502,78369b3d,291f1ffd,5da44964,888d5eba,3c3f60c,95082bfa,9aa66635,a4b0defc,b2514e97,515aa0ec,3f65ce8,6f6962f7,72eaca41,d5ea7983), +S(605ccd66,4f18c83d,edf36f62,e5089f14,4ed23f4,f88635fa,ab161567,fd20c8d5,cfccf020,363a805c,1d614aa5,b9a912ec,99cfea61,5c088789,275ef531,dddf2418), +S(d1e4f37e,7d3902aa,dfdd7254,fc727a44,98eb9303,a12fe71b,4d193be4,8dba6913,bdd29d53,4881cbc6,c2e301fb,7d757bc9,9224f12f,4296e834,9badb88f,84fcc289), +S(f30b6d53,f330e6b6,b23d21df,7b4350a0,c42ad202,4a92751a,5dfed94c,47bbe60f,b5ca6c03,b31d06cb,183b0b18,4432a06d,8143d511,8af4bc01,c364f024,b46e0c38), +S(540944cd,42101851,c2cdb0ad,61264e18,cbf948cf,2090df68,54482628,74271ecf,cd16820b,4ccf9131,476b8778,ba3e83,f5970507,7110686c,653be572,2e99db3f), +S(846e5478,5d9cad5b,5109c7e4,6fd62b04,f686c723,1fc3c0af,66bea20a,d9d60dd0,4b1a28c1,78bd097f,aeee951f,fd4f46a9,4658a76c,268ee7b7,9aea4bcd,e75fc8ff), +S(16e732f4,43b4c616,24a495d5,4497a23c,c95612d0,58df9f81,11d1340c,4b2b8b5f,61ee476f,30ac2be7,e3ff09f3,ebf0b3e,2d76177a,30573465,101f4cc4,ec0585be), +S(4f30ef37,2c730ba,a6a40ff1,94b6b58f,436111d6,848b4e60,10be9b9f,abef17b7,b579a133,7f3247f2,8c6afc05,644778f2,3668e73a,a7c6d14b,649bf948,ef126142), +S(595a0d2f,1668c0b4,9ba0994f,3b681c42,6e3a67be,e957bf52,47acd9c4,7cb7d009,fb10684b,3ef1b0ee,37684ba7,53858b3,3586b837,aba6d82a,958eb947,2eca319e), +S(85dfb59e,d7ef6e0e,355e0ce1,304fe5dc,8bc6a3ad,74de3352,2089f224,8894e0c4,7a9b9ad1,10099903,d0d84a33,6838d422,5f98abde,32d82ab1,a383969c,1fb98bb2), +S(c8e13980,cf58416d,8719bc94,96e21774,c29f2e1c,5a36e760,2ce7783e,2c810fd5,5bdcded7,bb484d46,48bc40e3,ee6a3761,cf995e36,2af21f0,10048a91,6fbd4717), +S(80b98fb8,e48f44e,db69fd8b,18eec95,2404fb59,45c8a35c,bf3616e8,c746aecd,d44010a7,20622d14,6af5319e,155fe4ff,591bb829,f5086c7b,1fc1ed6a,32ccbaa5), +S(17629b1,cf015e58,eccdc7a,de049215,fca806e7,805e0e35,951df2ed,5cb87d38,afd56698,44f6aefb,528dcea4,29438e0c,d10c4b21,23f02444,a950834,97a61f17), +S(592677f8,695479dc,b215af2d,bbc90621,e7f3cba8,650563fe,1b2a8765,6c44107b,3741e4e1,b39b0e2a,58373166,854a1d31,ed062a25,c4e3e1fe,bc82e941,eeaaf50d), +S(98d5f85a,a93c9d87,e34e3bb3,597d9380,f0a7e5c5,b03ec219,4025c89e,42126453,dbe42a83,66753aec,61f7f01d,e5dfde1e,b4b989cf,95bd36bc,a66ddc0e,ffeea196), +S(9187b546,70d2b9a6,b711c88d,353bee60,72a1f5d9,ce75288d,4e6c9111,80dd4126,80e73529,d211ea24,d4bccff2,b9de3e31,c6307ee2,3cd9267e,b2d372ef,78f8d2c0), +S(e38c81ad,8ddfd8ca,4e01f380,78eafecb,f8edba6,8e33e565,309a3ad9,f0abe0eb,9f0ace1,f05f0a85,a1488644,88cce81a,2cf55eb3,a91fc10a,e6b82f47,60dbe618), +S(7ee9955f,99e218e7,dadfed94,dad7054e,3e0b97ba,932338db,69ed056b,6f8adf55,5244e198,524a105e,2b5de11,81d7bfe9,ad56aa0,128a3d87,8cbcc5c0,25b41ca), +S(eb9e5ae8,cdf64b28,76349aab,c3f75c9c,9d95a335,3214d0cd,d43123c,265b08d,858611ee,f67a32b9,7b8a9090,6639e998,a05d9bbf,8ccb7c1b,9e5eb711,4216b877), +S(2aa74ebd,7e8b6b2d,952effaf,e5545eb9,e99b9678,a2515698,975247ac,c83ff081,1ec12cbe,6877aafc,f353f641,1a5edf9f,e4bcc09f,31422df,d076932d,8f0defbf), +S(1b7b8fee,a3ed4af1,cf9b07fe,b435ef76,1d081b1d,f1007697,f78fe5d9,89076aec,b4aa0d8a,efbc71d9,d338e998,197054f0,20c5a2df,7a9504b1,ca7cb603,6641f85d), +S(3f293b75,9f152a4c,b92e319d,e5d02b82,f5dcfbc,2ee7a53d,fdf7ef6c,e2595c32,b67babb8,d1d1963,fd742c22,5ad5bbe4,27e57d6e,b9e17bbb,f91d2c1e,a455c1d0), +S(3eb9968a,c9b01fd0,882ec65a,8f9f5a5a,b0fbec2d,e2dcbf88,cc9a70b7,887ca59a,1a4de130,4a46fcc7,6719c254,dad5e88e,9d6a0839,9a9a28ac,7f171aa5,9624ee2d), +S(a559381a,f41b944f,e2bab9d9,62ec7c53,efb25ce4,1ff1a456,54a99f46,d97ce20c,ebc6f66f,75ad7322,4c1319c6,4268c997,4142,11ca65b4,58c5f79a,be0ba0cd), +S(a8bc942f,c60ff2e1,140f9a97,3d7e0b8b,77698254,57098005,f9186e97,9e430593,2a82070f,25480267,c4fca773,3173b354,fcd5cc1b,ae497af8,58b7d451,8f048c73), +S(2f456ca2,c4f8806b,ce4caf12,32446b07,3405dcab,7b3cdcc0,247dd079,adc7a626,7308e58,5b9bafab,b2dee049,9bbf60ac,fdb37242,3e915156,15314ffe,5ad866fd), +S(b56f4e9f,9e4fd1fc,7d8edde0,98f935f8,4c750d70,5f0c132b,d8c465b6,6a540f17,cd171acb,d63357a9,2c23ee52,fa7d2e2,de2bd69c,343357ab,b95d0350,fdffec02)}, +{S(ec474055,43c52e68,5c9e6c75,97616fbe,edb70df4,fe3c375d,d7d24729,2b120851,22c1c1a7,30066375,5ef8c2fc,86452667,90347223,f11a32d7,9f1c0169,a467530c), +S(3f50e502,c45fd922,94fcc46c,b3118a86,43af00d1,634bd694,dfc0eeb8,be2dd4d5,7cb992e0,f29fbc5f,2887161e,6d1e266d,f11fb723,3b6c020f,26eee393,fe96b526), +S(443007f2,43c3f6f9,76914031,c41e0d49,61337340,9bd4a681,f20e4c79,934fc2de,df67adec,c9ce5f6a,e6c8312,699e0353,68ee87e3,1e96790f,f0bd3408,94af74e2), +S(1e15b9e9,c28f77df,75837a0,cc9504ab,a3a49aef,26a88d99,543fa7d2,a875620b,2a081093,6afbc025,3808ba31,f5597287,e32898ac,77fd0021,9e6fc298,26b0370c), +S(cfff0258,ff6c0d97,99823447,775b75b9,1881e06e,bbd72ba4,28f8248c,5cf2144e,61e63569,5c4a8fb4,f68f974,219bbf4e,e0c277dd,4b74b843,88f99041,f97809e8), +S(2824f4b,f72f9229,2aa04058,7a0c5395,4c87e7dd,bc5dd199,af6918e,6db62f1e,16ab1473,3bf8382c,521af6fd,27f8b2b3,b421dbdd,bcf06c62,3bcd86b6,4bf33274), +S(5dc7571e,27d6b955,6c789b4a,80d49fd3,17416fa4,e04a7eb2,3cdbb88c,9c253a44,b7261e2e,39327d68,a5456abc,9d4600c7,fb6d6e51,a732c7f6,c64cbd0d,56de4a17), +S(e93f3aaa,5d9edc53,6029d332,9ac0bffe,af27d4dd,40f550e5,3df879a2,a5c1d993,25b442d7,f2e2e03e,c7f1588,16a1af43,b5d2870f,e0cdf429,babb19e8,951c0982), +S(8f91f5a5,7aa40d62,ba407d8,6ea5678b,65c84ea8,f241e2aa,dd6df242,52635a86,e9333d7b,d6c319be,3ff4f5b6,f286a8eb,27d5a1bd,29646cdf,77441c40,f716a6f0), +S(77d398e0,228add30,e9e120ea,b16436be,30c254ae,65016672,8bea1198,de1fb17f,749a20c8,ad6f4312,fb6e6fa,c390a4a8,209704be,3355362f,31db9b45,f3876963), +S(96976a85,b6dfc4b6,13dde357,c21c3518,a5f55c7b,a2d22976,592d7632,3b5a8546,96dc660f,8ef3b0b6,adbe77b5,69024fb5,dd713566,617cfc51,c8013f2,5b424e9a), +S(49093c4d,26194278,623c2ff9,6c8e2f11,f9edf3b,13c33099,57b57f1,9db451c6,5d53ff56,50b82edc,9dee9f43,ed6db93b,f6a26233,2dbcd699,130aa9ce,5130384f), +S(49187f03,d5f5f628,b9210b88,8ac4f1b5,2f754015,541e9f38,162e969d,6a99f4f8,276aacaf,d38d0bbb,416bcd0b,8ea590d9,7735a3f2,8de72aaa,76bed0d,6644bd80), +S(7d64e446,65c03917,87fe0b14,16ab1048,3a6025af,b20e8c19,3bbba444,2864c587,2c0da181,6507f8b6,4c9e5684,a4d53d98,d6b88215,772def9f,fa5a7a1b,f2b2ccee), +S(2223484b,9ee12b26,2a21a18d,2682ab01,c291ee1c,fe3b4b9e,2e93fb67,aa08535d,4cd26418,bf0d62fd,b266a768,5f7aaffe,d7bc95e1,be41c6bc,7a0c9076,1ace3974), +S(aac92330,7d6a55d8,552ce6f3,9c531d5e,afdd5313,f801242c,21df07b3,a656c618,93d9be6c,590901a9,1413cc23,94cb426e,e6a61593,93511c,e67e1ffe,68b8f3c4), +S(6ec1a0c7,fe40c40a,f3515ff6,60f0b53b,8fb6be3d,d912f8b2,c7a473d2,3e49d201,b10f000c,191e9423,60fe6b5b,2b6b7b85,73c0c2ee,384dedd6,e3dc04a9,7834f93b), +S(bd982a5d,a4d0291c,38568fae,ebc76df3,f2b0e5b9,1cd0d3b6,d2f32077,6c35c43,48566068,d5142f6a,90b13105,e7841d32,38d869d4,fcc7319,3e3cc9ea,76739c5b), +S(25d54513,b9084ddc,a3f20e18,94382290,115ad5f2,dc72c267,ba845b3c,6ade39f9,e908508,7fc5efab,a6f62c41,ea8fe856,226c8e2f,95dc31fd,2b49a7c3,6aa53b39), +S(29ab6cd5,add595d0,cb64ead9,c3d275a6,ce383f15,9340faf5,118ec2d2,9bb9a62d,54584613,dc27c249,d5d1210e,9e121aa4,7d606fad,1c4621e1,67f67b90,d8f3434c), +S(4cfd960,86f86d5,bd805667,55979c32,d5419dbc,946d63a3,40dcc6f,6d6dcd48,f032b7b5,9d85d0a9,fdc290bd,a1fc703,55b5404c,f70d45c,d15fa9e1,33ee9319), +S(9c786066,b6642e11,139aa303,800314b0,6afd4d97,e8314a1,de9d7002,5b7bbbf4,463a2ded,e2185c8d,944f29f0,140f6b66,9ad6e3aa,8ab6e292,a2af551e,685e58ca), +S(4e98485,f15c506d,6cd29d7c,3f9a59ea,4bfab065,78d86b63,f25e74e3,e7aea96,2baf3fb1,c26f2b0b,1a0725b1,5d1ceeaa,7ccece9,a1dd8f2,7f80d825,d8cf1d71), +S(8412c389,bc88e9bc,b157d835,85af0dfd,48689532,e38044b9,117b8acd,ce3b62cb,17eaa404,ffc1f62a,38f7ce99,6216b1f,40bb62e9,6d1f7a5,8bca370,c0d30b44), +S(31b9b8dd,7d37b38e,892e94c7,a5e817c8,ffaa1c1c,f56979ff,7f25815b,758b6d09,cdb680a,ae795ef1,f94e7e87,50ad9077,7a55eec6,c6f0795a,ef951e3c,ab45d186), +S(2be45d05,e89c58b1,8212890b,b6eaf935,6f03e37a,fd957291,4ab71a97,7af8350d,c3b05f04,c9f7a1db,b6689fe0,6ecf7a80,3ecaa147,8d09a1ec,9a7d71dd,a75406da), +S(5185cfa5,fe6302c,b5573594,61f375dd,c483a66b,c615b5f9,30abbd4a,5c7ae0c,83cc447e,53c91e07,6f44d265,389bef06,549b8d78,9776000b,5c35ce36,5fcff98d), +S(cd42328d,e4a16323,c51ef888,b7e67ba,f9ee1c53,82161b90,65e1db15,bddcffd9,caed06b1,7e86b470,b665de93,74725fdc,94792c57,5509ebfd,f012133e,122302f3), +S(7a1ffea,8fe5114b,8a638306,3b7811c3,25a40c19,42451557,679e75e2,b304ab91,1ef3fbde,4f0283ab,96efbc83,bcbb5a6a,d781a215,e6ff6262,ca50b9c3,986816db), +S(cf0bdf47,a3f15b24,5c7136c2,3a3e38f2,661fa8a9,4df29fbd,8b41ef22,c291dc6e,c73d1fe3,919e0aee,5b3adc4b,1a86e709,4b039302,d44a0d56,638c3eba,24857a99), +S(3a571630,935c1f02,d6fd8744,2c082060,cd5e792a,1c6f92bd,c4eed01,686df50d,7a1ec78c,4a660cd0,ae90c00d,1a8f5f22,1f5507e1,4487e5ee,2dea74d6,17a69494), +S(1c5e5481,32b49a7f,66ae9fed,8323480e,d1ab974,622e7cf0,8993895e,ec87fac,b00309f0,7c80b970,d446a605,e2b3d52c,5c215314,d901cdb3,aaa284c1,a03d2740)}, +{S(2b081f0,268d6ff4,1090561d,79144bb9,554b1f3f,1f0f2cfb,c9344e2,b692157a,597920fb,c528543c,26499af1,8b5e7d7b,5ebf5ada,5df4a46c,edef52f2,1e2fda5e), +S(2ce45dc7,d84d3143,884d6696,73738e55,e30f6045,8bac95cc,c30e86f8,71779827,deb79108,80a1b675,a628fb09,725c9307,d1629b07,8027f566,29f8560c,2ea80458), +S(9dfa0cb6,2a63244a,35ce3a0c,f102e7c7,93a4530e,21c6c03f,15a4fb91,e116c480,b01c1aff,902f0831,bc8cd268,663f0ce3,6d8e22be,86026460,a8950636,ce44626b), +S(61a32d1d,cbd7e887,def51ffc,9c1dfd55,d06d72f6,a73ee2df,f83cfa0f,52d47bb4,69a3b17c,fa91e3d6,faf28d83,2695aa66,c87b14ee,7b2d987c,80242fc,ce2cc42e), +S(8cbbac63,5414c0ac,b6d7f659,5c6eca39,886c3ceb,82549f72,d07a4019,e3076eb8,c838dc49,fd5af1b5,e503a430,71901bcc,90e1ea38,9f735e31,236491ec,43e7b621), +S(d3f77c5f,663c6efa,670b46bf,dfa96af4,fc4720d8,e1df6e8c,1ffc5696,f37cb55,aeea0c3e,50eee6a9,16462a13,90ce5d47,c060efff,1fd3108,1db77513,34300332), +S(6f774118,4a0210a0,79695d20,f93f861b,658137c,3a072076,7d80e5fb,8b1ebdff,c12aecc9,b55bff04,bd6b6e73,870deadc,666973b8,ec498bfd,bcc4c33d,23f5d674), +S(fecfabd4,897a948e,5fab7200,969f9955,9eb1c9dd,2a31325f,34dc4f80,13da72c9,ba70c9bc,c8048aee,6fdaf5f1,8ef638ba,ce739c0c,76ec4c13,fd4dd6c1,1663d02d), +S(d1a1a1d4,24fb5ab1,3e985c86,9bd7c02f,f81b4633,dcd22e96,c3f33489,2e80d543,cd5b79ae,af62769f,dce99530,8b921b5e,39a60fd6,f989dd7e,1d0d7219,e9ee8865), +S(7099682a,c3c083a8,80467746,fb924d4a,56f23d16,a3b57f10,1a824b9e,653d45,6a9c296b,cdd72c93,df840003,24ce78b9,1f9df6b2,bfa33922,ef32733,fe49cb31), +S(1035866a,4e9ff0fe,6b0066c6,3f0a2392,c0b8cd61,36e13ada,21f6dae9,f22c39eb,6390f9ae,ec1989de,2146cd00,a5eee99e,76ea4536,423e9bf2,c778ff29,85538fa8), +S(e18351cf,163e4df7,d31851c0,409b5705,a5ffd472,dbda5dd3,bf05e66b,fae50fec,264c1d26,41f185e2,72b908d4,77222484,c651e8e1,9a9e1fb0,1ec5ed4a,8a4b6c08), +S(dfbee778,ae4bc89,24f32c18,bc0a740f,d01922b1,28e1a595,283bfb4a,fd8f2f76,d11f9b3c,25ae3619,99ec2c9c,2f1a5903,d80eae59,e096c5d,c5e37201,81756acb), +S(842cdb54,414fa977,58ae3fb1,9316ef32,af9c4f0d,649f0abd,cb94267a,124b59fe,a016f899,288f4caf,dcc6edcc,3cbcb561,fdb4047a,f789e1a8,51ad21b3,be62f5c8), +S(3deb5d22,a81540ef,cff29ac5,585a056a,204e4d67,2fb858f3,5c23e939,790c744f,20d73911,5b24b1a0,a4b31302,73321dc5,d8b74398,d6516439,4e1423f8,b4022d6f), +S(3108e61a,1e0f079,f76e3ab0,d69cf068,779674e6,49768aab,718a09b0,640251bc,245a9f2d,141f390c,f1a17bcc,a06c5a66,5cf3a87c,1096f5e9,b04c4fd6,737d9a56), +S(63b9eaa,ce6b32cb,e4cf4a69,6599f8fb,3797bff5,9103ba0,c1351e78,b16cb0fa,938ac414,ef911df6,bda32b5f,1f69cd7a,87a25d82,177763de,568ca95,e846fa5a), +S(f37a5a41,cc96a04c,c882c27e,e362d054,7d6267f1,c91c5403,2daa5c12,1700abda,108bd6ad,27aa72de,48406693,758a74df,53a3ff98,d490e303,54c45ffa,c64638bc), +S(52afb7fd,6a16dc6b,98f9d7d9,555068d2,c2317035,b7492e8a,fbf28aea,3b1fcaf3,548d8ca1,2cf7a11a,b0100455,c7240290,6cb2e92b,101d1e2e,32ab263a,3f3de413), +S(f644fce7,874e9154,8f3fb284,b7d1ba17,fad6eb6e,c581f57d,5aa11804,86de9889,b2acbd8f,5bed4270,ec131ea,1891c99d,ddb46648,60acaf39,d68d2a54,a58b92bc), +S(863cdfdc,66065a4,50c2b7c3,1d694c58,e63ccc09,fccfacdb,4fdf0b1a,b150e937,14d168dc,c84d859b,55a3d5af,9d17ce4e,83bd90ed,55e099f2,50932dad,b5d2693a), +S(9f5569e0,50a26288,5d91f82e,9cacdf9e,f4487676,730f4da1,46ce8769,3d8807ba,cba008af,547e01f,6a9c6c45,8f9d71e1,8ad062c4,4b305b52,3f3a6655,3979a2b9), +S(a0f14b6b,99f0bd74,cf9864bb,17b1c43d,51ade513,6cd72a15,89312dee,706d50c1,e2bd2d82,c549b4da,cebfb888,c1a7c5d2,f0757fe8,53e07fb4,747eb7a1,542137cc), +S(9e7bd727,fbab45a9,db36d17d,5e5437eb,f028a10b,392ea470,d5cff0d3,2e9bb0fc,fb52eb32,e43133db,28125280,e3cc55a6,76877c58,b4051f70,9c031f84,24f12d9f), +S(7d8b1a30,4c0c8931,2d5d712d,ab396efc,7a117483,7f62bb38,62a81a3,660b1068,472a2dbf,ee99c398,94d14c1e,ce87cf17,c8aee10a,4720357c,c5ce79a6,19aafe2b), +S(d5eb073c,a5afa126,70602de8,417fe50d,bd8f0768,d615ef2f,565e421b,4e7842f9,52571e4c,e4f0c424,fd288f3e,8b6c54b7,7481c3a,43230fc7,4c6f48b,d4041089), +S(3c41cd8a,77728b07,ea592254,5ac45462,2c7927fb,6a7aeefd,61635cc4,217acc90,eab0f00e,84099fcc,c2f4d339,77ff7d68,4c035b3f,34c6c4e6,aa812c9f,43af366c), +S(1eeeca5e,cadfae31,188218ae,7beda45,57f85c25,5c99dd64,1d00d8ce,2e6f7809,d7e5c2ff,4ddf421f,cf09b655,113b8cf1,a4c25e90,d02b871,91dbac55,d6606ef1), +S(54c13737,454414e1,76bfaf1e,b4402bf8,678daab1,555412d0,c6d3fd44,653510ae,753f6a,f382d0be,f1dab47c,1b9368f9,57d586c4,acef0d19,dc241ce,f008ea3a), +S(4d608c37,1fd6f635,9ffc57c1,9f1aa5b3,5b0f5702,55851cec,34278d2f,465fc8f4,12d1592d,c2cbccc3,7e5c9fae,4b864e9a,ca6967e,9d4852e,9adc9e31,1000670f), +S(71157d64,8c0a1a33,19b713af,f806cf9b,c91a446e,2ba48ca2,fdd1ed4e,8c43da59,c2ac2aeb,a298fcfa,c0d5eefc,6eae54ec,330f5c0,5b34952a,9821ded3,9b72d383), +S(327f876c,93652555,fa80a054,968b4712,930dc930,12ee6b8d,c10263ed,3b89a762,4d2bfb15,4cadbfd9,4f6696da,a1e66846,8aacaf8f,1428201,636026a5,46dfc92e)}, +{S(4d3b98d0,b5926a8b,3e5622d6,10b30e88,caa6e7ba,eb10bc3c,38aec3c9,c1267578,e84056d8,4726291d,e6880a2f,2d3b0b01,371dfa27,5b8c9cff,4805d18e,a5bdc788), +S(6e463689,111d1a5d,d10b09e1,5d0f438b,1cebdb67,7a6cd230,bf6349c3,70667db9,de10eb3f,5d2f4320,7265952f,b33fc23f,154972fd,d3394cc0,21b66276,1b51db3), +S(48235e7b,76c94c32,b0d21bf1,7fc215ed,df036366,a9ef494,19723485,78db8943,4f5ac8ce,36c77403,b2fa83ba,1fd0e88a,3da4c8cd,3c10ddb,aafe2d0,5da40a2d), +S(668af7c1,4063dfba,1a4187f3,f69cb457,cae4edbf,a3bf9669,4080b6de,bc3e2f0e,ec95f37c,7bac26a0,df23275a,283828a8,5a102d8,f33eef1e,87cb56c1,850740cf), +S(d4426fcd,cbdfd904,725fb501,656b9f2e,2a9f9ee3,c6522064,f078165f,61c31d97,e73f2a38,c56838a7,174ee704,948d28fa,5b5fdc34,7774df9f,72f27834,a85eb4d), +S(d0f49ec3,42076b68,4cd91172,f15584fc,ea38aaf0,a3201063,f854ff1d,f68d4600,28d95ef2,82dd7d6d,72be7854,e8858b1d,a142002b,ad7b7b4d,bd1e582e,94341e16), +S(8a36f3c3,50bc0f1a,1b1687ed,4ff83a68,1578d74c,c28fa875,f6969e52,4887bbb1,15ab9e05,c3ff823d,ba090e21,1033c34c,fa713d39,feec4346,88e3ecba,4b431e10), +S(4d1ef23b,b316e821,7d2cc409,a1baa273,cc06f79,8fdd4d16,5d5b6805,3718e238,fc37e62b,db18154a,2add98b0,ec221e8b,bd1a2096,ac2dd1fb,cf8e2e64,821301fe), +S(eec1f8e5,76e87803,bac48bb4,65ed923a,a68b2965,64365d45,bd1c24c4,cf7041b0,2c6985e4,7cccbc38,3b85be66,ab34a166,c98a8000,aad08f73,616e4d2,2a15a009), +S(9fbc20e4,de372a38,90443786,bd7cfc40,c6195b29,4cf51874,6ccd9ecb,cee223e9,f734bfc8,a6973209,903edaf8,52f63bca,b23fc1a4,879906b9,1c5df169,9d24683a), +S(7984c8ec,a2b02dd4,e8b9c69c,6f803418,48f108fc,b63d7038,de58e567,e64a894,49adeb11,13c705a0,9eb01e50,dea5be48,86e5d424,689282ba,6d64f745,74f45e8c), +S(29a7400b,16f5712a,2324becc,29fc4b98,57fbb926,f8741dcb,324c26d9,6cd178a3,90770be5,5c0a94a8,16bcfa38,aeab11aa,5ec3b7d9,eb4e7d29,1bee1c02,69e87267), +S(8299d2fc,84770bff,a4e630b9,8f2e6744,99b1c7f5,719e907a,d70515f5,140a00c0,c790968f,a3c3d4ee,3e25a1ee,8e1d4923,3c22f034,ba7c172,b5d7d91c,99eabfa8), +S(5cfbd498,5b608db3,5d1a2872,b9cd03fd,d775e498,4629f41,61a2bde4,fb2582f1,8288fa89,81056333,acd1720b,bde757b4,e83d0a49,9c5f2220,521a0bc8,dbe827f8), +S(281f1fb8,e144e39d,9ec2104a,96bf0f1d,494eaff3,57fe084,63825228,ecd286e1,ae40e075,d19ee5f1,1dd7e22b,f1c277ed,9a02abe9,975609c,a7c811f9,7c54e493), +S(51698bc6,73d3289d,6b4882b0,cab14e67,97d31221,e5bc6e53,af061aa1,9f546daf,7b850099,fe977f6c,f50abe00,bb3a0b68,90f47c45,24e9ae02,94304b6b,20bd986c), +S(db701e92,9b696c86,d7fb459c,97af90df,ef847bf5,1d235337,2a2a4792,5fa8ae53,edc7e98f,1a108bc4,8fdbe65c,2904058f,7da5e188,e71d194c,4e9dbfe6,8a55d18), +S(c900f57f,e9a31d4c,9715a822,5a906e90,22d81c12,714006d5,81be0c7b,aeb5a490,8493eb00,90517d9c,b70a4bc,39043ffb,e0863475,17cde2,a9bd0d95,f616bb66), +S(d74e842a,fe2da0df,df6342bb,582fc223,717e0641,f1ce0e14,584c5c63,f379ad72,cefdbd7b,b4ecbdaf,409a0fa3,9a0a305,b1bd986,4913f977,bec6c47d,5d525c10), +S(b00a5f4,f033d126,64366147,a1bbb9b6,ea60a38b,863c5f3a,e323e8e5,1aee200c,11e9f1f7,b7701a4c,26a881ce,30fac1e0,92e157d7,b9c2e4ce,cffeb38a,172ead87), +S(5772b134,68bf9f09,d26074c5,16dd7472,d3a83624,92306cc5,c7544ec0,d73de280,2e2a7931,aefe2a31,6dbad1c,e7f9d42b,7f38197f,43024f16,9e27fbc,7af31d0b), +S(8bf8af02,ccdafb15,598f6725,5f172fb4,ba8960e0,6c81ffa5,b4c1c313,6f95f29b,96041af,1efd128,ef133e5e,b0aa3d9a,6ac3a651,92598b09,ed649847,385a9b2c), +S(292889a2,d8329139,3410385f,cf5bf489,7e1ee23c,e0e3b5ed,82ceb340,d89f87a5,41099fb2,bcec7e07,d4d4ad14,3cf605d1,b0a32487,1736063b,e49b06f6,d648aa69), +S(ad227b2b,737dfd02,665c15d5,9b28c7e8,76413dfa,25c9068b,90efa79,ce83142b,82f1eef1,7e2f6b86,87137302,741f8486,26fad679,9c6a22fb,3a49e341,c7e51e9a), +S(b4245dc5,5df02839,4cff2610,4a4255ef,89f3e708,21541c3a,4631ee4c,145bf85,5a40f72b,7a67540b,6858e5e,b15005c1,3fee862f,3cc54a52,7643204f,d0b8be2f), +S(15aaef61,568537a4,695c1990,c05ecb9,2c605232,f705c3e3,729720de,7e9c2400,e6efd1fb,b74e9e43,ec1244e0,bb4cff2,2a5ede8c,848a4f5f,5eec6f8c,77b6f5af), +S(ade2e63d,4a828328,b4c53763,30790331,734d7f90,37c1a584,59570c8,f31e72d1,c42898ab,3633dc7b,f3a454f9,d5475c4e,fcf1f786,d1f609fa,23616f26,b23a1a97), +S(d8a9043d,297681ea,c5ed63a5,de306500,6b66e4fb,167aa5ec,c76a8e2e,df426e7a,cd3de058,a0a93d7d,7122d777,1446b2b4,d4cf53a7,1759fea3,78adcf03,5093f4f6), +S(30651cb,592d282b,5348f192,5be3f04d,da5033bc,39e2fc7b,1e61500d,9769b57c,dadf77cc,44853f67,53b1dbdc,17a97d3c,e6d5b2e7,8c6087fa,800c5af9,ccdc54c), +S(aa21c60d,6f7d6253,9d42bafe,95c58f30,33c0396c,fa0ceef9,6d2f91ed,d6569044,4d519779,3b19515,92e2d952,2be520b1,11a5453e,ec6d7ccb,3e6db3bd,3d0c84c9), +S(5335cea5,e99eeb23,765b3444,d9bc7be6,1da67d6,91bcc42f,d43ae543,e9c22bc,c4072fdf,8963addb,5f980f7f,f314795,373cf3dc,935e0e64,c3d3d98c,342530cf), +S(708a530e,9e52c73b,ee87c9d8,8161c810,5d5762,2c29ae69,1cf999a8,3a1187a5,6477b7ee,1e065768,569a923,4492c7d7,c13258c3,92cac175,a75b0e63,b8c2426f)}, +{S(3fbd5a4d,ebbeff54,8c2271e5,33dbaed3,fb8ccc23,e3fa2579,4c8f7fd4,47ae186e,fdee4625,45bf75f5,5c29a724,6496d970,4616c54,ba01d0ba,feb9155b,cafdb555), +S(c1483ec1,78ba8414,c371b57c,49c687fa,69669e2,e3e1067,cc6d2a93,b1a9d24e,edf94395,962adfed,c2ebb3bb,29346136,e4dc870c,5c76299e,3b07da35,6bb26bed), +S(26df4b09,693a3905,2cb7a1be,5bc2cc97,222b70e3,3d297a54,43741228,beb77017,a3d6b908,cc6d5f80,aecda93,99e17a8,ce33c423,f00cfc4,dea8354,af502760), +S(b6c265d5,90475506,e15b2388,b894718b,be67aee5,ba40ceca,51876946,e336d903,b451d3f1,2c666c85,bf9486cb,296c39f9,49f9f98e,96d50a19,80f86f85,a1efb999), +S(da6cf69c,feec7b1f,c848639a,7e27932a,f49cd695,a2e56a50,693fa862,6e257c66,4506f44e,e6e0d822,7e67dc4a,9f8e2ec2,d3ec0c3a,c2a70c7d,d25fa9c,34cbe3ae), +S(d57648db,adf18b77,db185ffe,3f86f859,6adeec05,ffb86215,4b894a0,75776eac,a3f2fec7,7186d81e,4228cb1f,691e00e4,82a125a5,bbe9e6ec,45a53604,4932491e), +S(4de6cc4,d64d52c8,49c0e8d2,45409ba0,88248399,1916df3c,238be4de,ee2504d2,b389e7f1,ca72e9e,1cec2ed7,70f21441,590f0bab,1b963f1c,411f9bff,d3df03f0), +S(15f1bb11,78b01439,f26412,1d36a44d,b8333fbc,eabeb471,da2e6c1,1b8b3ee3,bf137117,35e10854,95acf3ad,97fe510b,33d6628f,e67d0067,499169e6,6c12274c), +S(badc76d5,481e77,9df71d6e,223c6965,9e9ecba5,8415a95b,eb7118cc,b1f931a4,475e47ee,115d258,3f0607f1,7542ccde,626e6d57,6ea884f9,61b41354,aef37247), +S(13015ae5,d770f4a9,75825bae,a6cbbece,78536dcb,78d7116e,d304aaca,199add2b,f5e28585,7a99ff0d,a4fd15e,8ac650a,98421629,aa102bca,25df3930,7e5cfcbb), +S(7734d2ac,707b9b53,afbd2a64,50c9b609,1905c391,958d7215,f92353ee,fd3c7be5,751d38f,ef48bfea,8fa5de06,8188a658,ae6c9c75,a359a4ea,efaac5e0,b5e859aa), +S(91814384,7fe2ed34,e9cc9c61,3fc2c67f,2b76a208,561d0e06,271b812f,6c678856,9a97f6e0,9888e076,93c9ebec,b8773485,c3c5d208,c793a77c,6984fb09,cdfd67b2), +S(98c516fa,2a2c8073,70ca9d7c,b4187108,ea345652,c8f814b8,b4a9405f,b48c2469,7b3446f3,2e8c4764,a8eb0846,4be3bc6d,f42b8d14,b7da65a2,ac96a018,d0831c7a), +S(5691d1e3,713302c7,48bf633,189ce032,10832e4a,9af1dbc2,abc3e99b,cb4faa01,d802e21a,fab84c54,5d665ed3,54130d9d,f7f18283,30b3a1fe,e30c2298,8b71654b), +S(1f8cb624,6440b640,aadba62d,c02f4ce7,a0ba9be7,d535987,64072fed,95c0d1a1,647a9dea,abf8247e,f46b60c6,53cdcd5e,cff0d1c6,88b7519b,a778f9ff,c894e1f6), +S(1489af53,94878f07,5cfb2e20,931fa3a4,e585d494,78818e4,f47f05e1,2be54d14,cd5bd721,4e535822,43270bc2,dc692ba4,c57e494c,eba92d4c,dd2e13c8,e24d8550), +S(66159248,2b2229d,ea70ff76,d2a5e70f,ad1905c0,9211e3d6,2d1d652f,ccd709a7,8f5ab85,57948aec,67e7b538,fa9c704b,ae939c22,4041e6e1,65f6045b,a6fd0fdf), +S(bc894efc,d0fb7497,ba70d654,961aa79b,6ac5a795,95537c80,82c525c,2c44c3a1,d5254292,ef0fb6fc,db587393,3b17adfd,87d13320,858ff783,75e356fb,b0d3415e), +S(f117d7f6,85457601,9b559bf5,f5bc150c,13363e7b,72123435,b441d98b,d169dd27,a8f4a23e,dd0d8f2f,8950c124,1abac43e,e629b0e1,8505c3bf,780ea378,20c8623f), +S(2a8d99c2,65a66a51,56b60556,775c61bc,b2a81a62,34896a31,16238c2a,b7716ec3,5e842306,efe11f66,5a049c0b,fe3ac74d,d72c5033,6dbd04bf,2a77b0d2,4d7ea651), +S(ea747597,1a6b6d94,2e368bcd,9979876e,afa4622d,313d819d,5e8291c8,2da95830,41d4a478,e0950bb9,e6595bef,3c197e5,d0f77ae,6340ca8f,2947fec4,70465193), +S(114150c3,fe8853ed,9f3e26f7,bc9f3d6f,aa50ba0e,6ae2d8ff,97924b04,dd9678b4,5530c22f,4ac30716,2b272015,460426ba,9602256c,ab735174,1a2fbbfd,cd71d134), +S(65d96017,c91a746a,656eb595,d39dc9bb,3476dc0b,1a1036f2,df7a4ea8,1846631,de46bfad,6999b108,1f358edd,7809919e,4de768f1,fb21dc09,4b248bbd,56b3dc76), +S(f2aec214,61c040c0,ebd18204,bc277312,732b452,266bfd55,aa071853,e458bea7,52a1b71a,eefe2c48,5ae2918,e236f1d2,1622d37,13b4bc04,36124567,d48cc453), +S(370ef89d,c39e637e,8bf6be31,63a4f76,7cebb202,c868647e,db18f991,977681de,e6d402ba,9769363a,b963729,822bd6aa,9794592f,36e54461,579ae53d,4c8bc4cd), +S(8db6356c,4f31f46f,961e4342,a1ff50a1,8240629c,a0decc36,e1bb24af,f6742e57,8ee033bb,96958466,15626ad6,736e9025,fb76320b,c2d0ceb8,ce3400cd,743f934f), +S(14a1a08,502510e7,1060f291,1316ee01,b1fc2bd3,c88eaa1b,656cba0e,8e3515e4,5a4dc536,b62c349b,c9bfc6d7,fb677231,1368655e,fcb9c89e,572aa58d,a57f08c6), +S(d530fc7c,4d5b4fd1,5f44ba0,c0f08f24,889b278a,93ee30ab,935fc112,5e244a58,39c0ea88,5984c2d1,d5119a28,7cd842ca,d3cb54c8,ab6aa222,c01e7152,98aad10f), +S(50f3c13c,a474f604,ca992658,bca68207,76acff7d,d507d63a,b5e18b28,5c5be81,685e151c,7d8fddee,6c9d8513,dbf167e2,c32dd70f,b6932397,38eb63fb,3e4f7afe), +S(c0a72dda,13174682,726ede1f,7ecbaa68,b4b137f6,d44298d3,4e17b7fc,10e19d4a,1e45ff3e,4a4239ba,4a897489,a265a60d,9a91f3f2,83fe2e75,9e770156,c9ebb3ca), +S(7121e14e,7e2a2c57,76b5702e,c83a845c,28785c79,9099a007,54b50fca,b4d9279c,e6b3ff5,ce62fa35,adf45e69,2ccafb91,b805d7cc,b6eff2e1,38dfd680,d0684401), +S(c0c01f34,ae41b8cf,e466b4c9,c6a5d5f6,14f570d6,fcbef768,a81a6c8f,5ff4adb,f47b0a41,1bca80a3,836c85f4,bf8a4731,3243bc2e,8f2ea47a,3b1008b,53caebca)}, +{S(4f20ce51,84fb2949,443286cd,8ea201eb,15248749,6e15aab6,f3ea2597,d4cbf47c,bf37770,62691c5a,d6c6cb8d,c30fd3b1,73578a3,bcac43c2,c8404b6e,c085c97c), +S(17ceec36,7fad4365,520599d7,62c66c12,5abeff81,ce7242dc,bde4e799,402759c0,91e024e1,e2147fe9,73091001,984dd3c0,9f887257,73bbbedf,47f00c7b,c5c9f626), +S(dcffc4a,5557f2a6,ac7a3527,5a8228ec,325ea0bd,d9bf52c3,8a78217,6bd716,87658163,dcfc39e2,ad08a499,898a1505,988d9b86,72b6d1e9,64e6845b,cb41129e), +S(625fff43,45337aa2,1efa0884,73a6662e,d5340470,a79576a4,362e30dc,bcf762d4,92ad0a66,d0bea2a6,d7eedfe0,e33295b9,3a656e45,9220026a,5ff3be8f,83184187), +S(410b96fe,7db23faa,7d123e97,c1a82a9,7b24a26a,80143e50,dcc6d9a9,1a6e81d2,ca0da356,dce88799,5f8cc790,64d197aa,6532dcf1,20fe93c3,7e2ff4e2,f14394a7), +S(8136e51d,ca68170b,136d40fe,76980b4d,d4f435fd,e38f3017,99de734c,b2491551,823dd1ed,de1d326,676649a3,9d5ba083,7c48e180,ecd0a648,eaffe7c8,2894e819), +S(64a67d9a,a7a31390,3ed9e348,e7300917,6c1d52d0,be63f54b,aa3ee8f3,f1227a52,ef770581,df4aa013,6d191e99,cde7f42,a14fdfbb,11e1b709,bb540100,1dcda1ed), +S(5fcf0465,a905aa8a,a1da5073,d524e8a3,30af663e,f4307359,c03a4c6c,c423dd9a,58641e67,fa821fc1,2307a66e,fe0129e6,4ace7c36,c3f5395c,db87667e,5e742a42), +S(aae6747f,ac3d8c9a,148009ea,c2d25574,39a8b546,455fb3a4,5016891a,f9372dbc,66084f19,b1d97f2c,22e182c,d5450d43,d56636e4,92651cf6,22772a7c,5b46d9), +S(377dc2c8,13e36bb4,642d1e02,cafce754,2ac6d9fd,c2212edb,5432674f,38e242c7,8395dc2a,39d3b1cd,ae9d7d37,d0c4597a,11f931d8,75c8bcf5,8eab03d3,674d5841), +S(35c598c0,7ac5dc3,7afe6895,29d815e9,406e2608,292ffa0e,7b24df65,3278d8ce,e793aaf1,45f538f6,c133309e,53cb5343,dc1dcc74,985c57f,27361c6,aae23e7b), +S(e9666336,6bb286d6,c86f425a,2d5658cc,1d733223,9ec2e9de,c8ab7295,4b329845,908dc533,b6098e9e,9b737e4,b96e7345,e635f591,60bb3df2,75e165bd,d1cc5998), +S(46fab0d4,7fc6586a,31cf861d,ff5e0bb8,cc12b60a,53103007,c8974ab8,204af703,845ab7de,7654fb36,618dbfb1,287534a9,2d43db6f,2a2cdfe4,5365b4b1,893fbe9d), +S(4d80486f,fe748d1e,f88aabff,76bb82c6,a45db736,76ee0ff7,d77cdffa,2c69d07c,2a52044b,d4fc6a59,fd16dabb,df35bb6,8057ad4c,292e87b5,528a3847,c8784638), +S(2c1d108b,f4945c0e,df62cc15,6bf0830f,7a45ca,1baa636e,9f759bb8,bf078a55,81e34495,d269afbc,1be39ce7,5417ebf7,d45decb6,eaddb635,4480a7f7,8d7dd34d), +S(320a08af,eac009eb,7f254b8d,395d836f,ca6ea527,4e2f309d,dfb7f120,2f1b3cdb,75269a2,41199c0e,5f1cd9e2,d102a294,2324a3ea,cfae231f,99ccc5f3,e0af00c2), +S(8b893fcb,9a524af2,6de5aa38,8ac3dc,2159817c,7062e5c9,d5c9e7f7,dd889ad8,cec6a5ba,481f7e3,88c1cab,c11505f2,39afa143,68977ed6,52ea2d6a,19d2cbfd), +S(ea89b95b,36cd5203,22c8e5af,7461f9e1,a054f23d,2720469,fa74cd67,3a52aab5,5325d16c,4b866865,2437b6b8,598b31c4,59e6101,2cc1b147,e0473527,5935ada5), +S(cdfea79a,8c16ce78,75a9fa1c,5b7647fb,ad641ffc,5b73fb31,d9354a1c,3c1cabfc,184c309b,b0f52999,2a3f6b93,77b9e6a7,6da6b943,d8031408,b71223cf,b3ba9100), +S(3daaaf0f,785a6397,c652331,630931ee,a975c522,35899736,1b7e5fcb,409880fa,952efec1,ebd4c107,b26a98f3,c6683903,a498c840,ff4a36c7,ade569e4,c899919b), +S(7cea5226,a56d21cd,45bfdbb0,7fea6670,40247c70,ef43da28,d1f8bbf0,6e4ef2a6,b03edff9,6a5f32c5,6f8f63f6,ba9feb68,f43cca62,391ea587,81396c7,5d963b67), +S(1f5f4c27,847ba921,c63cef52,8b57fef5,5bdb5344,ea67a23,c173828d,c59199e1,d37f6918,e0b774ad,317dbcac,75c82188,c8a421f0,ff5756bd,853a05b0,c95ef089), +S(36cd4da9,2a77613b,6417deac,1d9a0dad,1bf0e506,de26b529,7fffbd03,4a4663f3,ec1dd8f6,6226bf5f,fedb071f,7027f9d8,d931e6af,e378396c,d0d296eb,a63737e3), +S(9835c156,1be21ce5,db788f1,3c0aea13,fde6861e,97cb2cc7,a67fbd37,17eefadc,7fad454b,7372d969,a6e754ef,c73415d7,fcd4d589,c8e255c5,1adf5a9a,82228f42), +S(5e218414,d9c9f0ad,35ded20e,76a484a1,d41b3894,ba9d3be4,bcb4546b,371d0e4d,76966ecf,9c8f1c9a,452cf971,10ca6555,2ca59d31,21092e93,333bbd61,6eb9cfcb), +S(b105f4f4,40e7ea66,e3272da9,d6b2b76e,d00e96a5,6f95224,34ca0df1,5340c585,9e8fea7f,35bc9eec,f82ae118,bcb6dc33,acae587b,f37b149,1f8312e2,4ffc86d8), +S(81d5713e,a732b4d,98d085a9,75cac9b5,3fa65171,e5cf49f4,684a7856,7c24fea9,32480cf7,a0bc0c50,a4de8200,9343b524,4a0f2aa8,ce67b11f,4a5482cc,6fa00bf2), +S(d47b4f1,88f5e7ed,a9eab2e5,8ad2c140,c6278d63,517bfaca,8cfb64aa,cfbcc7ec,524f6580,9d3ee034,afb1e64b,1a0f8ae1,1e464915,3722e345,bfda9671,1b94a5), +S(16e85ad8,6a953564,39b97957,7bedd0e9,6e2eed72,76ba269a,626fbd58,447996c0,8bf74f51,4bdbb6c1,4de81a3,1ff12aa5,de49bd52,63a962ab,b777439a,47eadee7), +S(c299c6b0,6e6c78ae,852bd55c,dea35f99,d264cb5a,e836b77d,ab209ac9,c05201e1,a558c66d,c9ee7fa4,c777b0db,288b328,428b230a,7c53d516,522ccec4,af0ae08c), +S(63c4624,35ef974b,393b05b3,7d1c89d7,b0d8958,ebd541d7,584e2bbc,7235c795,1d806446,ecfc7bfb,bce099f2,6ce37a49,61b53453,5b65642,c0cd23f5,a4eef9d7), +S(6d36d105,ed8cc5ce,53f2cb69,8ab620f9,469a3e5c,b25bf6e6,d413f414,c5af726a,1b45a3cb,1c889961,8d273993,6a3affd6,233a66c9,4bef75ca,3a8fb6e4,ec05ffb2)}, +{S(abdd85c7,a2f8bc31,343382d4,e405978,3874c8d0,1405ef14,85047cf7,f0f71d50,d5a03157,798fe828,a03ab63e,84bb007,b53a5315,1db7af14,e4ab612a,736232d4), +S(31297c6c,f567267b,3c8d65a9,72afc752,e8525eb3,de2958aa,76f72e14,5ad903d7,f4735877,a6c6d89b,d1beb50b,edd1235b,5f5e5d0a,878e4610,e7d756c5,34813389), +S(64706e69,11a7d0a1,2e587c86,91117a27,cbfa64ad,1d5617fc,81e55b8f,64e0da86,59d9af3a,419957d2,b3de7570,15fd8531,a5d07430,5cfd7444,5e7e70b3,57e62772), +S(a4988ed2,89d8397c,f1b897d3,b81d80fa,92658ce,2b935f4e,e2e3f0f9,b193af51,813fb8,73270570,50f23c3,f8082bcb,563ee366,1f6b2af3,f631f5f,916c8478), +S(3c2769bf,af401993,595a01d9,9c72a6f2,699591fe,4b869077,8c6b5ee0,f172a866,f3e0d8b6,cff168c,95873f44,871d27b,df1e79a2,d9e0bd4f,6f90f682,538c1f24), +S(49d93e09,df655edd,19548fbe,affce201,4c6822a7,e196eb98,b9ddfad7,3cb70125,26e6957f,84ced17b,c64f710f,b37656d,31ba088a,98350337,8f7323cf,c57f0eee), +S(53c06842,49997cb2,6e5b4cc,5f166fe7,db0ec0bd,52639a27,d8fedea7,214a78bb,8a8dd3f1,b3081dd4,948255ed,dd178089,a0fa7342,1ea616a5,1f639057,34a489c6), +S(7a8e7d18,3f2aa640,d0e2ea02,4cdca5fa,1767d9f,9ae38805,5d38e8e4,a81d33b7,c2fb92e3,5556fd14,4a894be2,3d97c6d4,30872ccb,25e239c0,d959a24f,aaa77397), +S(a5221a2d,29cf3ef2,f066897e,4ee74ac2,95b34cd7,54390814,297537ae,abdf603f,ec0ff395,8c3a1d1b,5a379417,5a61cd97,782c9683,aa2c7c07,5d147db0,2b134278), +S(3f49da9c,1d62eccc,afc4b88c,814e44dc,8440341d,f347de1,fb60126d,59578dbd,c3cf8e96,2fa9478a,f1be08dc,961734ca,5021a65d,b1b45f80,78fa8e8f,d2813a79), +S(47b16636,f5a64b07,534be14d,6ae37af1,9da79b42,666b201d,d0afda9a,2daeb6b6,f1218111,31ebd87e,e1fd7c9b,d24a0a11,a12e842c,6c00f445,6a342309,9b171f12), +S(a7b5a8ea,1f23ff1e,c1768eaa,2fef0d66,b75744c6,dc925d3f,9068beff,d69b32f4,fe01a23c,b0e5acac,e60058a2,889f9434,9ffce6c,b24f4a3a,662e0079,99bcb690), +S(3e14e2c,e7044716,d42e9b6e,54cb0500,a1e4374e,18917336,e3205e31,4a878b47,18af982d,2c78ac23,818644f1,ec657da8,ad66bdb,3d5a9b84,3f8bb988,4ef8dc3f), +S(71393e6,746d3072,830299c6,c1244303,750742be,361c5f08,6eb314a4,76f1736a,dc30a7ea,9b644339,ce8f1fe4,eeeba07,5bb08934,8135e819,cb061559,aa14e42f), +S(37721b73,e6861f15,7993696d,aded49d3,78994f3d,e2b573a7,defc907e,d6f301f2,ee0e1755,d8efb25a,5cf4d783,ec847425,746fa442,d460cead,56e73a69,42561de1), +S(7803c663,509fc9cc,55b372e1,dc0fa76f,149a0ca6,3db4516c,4abc0ad7,5961e4ac,356c72f7,794a70e4,db3463be,eaa847cb,256c58cd,b6a7d862,fde4feef,d896a46f), +S(32976d3d,a3d033cd,c073b0f,c7d2f445,25646893,fbded1c8,1a0a1761,a8703206,5e6b7900,a069ce4c,65cd84cd,f290f092,2b936bda,af6ea40d,9c36a321,a7c9dcfc), +S(c52c7b18,b5fae5fd,a4e3597f,39c96b8c,6d6c856a,80f1210d,a1ebfc15,34850763,b87e50f6,20b66865,307d0747,a02ba22a,b310712b,cb0bab6b,963c589c,c5a208b1), +S(7de59c8c,3922fd51,68f4151e,cb783775,cd0bc0b,1185ecd3,6ee075e1,14e66cf7,688e2cad,e4d49da7,fe691497,412c9372,c67288e8,ca4b64de,308eabeb,723fda15), +S(ac49d6f3,32cda691,c345f099,667ace08,f6496126,830c39ed,877223a8,cedc8be7,267e6a52,5ddae4f6,7e05f0e8,52b9dfe,5101c491,64d791c9,82249937,c3a7b031), +S(5a92401b,698cc394,c9b714c8,bdcd92d1,20fa72e9,b1311839,1c383024,f469ed22,e29f2926,84c255a9,a739ef0e,5d13cc55,987f5b3a,5c6ed623,29431033,70edb4a2), +S(3609dfba,51616095,ab060e77,d6779025,6456eddb,f4b651c6,442cd673,f893878b,f85fa9b9,442050d8,ad9d9314,9ede8698,91dfc99e,c05a2a48,5854cbeb,55a6c380), +S(332bb85e,92c90a15,3bf602f,45dc33ab,3dea5ef8,7034af81,944113a7,4edc94d9,59b6c879,5f2a824,96d631b5,ceff8708,507db41a,375c7257,7533d8f1,461fbaf1), +S(16e9e054,916b894e,730d7126,27b1bc81,e7689efc,23cfeacb,a423362,df49d87f,303d0428,b701f1e5,fe8ae460,e54adeb2,d4b5aa93,a9c7d7ec,7b903cdb,20e440f3), +S(4e62ab89,1d4c4cf0,2c44915a,4e2fd522,88d75aa8,e22b7463,30dbfbca,97ed9515,a7c21be3,3b5cd522,4de0bd25,faa9c2de,5d6b2f50,b50a6901,b7167b3,c4def4fc), +S(649eedbd,5612c429,2aedbacc,b846e759,4a2b5870,f21452f3,1ac9e697,fc055db9,ca694303,ee206a4a,acfc4cb3,1aa9f117,8fcbe37f,d6bd11a4,669289cc,7c37b0a), +S(e858f72a,5fe2314,951ca096,8ba59760,e3d2a667,e76dcae8,c3ae2d7a,4721afbc,f1c7131d,3e2d0468,ebb89bce,700e0eca,ae83afee,75620938,60e1fc70,cfc7810a), +S(cd351498,29ccb1e6,9b18e35a,72a24b30,e074793d,aab4028b,1c5eefe2,b7b3163d,6bbd52b2,93b43cb3,a19f6291,69ba5b2a,59785099,16842093,1e58dc1,a040c57b), +S(19ffe344,69ba3e43,7d901863,3be7c298,ad8b65a0,49c30dc1,bae30ca5,97ab38fb,c33ca345,efeec662,96802e95,69f0f34d,12ceb64f,30fc704b,b77261f0,ce5c98eb), +S(8a2f772a,a38a5b55,a7081d0a,61bc27d5,89f9832b,1326a230,d81b9f58,4d634293,a4707a0e,a7bf528c,ac62e361,6f09287c,182aa3b6,6862430,dcfef3c2,69d1567), +S(e583bee3,1dbc8f0e,572eb18f,366f88e9,3a7a0484,b4299b9d,335f7836,a222636,8a4fae1b,be122228,be9d8afe,be223c53,dac161ae,ca77ff4f,e14d9c78,894fdfec), +S(8b6e862a,35566848,50b6d4f4,39a25950,47abf695,c08b6414,f95a1335,8dd553fd,15a1f76e,f12ee34b,f2ef43d2,b14605e,db53c3a5,e7cc7c2f,27fc252b,c1641642)}, +{S(1c185b5d,e988ae93,eebe0aa4,a98396aa,fff2671d,8246ce2a,4394db96,7a541ad4,dddf4244,3532024f,d225f86d,133b8156,3ea8c92b,f0ddc354,88e6a04a,d41da5fc), +S(addee173,b29de510,58dc107a,47fad47e,c48bf332,2f7c138d,51060322,571faacd,3890624e,c6920ca8,6a9aadb9,90a15156,799dd771,901823e4,9f3bfcb6,8bf05d5c), +S(9e20bbed,ccdd5c05,d683b2ef,852760b8,e246e5d9,6a8900ea,999ac8bf,5e8f12e3,9f28e5a,b4257f6b,b826d076,ffff259e,1caeda5b,7d34f658,ddfa0401,7cd4768e), +S(dc825d1,5f707c17,46920014,9d7be56,acf2d1d3,c444fa27,cefe5019,6f5b317f,226d4960,2f349d4e,9cd10a57,6bf01681,e4981cb6,4235d347,72a1e5ce,7694a20c), +S(812e2cda,3f473919,1f2ac087,7d70d0e0,2ca0551f,10c96d95,51ba4199,22780f90,c8d05855,6b6364bc,d9aff119,5b9ef26b,85cffa72,1e880b83,eed73cbd,d23b91e1), +S(aebb0870,76f5918e,68194fce,42d0b925,cfd2a506,359af62,146c8ceb,8502231a,c1c19605,e0456cb1,3e57229b,45c83ff7,c3695a2a,31908bc0,31b08140,9c2040fb), +S(af7332f3,3ec274c8,d34f47ac,fcbacf8f,7980cca5,7220012b,8fd5ff94,cbf3d8b,d439f1a2,89799dc8,92b7e53d,a84a9e82,7bf7bdb,7240c34a,caef59a,777188a8), +S(baf71cf,7851a758,12d7e09b,192741f2,1b5d2a36,6e31892e,e54c282c,81163a6b,1ef3bf2c,a81acdfe,17cd6b45,266241a0,22caf299,ed4d87cd,68d3d4d4,526b4d38), +S(615991c5,d250cebf,8c7bd1b2,969213f0,403c7da1,a3ba913,44fd0490,88c2474d,4f014177,12142cca,163f29a1,f5790004,32726712,93c2e87e,f46d2138,c14040b6), +S(b1574b39,26ff27c7,b2dace6,6108b93f,3fc75d48,478567cc,66bba29e,750c0c86,2759967d,8d05be25,3f88a66f,830dfb83,5139e32d,6f42cf3a,43b199ce,ab85b55c), +S(5fe92a7f,d1c407fc,967dbb19,e9fd4d,8361aefc,a3d5a9a4,2f8237a3,458e5e90,9b89ce35,57d469b6,9b9034d6,cee93609,c291d023,d1d9349a,d9bcf47a,aed8b2a9), +S(d65b0a5c,41b2dc6b,e5aa87e4,adfef952,621f9d99,550e424d,176ee180,65f666e,a76fad91,3b80b0cc,3d3ceac3,9a465cb9,4d8c79de,92adf9cd,7a4efae7,c85c30a4), +S(61d7de65,fe34ec4c,f82f67b1,75887263,11683263,145cbeae,18ed192d,14ced48d,effac049,d7e5412c,5052160a,6d1b2230,7157669b,856af0e,e3e46a25,2d2ee19), +S(9a77de66,5165a9be,3dd2758c,39aa7a14,1f052358,fbac634,5ea701c8,c93bc4a9,1044e428,bb381024,70108d56,b8b3e3bc,7512300c,5a6ae44b,93b2098f,a13fc023), +S(4ccb2426,b6eed0f9,651f80d5,72b23e78,d84d6928,57648077,3663216a,bc8a418f,1840c,bf5ccdd7,19f7fa8a,33e7151,aa351d,2f620972,6ec67d1f,fdada8c6), +S(53f96bb7,86516e0f,2ac7611a,1aac61d3,cfbca76a,9609fe,e4cae036,52f68271,97e3acbc,468b777b,bd1c8263,5332dcc4,b08b9fb1,9608fb35,cd51e49b,f09d9087), +S(395253a1,b6a349a6,dfdb0d6e,65695572,2a597411,fdea9294,6e48d107,596d8ac8,c57110d4,dd0d35a7,663fb3aa,e15d8c4,dce5cb67,d3173d91,a6ff7ea2,1bd28107), +S(d7becbeb,c47d0de0,899ffdff,8620124d,b29c8e5a,fd71a0ed,76e0df76,bd4e26e6,d8b52fa3,e16e7f19,e925e769,3b5a731e,18f3163b,1ad4db34,7f878381,da75fc15), +S(fa3afae0,4f8c1fa2,778446af,88e29150,256b0413,d9bfeb44,45288e41,29be15a5,9dc76b39,574453ab,2d46cf23,ce8cdb06,cbe7df15,d03fd390,4470a86a,822028df), +S(da56da00,dfdd788f,90a12219,db03cac1,403efef3,ae706031,e153aa16,b3a52eb3,1012ca8e,ae20efdf,41c77128,93fce97,fc66b187,caec55db,7aaa81ef,cc12838f), +S(f07866f0,cca3474c,40e7fa59,26df41c0,e46fbfce,faab92e8,9ccd1170,3ccf79bf,37ed66d5,5e891f4,e644fa04,182f34b6,1f1aedbc,d2a71aac,dd1523bf,f579dace), +S(853f72d1,edc4d953,348528b8,3656894d,67032333,28a16801,64a84511,15c5e968,197737d0,de83e73b,247d861,510ac76c,3ca214d8,ebbb958a,74ce1c31,5e715e87), +S(7c7eae74,dce7ef76,9ef0ce86,cf6ac861,ffc3d4a9,6313f379,fb2c0325,daa91aba,131e1689,fb017e15,e869d858,2dcfc4f9,153d1e8d,246fd613,b3922302,5b5c3767), +S(56028652,bce9dc6c,c8b4ad5c,f9f222c3,412e5bb7,8d556225,2c06c2e4,25a6e31a,2aa8e093,d8653f6,2153972c,e54806ba,666d49ba,3787934a,a37bd65e,79374ac0), +S(2eb98b01,550a00dc,59d280b0,71e472b5,a65eea89,298fe4b0,9f6f0e07,9315ad7b,74e22fc5,3daecdee,6a0b50be,e17f1d7d,d9481e77,28778957,274c8d29,a0d89fdc), +S(7268b61b,f65d73aa,37766a99,9960d998,18aa4ef2,ae8a97b1,db8476fb,32f891a4,824e99db,3157b706,38573513,618f6901,ce1fcff8,f25019d7,c5c45bb2,f3bb4d47), +S(cdea8771,4a764e3f,a94e7356,879b7d9e,da7c5b6f,28c172a6,1c0ab012,9b9ddd7b,daf49b12,34ce20aa,263b4349,f9f88cc5,1334db26,59b7c587,212f407f,cbb2644b), +S(38831af3,193c8860,690a9d74,cc0079c0,9e3ae0fa,ebe0da02,67ad6e23,99059d19,be188500,5193f11f,e34e70a7,e470cedc,902bee92,e7041403,c2f1ae53,7a8bb077), +S(df3acf55,bc6d97ce,34ebeb46,34fe1010,ed3d6d6,383c11a7,53a93123,e9c8381f,94c22735,ae6f858a,59f663e2,12532e14,4efe6a81,981c7619,e5002968,dcb81df5), +S(a8b08b86,4946ac6d,a101eb85,ee7bdf55,24282ca1,a9956e4a,eeb1afe9,87a43ddc,80ff0174,375c95fe,cea6e00,20f17123,5cda4bba,d4ef893c,78ffe37c,205d5577), +S(fd9941ce,e1c26864,248f7035,352787d1,aba9e93e,f5edd333,d08c89b8,4bb9dc8f,85be138a,42bf190b,921681fa,8777a619,878d4d02,11016c72,8bc151ab,1a687b5a), +S(7e2cd40e,f8c94077,f44b1d15,48425e3d,7e125be6,46707bad,2818b0ed,a7dc0151,6fa48af7,d523054c,7d59e574,cde106a2,776411bf,5111f7d3,65c43ac5,df8ddd68)}, +{S(282c5bc7,5b9c3f76,73e244af,29f22b80,c171bcac,d7e39b4f,ac7ba6cc,656d9010,e8db2eb0,a56699f1,73d5b5f7,99d39e14,dde34648,f159ad0d,c1c7767a,19ae72aa), +S(d5a3eb7,cad9c548,839ceb7f,67145e0e,96c60d8d,68415f76,73b73700,5ce3a8b,34ae4e12,355d1df1,25149efb,1a9050fd,490e251c,4404fb37,31b6dcc9,e233b9f1), +S(68718b29,86197989,3c5f7b1b,48abc254,13bd23c8,96c8828,7000ebe6,6db742a2,bef9d2a1,bb596fdb,3caeef3b,4d950568,8a94b436,4fd85f37,30b20de,b9e9a4fe), +S(a5ed1709,7932011f,9a597511,a526e61d,f22d0bd8,ae3e15ce,655820e6,b1ff1238,dd6dc7d0,81e70b57,4f235c10,c7c3dbed,a57743c1,15e6fe01,a20ac751,34cdace), +S(ec37904d,9662a487,1a471d9f,778bdef3,430df9e2,26fc42e4,7fc4bf5f,80e3a9c4,8413f2f,1ed55d8b,8448e336,ac9d1418,c48846e2,acb43509,f1a3d935,8cd18ed6), +S(b09f9c76,1cbbb685,f695328,61c459a4,d2b16989,3cbbad2f,dd49c87,1d860db4,dbbf9049,31b18454,21c41f2d,2185e3d6,c8f55dad,f1514ab0,655c856e,3391278e), +S(ed1a335,48864e9d,b41abcad,3344f4e7,ebe57841,9371095a,6b95fe4e,ae59edd7,d1146be9,83adc77d,bd9c107f,3092a9c2,9c271248,d78ce913,7831127c,c403f44c), +S(d39507d2,6ba377f5,c7116aca,78df331d,a795cdfb,54e5c912,8558c0e,997b74f3,fa7971d4,32cb5a44,589dc705,de28ad0,382206f1,6e11229f,86ff82a,efef3131), +S(641dc311,baa77b14,35f408e1,528445df,53c5ac5c,32803a3d,84e8fb66,60d71d,2b355a47,76980bfc,8a4e0ac6,a3bd7b02,a6b20ffb,f8650b16,89010456,6953e49c), +S(c3dd73bc,cfb744bc,57bc95f9,3c260df7,7f3b7e74,9e4a5237,f3865f8f,f0c89489,15d58dfb,83654754,80e53bb2,a1ba430a,ce213c38,ea71c7b7,51b4143a,fe2bd124), +S(3f883fa2,e834df1a,6e9b5c46,b663880e,9a0b42f1,891b92c,eb30600d,5641813e,7acff194,a5fb76e5,bd3d8fd4,2c7f07a8,3a991ba6,7f0e4edd,c55e1d8d,3025d590), +S(70c8d4f5,21d808e7,221bd5c6,31f171a9,5e7aa358,4477068c,2549c59e,228688bf,52badf20,6106d5a8,d7bff921,580eb5f5,3a53aeff,e0369f9a,1bcb282d,7b4cc26c), +S(ae08db34,874d39ff,bfb9c92c,5e4253ca,7ed508fd,d12841e9,63600461,b2b3a0e1,dc0504ef,d209be71,381eefd2,91508120,fb6ec1e,df62d24a,cb1d77a9,4eebf1be), +S(627027ad,4aa88477,c6240517,87a25b88,7d5b98f,b968221e,8e45d584,3db6e0bc,34b553a7,c6ac7004,69367afd,17c5eaf8,7605ca18,6a57667b,650fd8c7,18ab76aa), +S(573ef2ae,72ae8fd5,eeb0b720,f8967b44,f7d9d96d,c8a4825c,23a3dbed,fd2bb442,264f508e,efe5e0a2,55e55a54,bbf739b5,757d0a15,994ea9b8,4e139738,7c484786), +S(28907848,cf84eec6,773a384,ce5f4a5a,24c8afc8,606488a2,ccdeff25,6f896dab,ea87d4f,41df8727,2fe84537,d11126d5,62618bee,a51008ca,895a8375,4f05ec5e), +S(163db4c4,536114f0,75521627,c61f62d9,14214d64,ac9e66b0,d85b9991,62c54c5b,7ffc24e1,11c0c845,1c574e9b,e4b56610,696d3667,a6e6abbe,9d1a5ea9,4122aa1f), +S(2ec11f2b,71ffc28c,fb5e779e,7739098e,c969bc78,3cca5a22,77d2bf53,e6574d1c,c5e9fdf2,89a3090d,e24d13a1,bc8377d9,de0bcf4,63482ebd,9620cbdf,8b238fb0), +S(30549ae0,9a46820f,f49423b8,9c6fdd48,703132fd,ac166dc9,90609a32,49039f0a,b8c94b4b,36d39247,732976e,fc16d500,ccdc07f0,d7b97db5,7a1d9fbf,d8cb5d2), +S(98685f94,a043399c,89e74674,240322ac,5a595bf5,41aaa44e,d781781a,10fe9225,4506b1ef,7561b811,53f44e8f,325f9222,e999013,30523885,d8c59864,db13a3ef), +S(9acba196,3014ea9,1baba28c,e273c6e5,b9a2e1a0,98216c3b,194a0b56,dbda7db6,f0a3358e,eec737af,2e313262,b29ddf6,2adb9e97,9f56def2,65102272,6b976290), +S(e81e91a1,7aeec75c,19df0ef7,fd07ce2b,e477c031,179e3f99,4ca13857,e2b5ff93,65236424,aaa8b6cb,fdb2fb20,46ae3c3d,839d97ed,217edc6c,c774f889,d2ce8b45), +S(61e60aeb,821c3f80,b53ca78,2c3b4d21,960eb0d2,c90202f0,a5fba651,1725ddba,b029275f,690d10bc,b52e8bb2,acceb071,f07834fe,64175088,a97e26f9,8ff34432), +S(a931c410,8fcb4346,6802dd4a,8ec2cf62,cf4c5558,8129299c,b3a87e95,6fba2a34,c21a8dd1,43d4a639,339fec49,f56d717c,658a55af,ad72da1,c754fb9a,117cf6e7), +S(fb5c106f,da32fcfe,ffe9b5a2,7ac8cfd8,d9a73da1,5fa6340f,e09d187a,7a83cb88,a3f4c60f,90003375,11c39100,ba4c4721,c6c138c1,cbae09dc,46d1a1d2,5baa95fb), +S(dc25e18a,18f0035c,2a05e80d,d6b38830,7fb3b176,a66ae451,8c5640db,7540dd24,3ba83beb,3e6b29c2,97a0ead6,148f9b93,711556e2,e5fd513e,ee649228,c62d8f3c), +S(ecf7b689,ca03b840,739283e9,c3003a01,65ea3f,3bd17e06,9260c0e9,ad403273,5e0dbad6,47997fca,c0d7ba2a,170a7954,67036ae8,e61dc532,b5fe184a,deb8a7ea), +S(263e593b,10c982d5,1bf89ec9,71f6a3f4,60e53bf4,cb2f6af3,2381214b,2e981bbc,e255bc11,11470eb8,894ead67,c618d7ca,a6b76ae1,a230ef05,3830d028,4a7faf37), +S(f79781e7,a4137ac4,7a9a9d00,9d239b37,6cd0fa3c,b9f5de46,8cba5a11,ffcdd69,d10ba78,896e086d,5e25444,165e79d9,7b3d485,1a448e03,26d8906b,2f27745b), +S(a4d28024,11f577c1,c5d08fbc,457a46bd,428f4d2a,b29475ea,ef622876,593e49f0,e4855491,ac0342b1,dc804bc2,7ae23877,82eeaf22,52874a00,4d4e0d66,b07b434f), +S(87195a80,dc83be4e,cfc9d4b8,29725cbe,11101c26,13c98f2,641753af,1ee840f8,f9fce233,66931c51,4ea09224,b565dec7,22763d8f,6f572057,fdd7d96e,9811289a), +S(210a917a,d9df2779,6746ff30,1ad9ccc8,78f61a5f,1ff4082b,5364dacd,57b4a278,98f1e4ab,af4a1a84,85c6417e,7298c82,c87619e5,500df403,80d8ec01,f384d9fe)}, +{S(6c16768c,433a000b,adc47b10,ba4e132c,f5480e65,ae83d1a6,8aec34d2,c00c76dd,ca1a47dd,66c2d74a,ddb69283,2ea289a6,ae679669,edd80bdd,4ffdab2a,defbb542), +S(f757e860,ed04db61,594bd647,5ae81b7e,d6d2fa58,80cad10a,7756fa26,810b8543,f2aad599,4e491e02,9b1ae256,2c90912a,1c9aa6cd,dfc2331d,a0069a79,861208a), +S(d9f269d2,9aa777c6,9989d706,91403dfd,9025b491,ba03ddf2,dab8c9,af7dc764,1b39b85c,cb4749fb,7f47086a,ce63924f,3ebb4213,af5dfc95,fda796e6,c6b0b8b0), +S(d05e14f6,fe6ca50,a23e9339,e449f771,98e842d4,80a72d5f,8f5e4c06,43547cb9,869e3bea,6b19e0f2,de83fa8a,e932086d,d66e838b,637ea603,5f0fa081,5912c8f1), +S(9f723d81,1818046f,b7512abb,faeb46d3,52d8da9b,3abe819f,3861f9c9,963c583b,37df0657,3f2bb428,6c8b3efe,f6941e2c,4e48d90b,931cd0a5,78a4b52c,6581ee7a), +S(e65f0b42,54ad9df9,681c0db,3428ccaa,11194df3,9e837aab,4564e1fa,254e6f97,43e59d10,54aa35b5,80373e08,cfc02aaa,4f581406,58341e67,7e50977e,5bd893dc), +S(605d61db,589fd91,78a65cb5,99697001,73afca81,23f663ac,5fffd0b9,8f5e7a64,a976a9d,a47745f,447ad4dd,7eb63875,c228b979,a7dda50a,d994df7b,545d0ede), +S(43298aaa,faf20e9d,c2240256,493ef19f,5630db6b,f6376e4a,356bd034,98f1be7e,737551c3,653af1cb,4f8c1e8a,347f50ca,142c03e0,29007f29,c76bb763,b52ed053), +S(8afba782,d6373f0c,54734f1b,4b854e63,bf2a3b4f,23f57a3e,6c2eae86,25c691c6,da3054aa,228b9757,b7321da0,64516249,652fd814,15017584,2c7683ce,1a3638a2), +S(3156d359,e01d64fa,9c8fd8b2,c47c3492,82dd459a,fe89d94f,35906da2,c6d0208,85a23f48,f0a7448f,c57ee545,3978e2cb,6f2bbe54,864477d8,a63775f7,7ff7289f), +S(88e1a44b,1e206eab,49fe97af,30be5e47,25e1011f,312a5222,e9e80819,b3f26357,63dfe52e,10317c4e,227b2a5a,d61b713e,2d93aba7,f0a51e0,b5621191,40c58ded), +S(d10de96b,f2e4a6f8,78e0f37e,15569f3c,b9717a38,7fb98928,6d65d171,4b81b301,2c0a46c9,6a2e3884,e7f3b146,acc170d2,6d12b959,4b75a901,dd535016,f0355ae2), +S(eb36b865,812ae4bd,7893e50,5aef6f14,bfc90c1b,42e75ea5,91615aa,a2101784,1523537b,790b2a61,fb6696d0,a622ff31,efea1255,e1dceb86,763985e2,6c5ca8df), +S(d54be697,e41396c6,3d63f96f,bde9bba2,36ab1649,3c156159,3df81d69,c906fe60,89de1769,433b5678,1f7a2206,ca98258,20d0c7dd,a6d5b672,f77029c2,6bb59f33), +S(d5aa72fc,9063c2f8,bd0fec97,da30dcd2,a5b36aee,7894463a,f7042795,1998c979,ed90095d,bf2d3a67,2d2f1a0f,9737c4d,e8f3e773,c04b77d3,a2345dda,ab662199), +S(ee8cd53e,8ab64281,b5cad323,f03fd06d,7aa166eb,df9185b4,8d0eb0e6,1bd0bc61,4781263d,fc518e4,809e5ea7,7f9df238,1ee7b6ee,ab25c1d9,5cbf3fce,72fdd615), +S(ddc5e95e,2a46736d,9bbeee74,74364bf9,e1d2724f,c43522c,cffa05a8,7d078be9,60908fb,809ae964,98a26cd9,67532df2,409491aa,73c46803,eb58861,7ad86745), +S(ae503a2b,b6250ff6,6ee615d8,41cae4e,751160fe,aef7f33b,dd1feaad,ab236b58,6e53d2a8,8f09f78f,96d49a6,2f98773b,a282b575,ab6e24f8,4d604c3c,8583a66c), +S(8a502d08,bb3cc1da,438c5780,e2120c50,12c1a972,8aaab6bc,5d908b6e,2a83dbdb,fa02e62b,85d7de78,8cf11d9e,ab406523,bba1f912,53006a89,f3a491cc,dd99575c), +S(b52891bf,5acb0019,a8d10b94,87fa47c4,22f83a00,ef539e91,44bd9f7a,d5075716,ae58653a,b167a9e4,b71eecd7,4f4a8786,19c19026,29c0018d,9f082e7d,5920b2f), +S(176170af,b40a3e79,8a88b98f,fb6c578c,d1ab56b5,b7f4142e,b2d84a59,1b009f97,6e1d5682,36176d58,ce5fcac6,4d4d2885,5db107dd,5215c71f,b4076aaf,d31c5d24), +S(27359f7e,8d3e3dcd,ea35f603,d8fb15c0,bd63c08c,3ae4d2fe,8cb6434a,ae2e716d,a0d64207,8fba00dd,4683d597,27f3c67f,3c25075d,802a4ea8,eb08c20b,47a941f9), +S(1e9d955a,2f68478,5227e866,491990a5,62c802ed,1b106bb5,42d02d29,93542067,fbf5f466,57707b3,3f116a23,fe5991a8,90a9583f,fd063943,37a19aa7,e125ccab), +S(b5c4c10b,1b0e0813,37deef6f,c089d2e1,ee14da2d,cbb48e6,74b7dbd4,429e22eb,fdac245,b109947,8f6a53a2,8a1ec4fe,da43b4a9,2ef49e25,8f9296c2,88c48378), +S(bd2f651c,ff6e614b,1d6535cf,c3a2c5d2,da5307b0,1cbd3f48,655623c2,55503916,3715b0bd,bcf29d97,63d7fb35,f9c5b54c,769a863,3517a2d6,8dde74e4,c4277779), +S(c4c2a8e8,f1e257a8,fcd0b11b,30635c5e,782fedcf,f99b0b95,828e1369,3ee0af73,3a08abb4,777a066b,49ec4c01,aa5b0868,f100a473,e555def1,7c5a9d84,b1fd9ae), +S(4aa77ce,15dd97ff,47c1125a,77bcf0e9,d302b79a,e8a919c6,a875e5ed,eab8c2ec,31a09dc4,89a90240,334836f6,302d7e81,57f19762,a9b5f727,6c276e63,560a9d10), +S(3731162e,66a8d2d8,ff4df3e,95950103,f5a03f9a,86bf37e5,605746,cf4be846,e19d7835,10af5daf,724be4b1,932dfac6,23899ccf,7e3e58ab,5bf3265c,667cbf28), +S(6e2114ed,297ba44f,c3926603,bc03a87c,af3e9f2c,8bd84e64,afcd9846,bd9c8f0a,faa6e5f3,3d90f91d,82592af0,7f3a26e2,f6f4138a,2f06a6a1,4286eb71,2e95cf94), +S(50d775b5,f72d186b,266a14e5,254cb5aa,49fd8633,81c36b09,842632d7,ff004130,cbfe11c4,f0b15aa8,3ae8dbcb,9feff9c0,d68a26ba,11095b3c,ba94739a,2091bbc2), +S(8f3ccf31,f8b74b9b,624a5d1b,7cb1096e,202fe5e7,233777aa,859864d3,775732c0,980e32c1,d2c61ace,7610b926,6831ac27,56f19788,ab7a77da,18c421a0,9a46bad4), +S(24cfc017,6da2b46f,a8bb5bf9,636be1ef,fd7e297f,29122fb3,e84c9ab0,c18ada5f,14007044,f8639e59,67978eb2,a21256d8,126a635e,5b07eb0d,97059ec5,6875a3c4)}, +{S(6efcde8b,e99d9ee8,ee0d6b8f,a76584bd,5deb67b1,415e729b,48f3d41a,f1cc1386,4ddcef4a,a6ad5be2,d1e83449,9eca4a8c,73219f80,464a4a9e,ebb7f3f1,b70c9fd2), +S(24fdd052,a1e535e2,4eb79ffd,f03093f8,5778241a,b845b548,31b9a82,730ee3e,c6ff8ebc,7edfd9df,9b7410a,7f54c93d,ff0c682b,152bf4db,1b79c0a6,9889797d), +S(aaaf86ed,31dbf395,687c959,6c445b6c,dcd1fe7e,ba2aa13d,1bf41867,dc87b30b,582b9683,729be5c,85fa83e,2ba2abac,e3037262,2a24aa35,c7753312,1de2fb93), +S(23930d0d,2400db1d,56525bb4,67172fe5,e930bf86,21124fa4,6c5a421e,10b059ea,5e11f202,beca3d5e,dc9b282c,2e86d5d9,30f8f5d,27a5c4d,d2cd6dde,6d1497ef), +S(76ad10d0,bc92ad8f,55b665a1,8ee84e01,2e92dcc9,37e0c604,59bd6fd4,ded2d9d2,d4ca7386,ce0c4c5,fd37da9b,eb8fb040,97d98891,35a5ecc0,320dfffc,95ed3c10), +S(10b324b,e959f0c8,c8a82142,4a8f87c1,fdeb7f88,258e1021,c9cfaa66,b131f3a4,590e672a,daa8d547,161f635f,153fa12,b3500694,677af3f8,90dd4ca6,9620bb56), +S(afdb2acb,ebfdc11b,3577177c,d8bcde00,65151495,79c6ad2b,f7386275,a9314317,87d7786f,5ba775c0,ea47b141,cd0d4274,c7e58634,b64e4c58,f7f0c595,5a307250), +S(574cddbd,59b34df5,30f5dc4,61884ebd,1c867ed5,6cb60832,4a11b1f5,29ebf733,1bfea852,34256807,1fdb4f5c,485caa73,7136e3c3,b4b8a39a,389d7dc8,724f16fa), +S(97ffea2b,5de34e1d,495ce082,d0097b72,e7daddb8,1cb622c,2c14e814,bb0ae278,45fd3d2a,9d1e6530,61b4a356,65aa9e70,43766950,622e1c25,2baab265,6d4ed95f), +S(de627f6a,a7b56d85,535c398,80d0276b,b910ce4a,6066435b,512e5e0,21ef55ef,753033a6,ef89f053,c0e662c8,1557e6cc,d8b4c8d4,5204f5d,e1c8c742,72b96277), +S(b126c35a,d7993bd0,164867c,58c88421,d2cddb6f,d16a5966,7d9683bb,1b428eb5,a9ed1bb9,e9eacf9e,e712bcda,be629143,ad0e7652,82cbfab8,e586cb07,131e5b1d), +S(847b90cb,8837f488,ef027a05,71b2be6c,620cf86f,ead235ad,e76e3408,d0dd1073,9a2667be,6ce36e7b,d76117a9,fdb8f1b8,7c7cb45e,1a03f53e,7b32bc63,6f274b4e), +S(8ea21457,6f1bc2c8,fbee9065,c2cf5c3e,7a3b9fe5,403fb980,96040c2e,c6fe1488,dd75b454,acef4d3b,1b355a63,f0cd17a6,66aa9e65,f1262629,f0c7d1e0,33571b58), +S(9e11bb60,ba4b2d5d,fe53bb9c,598edb16,f3926bea,1cc90eb4,3e05ca34,e83f1896,263d7ea,50d83b8,791fc911,a4f73cac,4d42a09a,85f5ae68,86cb268a,fd562dd0), +S(f741856e,f353a7c7,17db9a13,4ab4aaf9,13c1f7da,cef08bfd,6f81dce5,b1130e20,ee63dd2f,48e15f68,d1acbf49,705fe010,231e26b5,14146c47,1a689960,d568eca4), +S(671ef05a,410b41d9,3b092b04,e523468d,44837d2d,26dba670,27400715,eeefa2b5,686d318b,b49eccbf,40dc18af,f1938fa9,b16d4d2c,c19dd2ac,47c7830f,89b8d55c), +S(59ea10a1,e5bffd6,a34593f4,b986e37b,5294ddbc,60d92906,52c6e9d5,75f88c55,c0a2eb5,6d04ab99,abb5b76f,7b2b55c9,c09d44f3,3785e3d4,64554c3e,dc7a334c), +S(37f2c7c5,69c6fd15,9b721d8b,8d40138e,a8873b6b,452af0a7,89a50551,e9703c1e,d114109f,f9e6d7c0,c51a542f,b2e3ef5b,74654bef,5eb84aef,c87f5096,2a30c078), +S(1d280637,9d77e509,126a440e,b1e56f1a,8723728e,97c92420,5ed13081,98c868b9,85003989,93a4a600,dfd0f092,b13a1186,c1c52dd8,8fc8eace,9bd4f1c1,b47741d8), +S(39aed6e6,a123061c,228d3d1f,857e0c9b,29b70cdc,549b4ea1,9fb6802a,8d8beacf,6bf86967,98e3dbf6,75865a1a,b86d5bbb,10f16e8,4f9104a0,87602c,e6946aec), +S(aa770804,4a996b1d,5bda074c,941b30c1,d1474da6,47d7c4ed,248d3a9f,c3c3c525,10ba5652,b20482f,fc2434ce,ac185d8d,af6cc6e3,61e77d3f,258abc0b,55610879), +S(7626a96,9f9ef188,3ea82737,83e5571e,4054fb73,6190977a,299c2a05,d29f60c7,172d4618,e5f88055,ebfcdf9f,55267ee5,cdf18396,1d5a2a22,55b87ba3,c7d7d2b9), +S(1a550684,d1195da7,c4b09349,f149eae2,5a1ef23,c9a81109,115d93e4,c98cdbda,c31d7dc1,b7efd019,c491010e,30f90ed8,7503c4bb,1b37fbce,3dae199,6609e3b1), +S(8d2306d2,dd8c753f,2b093e62,86fc282,ba3e1dbd,7b4ba101,83d1070e,d2d06e67,97dd14c2,d2c1d147,486a3dfc,d608ba28,d63fc03,251a106c,9811b088,978e3a5e), +S(f31a69ab,97039589,940851f3,cdc98bc5,d400ff93,63794f81,4d88215,4f00db99,56e510be,7f41b009,89792401,13641590,40f5f305,f27fe1e2,db1cd7ae,887ff5e2), +S(ce96b3e9,6eb94b7c,8bdc7b57,efd2186f,62e23e72,f11337ab,be7405d3,43b4d762,cc0dc898,33e7a632,d0fed52d,487f2c60,96c69664,f698a71c,3f7f8a29,4f181add), +S(bed97e25,7d31b5fd,36b41227,462d9122,706da670,d432ceff,5d37d83e,fefda56c,c0cfe30a,2c3b3074,1af492b6,e3797c4f,3b00593c,6806e2e2,f2cff401,6e877ff6), +S(923bc6c9,960f6e4d,ca2a7070,6d160e19,83a16b6c,8535783f,12c5ac69,4aad226a,c47f08b,6b2056d2,8e9f119,9ec6d5ce,b48801b8,7ee56280,d6a48352,b2b42b1), +S(b3cb28fb,7465cdda,85823dcf,819400b,357bce11,23d9229a,eddb8262,53b246c3,cf035ed0,b624dd68,8a31eb5f,3b28e83e,c0bf9453,649dfe4f,44078eac,9345f2a6), +S(c69aa2b9,ab3c5e45,8713a912,e7f95bb,4e5498a6,d4090323,5cfed1c9,c2a60709,2e95e198,85637d55,744e32a7,98c02c7e,b29f3bf5,7cf7c870,7cafdf41,f6710f0c), +S(45996af,5795ea6e,43e0fd29,671e119b,8b8d6ad2,4eac90ec,d27d5db1,b4fb6a39,2c0651f3,1c7d93cc,98d79d7d,f21110fc,8c1dd74b,f1ffefac,a3d52484,f8da40cd), +S(264559d8,7829256b,ed116900,d82d0c37,9f0e4d12,53c68e6f,cf2d41ae,7cddab8b,861a42e6,d92caed3,108439c8,fcbf8d28,8579ce50,c6350e19,3609b4b9,ffe217bc)}, +{S(ac13e0db,846df259,fc38d6,3b0248ec,9fcfa8d4,bcee368b,1f4a66c6,d41f9163,6721b0df,2ed06fda,9b485cc2,aa56f1f3,3a913e99,f6809577,95280451,9ddc96ec), +S(b6b7227f,228da269,a0e5640b,8a2cfa34,555ccdec,2243dd0d,4b2da0a9,b4cb5e4,6afe41f9,dc129d28,4786bb76,17786c8d,42597435,240f998a,f970620,90d32059), +S(460672e4,4f2768b9,842a98a5,ca8b90df,7d9f52bc,3fa2665c,4272d7ad,5f48b992,6d7f8b36,13b38fa5,80ed1d4a,21d196bf,be491b46,49c96da8,342441d3,f4af4ca2), +S(1d3d4ab8,b7c06136,8dfd612a,25f04016,2bd3f6cd,cd9cf58d,c11647a0,d28b629f,434dca08,17bbf964,eb0a316c,b2b0df20,eb2e965d,c4d8d795,1d4a6e66,5ed23d38), +S(9c5d6342,303bc7c,73763cb9,2e3d7069,7d913f6c,1a6e2f47,39470da3,22b7c1b,825c1a54,395b9b41,ccc2e3b5,3fe1092,f04c382f,b2ee3a29,fd59e255,5f22fc15), +S(5c751285,a4b55535,fe24fe27,568868f3,afb43cf,aad1d2b1,c6367daa,ac9493b2,e2388ab4,414c4e4f,e34a4c78,c869dd93,7094ce2d,4f4666a8,2eef8047,3b681fb6), +S(8c1592f3,8d73e277,d3c18d4,ee3eabce,32e86f92,2b27c2f0,1f50509e,74dbc211,399c9507,43cd9e7b,200c255b,bd25670e,cc111462,2d5dfacf,9dbebdb,53ee59ab), +S(85320e36,5f40235e,621171d5,c8008845,890f521b,d7e2cccb,88c7fb7f,a08200c,96bbe8ec,74b5f1b1,2a6ecbee,2aea6f0c,b6d0657,aac3556c,ddc4e46f,17cd31f1), +S(5fc21f20,13403705,687b8ad3,387a725a,f2e6300e,13d28403,569d4cb6,5dda7f34,bb709fbf,be95aeef,c00846b6,a4645b72,dbb4e1ed,866edb57,7bc5d9a8,2b774b0b), +S(fa40e658,588f8a5e,29d380e9,c1a6482c,888f53e5,e331f8ed,9b1273a,56d094e5,5486cff5,3b7baaaa,de8a51a6,1d1a9255,95ecbea3,39955c0e,172de4c3,4762eca1), +S(9f87d04c,5fcc48f,375c40af,3197c28f,c62cf3c5,10fcdbde,5aec79a7,4e6a6bc0,9a6cc172,23a770c7,a03b5333,6922170d,e9409f3b,9846b9f4,41832ae1,f70f5c57), +S(bb66dd5b,2f88786e,736b50,e536a0f0,3d59b86,511e95ca,1bab2cb8,875bb187,f8215527,c76a5af,e5e76a33,eb2622d,5f822ad1,d284c68b,c840f65d,4f731c63), +S(74d223e4,bce2d6b9,b2fa9482,46327e04,18eda6c,cfdd76c7,cda8be62,3f6dd3a9,b7276bb3,817c0e72,e1ab002d,50531065,e1c4ca30,9c6d6f18,bb5796ee,457b4270), +S(80298b62,eb4d3ff2,e10607dd,dbcacda4,3bb30e57,f3c8c7e7,6f9f3968,bf391316,fc72362b,48c8b606,4e428e6d,1ef2ac87,931caf75,e936a33c,228a5caa,c460c5f0), +S(8519f27d,9560acdc,509fddee,9b4a4a7a,8b13496f,14760a08,22609f3b,2ae07963,193aa9db,b98293f8,e70d7253,51d3893,a9f5fc73,6f3c8e65,28a2dfd6,5dedc220), +S(49d734f9,c8eff915,fd66757b,d6484bc9,548f20a,d8c05959,f651eb36,e45cb88,4c594f79,7651b49e,929932a4,59e3bf21,3e74c0b8,acb20907,697a25a7,ed21057b), +S(6a528c6d,19b1e28d,b4d9ec9e,19c4f7be,184ef845,1f41b322,e5932f05,575bcc4a,7350b90b,c22ab41f,40c13a80,18749e8c,275d3e5e,5d687df0,ddd47133,c092eadc), +S(6f3df40f,5647143f,cb93b23,4795d9a7,708db6b8,2e2df53c,f214de4b,61eebaa9,dee10664,54b625ba,34ce4b54,f7285714,7874b5d0,6b38b1dc,37b7471f,9208dcbe), +S(5abfd7eb,c4c5dc14,cbf0e335,f2e87e7a,7db96a2c,b78000aa,64fa8aca,517ee1e5,d65a98d4,20d872e4,4c43997,55cca5c0,bb94ccc0,b25e30fe,8b5a4fcc,7006364f), +S(1bf3714b,da04d769,782e37cb,c4a4b347,f9fc769d,a18e4940,d19a205a,bdd22a23,d0852b21,33b04274,183f4de4,9a20769e,4a08ea16,ca8782bd,84a4da7c,64c928a2), +S(773ab884,a4e90454,ea467caf,f18c3b64,e316468c,b5789fa6,4958f73e,ec3204f1,62213b85,b4838d8a,fa3a14f9,32db7d79,dec538c7,d872d9d2,be1640a2,4e367caa), +S(33a283d9,9b7564ed,6ed10d88,ba26ba,fbf3a375,e00e10d1,577fce27,2c204324,bf84dac3,40736625,cf0e6be6,98072c6c,5fb8bf9d,2850be84,ded3f652,569370d2), +S(62bdb467,596ffefa,22b735fd,d3dfd959,d4a6e187,a19d4c1f,4d647b4e,db380c3b,210a8e93,d1a184d0,a3548be7,6283d180,8e4f32d9,52834c,515953f0,4ecf9acf), +S(ef16d3a3,233f03da,5864801a,c246756b,d1356137,971bc164,b5512067,b369dad2,480e3d32,7f1df8b0,646c3b58,a51126a3,e91522de,ab77d6d2,f2bedadf,1219b877), +S(a6834869,c006d044,a9dcfb9,8a5a14df,86469fd1,fd0cba06,a4e8ec1e,1fba89d6,c1a3e0ff,7abeb1e,8cac11a6,8c1b4c1c,f663e615,9f508c35,f4747f50,84b247e9), +S(203d13c6,53a3c36e,55a836de,b38c7443,681d7b7,c681d71a,38fb0fde,986ce9c3,5d7dba97,573ffd85,b3fd4417,f09192e1,92461c4c,125a9947,ced9c737,ecac65b2), +S(c48819,b8f32966,bd50f162,30f5c0a1,45cb3570,d9c4b104,4c306696,2f4d6667,feb08ff9,1f543c1,35b6e0f0,b21d7624,91ac096a,181bf093,fcf8f4b7,bf6559a2), +S(31441031,ceabfbf8,59bcdd8b,6e177f91,df7bfe08,f9015172,1ead3acd,ab64acff,e36315bf,6f087118,32894704,8d2fd259,6b8beae2,e1917341,d690a1f,786db5f9), +S(e3e4750a,310c48,38920654,b6afa032,79589d52,74e48139,6e22d9cd,3c05fbdd,f05868fe,5452da6f,fadcafb6,69e5edfb,4b9a7840,3a305004,345ddce1,eaca43ac), +S(3659ba70,60d8200c,9512facb,5c730111,4cdc2b9b,aa5bde14,8ad9bf9d,d8f8fb8c,b1185617,f91fe5e8,ec68da07,138b6780,e1ebd12b,1bb44eca,8a1b9472,8337585e), +S(1a46b7e9,fe99a4ea,492fbc90,3281b924,6831fe59,9360af53,bde4ce8b,43ed5996,97c317e1,5c0e23a8,f1c11f7b,5f9c140a,af786b56,10ad8ba3,d11b12ed,17379f81), +S(f16a409c,677a40be,402f8efb,3752373c,aced053c,6f702b82,8bda222c,a412b6fd,d5becee8,ebacd866,285958a5,8b1cf1b1,e9abf9a6,db61435b,d9725187,135fa955)}, +{S(32c932eb,6fa35974,90a408a6,ce962d7a,ef2bd22,72cdaa,cb80f798,9836abc3,3e145848,c2f8197e,f0264d7c,370d1784,7d21a09c,77fd9f7a,73245ce7,2ce5f3f6), +S(49d837bb,63890b4e,8a4a63ea,6d88599a,c9961c20,80dcc955,aca6a101,bc935f16,358a7f6d,b540ac03,78d83bc,304cabf1,84c7580c,46c258ec,58f22254,e3e03aa), +S(23516ddd,40dab9d8,63dcad6c,cd325503,b783379,d870ace0,9a0b238c,d7b6b2bf,b1fb8268,a7814efc,54f3d637,88956b67,a3997a31,10a738a4,94786d95,a5fa1c59), +S(6b4e215e,df56e6ce,6378fa98,5d604f68,e3561275,788283d6,c40cb249,6d16310e,cdf9537e,e6f4304,dbcb9df,f8b97a71,a12f014e,29867e5,6b09b388,78c9ce8d), +S(f4f30433,c933dddb,949ad868,cc0d52e5,247149a,7ec98f12,3e7f63b4,acf6b7b9,949123eb,9fb848fc,d7b94401,a64b21a3,53fde44c,d93dae3e,b7a2d3d4,78055af2), +S(dc3523f4,cd24be1b,30787dd7,5140fff,b66e4487,55e9a3c9,6124fe59,c07faa28,47b945d7,6d37b855,8ede59fe,e297a8e7,81d3ea96,f0a81588,b68db767,9b9641f5), +S(b92cace4,e31dc724,3b3530b1,f90de1c3,47cc39e5,5b247455,a1296912,4e3c2a09,78f89163,c735cb13,b1d8fe7e,547027f,68d8f864,a1f093b,22c0d9cb,95fe28c2), +S(8f7ed1f1,77238a68,bbe32e4d,ae6d67fd,be07c9a2,9fc6b940,6ef81a77,65a8fb75,98e627d8,d32095bd,5913daa5,920c5c60,334691be,537b08d6,da5b8c19,7bf81c8f), +S(47fa27ac,e035176f,34c59581,8d3dca2c,a2b40e53,29756c55,7cf81f75,4f99316a,ddee5921,f381ce26,3634a34d,1b4f9513,4d9f0e50,5e96bb79,b87d98b5,282aee7c), +S(7584cb68,60ae81f2,e0df701c,97d7aa29,8132cb96,fee4ad59,15424bec,2e280dcd,4b76458b,e3926b5b,bf59ad77,da4a96c9,1f9147bd,88a234c0,74b0e09c,a6993228), +S(2cd4c11e,70d432ff,38550aca,481667f4,d09ad11f,9aed62d4,968492d7,5de28dae,82514708,3e5bf46,341177e8,9ad2cfb3,a215578c,52f9436,d3952432,e9acd430), +S(2b524c99,2b18a6e0,30863716,362d236d,e385a10c,3679eec,2774edb7,a1a89be9,1abb3b28,3477769a,5c7b4580,93efb22e,f2e61296,da90d4d3,1d6b2ff9,1766f89d), +S(d642c258,9d0e47ef,f5b2b60d,9321db58,727315ad,522daf58,3bdf35d3,336f1081,1019505a,994030be,484e5340,abea0b7a,51276c99,29cd1f1b,9d19798d,aaacf3d9), +S(3e5e09b,451bcf5d,549f1d66,b96da0ea,25e63270,dae59606,bfc3165b,f89f29fd,2ce591f5,32d57be6,4fc48aa4,ba40231d,9c104615,b76ed6bf,11957694,16d2f0e9), +S(4756965b,82fc23bf,64041d23,a23cba32,cb71d3e7,ef3e6c03,51b20f3f,dec049b6,75f3a293,eae07f4,362c47e9,44a78561,323244ac,bcecef0c,6ba2f5fe,d1933679), +S(f296e9c1,41694ce2,c197ba85,bb9f172,54fc0bc7,f89347,a0e92b8,58491a39,73c7fbdd,91c88ce2,bbcadaae,df8880f6,aff07e8d,3a1ce05,a468e3c2,3008d98d), +S(b437d387,ddae39cf,e26edc85,b0e600bc,2a199b6d,b521f9c9,88d921dd,7e6fc761,ce2111f4,d937905e,2af7f2dc,559f9eb8,bef286dd,909a5965,53c7f61c,f51aed18), +S(bacd4a38,f3e1b7b1,b601fa5a,2a579e87,459fd189,a607314,5a0dcfb6,1ad3c21b,8be8d6b3,9553648f,2a94754f,4c6c14,c4917296,aa9987f0,deeb7e66,d81c3777), +S(d8164748,8ac6bca,945fce70,e8f6a256,90512c8c,dd4c8fbf,b553c131,96f7f607,16b75474,65a80a67,86b5246f,e086d32c,4db03b83,58271938,41877c38,2b5bebed), +S(9c2b0749,cef57b4e,36b31328,e01503dd,ddbd2834,5cd86ca2,5224b967,1b7897d5,f020f978,4eed44cf,cc4aa33f,b2eb4b71,f24b5f3a,a8dc1d72,569bdefb,5f6276fc), +S(ea277814,9f0ab428,63b05bb1,c113ea7b,91afb815,e8f0791,12c11573,eb044e4d,8199dc4f,4e72b691,1c562ded,1220aec3,ab967029,139d30ac,58c753d2,f4548030), +S(4be6fcf8,40673659,5a9e4f2e,877ad7bf,28e25177,63d74238,6e43e6da,1c1c43fd,eb5456f3,d1c40592,2eec37ab,3e0d08da,b7cd257d,9babab02,44e5b2d6,a827a7cb), +S(3f1e9ab5,160733e2,9e7aeb6a,378d169f,9be5c266,a6462e2d,e736be07,f88c1da1,907fa0b9,814da057,9bb11309,aab51902,a0699aad,9422e1f,b8f1a8c4,aa9d4399), +S(eb730dbb,1ba9b2f,50453837,35ec6da2,ac4b5019,86cf03f0,3f5061e2,a28285f9,41dc3a0f,f42fb1b5,d3b464a5,6e305fe5,c60c4561,d6e5a6a7,8cba87ce,15c392fa), +S(aeac891d,f7032059,54d0bab7,41927702,1a595a4c,37bfc34c,5d315876,3e85f3ce,168f8260,1331b5c5,edf941d9,9f1cfe0b,72fd2a1c,3e4bbc2c,c62d47e6,6399105d), +S(667e04e6,daca6315,4888ac26,a268876a,f4b754fb,87687ca7,3c4cff77,d6dac204,1826a26a,cdca828,8e2ac81b,855a4d40,86f3009b,162fba82,83cb1d17,b9f7aa4c), +S(240ec754,24e46326,8e2e4ce0,240f335c,78c46150,1e18cedc,b32e3c51,77ade3e5,be09c744,cf6e9c6a,75976c03,530329af,5e11e5ed,3fb13e8c,af40bc5f,95872645), +S(7b83e4b7,70e7a442,3efbb501,c23881c5,2bbde4b9,d5aacc38,7071decf,79690025,d242ed74,441d1ae6,61b97c83,70be2f52,dcbc2831,1e8707e0,1b44c827,420dcd45), +S(63589c41,fa8975f4,c8738f57,579cc0d8,447218c,69da1a34,ee06af0c,215f6c27,c34f2ede,7589760b,80dbae48,94a3c13c,7351bf5c,33a35351,9988ba67,c2a56d48), +S(db092b0f,4638ee45,190473c7,cb60cfec,45c94d96,99aaf289,82d28af,16ba1c66,8a96ecdf,29ad2fd6,3a85a7fc,b73ab6d7,719bbd6b,98d052b3,3a0cd91,ab924f46), +S(11c4dd8d,3eddc0cd,9a832dd2,dc91c8bd,491fdb51,f5da21c5,732dfb7a,362b8df9,ba4c2789,740b53d5,51bc9fbc,776f049b,e848182d,9d13abb7,e7cd860,96911eff), +S(a65a3a01,df3b5ef2,e620d431,49fbe1,4d71457f,19d1ed35,aea39d57,89303fdd,86715f6b,f300a390,470bc272,6f12d389,7979e2fd,b0512c35,252bb571,fd19752c)}, +{S(d8558716,b7033a9b,29afb346,fd71663a,79b6e86,2719bf12,6e532dc3,f581b7d,a790d460,1e5b2630,1ad6ec43,62f79120,d75449d,8a500e2e,6f17c021,8037a405), +S(842c01b3,54353026,c43dedc7,8829ead1,db35b63d,8c4d0d36,8cd7b661,2eb5e11,f173cab1,a37ee0d0,68e097af,17bf859c,13bb4823,255abddb,f0dbeffc,573e06e7), +S(acac5cae,414c3556,38e293fa,e7cda051,18924e9d,abb81bdd,29123768,c7f21443,5d17b909,5b997254,5f56770c,dcb8af40,e37e1a8b,6e01a989,34ec22fb,f7d04537), +S(c8e73810,c024c6eb,d5398bda,3784261e,542279e5,3438d49e,83b2639f,80889aea,7a2183e7,be4f81,b0337993,935657c4,c55d20df,729d2e8d,b25af238,f3d85f4b), +S(f78c5f53,5e7ccb53,555a6f2c,b1de1c5f,da379360,f6a7fc52,eaf86ecb,dbb3bf90,cf2d33f5,eab2ee1d,5a32eea3,18f9927b,cc982fed,cc9add2e,2461ba14,9def0292), +S(4cd40c43,bdb8a042,2babc95d,eb00a405,59519074,5906a8b7,b5ea00da,b7f995f5,a0bd1c74,79125d2f,5baec520,21fb7c62,415817f7,2afb80,b2315dda,40cf4c4b), +S(647c5950,f8a7fe9,e6945b3d,6da91932,b486a4fb,ed903836,9fbc20f9,a849ac08,d331cf32,d72e148,b47af547,6794a33d,55f49ffb,be47db02,7d2de73c,542bbbc5), +S(97664e78,980a49f0,8269ff19,649e86cd,7da88a76,eb1441d8,a5f3fd2a,6ea335d2,b2898268,9a8cd91b,b1b16be8,ee46b4bc,252f7016,f72432c0,431f1264,8d7450a7), +S(523f68b,b39c2ded,81d22a4e,575483ee,d8748c9f,52c06081,391c27d7,7afe3805,5c331672,4464dc47,cc9cfe32,864b6095,ee8bd6a8,42c1af98,b3e33183,a46e2471), +S(cad866de,5cbf4938,989b835d,5aed958,cd7c316b,980b7c76,2109d688,d7ef5b25,3ae79c30,e77d6d4e,fe404b8f,324179c2,f677f434,8a1c4367,2a0fb5eb,b706607a), +S(ba065cef,b47170a,d6796033,d157fd1c,f22052d0,7b7f9992,6cd58e03,316f95a5,26177c08,bc535702,7f5d03a4,9d982637,d74a6b20,696be76e,742243be,b9ecddca), +S(27ca8178,be756f12,22cebe6c,d05310d8,5a6c4f59,eec71613,7777b625,e6d44c97,de547a17,ddee9fc5,1fecee01,45f9cda1,b65f097,5d1b9544,aa2317f5,102537cb), +S(bfab1d94,d04f4909,dee00998,78f77cc7,d9de94a7,96b5b770,5f3c759d,2ae97ec1,6ec39a8d,9e900a79,b8b88098,d1e5d79d,b75ef91,e442cb2f,27ea531a,2db21bb9), +S(b48a4f25,9d82242,59f08a08,29b05ac8,ae6b97b5,56cccb84,20a479f5,df92701e,beef137f,9f9acdc,8d31a780,2290fe79,9d9470a7,3c8a01a,35abcbee,9730d17a), +S(e3f5d307,ed2f2f13,d23ae5b5,9dd567f0,8161996,776d506f,b53e14f2,70a52370,40ecc697,7da3771f,32a66438,cf70ea9e,550194be,1af85a08,c8a4515d,32365803), +S(818b0462,d5a815b1,57216ab2,4d795886,17cc99bb,7a7abd91,655cacb7,ba99335e,c6ad05a6,7d2a391,a15b6600,7716e02c,9fe40db2,f82283ef,c9c0a7d5,ebe854f4), +S(7e3c52ed,23220b73,ba47613a,bf39a9fb,b3a6bb6e,22c972a9,3ef21a61,50cdf830,b3e4a95b,875719b3,bec1b113,9e29670d,4ba8f39a,2fb76700,f69961fc,bd01fa2c), +S(594e4129,9c1a117e,ce8564bf,ba88ce04,297f2e14,7ecda07c,5f12913c,14d9a5cc,60bd54c8,7395fee2,7fedccfb,ca9524a9,b5750b2d,d712621d,e73e0692,46c2e347), +S(3686bf4c,f387e340,6fc314e,f02c637,ee6f5062,ee9bb567,235b00e6,4d516648,915e5904,b106e057,a0db43,151ac9f8,4871e843,126d5285,337dc3b4,52c67165), +S(338dbd1f,42480753,516d3cb2,c535492b,72849870,a7828b48,643dc143,b966ea61,e51f11ec,86104334,9e9dae17,78116032,949c66c5,3c4d441d,3c88cf4,c7ad61c9), +S(56f935ae,f58bb403,7649198d,1a5da704,26fd944e,c5694c18,38c94287,2130215e,a9c48fd0,3b059474,e528016f,9c998e02,cac7c40b,8c859852,b58b9082,b638222b), +S(1faadcd3,da472591,cc723754,82546c81,c4f53c14,d0d8dc5e,ab95a58f,379e6899,5bdcc45f,42d0ba3f,783a0806,a5d08c74,a1b1b9f5,a559248a,8681b153,74e74958), +S(532d8cd8,fdf838c7,70b87ca1,4703a884,116dd928,74acc660,6ddddd61,8eb053e8,67a31325,853db4d,3e5877b1,c76e7e39,468d2d77,37cb8a6d,af4f16b8,17cd8ad8), +S(8a8cbfd6,d45e5740,aa9f0a21,f40e3671,ef897fe,bf2bf753,ee2d2f75,844ab648,d00eed6,efefa26,46c36895,3a54045d,96da4cce,8ffc554b,9bc989ac,2f62acaf), +S(38ae095a,3c705343,38e542ff,6789902b,cc1b0b5,7763cc43,2f50cd9a,d26d0f1f,100de239,87026f09,e483839c,fe9e1f10,11bcfafa,662a9331,95a8e4ec,e4fc804c), +S(82d9e5a8,385de1f4,fa541796,a00533d9,a3aa4656,74583d07,c4b3c344,b6ff8cb6,70bf2bd3,5765165b,a466171e,f26439e8,f790e178,f67ef5,d2e15e98,435b4261), +S(1843988b,42ddec86,dcc6c9ab,36b381ad,a0ca745e,aba36bf0,237e2830,579aaafb,f1bdc95c,d76337e,cb3cfd65,d9c30b7a,e7c7d667,65c9db5a,6130edf5,e240cec4), +S(a32f7415,9c2743c7,2ef192bf,4a68e838,97a86a0a,3997d1ce,fda3c581,b4fbe683,8862903b,db791be1,dbab5031,ca57f161,b6449bcc,db061438,f45e610d,50ff3bef), +S(b09dcc04,d9c30c35,2bd63880,a766da1,f6314287,dc201bbf,9605516,3db2a09,7580cf9b,7e30dbf2,8f72e9c,a5152ff1,956ae42b,3e952b18,512824c4,7f4e5b9c), +S(ca07cbfb,b24ad1a5,edd9a12a,8ac54157,6f3f2ba1,4b878d82,ab7dc996,bd7e2c95,5123ceef,cd20f120,b575dd98,43ef9936,c53cf90c,c481f340,fa166452,72af1c8d), +S(f8058324,c6b9c2e7,e62147e9,a41ad78d,60e3ecf4,17524c05,80832add,f11349e2,6a39f1a5,f577a932,3217e559,f15eeddc,af6b674a,9d921772,a053b960,a4dfd633), +S(2e3c0532,6255d80f,a42fc69,d5c92aa4,cd326a5,3e8535f0,435efb7b,694a09ec,ffe0076e,9a93904a,42251dbf,47d03e54,1fb75ac3,8f8499ae,dacb797d,7738c9b1)}, +{S(7bd8469f,80f009fa,b4960cdc,bbfbd4ad,d8e37bb,a4b2a34e,d5c95d17,7a94c207,f3062154,c3bcc160,b2aee99,aac98446,516a277d,85b37fe9,34be9359,4af905c6), +S(139b7c10,ce844844,f5d0a9db,bd7e1679,17b37e93,9bb6fd2b,4f19643,f22a6af1,32d4e929,27f5951b,ffa4ddde,4b091ec8,531a6f23,f1772c9d,ada292db,2b88c1da), +S(f49cdd14,14b38e5a,2dd34bff,3d01e1cf,ddefb954,2a641edb,df698d83,774ee70,5c10a6d9,200253e4,a932a42d,2e770f18,69d0336f,3c44f480,ce4a3305,83050c31), +S(ee145304,4771c862,745f03b,4776ade3,104ea0cf,eda8710a,5fa108eb,1e946826,b91f14,b6127808,f1175b72,2c09e02c,66eae622,109f4156,261d65ff,506b88bd), +S(c9ebbdda,867f333d,39142483,2e4150a8,c98090ec,d8ba9c09,3673330a,8777d790,c46d72c6,6028477c,e4754960,d40bd10b,b2defc1a,17dbf018,538b71b2,d208372b), +S(707bf0e3,9f2c8c6c,73a5d0d3,3edb32e3,46e73ac5,dbeef6c,60fb5ebe,b95ece24,adc6edbe,151bcb7c,2ed5fab,1cb9b2de,3ba2f3c5,ca762082,902582cd,e9e27f54), +S(4a002722,9fda7d33,320fc533,27b6c9cb,88a09c2d,e95aad01,65f68f45,1c82e2a9,233416cf,1cc1ee38,90816a09,17c5fd0d,da0bb8f5,d33c709f,6f1b07b9,916282e0), +S(8efefe27,b45a4cc0,3088b6e2,2a0baeb0,3e772763,58af3217,f39c7222,1e20b59a,b9f3fcdf,65771acf,cc7b7486,9b10bc3f,b0e8fb2,960cad82,24ea2430,fdad1634), +S(7bd3815d,6779f321,195047a5,b1772b19,ab29a99f,cc082e93,c442e927,b1ddb235,eeeb4bb7,480f3dd0,92e627a,a042533d,a9eb598a,6cd1ed9,2d75aa89,a592ae8f), +S(883f939b,6bc9169a,3860d36,9894c4b5,2863b5d8,d0348c4c,62368a94,737fc3cb,96e37629,c05b7231,8800ad96,8e922f7e,5b8a2c39,62a25210,9b3e4949,4b24934f), +S(4ad8cfb8,e8ba3265,4d32a656,76822176,95c40b92,e97c6d3b,af26449e,149f4b3c,491d3eda,89930ffe,e401b994,54919947,7ef33a8d,6cfdfb9,eb28295a,c5ce94fa), +S(ff15cd1a,4b185632,c6f11ee7,19319bd3,abce5167,65539608,b1ee3a4e,1671369,24df322b,ab157296,40aeb039,c00ab8,91c96833,4142f87a,1e00d105,b08c63a2), +S(3fc8e63e,995fda97,1d09d96d,4c84e18c,3e0f4d6a,9f8bca41,20c7c832,c4e9d49b,e17b239d,8e6f7fe7,3c4e46d,3aef9040,6bd631f2,da1677c8,db698484,85922ae0), +S(d88b3d3,6bfe995e,45812e9f,63e8b6e7,d5a87562,1c4a23b7,ab46f6ad,2f7d1e81,63079694,7c97b00e,311bfdb6,198c2c4e,eda57d09,b17fd74f,7140b40e,d2842d06), +S(da6971d1,4c0e9c37,e5b1379b,9cedd83e,218ba47,95e4af56,7956922,c64750cc,a14a0bd1,ebd0727a,258c1246,3aaff478,fcb490f0,53d08a40,44cedc97,61be43fa), +S(d098ccf,e2fee442,74377e1c,57d0b924,45f0954f,7af643d8,b7ed5d9e,956fba23,85c99754,17df24ef,2786621b,c0be5069,a9c59da1,61e14759,ee26b524,e9587d18), +S(633f9b18,9dd98f3d,8c4de,528f7170,1c9d5972,cabe3219,cc4e5f0e,e7e094e0,3d69c877,28c859e5,d9e8ea27,3c04ec98,ca084df5,d7c9cb34,9fa537ad,f7da0b5e), +S(2e14be9,af0dda46,8d59df19,9ac9edb0,c875f829,5715cdda,5ba3bed5,d54fcab2,a04688b,64c5d34c,752396d7,f864a9e1,59eea9aa,db8c93c1,5b4d7cd2,539bfa0), +S(adc92567,7678b197,1e45ed31,38a991dd,a4cd3586,a1ce1498,3ea30be0,642a2dbf,70f2c69b,7e47aa55,cab6ab22,e6482571,e8e1ea52,a52df934,d5ab99d9,acce2770), +S(ab89aaff,b04be186,183e8076,46c64111,476c552d,10df84ba,10a1efdb,32c01162,fccc1e20,17ac63a4,b9f78ca5,af245a74,4174c952,cfe29491,11ce1d71,e4be8f87), +S(1195576c,ca3a49b9,4db3f827,1ff2308e,66b66739,a30d73cd,e8acda4,a382002c,6a2be3a1,c6ae9f0d,b314a7d4,728977f2,17e7c7d0,199868fb,c7f79d31,6cd7d32), +S(8a15bed9,bfa215f5,42c62c89,da0adb8,c68cbc33,d9c879d7,a2f2803,b7068556,ef437bc1,1786cd73,6dc321d0,a3360517,3e7572f5,bce04b7a,3c8cdb85,cb56e697), +S(b4521d6d,f9b20080,4d3799ca,4cdc87bc,ea970d60,a3005071,e910210f,5654da88,c4ddf348,2a23e98f,b86ab9e8,4decc6b6,ad18d879,e96435d7,4b944d8c,f7cc1587), +S(4074523e,b75634f7,6442c3bf,ed9a52d4,5f6636f0,77a10e84,5e6ed950,b673a9ea,d8889a02,ec95b511,aa74db1a,10c91547,45b89b57,981011a0,9d4ce57b,e4e1f032), +S(b2e71794,e6ac98d1,ce532974,df79215e,bed8c668,561dc391,505e9e26,8444a858,94d8ff19,b8a74599,fbe5f471,e7f3e1ff,e0238cc9,2504f99a,9c4f5fbc,2e482854), +S(2e672209,8a6b4ca3,905a8910,6d23daf5,aeee63e4,34e7bade,70395df0,e5a1af87,708e9fd2,a3c0a3b1,b0e03f96,c3d477d2,abf6dc0c,bb8a7181,ca4b18db,ed12e3f7), +S(7ec0fbda,63fe7404,438e36,d567d9b0,bdf18b09,d929329b,24a8bc91,816fd433,f80ab84a,99d214fa,5d288e3b,c2b5560f,a1791412,9c3d16ff,cabed23,736e4f85), +S(f166252a,34572146,8bf3a3d7,bdd2c67c,b0d36b02,d7a70033,add26f97,128b1637,134eea4a,42b482c7,ad625407,bb89a615,656e3a2d,232f4bbb,a33660b2,403d6f63), +S(7af860e0,27d3b1df,aa0244e2,51f9459e,488afbce,6a3aa610,e5e223b7,81ba2d93,6ad22116,415c668,7dd3f4f7,b5a00599,bd35705,951e1093,3f85f815,4d0c8af7), +S(e4ad03b7,e01c5d04,7030fe59,6e7e7960,77d9847a,e604d2c1,d801a5eb,e21c0731,c7757ea8,f57af58f,b64f3eb9,c7762bc9,544f28d,a80d760f,c46b0c9,589019e8), +S(ffb2f941,f27aa8ad,6a59ed01,24e83bb,d49f2588,a5602389,15329f6d,f77220dc,6812c00,7dd44185,fc3f0687,6f7a62d0,d31adc40,c0a1a060,c67df13b,e4cd4873), +S(42ca15ab,9f245041,ce991e19,3d696f4f,4c277df9,8cad603,8ad0772c,2da6e03,972d10d9,37e3a836,9b831b2e,347ff11,29917a59,7ef94158,7c977604,73cb849c)}, +{S(576abbcb,8b768480,882aefc,81380709,831625a4,b9de63a7,b9c3390b,9cb4c7fe,b49453e4,6e17bbae,2f1f8f9b,91c3ed04,80d5f194,33917cbb,d28b878,bc6e6c4e), +S(f9d8a157,c151181,3e085c1d,ef2958fb,df2a17b2,6b330a0b,2d512c87,69e5c14,7eacca29,26aa402f,f8b78d57,f5e02add,91087da9,d607bb41,b56a40f8,f7b19b78), +S(d31dff73,7d2d3422,7fe39dee,b2eb4bcf,dc84bd39,d6cfc4ea,ff09812,23400a80,4af55e8a,fe8e8ab1,2e2c4463,d41824df,7b53e44d,efd946ad,b6128214,4244055d), +S(9ff2bce8,a9fe6c7e,e68a8292,f0d2f4c4,8d963c47,63018a55,89a2c130,667bc861,eb138923,94aadfc9,6eca7c5,78c0fcc,bb31a40f,98d02e93,a140abd3,cdf041b3), +S(1397cd8b,aed3c601,b6eee616,243a61dc,fead22fa,da50db4c,1f9e2776,6e5bc9da,534a8e23,59316503,cae233f0,3b6ef0bf,1c7e0105,119d1a49,ee688f04,40695c66), +S(4ee38986,511024ab,5385f710,42bc3778,7cbedd0a,ad13ba24,b77f42c8,2ae935d6,cf87468,24a38404,f313965,a64c927e,4ba0b7e0,140f6b36,47e2049e,35a74e4f), +S(7614cd7f,9b5f1455,74d0d38a,370f69ca,f3050297,10af5242,e5ccf19b,187dd189,b946eded,e4b72db1,6dad876e,396e836a,875d7c9a,28a9c739,f665c741,29ab7648), +S(67fd2372,5bfb445e,5254bc42,f7dbc1a1,65bd4017,cd1019b0,8a3f96cb,7b3c7cec,b556e950,a144febd,a81dd3f2,f729ecb,fe43fc78,8658bb7d,2b9735d7,b06a920a), +S(57572b1f,1f17070e,e9b30b6b,c7168cb2,4741ec5a,b3496b1a,c06ec0f2,5f910fce,8cfe2940,3dc97084,7ab28da7,167e78fe,f2310c83,ca476a97,91ca35a9,610bc560), +S(1f111332,1e31a294,cab4df73,5a0ef333,e753c2f,7c83705c,9a5bf27,1321c4f8,8fed26de,202c92dc,5b51b13b,6e9bae41,3c7c88d7,b858dd72,a11f073b,e2945f9b), +S(23c9e313,b04eebff,15fb0625,43de6975,d19decf6,6416f4d1,855083bb,d738f882,90673370,f380ca49,e876d5f4,b6649de0,24f4454,29cf9d91,96f4f196,8a49ed99), +S(b9251407,6ef7f01e,379aafe8,8f22c156,65a85ead,f671d8c9,89602c5f,804725e7,b3a9409f,7bf973b4,aebe08e1,5ac65562,56983f89,23415e0d,eeda4f4a,c0d7c5f2), +S(1bf9deee,948b3fe1,b4345800,51c67266,8fdb7af2,99275a83,706f9716,7e38e38a,688fc563,771b7d27,f9c09953,c40cf009,a55d7329,5fae0b7d,8fc37710,729a3911), +S(34e20de5,9d00dd45,19a70b3f,2994fc4,588ca9b2,beaf6afe,4a1daae2,10692f33,7804aff0,a43f1ba0,438c05ff,8d013e3b,e5180bb7,3a969825,fc97ef52,6da1b6a8), +S(80fc119e,85e88b0c,8c84d23f,9e44e96,1c7722d8,51d4c9bf,f1824fb3,365823ef,efee941a,a60743a,28b6ffd,39762f9e,437d2b00,206e718,7fc423bf,4eff0caa), +S(89ab0f45,e3860393,f24b1845,7578fe79,b812926a,6bff3788,c8baf283,89fdbf0e,57d4fc21,42bf446f,8e4d9331,659e7673,90391fe6,62e77ee7,f7a4886c,8f440c8d), +S(1f092931,664bb98b,79d8fb4c,efb287a0,f72641fb,1cebe711,820c92e0,42f26437,59f63ca0,b8e2e959,a97b1c1d,1cfa4c02,380dc42f,db7cb5b0,995ceba1,d7e45d94), +S(95ac9f36,f447928f,344eb4e1,9ea806,717600e5,148ad222,fdd52a83,86bc3537,cdef5355,e928b1e8,225b5a53,bb976822,6fb50d1f,6c6cde20,758d5ab0,e9f28543), +S(a9ce5ddd,9941ea69,1343ea71,c85fcd73,6269826d,6eda5008,44cdd1b9,4a66044d,29504563,1fcb7590,27d904c5,4ffc325,2ce3c8a2,169f4649,907db751,2ef3ce43), +S(2edf81,45c4bcf9,62425707,ccb36a3e,7fa1fadb,4062d14d,f78771eb,f3ec15d9,dcfc961c,547548f2,73206d9e,aa0d829,a235f66c,5afbba92,68fdf9e6,abc8260b), +S(fcf5b985,c935e207,92907b93,e9976ceb,ed320a14,3cf286ad,b38540ad,b4077dee,8a0e0b4d,1ab114b1,caf7d0d,f749f219,b75acea5,6a71b3f6,aa18557b,1da85262), +S(2bd4391f,42b70803,2baf4816,54569f48,95f1434e,be6f146d,41447f45,f14581b3,dbc9937a,61f43af7,42635810,5cdfa02c,49a5186,ce67bbbd,7ced2842,19a37506), +S(eb00deae,6cf69ccb,abe6b93e,e5493e05,d22e53c1,b069a6c,4660330a,4e3bc069,18002f2f,61b08dbb,60c784b8,4c6d71d4,6b004e6a,3089a0d5,f853d659,83242d9b), +S(c7c62a5f,ce15326f,25b2fc5b,697cc7f7,26d231e9,e7e9f15f,5998b8b0,10605524,8ad4b370,ea0506f6,f25eb16a,78f87ef2,f408cd17,fa4ec63d,4ee21448,1d5286b7), +S(aa1c2baf,632673de,6f6704aa,5a76c077,be0c24b5,223de654,88d1386f,15a1a002,de4648e4,fda7db79,41efc5e8,6fec516b,c6aef164,62d6dc08,fe93ebc7,a85261f5), +S(11871161,13c3c670,e7f5366,edd22282,1f76ec98,d1a3500d,f0e483d1,e53f2666,d0042c9e,8dc1d72c,f53836f3,2c76b5b6,52fd5ec1,9e8fde42,aed1a7e0,9d242745), +S(e232a92c,9ffdabcf,24422182,34078534,6b6b79f5,983ddd57,2580c3df,e4ee4118,6c1144c7,471342d8,7a784fe1,587ef576,483f8980,bbab12f9,35aa0d84,83c1d76d), +S(1ab6237,3998ded,e50aec45,8043f830,8a7b4564,2dd3c9bb,4804f98e,a7c2e0c9,5528e158,6a23aec9,81f04b51,b90576a9,a9e7feb5,53200e51,e604898f,e55996f3), +S(3bc24bc9,cbc58de3,46644de9,b17ffa7,39a0f7d8,83eb9f52,af19eaf4,d8d52891,f71cf5b,7587c275,8014127b,f404b70b,b257bad7,f5b78d2e,c792e1d6,b2fa4493), +S(a2bf9afe,e6eec182,ef5866a,b4bdfe2e,9d045323,343aa422,8c1a13ae,fee515dd,a5ee438e,3aa35484,c5f5a1d5,43fa15d7,ff0d1c55,6571678b,a3c5694e,f93cfa1d), +S(a0b2b4f,ed0ddd23,8812806c,fccdfa9,7fb3b42a,748721ae,6477dc9b,18953133,325ee7d3,4a540d0,fc3e3935,79ba7372,905c7b17,4f12b456,b43db5c7,cb50ec66), +S(e7b9796b,5ca006d1,632f482d,7f0fe393,2cf16a5a,e104eea7,a7ea1c25,1073e879,ed476773,e6e961d0,20bdefd5,8c833e35,634a40da,1256750c,c718ef75,45575e97)}, +{S(a8565dfb,75f8eea8,ca9ca6e7,c7d18a5,bf3e437,5d1f4e87,68d5f51a,57199ac5,daa7d7c6,cb86b215,a682141f,2308d9b,4c204196,eb779f32,fcddf0a2,da194921), +S(974619cb,86016199,20f507ee,62d10295,44abdd66,456952a0,54e945bd,7890250f,6c8d8bc8,21da8234,1ffd0cf0,548be1dc,a1bb7e1f,47354dc8,3e5d96c8,2c9676f3), +S(24bbdc24,1396b6e1,75f23a6,4bfb41fe,f8329b80,d306586a,ecb69e41,2a2014b8,aa6448ec,f00a0710,27b46f09,d696642b,9274ce3a,11a3e986,e84536e3,7fd7b2f8), +S(eed9a6b4,68004486,e3bd388d,591d3b65,2f35a3f1,9401e5de,81a86f5e,b7cd972c,c81f9aaa,d7300671,b3dbdd73,a095c79a,d73ffbd5,9f845eed,9fe3a57f,a41e9468), +S(5260e0f6,fdc6858a,8d519d3f,6c71929e,36979b65,431a6f3a,a7507797,e54654e2,5af860e5,fbcf9676,bb00c329,d3e2e058,efc860e5,cb9006ad,224caa32,9fd49f07), +S(11e53f67,d844c511,b8118f28,de6ed9b8,66b70bf,214d4d1,ed79adfc,18f7d6bb,20dd984d,7b9eb626,77e411da,2e823045,685a4bc5,2a3f4e5a,3aedea95,1060b330), +S(98c9f3f6,81e220e6,d4bba711,fa8b212a,dcc21bc4,8219b813,eabdfac5,70e6fffe,bd0890be,d9cf4ec9,44f6abb1,56250329,a37d2cc4,64c931ba,8606c2ce,55127aa2), +S(f644f4f0,43d7713,ba4380d8,26ad0f3f,44106352,142fef13,7c6e05ce,5e9f1571,3192280b,f3971223,c00ed336,94779866,536020b6,79ba8cb5,c4f9c515,69d2f97d), +S(334ab869,32c4097c,8d8d8a23,d529b079,6a759d47,a907b047,548e735,5b3b766b,18f11736,d54c9d00,89149b07,35f5a9de,b15d9c,cde4ee06,155a4f3f,de98a7bb), +S(983542dc,61b43ee5,c4a7f36f,22da008e,832d4eac,6791d838,1a095d0e,6d8a14b5,cd225f2c,334d1ba9,94b0a681,d6be7696,16bfb2a2,426e9939,d2238cd4,43bebd02), +S(dbbac008,1b678270,4a0fcef0,73683822,a3d4107,d7f1a71b,41497da2,9cc942a0,cd25ef66,36f21a8b,532371ae,b91b67a,deea5797,983dc36f,54aed202,d9845515), +S(477949e6,9ed28a74,879bc8cc,660696cb,115e6392,5a63817b,60e5187f,1f77f3be,dd8ca490,fb8e3bc1,44f5fe9f,aa41ce73,56a1dce1,cc8e11c3,ca5725e,d1b764ae), +S(7616b9e8,b451d4e2,e4826586,9bfad6c8,ddbf5fd2,2342c6c8,42d6bbe0,398f94a2,4e3bb1a9,76efd345,3c4474ad,e6a494f6,4f97c6dc,c98cf68,72bca24b,dd9e946f), +S(b87fb86f,6ec4ad7d,5bec3bee,e8d68618,c8e4906d,1c584368,ec819f2f,871ca8c3,c64723c0,aa587911,4dda9c75,493f739b,e8c2221b,b2e75ee5,b25def54,a1d40c2f), +S(56ea4572,61a6ccfb,46fced99,1258b31e,8573a488,aa53b7ad,65333452,b06d41c4,d8529601,4145e12e,a72ae4d1,5ae6e5f6,9cc88ba1,4d79467a,3df3bfef,33d84290), +S(e4c6540a,19682e0d,e1f1258a,103037a0,af4df5ad,f27cbb7c,9e3ce67d,e23e13d8,a31e1b08,4bdb5728,36e53d93,1de035,c90b1efe,b5343b23,cac0e7a2,bf5b3868), +S(1902cf3b,90fae93,1855d758,24995b03,e1604861,199853c6,ece84903,c8bd67de,3b3d41e3,a2dd4c28,16d492c3,e6c53c83,e5203c7c,a8100d41,24cbdcd0,e12fe222), +S(6519f4d3,b5d731fe,eada6806,727623a4,daf924d9,b6337a51,56096ec4,16ab42d4,62e2c1ea,afa990bd,6dd91675,e3b2d1e2,acb2fee8,e56ec30b,eb25bdce,2d3ad30e), +S(e1128682,519b965e,a933f197,eb0997a0,16114459,4c0915cc,9c55ea4,a30c1ad1,cb1370ba,f8707c78,84817ee2,8227da3b,7b7c97c8,266af491,e0d52bc4,ea0f9614), +S(4366960c,6ff595d4,143d4cd4,f0f0df2d,3bf864d5,73790abc,23419c7d,6ed9201b,623faab8,2caebb5a,b4c42bf6,b2a686cd,4640cde1,a95a65a1,f8d32836,9e5ee0cb), +S(5acdf691,3c1e283,c1220355,6efd99c5,d347ef69,bda1d040,44cbf0d1,ae41b16a,1bca567a,71698c35,e35e031c,e8a98dd,e34270d1,4e2e2439,9276a7c3,6a1f35df), +S(807ecc04,81aae374,1efec46c,8c6c194b,faa0607c,cf5b7cda,fc270fb5,f5b416bd,cc60be6a,6736dd94,848fbb05,375f6459,d556866d,165a2c16,41984411,dda33fc3), +S(29c470bd,97737284,765adcaa,68a98af7,5e6c275f,fa4fcd5d,6c71d428,bd3bfd79,b19ab40f,33c15201,41fed31f,681f176,4a464373,23283677,a40b4018,99a6eec0), +S(41a6d6f9,40bb8abd,9e8748,dcfd23f0,5333eafc,4ce311a3,161440a6,619efabb,b2a3702e,900788cd,bf35204,27e0facd,b090804,62f65418,89a3c34f,ae2cc008), +S(d5f5096d,776ffdb,f694b9c5,c9a9ae0,ab5897ff,c5ca3320,82cb2a2b,8afcfe89,6461e24e,28560d11,336244da,2038e13,c69ed5,a7a435a6,d07a1d72,be43daa0), +S(f65a00d9,5707ce6c,6bd55e8b,4b0ef381,1eca65b2,9845433,d7b307e,518ea724,7ae079e,9aecabf0,4ec5210a,b85328f7,e60c8ff7,3deb037b,c8e6e1d3,34774734), +S(346cff42,23c9ed2d,a1082d46,eeaff341,f7866e72,d95561b9,678def2d,9f7cd187,f97f85d8,92002750,11efcc9e,f8ff58e4,894f105f,b94e7390,7e185806,575698b3), +S(d0e3cdff,a47417f3,86f64a2,4029e3fd,9bc7a464,6e839bf9,232a0d50,349ecaac,5bdbecfa,2a2b35d3,ce2e9837,222535c1,57ec5bda,5fd70186,1920803d,a279989e), +S(f6bbbd77,b8dba8fd,704a3f02,1bc418c0,f8524c49,ccfcd14d,fcbf7f04,c9a18d,38184001,f39b257b,6755a132,86bdfd92,1a8ff771,fdd5530d,48eb8227,ea70be1), +S(6717bbd0,f019990a,c01a2996,e34f0912,9bf60a3a,71d8124e,fd86c777,9cfad879,9581f790,a16825d8,f44f316f,db3f0bde,108643cc,b390bdc0,75f3dccb,6520029f), +S(417c765,ca91a120,2b07459e,3713d5e1,bbcdfa82,bbc26cc9,279fa2d2,59251fa2,8d281a2a,ed38a80a,cb697989,9839d7c5,265b4e78,8a9e1176,66cfb6fc,4143a935), +S(e2f349b0,f89c69bd,3c8cf2a4,10730dc5,8e0beed4,7048c58c,15f9ffc2,508d2cc2,e014d0d7,f07d8dc8,7e79f513,89fdea45,bdcbb417,1f63424c,81cb8426,1f2b3be0)}, +{S(aceb57c9,187a5202,118c4dbe,573906e1,646b0325,781c1352,574ed15,e02b87b,68ece7f4,4037ff05,d4b89120,d90f08c6,f0499fee,d4e9e02a,a2e68bcc,2d7b70a), +S(365e555e,de9130af,99f996b2,106229c,c36c1ea5,8b065cb5,38af3a5d,2cec1145,81fc523c,b4b97bd3,cccce1e1,d1980769,fbc25a9f,a403adba,8e7e8074,13c87f9c), +S(d0a3812c,b9244d7b,c1f5b652,adbb0df,22d15d41,b1724071,fd297d00,bc8cbb01,f8d7650e,fda2be30,24ded196,eb3baf7f,351d2013,2479640,16ee4c6,b469951), +S(8f4ce1e2,a51c0ebf,f5e34cb1,c6aedd87,85e415dc,e7307119,143bbe9a,3e7fc632,617009a,ee7d4d81,1ba2bf14,d1647911,bf1a3bbe,cba8dfda,9030ead3,803fc217), +S(ea23d837,54cb2e9f,9b884ef,f4d1a708,bc1826c6,59fea53b,f52c51b4,9fe0e21b,7e8c691b,cfc3b7e,56a7699c,4f56a11a,fca5710d,963d602b,b102e1c5,b36dc3f7), +S(e3c970b2,c764c9f4,ad8bdc15,cf995690,807f5d09,4a849787,9d278d18,eed6ceea,aad8c7d7,13ce5439,b9125d9e,c14b5d8a,1c694cfc,f84e6922,b7e58df1,4ab8a34), +S(8ade30a,94b236b9,9597be14,bd421130,b6843895,a85f3613,efcfa0ce,9781a96e,78e4bf57,974cfc0f,c310330e,6aa47de8,2b0f5009,5a703fa,50093d5b,a8e8f0ef), +S(fa5f1cd3,4427d71a,de7e79b2,b0a17ba9,66d05324,1f9996e,be8143c1,9186d24a,3481bd18,2319ddf8,f344e4b0,196b3ddb,10deef4,d8d75c0e,49fc5fe4,cbd6e1fc), +S(8b88b79e,8cd28dc8,58e3f1a6,155146b9,af1e3697,d57b7435,c649f6c3,bf8574ca,e736106c,8ffb9bf4,d83d79f2,4faf8fe2,ba5dc258,e4ae1b1b,b58a1a7e,4922c95b), +S(12078a5,5c46d721,96a148d2,fdf6505b,d059e423,c5d5295e,facc2b82,aec51f5d,66a4332d,cd265085,add9a141,2fae2562,17441d7,dd9596ad,46309a0d,bfb4e55e), +S(841523ef,29f5bffa,b31a526d,bf74b16b,fac3a3aa,391f7404,6675cba8,7808c171,7a3fc3f5,bac300b5,7ef843df,e334c995,cf66de11,2283fdfc,767cb57e,e7e7329c), +S(c8831ece,f4545c2b,387378b4,f88173d3,f1cc7db9,d064774d,60394f0a,ecaf5af6,f32f1a48,bb802757,34e66cbe,58a3ed3f,adf28dd9,374a42a,a824a095,6701322a), +S(30001ff3,7b1b1691,9a135a31,287e3a3d,383ef3ca,94748e33,a52c146,586dc4b9,9d71b25d,6fc35db7,26b58d1f,642dabb,46dfa64d,e0ec2a12,c53c414a,9dd2574b), +S(a17d3621,74d3c789,c4e00888,fd4b0f4e,ea3929cf,afea9e9f,7439901e,d6b0fe44,2bcf09ef,2d374194,510fc057,dc973fe1,bb687428,91e9056d,a5b4df7a,de79bf), +S(4725e2cb,19f95359,2da72565,d8405e09,92a64299,9ad74ed5,b41f5d24,44cb6b0f,be23fa82,7aec3121,7b90028d,b61d1092,764b2824,9f3fa0ef,91929db9,b2e0246b), +S(67c560dd,74c276c4,df3efbe3,b95dca4e,a56c4563,cc7ae225,ebea90e0,f5e212fa,2c9e3120,d52ef31d,7e9e36d6,eafbcdbf,ed8a28c6,7edefb94,1df7f38b,cb05c160), +S(8468da98,7b33b79b,e08da5fd,57cee298,ef86f624,3bb975da,2f4261e8,f7531d92,455d8a8e,b4f45693,2e8b6f77,ddefe070,591dd37f,d6ad3a27,5774055b,8a63e650), +S(3416d4bb,78de7570,b1e9e912,83a3e8fc,be6524d7,4463dee6,82e84e52,72c0953c,94e55458,2c17fffd,321364c9,16658093,986b56,f88b4818,129e19c8,ce685dcc), +S(5c66928c,a39a6e22,672c1dba,8bb6331b,41a7f43c,a72276a6,afd3e209,6416a9c5,181cdfc4,15e7d6a3,c24be94b,7fe328cc,ab624c0d,dfabb1b8,f9a73b56,cdfe1b28), +S(971f7a13,210680a3,ff6a12ad,17481a63,ef624d0c,e4121166,7e63aaf7,9cafce,5de2fd1b,3149e321,2980c7d,88a49018,26f83f18,7438061e,9bdb8d33,6a4b08f6), +S(650277a7,9ae7682d,c5f3526b,8411342e,b48277a4,9876caa7,61ec6815,9a1f13c3,a903255,fcf09808,cd97d92a,26dbd2e4,7a29571f,ae91107a,7cb6f0cc,3aea1985), +S(76a79cc9,7fb80ab3,e8d31e5a,d11f5ce4,74696d23,f1ee7aab,3928848b,556f483e,1779bc5d,c763d1ef,7611b402,4583f07d,c7dc9c96,7afcf83f,e6b6ee42,da75972e), +S(6e0b4015,474fe250,d372400f,13efa0b,70c4e8df,816c0e8b,8d27a7,a8168d54,f01dafc8,8178dcf7,15f8fcc2,e7163137,9e1dd4cb,6c88cfbd,e9a051f,ad204c3f), +S(ee5dd472,b5efeba9,d0e354dc,21228d22,40a69088,842d00dd,6b6358e4,309d1f5b,bce93ac,3fd4a098,9e74448f,5832643a,a2a172f2,eff1e2c6,c61ea99,cc6e7cdc), +S(df99a925,ef2e9f9e,57208fe6,5373ff94,876b1448,368dd453,436c59d0,f2a857e2,88dcfe81,4397f990,56f92a27,143c902a,2a6a66f7,f7e9652e,e0b16f13,33252a1e), +S(9186f095,43dc64db,ad582561,cab96a38,89be54ad,e1cdb27d,674af836,22b5d284,71ae31d5,a73b29f,54af1aa3,2d8e541b,14f7cebc,9279ac26,c846d466,aa975e20), +S(645da454,63357bfb,61b5b932,1897a73b,87af6077,81487bc8,af1a66ba,49bc5e37,4b925aab,aa7bbc19,5963025e,f1896cb5,b6463242,cd8a35f3,b1b404b0,7faf8e94), +S(5cd9a6c4,e9d372db,90a65f11,1f1a1b5,f28bc3b8,3d05f599,39979c91,5277eab1,c147420f,7dfc4ef4,d7d1f08c,1c523771,86a8d7a7,10cd7017,82b97c55,63287aa8), +S(4fd699b1,2c720ccd,7b977e5b,dc622671,18ac3028,bd635b26,fce648cf,335cacbb,3936f10c,aee5f51,26b86240,3249e1d3,5566714d,17ddc19e,cc4d1056,71e523f6), +S(b3fa0545,83510d6b,91226711,4bac7f4,ba4ae5fb,baad7230,3003efcc,4c3c18e1,57a3db8a,6cbf0a94,845e7d67,f9b01902,55aa5b66,ef31abd,34ee0410,ed55d0e0), +S(fd73c052,b194c6c6,dd46aca9,d640981a,ec796009,17a565eb,e77fd534,649a2115,9df8973e,37e877bb,fdf5454f,d9082926,fb09fea9,d162bde0,fb635483,59458f55), +S(2982dbbc,5f366c9f,78e29ebb,ecb1bb22,3deb5c4e,e638b458,3bd3a9af,3149f8ef,59e4a416,5099ddf5,4605acc6,384a4362,f6a2466b,ed1c127b,a918d94e,e93859e7)}, +{S(8aff982a,fbe09f67,6d6e0f49,e2b68f88,8f20dd2e,6387b420,8157ab24,d19027ed,f2350ea9,d00fd861,41259f03,b51b5326,6ce05a34,74508bd4,31ca74e1,366eaf92), +S(27ff285b,1e14961d,a042bd31,56aa44af,5e73717d,fa413a47,b300f358,e1960dd0,8b578851,264a8fea,2e29bbcb,cb9c90e4,93e8c731,983f4bba,65381e88,bc83a8a7), +S(fc6acf61,4a214859,1418ab5e,e0f0274a,309a8248,2cf01f73,db8a9790,825486df,190b9c0d,46953d99,c9de2bdc,bcc15d23,ee90485c,c4c152d8,e28322e5,4c927d54), +S(743bcc6,ac86b0be,a25cce81,1fdcfc13,73f23926,e3116fc8,9415b8c0,4c1983ac,f3df10fd,4afbd3b2,dc0678c9,102150e6,3d005680,6a5e45fe,c95ea495,9f2b8555), +S(bb165428,2c13362b,b1e017e6,6402613e,f82bbe22,9429f29c,6a1a522e,4956d67c,ec542c4f,7fbf3c6c,32e71aaa,86e3e4e7,e52b0d43,98589e15,1f17417a,40b31b07), +S(b3f74ed2,5a7fd474,5820a2f6,221349aa,e41af762,25c2b706,160a463d,1d59e7bc,a9af9d2d,89dcdfe0,21ca46e8,5f09bdb5,197c8f23,bc56d705,851974da,1608dad2), +S(20c0914e,f88902a8,6af0ff68,a08f96ea,25f15ea6,b1128900,120028a1,1049a77a,339567f2,71a1f1c7,16eb1d56,2f009537,68ff4cd3,9a81c6d9,6359d2f5,5d04db9c), +S(a3555aea,2e96f05,d25a145e,4ad0d2f7,fb453974,8c4a3097,a703c0f5,404a0e7a,ee236b76,8fa04380,b0448beb,d2589665,e43299ee,b9fc78fe,5a64db69,ac92b7df), +S(37191a66,1d2a7bd,c96a0767,ce47d97d,7acfb8c0,ce251e9a,1421e2d6,29230c2b,57093393,4783afd7,2df6524e,871c8e67,ff2f48c9,c73e2054,fb219cf,d3c2a68c), +S(1a2f5b6c,5fbe300,8b01407a,b0b28c3d,c823cca9,b4c71a1e,4fc814f1,e186e062,b2f1c632,a9d92a4c,82d31a55,f4fd50bd,d53ee99a,2e1452a4,e43e5ac4,b8cbb7c6), +S(2976575c,c5e70e47,cd9c10e1,32a593dd,12b65215,38613cb7,22390022,73fb41d0,c3f0b08d,a2a3a046,d87dcb13,38c35824,1a8b9959,e2567543,852dcf73,c4f5cba2), +S(bca28e75,5cd6ab74,85884b30,ef399f,44188695,fe9c4143,6016bdec,25d502f7,b67538d4,a571e935,cbefe237,c5a01f77,4ade337c,fec9f95f,3e9cf042,f0dbab6c), +S(3dfe1718,beafee83,b858048d,25d46ee6,7741d3bc,bec1e52d,3ce308cf,738b715,8499a8b3,a0c7c599,f62f056a,a8364494,ec6e0198,2c47bbf8,7e2df591,de0ff537), +S(bde6252e,a9e4823f,36bd1737,ce188fae,be4a271,9984c9e6,76f9f4ff,d070c1c1,2e5db82d,e02a1fe1,39d903,7e7adeef,12d40366,de0eb164,c04b2ef4,b1e849b6), +S(2c74b766,eebac93c,479fc0bd,78a3805,de50be2d,a6ad70c6,9048e43e,c91343af,ab7a929d,588ff993,55094f83,6e7b3b58,c6381bfb,b284f9bf,7dc44cc2,67cc741c), +S(f0e084a7,af9abfaf,b6ebf3c5,b526d545,b8b1cf5e,8e09a06c,3670aa37,6af83a3d,6bb279db,abdb2b2d,fcc97510,2b075dfe,b42d9e6a,5a8af760,f4b63788,c315f8dc), +S(715aa28f,4e52fc26,a2f4b9f,391894b0,6adc3b69,b508827b,4732396f,5eb7edb5,c5d0d68b,3a8c6532,2f6303ab,99b6c48a,88572c4c,56c780d1,d51d2441,86ba110c), +S(8f980e69,3511ec3,cca89b2c,362835bd,24d9c8a6,97deff86,5540f7c2,b0bacf8b,2d5e8470,f2041ca6,f158ac83,e92a2345,4059492f,af27ada2,92bbe51a,d67ee5aa), +S(6823a4e9,d80838b2,750dada3,cc31f59f,3cc9d6c8,3f33aa5,38d949aa,c4d6d657,e087127a,3ddc19cb,e4088a2a,6df61863,e8e81cf5,c5cea4a8,8cd2ab51,bfbcba8d), +S(8c9af14b,11add28a,818f85f3,276d1d7a,1e3478f4,23e74b72,caaf2440,24558538,a7c17174,da1eed2,7eeb7b6,c1d93e4e,9e4515c5,3cd888d5,e4527cdb,94a64fb1), +S(5fadb7c4,74b13592,a1a27f76,b7c2011a,102b66a0,c6ffbc02,a7306e1b,a9ccf49c,7bf61c4f,134f8b4,7a5f90a1,938918a1,4d151f2c,7f1c4bea,cb8c4773,cf11609d), +S(79a21b82,9325fbe5,c01ac979,8b89cc47,379eac4b,682fd747,47e0c04b,879b404d,abfa4d5c,7ff916c4,9f489c12,5235bd9d,a0395b6b,84d6699f,c96f9c0a,5a4cab2b), +S(b213d11d,e4b5601a,5f10827e,d39a7825,adc36bc0,1130a055,cf8b3e8e,fc96d10b,27c0e5b7,a739fcd0,5eb73321,3fd1bbb7,873de0a1,2b92cbc,21de57c6,2bc812b1), +S(299ef8e,e131f523,72949d7e,fc2f0f7f,9965e69b,56725b55,4d513435,ac8b0b3e,8ba93fa0,2a4d97b3,54d47c10,d5d791c5,f724b68,4f501eda,1931e563,2c6faf06), +S(5143ab76,43a21de7,7ffd0f3b,c4746fb0,589be22d,9d9ca2fb,89403a39,86d1cd37,20991000,a7c01e4b,26d9236a,45568bbd,91c968d6,c87dbe05,15063af,d8db5a03), +S(738ce787,49783066,923ceec9,a841d60b,56855e09,93e67cb9,9d52a0ca,7a64b5b2,aba44aa,272945fc,5eee0330,976b659a,a6455dde,feb5c894,cd274414,71610384), +S(6bb9bbe0,4c3dbaf,6c60adcf,5ec5fa59,29cdb04b,14633c10,5dfca2c,183e1d97,b7dac59b,5c35c3cc,15521da5,89c0d333,9dac05c6,614acaf1,d8b9e834,8e02c3c9), +S(f325eeb8,49a32b2a,fb19491d,8c3c112f,a7ca3443,438c8c19,99bdf791,6981472a,169df94,a26f26b1,e5aaf810,7a148faa,17742c3,10cac320,6daa69,f8aad67b), +S(d279bc0c,f7f58a85,b5abbe25,936d5088,4d8ae8a4,b415ea30,2c0f1133,de98603c,1e69875e,2e38f9af,222e03b1,6c833bd1,12bc10f8,1724da7e,bc780e6f,5228fd17), +S(224d079c,750eb1b4,2d70aa25,5fa0c3fd,c2d07c1d,ae4d6cb1,17c1e61c,5ec1c6b3,e54dc4fa,b0e05362,60d27fa7,ba53c37c,a37ce30e,617365dd,1c58a59d,2c93ed00), +S(f4741ca2,b3de5414,49426531,d546272d,ab8fc55d,8f65eb3d,5ea780a,d25cb53b,3b7290bf,dda0d0f,e3704f27,d8537063,f2fe9571,4a0791a3,e1a25865,96a5b0b1), +S(e931258e,8eb5559c,6d697272,8a704c17,b775a26,5b4527d4,a4d4d742,bbfd71fa,4e1ccc9,b3c0211f,17a14be9,636ab4bf,4c6b931e,44a1ca0c,c2642f2b,e8b2c928)}, +{S(fa01dd32,fada2843,c51845e6,3cdc1b76,79dee47b,d2f4b767,5133aa5e,62029057,6ea6596a,b0ea0201,b6c8bbbc,e9d07fd0,8040e1fa,198c8767,67ab6055,34a33), +S(97ec9d33,a9d88115,471619b5,3fc58a08,e6997662,7a28afc0,b75b2f49,55eba300,92ad1d6a,f8a0a100,27d9ba90,4f7fea6a,571f3c32,53393a7c,79abb0cf,9a558390), +S(ef364ba7,626d72a6,87bc9776,3f2c0833,50640bec,6ff4d80,9dabcf2,9ea9145c,7f8d7c48,1bd80ff4,8eccfa9d,2de5eeb9,800cb98,c02da539,3b3d6c83,8fe4a2ff), +S(45961303,a778b47a,89109231,3242304,30a17859,7d940e9f,fc2f25bd,1be61c00,5fa356b6,daad2b1d,7bb19cce,b9148d31,58d2651a,b4b436c0,b99193f6,61cb037d), +S(8aa677f4,d73c0725,e2163e5d,ed3dc312,7ad5ee29,f9bad8b8,5ab8f50d,ec6d77e9,1fcb9da0,d3fb9bc3,3a45bcdc,50aa2ba1,16c2b05e,836b539c,863163c7,2436c334), +S(8c6b2873,33082bf5,a3597a26,7cc14696,2b689f20,59caf1d9,35972c98,9b14c86b,aa86d282,a1107f8e,21307e0,2ad1420a,a4061fea,3e3dd6f5,9b5d6900,6bf4827c), +S(46c963f0,3bdbf433,cbd60858,5a4d659e,9815c286,9f684eaa,cd879d66,ceed05ed,be2a8d60,636c5b80,e443b13a,9e21c91e,90a9e781,1c35101a,dfd61a49,88193e86), +S(cdbe43bc,582f3936,314a88f9,fa21b29d,f4b5acf5,96cdac3,4667e9c4,b02b926b,8f2a5b62,4f20b20d,cce97348,d73d5653,8651dd41,dfedd476,8792fa61,1bac16fa), +S(6f9c5a84,1ffededc,ec45dc63,7ad15aea,207116aa,a3036ea,ddfb0656,1dfd074d,ddf1c22f,9168232d,cf9c36a5,dfb7835e,62d28405,bd32ec15,5e3ddb3e,df834088), +S(42000663,3223b99,e15a2a65,bd95b229,820abee9,5ba5be39,6f8879b7,3f421e7b,9f3f3d66,40de91bf,c6872619,87487226,57e60a4,3ac633cc,48f684c0,cf42696b), +S(f02335b9,9cb524b7,45fa9167,41da4259,f70279d8,efe851ab,f5b0b8a5,32a087ff,e1bc6767,ba068b22,cb7389e1,36805da5,c30ca62a,e59b92f5,48e4dd1d,5327cfbc), +S(5bbda2dc,cf8154e8,28ed49b1,2fdabc3e,eb8c3f9,d0da5878,77611ff4,49d72e7c,312377c3,6277addb,d5b044e,fe136626,d5f7e7e7,a73cfc4b,9751e8ec,e4f77084), +S(5cd5cb83,ba2f225d,1ef4faf6,22e226e1,eaa85a5e,99721d3,82aae23a,f9dff565,254f58ba,9c49244a,4178a067,b0e4bf6f,dd7f3e15,65e21637,bc41f9f3,55045908), +S(3b20ebc6,b453aa16,e5b61381,1d81ca1,f87dce6d,b54ba85b,d8578ee3,23bff228,8c9d3054,56627a,7313505b,4aa5140d,9fc40d83,bcc298a6,43842f04,70a335f4), +S(cd531999,cf33db75,df4430c6,bbcf32d0,642be18,5736d79b,f2947989,e52c8da8,c7e99c34,2a5c1112,400edc69,f58246e3,d3cebbef,2c43ff47,7520b027,e2aa7d78), +S(40b3856b,273bd2a5,145b70f,d16a2972,e488b33a,f3719143,db7bc567,26ff23c4,d8bf895f,71d96e6e,20d523dd,1256bd56,44e11442,c4757d74,f116ae44,69dc9b21), +S(1a0cf029,2d7cce75,32b74bae,acec6864,9e682788,3cef4bbd,c8b24fdb,53e885a5,32c87d92,6f969f69,7989837d,d8ec8ef1,c284d9db,2a86ecd3,5bbb6772,dea06692), +S(7fd5d251,93dd6c17,8d0be92c,342f94a3,c92c061,27998f4d,54f7dfb6,1326fefa,ea7d0755,e0a804bb,8b7ac8f2,dbe1dd7f,9ccd36ca,2fa94365,631ae455,5d080075), +S(51820145,6c07fa3e,70d7b24a,7754b11,e42828e9,c1b96b0f,fd79bead,2f44050e,126f5526,1a55b724,7d08c868,366d697f,a6898c66,d14094f3,44b0a6b3,613d043c), +S(86f2c87d,46038770,3be5ddc6,c2ba1ccc,7dfdd56c,a9986663,882f85da,345886da,ed34fc59,4b66f7e,f06f54de,84f3c7f6,ea1d877b,bbfc4185,3df800f2,fa805027), +S(7f7d8a69,5b86ca13,d6a0ba07,99e60cbe,f5c4e1f4,c74a62bb,93d94d4f,8c1f296e,44a14061,b2c741c4,6a52639e,9bf08776,5db5d496,92bb6d1b,e97f9ced,a89953e7), +S(ec61e956,83714c55,1b72ed5f,c5b09663,6dbdea9a,64d13ef8,c9cf0c55,89da5ae4,39a6e38f,9f7927cf,ffcd0847,df91e856,4188bf58,276bb4df,3721335a,5357c77a), +S(e5906c85,4a75bee9,322d70be,a5d31c76,31a59389,2f479bf,8dc11bef,9ad5101c,125b3a58,8c6c1c5f,288402f4,3ce74ec5,fe9c2dd3,3f3605df,9ab41210,32641524), +S(6c9faca8,b1b435b9,213fde17,ce967f05,46e6f27a,cf0e131,8496bcfd,d856b092,a04ac67d,4bb07624,6b59df97,2fbe2c1f,bb04be99,e269d33f,ccc81f76,3f567577), +S(61031a0c,730cf279,d929b4f,5608f16e,6b1b1440,c04e5a9,fa300ff8,27303def,acc4d732,afb4730e,39a10c0f,5ae2cee9,5099be03,bf5612ac,391900fd,b51238c2), +S(e58fa07f,ebc3aa4c,61ff4fe3,bfc8d04d,48a1e3c9,935317e1,83d537f9,7f35826b,d2402844,7e63c3e0,be630190,8139a75e,2e1a2b22,b05ce52b,e453ccf7,7c35f1fa), +S(4d4d2982,b45a339,1720af,cf6b92df,2c201d38,5b9b6c3a,8fc53b4f,fd3bfdd1,d72650fb,d130482d,116524fa,e2b3dd71,c68b4bbd,54fc55a8,f9824578,cff67503), +S(9adeb6f9,6ffcbb56,f171919c,a8a64c70,9b8ae835,828bd573,b7a1bbc1,3efb0360,6d920a2e,d2e3f41b,4820d838,ca342b66,9af35a7f,7b6d09fd,b1ba4298,9abe027c), +S(64ba9514,d8680f6c,dd66895d,9c5ad45f,6e29,33506f8e,d7be9770,822aa9b8,7ed8c0dd,59bce424,481f88d7,3e641b61,a010e490,97cf84ca,16c2e045,49e9c6ca), +S(9e4ac64d,9ca58a04,46ca18bf,c1700f2c,16937ef9,c82e8b55,9ccbd751,2a0c0222,315ba2e2,601b18b2,cf7f1720,9c4cff2f,e39dfcf0,c2546fb1,e930898b,5b023274), +S(f13a99e5,8dc72fcb,c62a492,d2850704,621ddf48,f1f433e6,9a9814c4,17d4b84a,cc3d3732,f0f4166a,55946e32,e1c01f91,491c82b8,ef0d269d,7a66f039,ac02dfae), +S(fd6451fb,84cfb18d,3ef0acf8,56c4ef4d,553c562,f7ae4d2a,303f2ea3,3e8f62bb,18ba314d,4e78ea87,490185a3,e43cbb33,5d54b6d,2dff17c0,2f526f78,ecd3f31e)}, +{S(f1a749e,6cab100e,2aeef8ee,6a654551,c0ff906e,e7d11d77,f390955e,9d29d783,a60f7295,3c8c3bf7,f1dc1358,e39baf76,3dba22a0,1ce7917e,aeabd996,e21e845b), +S(e8c45020,4c9d9ad,f7878aa4,184a1576,d4c65d5a,c1c4d494,ff427e86,8b42ec1e,aabff02d,8a715c2c,34414b27,808882c3,f656389c,71c26d6b,d7ac8013,83f4c57c), +S(c1febd79,1784fea9,bf378237,a05522de,1081df6c,27d22ea2,aad805dc,7c2f1c4c,c38782e9,fcc1004e,aa677f79,536aa069,7dd9002d,ac16936a,1f0b8736,8734174e), +S(91925564,4d9bdf2d,4522825b,5758b3f0,4d32da73,3a4e772,bfe3eb2c,9909f4ef,2568e18c,1a0448ab,d038ae62,a652d152,4bdec1c1,a0293695,9772bb65,d78450af), +S(25bb4202,9880c39,f5bde432,c1fa357c,7f4867f,6fee48b9,24ecc824,5e1a5253,5d43db2,64c23715,b4b0eeae,63127cf6,9b4bc79e,f96ea8cc,d17cb53c,c3ac0fc5), +S(2597e080,e772d36f,df500782,5f92f797,c61c72c7,8d801dd1,3deb1bfb,9e91b12a,fd5918b8,938ded17,a458d0ae,559c552f,bd45feb2,5b4f59a8,f5b735cb,bdab92c1), +S(70231b28,f578dc12,9f8ac54d,fd4e3577,73d0fcbf,65be0dcd,51132882,5a36e7e1,d12aaf89,4dff3e42,405a4140,58524e30,b7c6c4a1,83763268,6852acff,83d2b7cb), +S(f8ddfd5e,5f3b46a1,ab363169,12b74c97,b0bd654d,87824040,bf6d2cad,b4fcbf95,931fc58f,5b429636,5e080d5a,8fb35ba0,f92104d3,891d6584,8d24c0f7,fc95bda3), +S(a033f432,670a382c,57e2408d,3bdcd2a6,6758e63d,77574598,6b123e4,d927bf10,83b52f69,d79e7445,b6e33545,c23f16fd,52691151,96ee60d6,2ecf6de5,b2961a0c), +S(8e77f9ed,9a643f3c,bf197b09,80f92860,f37d8b83,93633230,6c902c38,3bb7f96d,71b4da9f,f736f9f1,f8c3c099,c34c1bc4,30bb5d26,3c861e2c,726fe891,cdf7d1ce), +S(f34153e2,29934c71,5d895102,778425f5,e92f4ee5,b96d1333,df207e62,6761b328,954584f1,64c8f35f,2c4e0188,76186ceb,3e91523a,5e8ac03,d5998253,49b7b8ac), +S(e133aa94,c0252f05,379b5bd7,75ba3f1f,92de2876,68613613,28946904,11b3ed52,40363801,613423b7,cc6c0cc5,af3641f4,dc2a7ac4,48b178ae,d1393605,103bd6dc), +S(28119c6f,a57d02ac,856edb00,f594c7be,22772b0d,700ad14,713affe5,7e385b5c,969b6cb2,8ef483a0,db4a96bb,92e2d332,6e6d86a1,73bc3d5,831bcbf2,5efc437d), +S(8c728d65,8b78d96,44003708,dadb48b,65dcf6f,6d9412c0,e31cce3d,b5384d00,bb3cf660,9908467d,285f1c7f,40f4f18,ca618093,92633beb,b4ce30c4,72680662), +S(477321b6,1fd5b4ef,3acd1e8d,8432ef5d,e70576ee,6b8490e6,839f1985,dec96490,88008466,2244e3f9,7d2ded5d,2193c70e,2d72c67b,9b7cd70e,9f14cb05,70306bee), +S(ebedd345,ccdd0e04,4bd3d4d7,e1f1cb6b,ec06ad10,5ec2cec8,821580f5,d08a63d4,4278bfb0,88e4ff81,a3fe15bb,e01be36,40450f85,885da0ae,e15c6b9f,e78ad14a), +S(f4795df9,41b315e2,24a98dac,d9149ff2,8b9a7bf,e758a1f3,5cb6336e,8e1f9814,6982bc20,285c27d8,12c5c648,d0635c7,fdab85e6,fc6905d8,65da387e,596da791), +S(65a5964e,ea76e30c,74c472bd,3ddd5169,11dcfb3e,1f2d7ff2,9661e254,4a38ea30,a7c394af,80ebbd32,e442271f,b061bb42,a7b1758f,44d7d952,89152fa2,a88fe3f9), +S(f3d10725,da6b6c76,6da6fb5b,969ba7c6,3e33b4f2,d062a446,4ffb20bc,dea2d376,4d65ff69,64518942,bc3142a6,2148137,7bb609dd,6545bc26,9678ea19,62812ddb), +S(f5fe0f35,cde00589,301584a2,f4f5b1e9,3977082e,9c9bd50d,7c2c672b,ef05cc9f,1b49ac82,486e6344,dea32ca3,c96cd5c1,446ac2fb,2a658a42,50425f32,e8d72e94), +S(fce17cd4,d9519a53,f0a100f,ca54d1f9,fa87eded,98a12654,769c95be,151e33c3,40d342ef,83a4d715,bd13df0,f21197c6,e189681b,efa0d925,248733f,5ee07b8), +S(fd5d90d4,a97c1d1c,4fe18a10,6808f46,f6ea4422,c4408860,c2256b66,618af8e0,7ffc76c3,539bdec8,f59a9a7b,b36fd534,99306cf3,2dd1fe43,a2db5b59,af2f7e3b), +S(1c71f824,1b147abd,9e3c1ca3,fad5146b,e531dae7,c9c0d586,4f2d8bd8,7a6457aa,23e7e758,2cfc92dd,e498c0af,b942182a,92e02bb0,7e95bc1b,763d8030,9ddc9137), +S(dfb018bd,9bc352,f36889b8,2a46512,8850a158,872554cb,3a3dad28,a0496f20,2daa780b,d615d778,3de8f5e8,25cbd934,5c021df1,9ef80a6d,39ff87db,67a1e5ca), +S(bbd320ee,dacc1282,d3fd2109,c26f6bcd,46205ec1,d96b806,dca35dc1,4baa823d,ae7beed,3b5f72bc,ba66c794,89c05666,efa85966,14bacc45,9a99d882,8edbdbfe), +S(c9cd8f21,a068f78b,ce5129c0,9084be52,e48d688b,f474e690,b7720360,e362dfce,a10b9fe2,78c7814e,37851b5a,36aa4246,54c6279e,89df8fc2,ed189ad8,11518f22), +S(ddcf39db,aba52181,72c36a53,50883245,39ccddd8,46ec4258,e72dcd71,40041491,85cadc4a,a569265d,412c8fa9,4872bce1,51a750f7,b43385e2,2db405e3,54428a5b), +S(391562c3,f19436b1,a6e41d06,7435fbe8,27de66b5,555540c5,3ca7a0cc,c7876457,c3a5d917,5b56f67c,66ff269f,72c0a1ac,74503106,9059aaad,f3e66dad,45a80ee0), +S(63d4b224,7b2d441d,680a0437,604533cf,1dc48c9,bdcb9e10,e0249960,f966b2d4,e25cb896,ba165d4,46f73344,61e6856d,4c186736,402dc6a0,d866f97e,bd5cdfff), +S(5fe057df,5d2508c7,611dc21d,412739fe,3e7cf9e9,670812df,cbb00255,4d44cb22,33b88e83,9f22a7bd,17c149bb,65bd4a49,29b2a29e,b975776c,e82189de,80c7d45c), +S(5ac83bf,498f7eb0,79507ac,d5fbc587,f758afa9,b6a1ee51,4c857f8d,608a7b1f,1c866393,8a91904,f0530bdd,ba15390a,4c10fc4c,ef8a2f07,d799c89f,69a33097), +S(b0f9e4b9,b29790b6,33bcc04f,d860cb0f,823d8d1a,4cc1a1c1,413c1606,cc9a8e2c,b617d40e,7bc52192,be344f46,f9021c0f,ccaf33fd,3e8e3118,93df993a,20c2ee7b)}, +{S(eccf169c,9514a854,8f7e1131,a7438469,4df7dc2,fab96462,20e5799d,6d3f672d,452e53a2,aaf17617,37055bb7,24b64f4a,8fef29ed,f8571ff9,a3a6d2c4,6acdb91e), +S(a77bcddd,a0fecd39,a99c6387,57bda1bf,30257248,6a3fa08a,e2d6ff17,e6e4b6ea,debf4c03,b4bb5c7a,8a386a7b,1e459426,6c78eec6,55f01cd9,f137ff18,c5fbdb1d), +S(a77b91ec,6db6a66e,a48de424,65079a2e,ce220fba,da221601,840546ec,2295c2a2,3c721fea,81f5fe05,163562a9,849bdb15,90bc818e,86674ea2,57fe8d0f,4050086c), +S(99a28a1a,3bf2af79,ef2bf134,d31880a,71c2aad3,824fb7df,23fc4fb7,d54b2910,620e2918,df14e3c5,dbfceada,1905941d,32d77592,89ec607a,f9851a6c,5592803d), +S(7eb52616,71402db8,905c7097,2af96b72,2bd77d,f124bbcc,5418f217,f6d8c7be,ce1e663c,8276bf42,99919592,11feb13b,66aefa37,5d6dca15,8b7b66a3,ffc6d7ec), +S(c88b1815,f183e6ea,3ce8469f,ada5b88b,805288d6,828473ba,368d52f,2145e7a4,55e78f2d,3784952e,cb47f6b0,113eb471,8cc58225,85f9d1e,2198dc60,af3f90c9), +S(dd893c5e,a2e4e70a,fcc161ac,47232d3b,77f16c95,54c98770,9a7a6f64,c0cf7ab1,a1a58b41,c7d4d0c5,6d6c908b,32d97467,b8b6ed20,73e6a677,54935665,6a92a480), +S(591b8422,eddbfaf9,d2c27c28,dd84dd30,712a15a0,deb752dd,dee682cc,34722ea7,877b0c99,6a248082,fd442509,b0ce4cc1,b181d4f8,8ff755dd,5f0dba66,ebf95d1f), +S(75f9e3a1,ffdd902,be5d1d2b,3ed18b37,62e42e95,8b024ce8,f892ee13,ab35c674,57fabc84,7c68cfdf,272effee,e7a6ee2c,5fecdeb4,8e4877c,ccf2a8de,2e2264cc), +S(c8a53d5,e1895cdf,db61c1a2,395a866b,ad803773,23ea43ca,775408f7,a4141cc6,ddeff9c9,97a11e4d,d0afab30,f63229f8,1b52ac,c25749ae,2749ddb4,2b201196), +S(8827d23,668f3006,b966cb19,698a066d,aea556b7,4108739d,d6414d8,e8dd78c9,3d009ac7,2baabb53,2e3658e1,8941d4b1,efe512b8,fd7696d5,14b12216,215f10e0), +S(dde6b713,5cf165c6,53c7f5db,542501bc,b0a41e3c,c6779aa6,194ac1d1,8a830b01,25c04b4a,937e16b6,e72616e2,d64a413b,6a7c29ac,71dfcbf6,826261dc,2507c16), +S(8cf6210c,5426b3a5,ed594699,da6cb8b9,8069a3d7,b926cae9,fedb2e96,25d20010,78017fc1,7915e3c8,62557896,acd002fc,7263bd7f,aed38fca,d63ccaa3,57391f30), +S(35772904,91661db6,340e7d1c,a98db8bc,2f50f557,283ccf11,8e446f71,925ade9b,fd8a4a56,b82dff95,a59e29ea,bd5d8e8b,a876bf95,4abf0537,60832d1b,d7edc31c), +S(60e4201c,4dbd9c99,c5eda030,f041f51d,f648f77b,13ec2072,4d89b6be,f249d793,ebd96057,d60b7cae,71349c51,1a3ca99e,847419ff,cdcaa0c8,54d75d40,8263d81b), +S(f39d686,b17ad518,3a7d300f,1bfd015c,57541f08,a96b5943,43d2ef82,bf20bb6e,f1298c9c,633a958a,a0d12b87,8c95836d,f9f93b5f,5e3a6bbd,93a75ba1,1b96d4d0), +S(37ea7dc7,2a3a0b4e,72412814,bc1e1233,17ea3e1c,c4ede35f,cab5d31c,93cc330b,aebaca93,8b14b315,708360e,5662e6a1,af25069b,cc07f581,225dd131,c656c607), +S(ff1f61ed,ba3cfc6f,2fdf3043,37205bab,301c965b,501e4f2f,fcacde00,dd127b25,fb1edca5,90e00f87,eeb56ef9,94e9bb12,b64ad1ea,f5ef0afe,6f0125b4,e100a483), +S(3376e0a5,b93f15b6,c46b92ea,e313ea2d,c5d0b961,a2623487,8919cf5e,25e9ae38,a4cfc1be,fd24647a,20ae014b,2041ab3f,6cb7585d,48a607f8,299e0c10,96bcfdf1), +S(be575f99,842187b,30bcb312,987ea218,3d613442,8878804,b5e7d920,12e58d9c,154e02b0,b573c81b,d2079a4f,4a6efe5f,5f37502b,33225064,4eb38b2c,3f0a1767), +S(5a215836,f1f2997d,9b09d4d0,6473c55c,46cd3006,70d85d6f,6b5531aa,c8da043f,ef5fba1e,b6e1deaf,bd83e480,fcd4984d,cf60f91f,4799e8b4,3f4edd15,f94b6d33), +S(d73fee2,16a503e3,a7d6b0a2,675adb1d,197c3fae,4d43835c,b6b043f5,d44909f5,6f2cc9ee,fbc36b4d,a5b3e704,c13daee9,cb81ce9d,470f1290,8b32f047,ae231053), +S(26fda2e4,d07ec613,ded58e14,ee84e421,ea58e5b9,5beed698,d847f6a6,db185f6,683c0002,bcd6d8b7,1d06e592,db4b961d,f2518fbb,47cb4ad9,96020d84,ed8a5909), +S(cd3d4e87,e433f2b5,5dc55c6,a3f280fc,57f899e1,f8f0777f,32705f3,eb24551c,2315d85b,7521e4e3,8e69f29b,a49a3203,abc7f280,ad49365a,4c78f21c,3ee12542), +S(652476ac,2c9b871c,e108fa13,6a739766,879a76ec,60d787ac,a1b7447a,67f8afd8,b66bf6db,cd3a1393,f70ac7b6,d53069d2,5f084dd7,f05c97a8,76f7f646,c7b67fa8), +S(61ab4f97,61c96446,ea7a75de,7ed36224,7b5ce8b9,e7b442c3,432f9fa0,ec74355e,f391652b,17a910f,6d476c29,89e854f7,d31a5f31,fead5fbd,5013ea56,e44985db), +S(36e4bb36,e62f78a6,a6155351,36a73637,13fe8be8,1c8c3460,a94bb642,4f7c80de,12b38983,c10079f9,b0016df7,fba0685d,5eb87518,234c65c0,7dff006,dbb6a563), +S(f5e4cb89,101e90d4,b2f50097,aa0b22fa,df076932,f4045e9b,7a9ce8d6,ba178780,c12ec4ae,56db7971,3a1bb0f,2559e3a1,de3f8200,650c809,74101940,181eb52b), +S(1138ad12,333790f9,20e979f6,a6471274,2a9bb567,2356e3c,80ffff89,a9de533,4caada48,a78ae26b,790f23c1,606a5820,98642f4,bab5bfff,95748f6a,2ccd6bc), +S(e0346d21,121ff741,fe4eaa23,938a4347,a71df442,9e55359e,aa20d691,c9f40840,c1197c8e,c36676a9,28a92b56,811845d5,d9632c65,9142cc12,3c65e54f,c282dbd), +S(d42011d6,1061388,fec6b7f,3f332b20,24ab318f,2a9ba7ed,23731207,3e32478e,451a2b16,5c82b1f3,e4d2a0a0,bb407b84,904db4d0,caaf733c,e31fa97d,2fb1735b), +S(63964eee,619074e0,780140fe,2e90836,e72328d2,448386d4,59c5be23,187f5048,c49304c5,947630be,5c60064e,3cb40436,c2a7f46c,b221937b,c7c5d7b1,76cf5e37)}, +{S(8f741868,43906722,ab9f5c6e,c796573b,622fa2ae,6d985bfe,ea4d51a1,8f141792,61ecd858,d6992c4a,bdc22472,fb8fd242,929dc5b5,36ea8e35,d1c8c513,bcb9e31e), +S(f2dd67e5,6f75c397,76b29366,149ba4ff,69385651,53afb385,3853acb7,9fc2bd59,3a24641c,d48ca39f,fe992bf1,50291604,79066af4,a0cf364c,9e52a9f,9b51eb66), +S(9386aa5e,c3452728,a8f65141,e2f43a14,c250173,9349c96d,e1968a4e,48cd30,a3a38a85,4f68048,d8f81002,3eef9966,780262cb,aacbe859,a8fc66fc,27c37f32), +S(6c9901ea,920c0f4c,ce51fde7,ab283f98,eebc30dd,c76a3219,1df4c4c9,db467aac,6773f8ae,e601201a,84dd4485,fa560e22,81d5eabb,25a3b3d8,525f4a56,65f79d05), +S(ed1eafec,876154e0,58597caa,8250b0ef,7262ff70,b719ec9b,63c0b2ff,9d167fe3,73505073,2b563f93,89078cc3,93ff9837,227ab8a6,c7d789c,6d2bc835,2018f77b), +S(515806b5,13d4d4bf,83533b56,3b39bf9c,4e808426,f2e4cf16,562e759,cf2d56ab,83c2fb,673a08a6,b8a86b1f,e1ba23d9,3347903a,d6855059,130d8d39,737ddead), +S(30a726d4,d8db1cfa,d59331a0,8f4b5376,36848547,914dcd75,37a80e40,109b8e35,8f628b92,6a11ddc0,dfb1cebb,934aeaa4,3840d442,a61145d1,803f771f,7bf65d7d), +S(116867a8,d72fb00e,80a6f267,e8163770,34affeff,36d667cd,38219f0a,e3c9038d,270f15be,b2a3d50a,4088720a,e9a2c3dd,df00817e,31e1a5b1,d850fe23,dfe51657), +S(abea2899,e4575c6a,201c96fb,a60a24ee,1f1fe0c9,b718b54d,18981938,4f33a1f4,d43d54e3,9e8d433a,ce66ad94,e52662fa,8013e778,f8bc2e3f,31938a6d,5681c660), +S(1fa796d,9f658aa8,6ccd0fb4,6a735651,102e3181,302e371b,8c965dd4,5f078b30,69815d18,43c3b4d9,f7fa4af7,3d2e5dda,390e5372,28608912,79826a53,a437031b), +S(f5022faa,c8caa29f,304ab6c3,d00931c5,e09085e2,73beab04,c1d18f87,1c0fde73,c6abd143,73213fe8,ffa5ec64,8a22dddd,fdf2cb25,e32afd58,4f92dca7,838e8249), +S(8190b10b,97bc72b9,301b1dc,cc60e69e,460e389e,ce7d5d11,4e2284de,853ea02f,f1ffb850,dbff0f06,561b75f6,5d2ae823,cb13881f,d1150eff,274db4cf,112d2253), +S(ea230fbe,c58d7e2f,1a3cea60,f9018562,d2fefb49,8efa312f,4beafcd3,139da094,6045d69d,b27bee6f,3357180c,e92d3866,b480faf4,2debc033,cfa118fb,b89c3bd2), +S(333d063,ccef6aa1,f78c81b3,4a84975c,82bc2cc2,bb897608,f0bed49d,cd08829,90ad105e,f72b7e4f,a927240d,9c69729b,a0aae3a2,3a45342,3be2c385,488840a1), +S(4d95cb48,58d808a3,be82f42c,da4f64a8,c64ae176,3b50257f,2e4ae655,fcc4802,5f6efffc,99bdde54,6d8ffde5,e9a551d0,121a39c3,86db540d,1caf74b4,894c5559), +S(b87b5eca,6e0111bc,5b756816,fa82acf9,77f81376,af796cdd,1e8fcb09,4d363d1,442fa845,9c2a7799,2c09015a,db80f26a,28428851,62432660,56026009,5f2f9d8), +S(34baf43a,a82cce1b,19945590,ef3cb582,2ab03142,6538ea5f,74571582,ee14cf00,9a76705b,c0141e29,75d11543,215377b5,3c051c31,156697cb,e8f56721,da386e2b), +S(f07c5d98,a2579c17,53b3fb58,22a139a1,53e7deeb,ae9304b,114bb188,d61cdd0a,ec18ce0c,1e51b8bc,e12f3d85,23739f8,bc25708f,32deb81d,a780cc4a,1010692d), +S(9a146c80,5ee261ad,3e708885,aa41041a,53bd3758,b3d1ab7a,1a44aa7e,29acca7,fc553e71,4ad8a192,90f94ed7,7c171f9d,9ad9a047,6791f045,4a3ab7d3,f8834f02), +S(c8088409,650feb74,9f9fe21,61772279,128db1d7,58610a9a,8b9fc4b,ef9683b7,692a6be3,132a08d3,82295ee7,1c469465,ae7d63d6,c20c7357,36935003,28799639), +S(53bdc8b2,3edd83b6,b149b79,c88130c6,b207f999,e7045285,7e828f81,b325b9d8,a9a039d1,79486167,8fda727b,1706e9ec,7ec3eba3,26e6a4a7,e27db3f0,8a6ee238), +S(fd08fb47,4af98207,3d8b4ef6,d39012f4,78225f1a,bde3c841,6fe3881b,4fd276c6,d38b53a9,100da1fd,1d2a987e,6907370e,7bca492e,98a22e5d,74a10c9b,93a197e1), +S(5c42ad93,2306363e,a0edf86d,31d14b04,c3f7bc09,c9fe1326,d1ad085d,c84fb7ca,1bdbf812,e9ad6486,ff572d4e,de5be4c9,59de7be3,f21e0dd8,76534091,f13ca3d3), +S(66257876,115e7eef,fc0e6132,9f177d3a,437c81c4,1150f86b,45904f86,30bae971,df830e1e,33aeded,721a0a6a,62a3a402,1d2b7ab7,438b7b3c,d834d67,3a857aed), +S(4feea8d8,2cc6601,c847deff,35581c1d,bf1f4070,402bb948,ce9a41ee,16661627,c09a7686,ad6bcec4,ea9ab0f7,8316adc0,7c7a2899,9332cee7,5d70c50d,249a0007), +S(2d3bb180,73f5345e,cff0c901,9a6f2fb4,e0a237a3,9315fc11,fd53c7d5,aec43670,58a9459c,2710ac75,ff2510ce,4c9c5fb8,b4f739c9,c6611494,daf896db,e43b080), +S(bd539f5f,47b25116,7159153,f402e0af,8650c17a,de7c5dde,2d9d9cc2,d0a3103d,407cab4f,ca581f10,eb386e20,9158541b,8649951e,b2f5e454,2a7032b6,53f0caa), +S(c7a72935,87ba5114,744c3d0,9030be19,9ccea57c,7f80be87,bfb5b79a,8f8e200,7c2a98f8,b4526422,b211bea0,875a81f1,d379012,486db005,e31b9682,404e14a3), +S(cdf20316,f4b63ca4,c472e1cd,b3a938be,291d98b9,3ad8f3f2,4f3e1a4d,f1a6cc80,ab993e8a,68988d4d,2749760f,241399c8,136ee9d2,3d4ae7d1,e6d26df4,6056587b), +S(1d341e6,2eca1f48,165bb2f3,86207da1,f2c7fc86,dff7a75,cb63976e,f21bb074,923b53ed,fe2f5bb5,56aa7cae,2a08ff86,160e3344,c4adc09a,e7aeadfd,f31e2b9c), +S(8704f69d,9d335975,f0e3bb83,5aa3024a,60103d89,e5578253,fbb3d537,1983ce4e,94f4adfa,31dbd13d,95c738b2,8a569453,cba45efd,1cfd20b6,78f6a724,e9a8d025), +S(7175407f,1b58f010,d4cda4c6,2511e59d,b7edcf28,f5476d99,5cf39944,b26b64f1,bc4baabc,bb1c2aaf,c92cbfe,ecb33791,4fe01748,8bb8e2d5,bd918104,4dbdc75a)}, +{S(a16a4734,9afd167f,d5e79d24,9784d87,5121fa24,2c3a54a,88f9b176,72669aa1,4df3fb81,7021efdc,e5296735,3a177b5c,51cc7762,4755ba28,1084db5c,4809e02c), +S(91d1abe3,8d3f9671,54337e03,d27fa6f8,c3007f32,323d15c8,31306b3a,30900328,b1b8c71d,b388009b,98000f9f,291b66e3,f890d42c,a5812f34,5c070f6,e73b89f6), +S(61b64b1c,f2a0e720,e9bb4853,537b9f38,66baff87,388df7f9,f14c06c7,12080b96,44444011,b6ddadc5,7ee00eed,b6af3772,e4116711,c3853f13,7f9c7b00,2bf2a1dc), +S(3b96b2ee,d9cf1ed6,3aaed8e9,aca3a464,d6a6fbf5,e6fd48f0,5aacc318,dfdbc87,51c41c26,506cac9e,bd0c5dbc,8ce8788a,3469e42d,de794707,9e0cd0d9,826e9c58), +S(7bbd147f,77b293ac,ff797b9,a52778de,5874b754,c08df397,72ed8ef7,53242efc,3e843df6,75abef2b,e4d32c83,205322cb,f53bde0,2563eb8e,b5dfbe6f,27d4cada), +S(becb7fc5,de84f994,9f97e55d,bdb6981e,f38c0c45,1e0e454,519c9411,5bae3d7,754145ec,ee6f9c7c,f91963fb,5b0a683a,ef24313f,1125570c,c9b9c7d2,afab99a8), +S(87936626,aa88346d,6d4330d9,3a188ed6,992bdbb8,387b395e,d21dab93,63d833eb,a28c868a,18dbe0e7,12ca5237,53f6a50b,9313e687,85f3b31f,ec778fac,87aa9327), +S(e79d4b2d,e33de1e2,e7eeeb44,d197aec1,f5883ad6,1394dd79,de274ef9,76e3b022,9c73ade7,7c661527,ec2ec6cd,b370c130,380bdd9a,4bcb668a,86e8259a,ca85f293), +S(863f0d65,34de1222,237a07bd,ebb066b5,2c1cdd83,d7a6d3df,278e57c8,bb59b8c7,c546940b,99d04ae2,5cf7c881,28a985cc,9b6223a6,ffc06fe9,8a3e0f68,439b9db6), +S(71e9b0d1,3972d9e0,2225bbda,5a1024e9,c373eeb,f6514eb1,c113ef88,dffdc3a,4436c52e,c58a34c,562638c7,8d76e3fa,29e3586d,fa667577,2fe0b932,c4a1ade2), +S(ef4a500d,c9369125,78fcfcbe,3c313bbf,f0323caa,75750b6b,a317e1e3,dd8054e3,e807e9cf,7911c919,fef82e40,a3ae1b9b,ed8ded38,e74126ed,863199de,c031f2a1), +S(806dd4e0,fbf72904,c7b0080b,4e7526bc,c71fc52d,f143da80,e571041,dd964915,2f4e2e67,3348c32d,6bcc0741,2e76f4fe,944f96bb,d73382c8,c6880cf6,629eac8a), +S(9ea889e8,acf0441d,6e299687,c532ea8f,8b9453ed,5fea0d47,f735056b,1eb3bfa1,e43f79a8,4d302f3c,88698896,5fa7b8f1,a92c620,dfcb3462,c4befe3f,4afbff5e), +S(9a990a22,1d27d8f3,40e79489,58cff3ca,2720dd3d,ac71688d,9c3c9e2f,afeee215,4957ac76,db370918,7992b0b,63370656,7e0f4a0a,9e5f1d9a,be8f7d5e,8a950eef), +S(d3291003,98ad3d92,1d6cbc6e,b37ac3f3,9360cea6,23edd794,64d34a51,fa7adc60,657c110,5bd8df6b,fe52addb,2fdfc41b,810a1ff7,8662021c,7c220b0d,b3509d14), +S(65eac576,e149d97,3cbd772c,60570870,e437e92c,2e5138ac,9c0534df,b7a45582,ebecb6a,edb87cc1,417e066e,fef8e52e,c61eb00c,dfd98205,91d63c08,9dfd5347), +S(b6976b99,c2515be2,2bc901fd,8671255b,f8fd76ca,1f3474cd,5eebe39e,98f6f14f,84ab17d,da67b61c,fd01881e,b1087e69,845aecc9,ce1535fe,1c7245fa,8df98181), +S(c7f5967f,f9910e10,54c93e1e,d0290102,9bf31787,15f53758,f5c53cd3,c79a52bf,bfb01210,5c1ec69c,847ceffc,d1105ac0,528129fe,3b4d3086,2b6e9562,836f5eb2), +S(ffa0da7a,e8984e4,d02a0fe3,acfb4e81,2a63d6b1,682dcd78,fd2635bf,88cfdf1d,49459ee5,3fad1097,2da786fe,45a2d201,e4a52260,7779b1d4,23defafe,29e70098), +S(5a53d683,3bc1740f,d02f278b,2ac15a87,f137f2,c798f157,725a4aac,63f1798d,ac5e7ec5,86d5960f,e25f9e25,7cf9ee05,110d9595,e440d032,c416d444,6242d10), +S(70f67487,9b030a4d,9ccc0bf2,90d5b78,c455f8bd,a1fa2b52,efaf0200,6b70a6cb,10f5b1c5,dc46c0c0,68757804,93805aa7,5a259dbd,95b4bd14,d031daef,a81bf7bb), +S(a4baf0d7,d3a53c29,e78ff81a,52d634a,e009391b,30a9aa91,df8f7bb6,13e3c16,c9f9d001,7f388f09,b6802c45,e1fa036e,99443467,c3847937,8b384a9,dada35cc), +S(351b8e4a,dd336c28,5d140c57,9f2b089d,3c656a05,b1ed6,4cdbaf7e,e5bc671b,b996e61c,cb14553c,b7b79803,c82332b6,704ce97,fb4e19a5,1f70b13d,f8e2732f), +S(d248350,92898c0,5dbb4465,18695efa,e59ac007,d58b5df5,bb3b7038,82f18e61,23455e7f,5104051a,44600be5,2e242a90,95213d25,b4fd65a7,62c3f9fc,9234c2a5), +S(d3fc6d75,10cb0b20,77b52b00,93e84d47,54dd1a28,4f3928f2,a9e3cc02,f1869588,26e86b02,c16171d4,4238aecf,666146f4,9386e0eb,52dfed87,7ac0b409,51ced10b), +S(1c611335,3d115906,182b0e4a,7eb3d39f,552c49f0,c5928aa1,15ae00dd,c23a3b70,1c3e3c4e,ed65ce47,ea82a33f,df8fa6b5,532977d9,53aed38a,f0f4dab3,98477c6b), +S(6487c5c6,abb6e673,821c4b0,2c485f83,3e149af1,83b3f025,71a81fbe,660e98e3,63c4f6b4,7eb37ed6,7668b41,1e83d9c8,9ea323f3,2d9e8918,20b65276,a8a7b7d6), +S(1b0baf63,6daaf2c4,28a62bce,bdd41de2,a4d7cf69,93f0b931,222a40cb,9f5f9a2f,af9a62cd,f91e2c6b,47f308af,e2de8f16,def4972f,24bf4c5b,2b1f92ac,f63a21d2), +S(95bbd974,78e1b8a4,1622e460,8aa82fe9,e77d43e7,492a0d21,1146d987,f9b8f255,412bc52e,d61c3880,210d3df7,f0d2f27,d458d51,388803e,fef1c016,d7c9e7f6), +S(a3466715,5b6ea598,2d3945fb,743a1510,c671b96f,a3494a57,e0349010,55ae087,de35a05a,1a943a42,7210165e,55d5cfae,3ac15490,dc6b0f43,34c0c99b,dd778608), +S(2ed76c11,52ac3600,7aa17c85,a5f902f1,7c845a05,a4e0aaa0,7b05e836,cbcad59,9c60b2bf,bc47a0dd,d3259151,37e89812,a08d39fe,cf5806be,eb538575,3b159531), +S(20e6e2e7,96946bb6,30c7071e,f1b92ea3,d53d280e,e450111,5f5da36f,840dd273,2c528501,b0eaa61b,b5f45e52,6878b9aa,7ee13686,c25796c3,3f8302e9,44b9469c)}, +{S(f040a2fa,b839c753,4e216425,6c2e8dd8,57c52dac,e75cab3d,512a7b1d,562075d2,9e211cf4,bab24e0e,f745e2a0,9b59565b,be7b2449,8123f6b2,ba383b25,29554b36), +S(c66813b,904831cc,12f89e3f,bde93eb3,11ade6dd,f6cfdf72,21cc61a2,ff46bf26,3b60c8c9,9da35a58,7b9650af,f85ca785,ece41146,e7ed8d6d,ef8d26d1,f3d055ce), +S(cd38ece8,7c7a9cbb,e23b58ef,59925633,734de285,f93b3ac4,eb01e03a,adab904b,a5f48fcd,afe414f4,1a44917a,5dcb80b9,30373af9,70e9f22d,c1af80f,a8b06320), +S(72d6f7db,199564a2,6e823a49,eb0171cb,ebb76a2a,add56c7c,6d3102a,9c3ee18c,bd2039ec,c390839f,e2d4451c,9437fef6,3e98dc62,3ab0eea4,c56376f2,e270f626), +S(2ea6c313,1e101867,2454e15c,d34d5fad,13829d5,4ca86062,f074e512,a274167e,67e3d34a,56f12e1b,43687f51,c2d56395,14355d7d,9cc52726,22f62ab8,91c8d5de), +S(d66bdd78,8b20da57,b2485804,a2f6e2ef,78c7ca87,ae1c5c66,fc533533,5b624162,1a8688a1,300e6d39,e130037d,3f074ccc,57addd1b,88977e64,2ab296ac,d6e054c9), +S(6d6458d5,d1683d85,8f9e40,15e5a94a,73868bda,54f6139c,446b5283,6d211542,e44c7ca8,33761e13,ca5458ff,dc682f22,3819411c,a3c5feb6,24f06412,471b9f5a), +S(49f8063,b3d98f6,f159f2e6,65b0e07,8ef8c7df,44da06c3,55b592ac,13402b9d,b0b2d838,4b24ab11,de895013,e897e825,45c3e8dd,6cdb0990,555cd871,5841f8cd), +S(8b2fb6bd,e60449da,2684f8e3,6267fff7,254051ac,faea37cb,102c9bfa,91abb2ca,c82cb9ab,c33c1817,10d3fb19,60f2850b,5072eb47,404266f7,c7964fb,f98027d3), +S(cf90331d,73644476,47c8f86e,eaa6e67b,f3fb4b3c,4c895b82,30ab2f38,80df1e42,9c493d94,3471efd5,ea90f723,db576a35,8cd1ee6,1a119b56,6c65b16,112eb2b4), +S(e70667cd,8d2759e,43f99417,ecc505a7,953d80dd,e7ce2cba,3c8c948b,d43a912a,92a534b3,51449a66,82395a3,b75877ae,851923a2,e791acc3,7293d728,777a2247), +S(4cc07d11,4a715e9f,4b4d0811,f0337c7e,f4bdff74,2fb008d2,1ce8a9ea,50520d47,478b279,613d92d3,dd24ae31,2658eda8,28a7d628,f0346e04,5d5d9dff,7178f093), +S(2a1cee60,4cdd3b2c,1f859bfa,af63d7e3,9aaad910,92c2a38f,a9362798,9753c30d,325c248e,d409e8f3,b96dccab,6fdb62a6,83b7eaf3,36d2864e,b821663d,ed31a6f5), +S(7c18d0bb,9a01969d,302616cb,bad8722e,d00103fa,9985a50b,765f0e2b,9a2ea14c,f6365a6c,b06e4749,c48c212c,63fff571,8f46e0cf,6fdc8c42,34d4db64,ceb72080), +S(a706754,65cde407,e853e882,8fb7a2fe,98638d7e,64b8df0f,b0a7a0b4,e629d0ee,fd694b2c,1354a5e9,415926d0,1590eaac,dbd1b36b,5ecc46b5,72467c3f,e2cc5393), +S(7ff57a63,36ec73da,cc1dc527,928cc6ff,4ec063b1,56b36292,23b8bbb0,a8ba2c7d,4d6dfc43,da0fe33a,1e75dbf5,5e5d669e,be6471d,eb8a4102,6db1a41e,9d5da637), +S(d4b1f7bc,87558c27,7e0fdf91,22bfe488,b3182555,599dd384,5cc039b5,93218e9f,992f79dd,c8f46682,5c44a54d,626b352f,7f59139b,d545f78b,44bd0b10,55c3c1fa), +S(897773f,a9de63a7,46ebf58e,248d0c21,10f90230,a792f0b6,ea5a25a0,9d1940d2,b7c7dd27,d561dde6,ca7588b,8e3a09c7,16297ba3,9d501744,f9639a25,b16b4f64), +S(2f9cb312,b071a600,e5d24cfc,79b0fdbb,f6da1527,10ec395d,53078453,1a3b07e7,49260f95,757b9b66,feeb5c20,16aa051,b444bfc8,836fd8a2,ab913e98,731fa97e), +S(5c53b27c,4c0ae241,8569c806,8dd43a5c,6fa23ac6,74d001b4,eee6a748,d86c9e6d,4e0e720a,f430972f,b0ab89b8,79a56eb4,f0af5161,cae83ca1,964a8099,f9d497c1), +S(2671ef50,5a321387,9560f0d9,e8588707,1c2b87b5,d06bb9d,dec3d179,6275b098,750ea18b,dbdcbd58,be994eb5,cb3539f5,8c3dc630,7d50bbf1,f69050d6,235826be), +S(59baa5ce,9d6e707b,b0738f4f,d37c9890,801ed796,a82afb2a,ecd2c5ba,195be65b,e6b66356,20a8a106,b58dc202,10cccdd1,e0e8c579,c92f3fbf,8b335765,b30d8291), +S(bb422d0,88abedca,e4686479,295aa1a1,77d7e68b,293bcd31,4097ddc1,af764b90,a96d33f6,46d4861d,a471f853,e0c6ae32,b1eea619,a7441504,a773f5e6,fc548805), +S(8d7df8a5,f08ba2b0,923662fc,e594f111,5295cf6e,c5aec9ca,df0f7236,fe51b362,26452215,7d8572d0,f057ec9,6f572f11,ebad3fd0,56032240,26b54df2,991f9046), +S(9e2b1637,352d8988,1e76fdec,c2dc8533,6a71b18b,3c98e59d,397602f5,8b9087d7,b997404f,1c0b1e64,90cff078,fdc47c42,aedf245a,e69d844c,18a146fa,6d8c3d13), +S(972c7bc4,6362bca6,b58f1d0b,87c0b8dc,fe91a217,7f0cd7af,404f6f06,47e09358,cfda778,a59d944b,4ec08bcb,3aabd70a,cd6f29c5,204c9161,fe2e5bd5,71d03f6c), +S(f7dd32ed,89ceaace,52e7f26b,202ea6a5,c7e8ff42,6c7ebc16,12106f7c,6fe51a54,7349c17d,d8ea6ad1,cb346e3d,26989950,3de00c11,4205b3b5,50d27ff7,67efe75d), +S(c9f96f88,3e34aed,97351928,fa77b07a,f4b01bb4,e4515f0,59745ee5,decc9fbc,6fd62453,dd6c9dab,10fb7d79,c15b4822,178eba31,258800e4,519e627e,91ef20c9), +S(9c28cc93,809b35b3,96a4c9cd,d6976391,17402ffb,5588cd76,7c41a92f,e971a9a,ca3b2634,28513516,86a661c4,747aece4,c8130d93,ff4108a6,3365e725,2bbb80ce), +S(263a3fca,437c4dbf,48ca36e6,aa892d61,abf58f6a,d3c82b1f,fe945dc,c45a15f8,604c5bec,69e0f1a7,3e8f8a80,4f762cda,96ba2198,35268887,910c8df0,e83d3044), +S(7fe42dfb,b3466ed4,d7cb8242,5e66b5e1,14a70516,b118911f,9170656a,3dbb04fa,d11385f4,b0a3a0bc,cf09374f,868cb30f,55175d77,2d3e463a,a298b6ed,1e6f6fa6), +S(53f2432b,a8171714,3fa9df3d,ff41ced2,4a29b314,bc5a8c96,f5f6400a,d7c0979,42ad1004,3e0f8648,332b1c1f,6ee4f821,b42a5b0a,361747ba,60816f2,ac84c58d)}, +{S(b8b52efd,bc367a5c,a1534bb2,f339a048,50fc4941,1668780,dcdb8b51,2daa7526,306a2236,856070ea,1e0fd846,cd571889,e20968cf,cd490bc9,facfc4e5,a5970b2a), +S(27e226b6,ed59c89,5bd20232,bc677c35,495d9601,5f37493f,5075718c,2017e42c,a130a5c8,54ed8ab3,ed657e0f,ee4a04cc,1b59a291,6e96465a,74b36144,7cc621f0), +S(1733f1c0,da38fa79,a7b37988,1822ef51,2392d8cb,59d1ad1e,afaf535a,e151fb64,a93ddb00,af779565,eeb230af,815f9434,958ad39b,387d9069,a03cfcb,8563a920), +S(e3f4b777,d06c8839,c63dfb41,73281787,72debac0,ed45b991,724c19bd,85ab3c58,2d6a84ea,745decd9,e6444b7a,dbb59fa3,21957b7c,3f8141e6,fd633d3f,7539dcdb), +S(a2b42fb8,9ac10df9,ebe804b6,c105e855,25cb05eb,7407d383,3031e216,64491ff5,d0973dbd,346a87b4,f4ddfddd,12be3131,e6c6a397,8e17be2c,bda23683,62f80765), +S(66d441a2,6b28378b,cf23d33b,ffac1163,7c23bbb7,7ad352e7,ff5cc09f,41bf6e91,982aa46e,5fa0b19a,28ecfdee,539c0ec,b5f06e2a,217f7687,6c3cbf1d,e92a6068), +S(3721fccc,20338f8a,779aceb8,eae3fc7f,bb0e4040,1de2c8e5,27941ad7,f789d0f7,d9516c54,8f457b6e,d44f6bbb,23f36c7c,e6fdc548,60e5042a,b3dd4f67,ad5ae3ea), +S(959e980,4618bed2,73b5cc48,5565df27,b8e09c9,a128a9e5,ea92e347,66e02015,cee3a227,1bddee01,3582d65d,c3e26c8a,f80a4601,abcff432,b1737127,91ca15a4), +S(f2e81d16,c19466a6,1b56931,935d03e2,aad6b8d0,7f193d97,bacdc29e,13cdcf38,afb8e973,8d563dc4,1e7688f6,c6b43b71,f366b576,9479f093,88fd09e5,faa1063f), +S(98305a48,800f92e0,bd815192,7b8658fc,60a97c64,c9f97383,68812614,3563910e,d32db8e2,6699b969,5b644c08,39f2399,f8ef45ad,a0d857c5,2d0c7c3f,96a62993), +S(8dbd4fba,113c50ba,ff3f251c,96aba9c0,440d8e69,8a1e4ec1,84fba97a,e497c443,f642b1d9,b012eef2,40c6ad38,fe441d11,cfb42ec2,a3c15540,45e64c76,c15be491), +S(deea5bb6,c7eac0a2,93e90817,836a3e55,2a7f1354,395296c8,97964c2a,4527a727,4cbe143c,c9fde617,c6142335,4323b9d8,bba13dd7,fbd46db5,cbf4ce2a,11c9c00), +S(349f46a5,8621034,9f207a07,4558787d,336cb0cf,a56c1e67,8dd3b04a,4d717f4b,a6479d8,f7f017a6,32c369c0,8679fecd,985b3c16,ff444ba0,3fe43575,8b96455a), +S(a6d818c9,dc182fd7,81343bc,b737811f,611c8499,e44a6cdb,33a36beb,7e44b545,1a8ee36e,d6e9b191,b9cbf840,3924e6b8,ac3c3f8a,cbc9a0b5,ff965d6c,734d741d), +S(f9cad333,7b82ea41,b00f3ef1,bba37b8b,fcb24e8a,175fe380,8e399b67,d21837e7,cb206854,4e7f2cda,28c035f1,b8b50009,319797da,bb498b99,d31e24e2,4fa27ca9), +S(25042b59,f9b29a9c,83d04515,c78f1c25,5b72f97f,7b387113,e88c36b9,9da3ebdc,d966ba9e,a7eb9734,e1481cb7,2df63252,7492e1c4,43f1fc9,c0efe0af,442b5a13), +S(e19c4319,b5c9a01e,b588c629,8a7c6b76,1b80bf4b,e39424e0,666ddc45,fd57e0f6,1b0a2c30,4a1bb1b1,9dd0b50d,29df625,bf958a73,46cc6b1d,81a213a3,b6636285), +S(59c26fc1,6d151c0c,7da0edf6,c474463c,587c45cb,7e407589,d15aad89,de223fa0,f7b227b5,4855c1c4,1e576431,8a7106eb,ea214686,ef815b42,db8c18ae,d5c940a5), +S(d967d546,e07ac1c2,31fd50df,a1d25a51,60594d88,3e816f6a,bd62c15c,446aeff6,8eee6c03,6e22a014,5d9cf3af,9b44e005,cd1d36ce,d7c420f5,e2db918b,e4fbf83a), +S(424b149d,9104254e,3f5772b3,7d973cf2,a46bd110,89d8f850,7666f04d,382c972b,7272ad07,54c18fbd,66e2abb3,952c526,d8113d5b,166283a3,9ac8ecb6,2b7a3e46), +S(40b4b2ac,bd299270,e64bc470,8607c586,3bb50913,45e573f3,a5e2461b,47dbc053,d094311e,fd81bb1f,4622d17e,68044107,a2a8ed54,3cd5ff8c,b531b28b,9b8ec99e), +S(79e79ded,6bc0d851,fa769b5e,8d65857c,f3c1c18e,6c990cb6,116fc45b,63e9f924,4fa89e89,ae4214fc,ba2aecdb,41984788,8154eaa6,bcbbe29f,f04a6262,7299f469), +S(a11ad5ea,59c644b2,8dd7402a,5f96a970,68d96e2e,eb77d59a,fe0c2fc,cc6b252f,38e379d5,150109df,36ed7ad3,a2daa41b,4fb9c731,718cf5e3,8f8f8cf7,d1f3d770), +S(b3002b00,ec5be154,cd8e5226,4b97f5c9,f444b305,8f59c4c,bcda5edf,9d10dc88,f7e9ae65,6ad2c823,8e8e0436,e007d821,b17d9405,984eccc4,617e3977,2f25d636), +S(8d1267b1,94da1334,fd20cb8f,77fa01cf,9e9ced90,43107e41,d1ec4057,eb6115a2,a7ba1b9e,2c6f0f19,5ff1f50a,7a8da22f,da3003fa,44b818b9,953b44d3,e6d6a0df), +S(dde6a3a0,87ef41db,2359e4e7,ca7cb064,424301e7,c5cbb5bc,4b6e504a,f3af4837,24175b1c,b4b39b7e,23718e26,be4a22bb,8bf54302,1f156234,e7f18010,d538aeb), +S(79efa584,2fb89f4e,85f556e,c4be170d,5c1ef88a,3f3f75cf,6b20fc1a,96984ad,b0704aaf,e4d8f30f,4f29fa85,6d55da13,91f5f3ce,36cdef6f,25133999,cc8541a), +S(3aa09dc0,5546977f,7369fa0a,7b60c94b,eab86a1,10d85af7,7b826475,7d67eaf5,343b4cf3,aa6c5ebc,ed041d7f,2381be57,f7fd32d0,29a2f42,a7c8821,4f425d8), +S(53fe8af9,8f9419fb,1445bb6a,94750d46,46be9f37,b7155763,88b11064,df2e6ffa,6cd77e81,84aeab9d,e9bf3093,bb9b21a3,a04a0719,fc428f3d,d5e14c8c,9b16cd7a), +S(fc395dc4,a5114dc8,bcb0f7f0,3a4d3e9,38a87a3d,78d33864,d1dc4cba,9e41e20e,c7991f6e,f72f82f6,b3147e56,74224929,fddeb8a5,97a1b1d4,8852733c,1830b941), +S(b1d25d51,b4558f5f,d0ccb868,3af9a9cf,62a169c6,91627fa5,92d80b18,36695f94,8f92258d,fcf16f4e,8415f53,e65457e8,9f090e72,5479c123,5a481464,a11cd4f9), +S(b866d6b1,42df940f,2cf28b54,c92f0c12,94e0b6a2,2a91f2ef,44bcd88c,4384480d,e6eb4f4c,bd95148f,765d8728,15652853,db1add7f,b4e27929,f19a64b7,f3b34c87)}, +{S(d4aaf32e,dd897f48,5ab16466,76d747cd,fec5b7a0,a05c917b,60c07311,45d16f89,4857e649,beff4089,2470f700,cadb73ae,d4866a84,c3f0b975,6fd8570e,df9d29d8), +S(4ebe5b8a,f3b1583c,9f41bd98,afaba549,f45c381e,c93ec9d1,4a543d87,9cefbaf3,63ed1d17,9b215f34,f1f580be,4b3f671f,2fa14689,74cd03d1,19fadae3,c92935ff), +S(20df6160,556dd3c5,a26620a8,70ff5323,cbbab94,be3e3bdd,ad8b936c,554f28f1,7168e7ab,cdbafad,26fbb5be,a09dadde,ed36c20f,c8deafaf,75a480b5,f980e981), +S(86c663f2,cc6f7ee2,50be25fd,fb35fd8e,5873481b,c477bf5b,c0f1bc1e,3f1320f,c13c5795,cce0ad92,e31240da,90a823d0,d2352314,f2852e67,cb62e0c2,8570994a), +S(3fd8085e,57f6870,b25e41d9,7df00126,150f6022,a7ede22f,d27da581,d234ccaa,c6657746,98d6ac03,ed1ea2d7,bd3f70be,86351c5d,407a4d7c,227fd7d0,c330ef04), +S(1510fcf0,b0fb5a23,c15e041,2a7f6d89,9fac4244,8ce316bf,d88fb58b,10e23118,1879dc07,b34d0a62,f0b9517f,3629ae0f,e8aa6d30,5a783f37,69bdf65,3b40408e), +S(67e9982b,c40f427,98df055c,2d8bdcc0,2ea97bad,68d34024,85498e27,d99e19e4,4f087caa,efc5fd7f,b099c134,a273635c,d1d5ace3,26e3103f,9b2fe22c,e95f288e), +S(e8eeab21,6c3395d6,d16338ea,de4108da,1c25e471,67fb13d5,99e8daaf,93e7345f,7fd2ba87,7c7266a5,65a31548,99950ea1,e5e3d73f,612addea,318ad5bc,a965228d), +S(ab20c7c8,9dd74c20,447bc762,e374c548,e7a8ac31,eec11123,1a040cd1,36e9a546,facacfb2,52eb9532,9106a26a,60128a0f,ae1d7e5c,fd39483c,aeb54dd9,231b55ee), +S(a9004211,b7cf5494,1c530a0e,d658fb6e,3b5d2ee1,37b7d7de,45fef6b5,efddbf0f,58cbaf67,5cc5a131,54eef7a1,462b5d1c,408d5d56,3553ca55,45388d77,c6391d4f), +S(8db64274,422ae0f5,6474b83a,89912fa,e3a39b6c,b3fb8370,308a572e,b6b3c020,9b71a72d,431fd44,aa8632ee,23bc678,61d96edd,b7ec72ab,4b1679b8,a4ba73e4), +S(301b330,c478189d,dce4314f,380cb2d8,38bbd416,5dfad8c4,90f2443f,2a56148b,737da0,1c05cf73,db36a1a4,5005f562,1327167f,d3b60ece,3da3705d,131903fe), +S(b9cbc7a3,4a1cbdd1,300e789d,b7ffec1c,dfe1f738,fbe1fe19,67dd7c14,92ee3ba7,5a816a0,9d08c4be,2b8d062f,200fde4c,534fbdbf,854c7e53,64532c08,60c97c01), +S(6a15e51,6f9f0a7c,25f2eac7,649285ea,d86a1e01,5a386dc,c7f94ba8,4782b45b,63eafaf4,660642ef,988aeee7,642e7c4b,71124a1c,2ca2f5c3,d4f2eec9,ea72d70e), +S(f4c696f3,34c56e08,2ab2e627,4d450f34,fa7fbce,29f3e14d,332bcadf,87d5fe0d,6ee44edf,f574d9a8,363f98b6,b863a648,27d3020,1e652935,be12041c,1bbcc7c3), +S(d2f3d5ad,237ba177,ed312bbb,1d02fb2a,e4bda20f,41f5c217,8b70dd9a,c26ee9b0,cc5912d4,2ea1af01,aa914b98,8c42cef8,46a5a059,664c8545,fc00b662,e0327920), +S(5588b0a4,757beb33,e668af5f,adf87fb3,2aed8e16,e6ceabf1,1576ae17,c6a2b843,70d8961b,ac203e89,c437b88b,ce331309,c4f7eca8,d614299c,74aef9b2,17c741de), +S(f993cd07,f6eb75ad,d41426d5,cc653886,18dde1f0,88aaf3cd,b2631eea,158373e0,1e74f804,5f60349e,a85b90e1,206f0ea4,b0cd3740,861186be,648063e8,58c2b395), +S(2cd04170,78291a50,750218b9,44a11a64,1cb75e7d,cd5cc4f9,64f53c8d,a1ef08f4,1f54a70f,f66ce343,c7ed3001,78d7b99e,49129e23,90b5a026,7ba25af5,3467b6d3), +S(52fc09a1,d4f0cc2e,c7ba6cba,1b30e1f0,b9e37f31,3bf59c33,60fc02e3,3b0c15e8,9bd14bcd,a7c7b6ab,dd7e17dd,ab81a1cf,846be336,a76858a1,8e8a0194,776f0a80), +S(90d29aba,764a9b49,1e2878c2,9b964bf6,e510af,3dd5aeb9,3fe29e13,b8f03b23,396b1f6d,e9b8fd1f,463ca064,11b09823,26cb6ab7,4bbbcaef,43031497,f149a620), +S(ce1d6e8e,ddd063f4,316cb006,b4a4213d,9e0952c8,43e6e1e7,570a35e,aad7fa53,a1abcd7,e2c23ad0,895c5aa8,82a805cd,1d7d434c,72f0c528,2ceec0b7,a7016f7c), +S(4df6e1d3,93a4be66,6fd88c75,e1e686a1,e2cb1844,f5f1303e,f7b0a751,99b42bf5,262d8b9,f7e202a3,78a51928,91ee3fc9,f269ef5d,e14dd0ff,f1fec9f4,4cdb9058), +S(f71b9bfa,bcc353a4,11a055eb,a7d6f48f,47c4e437,96382bcc,d5b882cd,a9059638,bfc1c3f8,fea7df8b,d1cd088c,b1f02e47,377d6656,9b3bd8a2,8b457ba5,e6453468), +S(ad5e9212,d3ef76d,8319fd98,72ee753f,ec99fab0,6244f4e2,a9567068,a635eb53,65fb538f,cb570092,7b0f775a,73ffb0c1,4e6c2274,e253f3a6,2dba9caa,27a3e5e4), +S(81a7dfa0,7659fdbd,57e1c8ae,20c14a80,ee8bfc51,46caa8db,b077b653,23bad4a,ac9d2438,3ef0d99f,26744be4,77e69d51,49d44ab9,84801bb,759d3a5b,7fed1e2e), +S(3bf8c1d0,a613316b,e90eab62,6788c8c3,b1641d65,d0e50245,9e5b19c1,ab1eb617,e1edb59a,8594d73,669e6f93,ca10e210,1254946b,8c9e8eac,3fa84a49,e4e2944f), +S(30f9283a,767c551c,e9fe87d9,5730eff6,fc302a4a,1810e4de,11ba62af,fa17eaae,1f383ac5,e714240d,67980617,d96b0c05,76008599,f8e3fa04,d57454e9,927e729b), +S(1c5d4ac6,91d37d0c,9db5e071,c809a59e,99056263,fbd83028,ee9530e9,c2b3f3c9,b98c7be9,7a2fb196,3d3d4a75,4f7fecce,2fbeb8fd,cf23c229,73b6875,86bd276a), +S(3dfe48e5,2f055be1,1db79fa4,501b44d8,f5ae8447,c5a1293a,a79f683f,1e1e9bf,2d7e8303,b988fc17,18c9b64c,1c03373d,27fd0c32,13c26e6c,b684ca94,49f79d5e), +S(adc4251b,c3ef6d5a,a4d6eb22,46ab2787,bc835b65,1d17ceae,489f181d,57d37248,4f0c489d,1c3a1814,a2f9c1c9,d6fe908f,4623aa44,ebaf4143,79fb8352,15234014), +S(edfe16b2,db401803,11f98920,7a2fef7,d05b2a3b,b676899f,9c6e2192,d38f93e0,1196fd0e,35a24c9,6b28b055,b4fa2f2d,a4c2aeff,3b91dd81,c2fe86c1,1d6bf682)}, +{S(b4b57b34,6e1b41b,7394e655,e059cc93,44c5d83e,f0ef17db,2789db5d,13777b78,6fa187a7,4d983b7e,cea6a268,61039430,63e599e7,cba73144,fe3eb23,677c6265), +S(9937238,7300054a,1a8713b7,6942f003,99818b28,6c6fba5d,ca60b9da,1aa7767,6c003e1,848ce30a,65601eb,e7b76acf,b2e122b6,882d7439,f463c042,ef1b31a), +S(ebd177f8,b5757665,58851c7f,a7ada38b,e3596080,f2679181,f994efd3,82714784,d0fe8eb0,97c852f7,b284d5f,bd81f77f,79c35af7,cc30338f,4e63211e,9e20a244), +S(367ef258,b279f923,a18215b7,67d396e4,c6bc874d,2be6b369,b01afffa,2e041741,bd961242,2452eddb,33831dcf,fb3a0273,30ef141f,6db77d91,5bec2ecb,553b6e6c), +S(d89f40c4,f752cff4,5bae5762,37f5096e,f27d46d0,d934d4de,c3011a28,59464e8e,9d32661e,e2319d6,f6427ea,a3014b5,cf98306c,666c4a9e,970dba2e,65e04886), +S(ef6ff862,1d84c5d5,22e490f4,db21181f,a17bafea,3e097868,4f1f0215,759772b9,ae006f11,aa85db2d,3624cf51,ae319ad2,8b4970e7,eac03301,1eb15db8,dc59d62b), +S(8b0a1b1b,d476bbfb,6da1d071,68d3a988,3b49802f,8ffa04a3,bbba1313,17c67a00,d8c74ae5,65c38597,8d9fda2e,dff6b932,1512e40b,ec5b62e2,59d4d81c,9b657b55), +S(9aa9250f,12ffde38,21384434,849d7eb7,bcafbae5,9a3b861f,68a3addb,d75d3715,19b4b1a8,8d8bfeee,38b54564,30d5f73e,ed0365fe,49092d4a,2f52fa12,b65e3ac7), +S(aaccc00f,55e96f0c,e66d9b43,12f9abd2,6772d8b4,30a6c62,edd2aab4,97acbc22,5af203cf,97d11147,82374056,f012f5f9,2825476a,820dce2e,6e1c4b33,cef5337c), +S(43c34546,2836b544,ddd6e432,6aa19b4a,9de7fdfb,86f43cae,ce98ce7c,32b1ccaf,dd518249,f1fbc1c7,1f905860,17a6f60b,15be97d4,18c66d42,f4f9adcd,d722c096), +S(9a38eb25,935441ab,8983097a,d58c821f,d784f091,5f85dc26,3f0c020b,b80c39a0,d8e6dc57,41e4ba5c,576179e8,9a6dcb4a,bd7178c6,13a1100b,e2bd731b,f3e819e2), +S(6b10527,204a4f7c,e8afcacc,fe771634,376f18da,f12774e,50f23a90,9efe0223,b443a451,529b4208,c8c98904,f5eb2ee,2e2ede2d,80ca50c5,aa29b95a,714181a), +S(1a88fecc,71d7550a,abf7faf0,8e884e95,835f6dc8,1815d2d7,7dab66ea,b238d6b2,82cf6711,1dd38ff,d0daebbc,ea2c064b,17b6b21d,34804f93,4a037936,9edec692), +S(a6b1751,f30507fe,5927b6d4,a92ebbbd,77358c02,9b750d05,a56e4d41,efb99144,ccf7c048,a2a0983d,fdcccfd,a071b80,e8035866,c479ea3a,3bbe7c80,12dfd618), +S(e186601e,8b545292,f23ae7fa,4cadc80f,1fcaa1a3,430ddec6,cfd2af47,c835cdf9,fd471f16,7c3683c9,2e5fc0c2,89b646a5,c8ebda6d,5b6da213,d862c3f6,2c292e9c), +S(91b3935,d8ce2b80,c179ee0b,87850140,4c418c7f,7cf94e4a,64b9fc9c,e396a093,45a5043b,8184546c,9083982f,550807d7,d61fe677,ce73ef21,9b3aa573,97c4eca1), +S(3fbe61fd,2a387654,dfc428e7,dac09e91,5e1ae7d6,d3794288,743f2535,20858ef5,206fd9a0,e3265118,e0a6475c,4df87e43,cc7c8898,59d8aa08,23b6dfff,b68b34d7), +S(31a35020,697d9d52,55476289,ce4fcbdc,4e1e0690,c2c36d1b,a4f4640f,e4c5ba18,91f660f9,159d463a,857f08ad,fc3c5ddd,804507c5,92f73de4,2ee44555,da538553), +S(7dc6b83a,10f26e71,e12c0bd,7ebcccc6,61b4394a,68f576fe,bfca1c23,256e8aa2,b4796977,bd386b98,f3e2fa8e,798b6548,fae52a80,40bb12ea,7e6ad675,64fc8736), +S(67a9c3ff,9c7b99b2,5318ff9e,2b85ee23,ec244655,8042ea8b,d880e23e,7d3ce221,a7bcbbbb,895ca7b1,847a43fa,98809ce4,98016123,bbb3c099,7d34debd,cb023f8d), +S(36602997,eba2c6c5,aab4cb65,8d4efd46,65ab3965,f643ff66,831646dc,f6443bf3,c82d0e80,ef775f9c,7ec7862a,e3158556,a57038d,e6850dd1,e349629c,2546239), +S(9eb9244b,299bfd76,f63bb140,ae2f42a1,4af1e072,83f8259f,6478ac03,d411df24,e43f91da,13c2ba21,a9d17d2f,7a8a629d,9051346,93a6552a,538d590,9d2bdd38), +S(ba4450fa,27d57993,3d949a1a,66013906,7d1a9716,6794993d,e45d9426,b4bfc5ed,8e3f3b9b,d8cb8210,7a5ae2af,92b96259,b73633f,6528ac04,20c3e101,6bb6d8a8), +S(e6d5335f,b67abd36,2712c7fe,575ee769,53d488b,236e8589,5664fb04,7f385248,9e255154,e070a5bb,e98e97f6,281fb999,a75e68ea,7681fdf6,fea093bd,919aa5a4), +S(63c099a9,300a331a,3bc4348a,a373e514,c84a810e,1ea8a8d1,4ac8d7cb,818eb534,ed7d4029,3cc4a086,b1d40c24,6086109,a02dbcb5,a864777,27939024,6fd6bf91), +S(7088617f,66cd93f,8130eaeb,874c3f77,3bcb0daa,78923b70,a65512a2,992554dc,5a3ff995,3c712066,291ac4a2,dfc2573e,1d0aed56,75ef526b,b15f61b0,d20f8156), +S(cc354aaf,746d756b,9387730f,2f12b999,4fcd815c,6d25cdab,2e1185aa,4aa639b3,fb1dead9,4fd76859,1aac8d79,5c337924,dc155fbe,5cd5c953,4d55ee31,f6d284a6), +S(e7e47c3a,e2bf4307,7f33ec3d,ac1ae2a7,5c669e61,e248f588,590cfe07,3e2186e0,46e9c4d5,4429fdcf,5efb375e,18f46cc8,3fa7a403,6013777f,e450e228,aebd4cd0), +S(c6ed5e63,28ec31b1,37041108,42d4ac23,fbb883bb,349d88db,1d747cf7,325fe9cc,21b8bfa4,b62807cf,d6cd11ed,a38084d5,7bb068d4,9f0dd30e,f3f431e2,b57022e4), +S(331924c7,50b3417e,48e279ff,6ed7f3dc,ba2e121e,9f69f8fb,e64093b6,c38a8cc6,357086be,e4cc0fe7,d45a49fe,41d004ce,80466165,316164ab,3b171f03,b9a7841f), +S(b4319cc9,f3e0d3b,313626ae,5385796b,c49b300c,88ba4553,dec0aa4a,77829372,b8f82bb6,6590afd4,48501f,63de3a5d,8f84edea,35c1ee44,88d6333e,f522a808), +S(da433d5e,11ceccc0,abc5c762,6ce7bab4,2e89b221,f785c409,282de545,f3fceb19,1b67242c,de57efcf,e214423b,506a1ade,718803d2,6dd84d88,97b18ede,590a2fcb)}, +{S(ebae7464,ece277b8,309d056c,cf3775e2,11a77aa,81c316a4,b6b7b953,6f90f539,62a4d6a2,95fdd811,f2051715,322f17e5,1753c9d0,835ef9a0,3e8dc9f5,c69bda31), +S(5b20700c,1af63394,a3e4cadb,b0ea682e,19cf495a,b908418a,d41f4c6c,ea4477f0,8435d15e,34b03a22,ca89c73d,326c2f88,142d2e23,8964ef6d,99287125,79738f78), +S(b2f25f91,138b974b,561328c0,92f50fdf,8a694004,fd4879d0,12a4a6cc,c8059d1d,d9ec0b2d,b8e81b2,f6feaf55,9776ff78,cda3401b,47826de0,ca06e579,9d866c09), +S(64e79790,7783d6fb,321eb785,acdeb2ff,4628270,fec3342c,527c8db0,a34c516e,c0c4da5d,abf3da9c,a8613f82,ca28e84,a1a18376,c9967c08,aaf70bea,7a2f34c2), +S(a50cae84,a08f4f32,4984853a,d4c6bdaf,77eaa788,9cb8fe95,72fd56e,9078ee73,120ecbf,76e47b38,503067c8,36853003,60ed261a,40fdf440,161ef2cd,19786b93), +S(76ff3ac8,80a451a9,6741fc70,82bc4c82,7bd51c08,95eea8c8,b422b8a9,96ba4794,25555d71,d4313a60,b189a154,58e0a40,c643c204,277334e,966e2abd,3a23f6c3), +S(307e5caa,8b708760,3d9f845b,b78f4f10,72c49c10,9747f91d,192f8d6e,70c0f4be,f5992f76,37167e1d,55cd31a6,1cdb4756,85eb1503,34fb6009,e0240a18,fa8302b8), +S(d8e62e47,b28fd165,4d420137,884dcf21,c10cb159,d9885843,da34b0d9,d09b2758,675c75b4,b903ad28,2055a71b,2c470e2b,1dce69bf,ecf160cf,3a027de2,55b723a9), +S(ec5639c7,73dac23d,3008dabf,732dc005,3154703d,26ee3bbc,7689286e,4a73e39f,aaa5ea4a,2cf5c23d,57cdd0d8,8accbbf9,9fd2c213,97bb45f8,83547876,3aab1248), +S(3d928ee3,2065557a,27722f08,5202f48f,40917ed6,c7ac1963,2a122226,8b0cb9df,ece112a4,e7a05ad6,17c2fd83,76f89102,9eb94eb0,930fb23c,a342d7f1,f021a0c7), +S(616228a5,cc6c3a92,cd694cec,4b2b8574,5dfffa90,b2a36d8f,32eaa6cc,2530de51,50d8d140,4d506a78,700f8e82,967b36a5,1b4de644,a8e22271,d509c8d2,4adf3148), +S(6f85f308,e847b145,c13a07be,bebdd4ba,6c138939,6afd8670,733f44a8,969406d0,864bcde1,be36c9c7,b7e04ef8,cd2366e2,b3c22902,5ee7efce,d005ef5b,ff7dae2b), +S(f3d1ecc3,53a82621,1bd78f0f,aa029076,c6ca779,9bdc54b2,128fa3d2,aec00c6d,75aa0cf9,fd0b7bed,19183e34,58142f66,c94a5aa9,3915435e,ae51c1fe,96625ccd), +S(a5918de3,f18cd8d1,2a234f9f,3a19fcaa,2d83671d,ad566f16,8aea2b1f,b9de41b0,c515dda6,43c0f6c8,d8fea16,5d595917,16b7f521,43d3b941,f28585ed,8a49c06c), +S(3c49e2ef,1d2d3464,81e05fa0,33366609,1615ebcf,535f68,be257f35,7bd91592,57901e0a,c8af3a31,aa404987,72c903fd,175c9b00,5c7458ee,ed667f11,57754132), +S(6c45ff2,c0c30320,83c343e6,dc80b4f7,bb64502a,52f412ff,ada521d4,a544a9f0,e9936037,f1e641eb,1cd6f801,a25271d3,cffe67d,c9bd7162,babf9855,9628a9a8), +S(66df5d95,acdf4260,ee0e465c,e3916d79,395df522,aa086aeb,6c283bb7,18296d46,cb1f3deb,8aea0337,625f46dd,903416d1,5647be91,1633c4c0,cf0e629a,413476fc), +S(428bbba5,ef351762,9eee4059,a3339213,40c7fee2,5ccb051c,88d75e53,ba618858,ef18809c,28227ccc,115876df,b3f378cd,374c0670,2c658501,7990e767,922c3999), +S(e8993820,d782657,ed8badc2,d515e360,df336730,860ef49e,65ca58dd,1a385815,feb41189,16c7e8f6,53c7f5a6,5fd7b6be,7a029814,149c4645,847073be,770959de), +S(2b77e42a,63502244,d6c7d1be,54b7857,9e2742d2,7143d689,fa3f70a3,5986ccf1,721e9da8,bee88ad4,2155dc9a,28be505,86648378,1d6af5b1,382cd47d,771e6428), +S(acffce3a,ed6beea3,2ad71633,21e1ca53,6f69ce76,fb5cd394,9d9dcc14,bbcee96,5384c97d,eac946c0,afc85b54,f3a56b79,fe263bff,63e1894c,6d52ef1b,9b456602), +S(e13d8d4b,25bece8d,90a008e4,c004824e,223b06b,7cf65ebd,1215e910,2e67b639,3e92b1f,14cbee57,9640b377,6ed5938f,9aee0e11,b139a678,3f207cf4,6dd7e20b), +S(d8f356d9,d2498eaa,b3fa12a,cb64562b,dff3e270,c7809a31,25a9ae65,9cb1f3c5,a5403cda,2d499a7c,7402b57c,c9f99e3,64f5085a,91fd8cfd,8a67c7a8,dbce04fb), +S(350062b5,22fb5d0a,8c79a5db,29e92216,79b9fbc6,3e1f95ca,e7d087f3,fedffc49,74cacf57,5e79c85b,d7e77a40,796e8750,a3ca57f2,a47cce8f,3d2de02d,b014df0b), +S(c159e630,9ab23135,58ebfb6b,22edaf93,eac8e16,77cd9f3b,1cd9492,20bf8e54,99244263,53f32608,831c6d74,da51d61,c344defe,f4c1e401,6a3db44b,4c57f4ae), +S(9e568b70,36a2daa2,fe7a3a52,49c56eb8,3fe4afa2,decebd60,c6c3245f,17bc6a13,b6643644,274eab9f,5e83c598,14978681,17c5a078,765156ae,3cb65fd3,830e06ae), +S(9bee7471,6b6c1ff5,62c1bc36,57a65de3,99a91d72,115703f4,4c3819a1,87828478,bb23a3da,ed34028a,7d39a7ed,fe2e23b,73e085a2,d6c2e51a,ef2a2076,a7c902ad), +S(c430c044,91228a7a,ea835698,ecf0f552,9aeef469,a36305cb,52902ccd,1c897473,40d0ee56,61cca82,80d11da,bffe97c4,f10c93aa,5e07224c,154b666e,bcd58c74), +S(2be073f6,b294a01b,eda0b0db,6832e4bc,23ef3889,7a859853,5ee726ef,ae0f15b1,6153f846,349c2a98,26008065,8be2a7d8,311a5e70,cc310ff8,7935a901,8d575813), +S(2934de46,a6d921f8,720567e6,b46e6362,36a7ed53,483b13ed,20958452,3225accd,5979698,26927cd7,abfe4c57,c53fc72a,48b71679,174c749d,aecdb057,e6a2d961), +S(4e9991b,92fa8c4e,4e8efe45,66966073,319e80d3,a54d4b7a,b61cfcc4,7ddaa5d5,9d03ea22,21d4d80e,261952e2,73f6a8cf,c31f6091,e5aa0a8f,2281ffbf,1345df9e), +S(ff3d6136,ffac5b0c,bfc6c5c0,c30dc01a,7ea3d56c,20bd3103,b178e3d3,ae180068,eccdc641,7b1bfff1,bf2fc8d3,2269523e,ab89890d,bffe0a19,8f594490,e7739bb8)} +#else +# error Configuration mismatch, invalid COMB_* parameters. Try deleting precomputed_ecmult_gen.c before the build. #endif }; #undef S diff --git a/src/secp256k1/src/precomputed_ecmult_gen.h b/src/secp256k1/src/precomputed_ecmult_gen.h index 7256ad2e30..283738a5ce 100644 --- a/src/secp256k1/src/precomputed_ecmult_gen.h +++ b/src/secp256k1/src/precomputed_ecmult_gen.h @@ -14,9 +14,9 @@ extern "C" { #include "group.h" #include "ecmult_gen.h" #ifdef EXHAUSTIVE_TEST_ORDER -static secp256k1_ge_storage secp256k1_ecmult_gen_prec_table[ECMULT_GEN_PREC_N(ECMULT_GEN_PREC_BITS)][ECMULT_GEN_PREC_G(ECMULT_GEN_PREC_BITS)]; +static secp256k1_ge_storage secp256k1_ecmult_gen_prec_table[COMB_BLOCKS][COMB_POINTS]; #else -extern const secp256k1_ge_storage secp256k1_ecmult_gen_prec_table[ECMULT_GEN_PREC_N(ECMULT_GEN_PREC_BITS)][ECMULT_GEN_PREC_G(ECMULT_GEN_PREC_BITS)]; +extern const secp256k1_ge_storage secp256k1_ecmult_gen_prec_table[COMB_BLOCKS][COMB_POINTS]; #endif /* defined(EXHAUSTIVE_TEST_ORDER) */ #ifdef __cplusplus diff --git a/src/secp256k1/src/scalar.h b/src/secp256k1/src/scalar.h index 98b1287bb5..70f49b1cf2 100644 --- a/src/secp256k1/src/scalar.h +++ b/src/secp256k1/src/scalar.h @@ -22,11 +22,11 @@ /** Clear a scalar to prevent the leak of sensitive data. */ static void secp256k1_scalar_clear(secp256k1_scalar *r); -/** Access bits from a scalar. All requested bits must belong to the same 32-bit limb. */ -static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count); +/** Access bits (1 < count <= 32) from a scalar. All requested bits must belong to the same 32-bit limb. */ +static uint32_t secp256k1_scalar_get_bits_limb32(const secp256k1_scalar *a, unsigned int offset, unsigned int count); -/** Access bits from a scalar. Not constant time in offset and count. */ -static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count); +/** Access bits (1 < count <= 32) from a scalar. offset + count must be < 256. Not constant time in offset and count. */ +static uint32_t secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count); /** Set a scalar from a big endian byte array. The scalar will be reduced modulo group order `n`. * In: bin: pointer to a 32-byte array. diff --git a/src/secp256k1/src/scalar_4x64_impl.h b/src/secp256k1/src/scalar_4x64_impl.h index 82cd957f16..4aaec85b99 100644 --- a/src/secp256k1/src/scalar_4x64_impl.h +++ b/src/secp256k1/src/scalar_4x64_impl.h @@ -45,23 +45,24 @@ SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsig SECP256K1_SCALAR_VERIFY(r); } -SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { +SECP256K1_INLINE static uint32_t secp256k1_scalar_get_bits_limb32(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { SECP256K1_SCALAR_VERIFY(a); + VERIFY_CHECK(count > 0 && count <= 32); VERIFY_CHECK((offset + count - 1) >> 6 == offset >> 6); - return (a->d[offset >> 6] >> (offset & 0x3F)) & ((((uint64_t)1) << count) - 1); + return (a->d[offset >> 6] >> (offset & 0x3F)) & (0xFFFFFFFF >> (32 - count)); } -SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { +SECP256K1_INLINE static uint32_t secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { SECP256K1_SCALAR_VERIFY(a); - VERIFY_CHECK(count < 32); + VERIFY_CHECK(count > 0 && count <= 32); VERIFY_CHECK(offset + count <= 256); if ((offset + count - 1) >> 6 == offset >> 6) { - return secp256k1_scalar_get_bits(a, offset, count); + return secp256k1_scalar_get_bits_limb32(a, offset, count); } else { VERIFY_CHECK((offset >> 6) + 1 < 4); - return ((a->d[offset >> 6] >> (offset & 0x3F)) | (a->d[(offset >> 6) + 1] << (64 - (offset & 0x3F)))) & ((((uint64_t)1) << count) - 1); + return ((a->d[offset >> 6] >> (offset & 0x3F)) | (a->d[(offset >> 6) + 1] << (64 - (offset & 0x3F)))) & (0xFFFFFFFF >> (32 - count)); } } diff --git a/src/secp256k1/src/scalar_8x32_impl.h b/src/secp256k1/src/scalar_8x32_impl.h index 58ae51bc02..c7d87b17d8 100644 --- a/src/secp256k1/src/scalar_8x32_impl.h +++ b/src/secp256k1/src/scalar_8x32_impl.h @@ -62,23 +62,24 @@ SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsig SECP256K1_SCALAR_VERIFY(r); } -SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { +SECP256K1_INLINE static uint32_t secp256k1_scalar_get_bits_limb32(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { SECP256K1_SCALAR_VERIFY(a); + VERIFY_CHECK(count > 0 && count <= 32); VERIFY_CHECK((offset + count - 1) >> 5 == offset >> 5); - return (a->d[offset >> 5] >> (offset & 0x1F)) & ((1 << count) - 1); + return (a->d[offset >> 5] >> (offset & 0x1F)) & (0xFFFFFFFF >> (32 - count)); } -SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { +SECP256K1_INLINE static uint32_t secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { SECP256K1_SCALAR_VERIFY(a); - VERIFY_CHECK(count < 32); + VERIFY_CHECK(count > 0 && count <= 32); VERIFY_CHECK(offset + count <= 256); if ((offset + count - 1) >> 5 == offset >> 5) { - return secp256k1_scalar_get_bits(a, offset, count); + return secp256k1_scalar_get_bits_limb32(a, offset, count); } else { VERIFY_CHECK((offset >> 5) + 1 < 8); - return ((a->d[offset >> 5] >> (offset & 0x1F)) | (a->d[(offset >> 5) + 1] << (32 - (offset & 0x1F)))) & ((((uint32_t)1) << count) - 1); + return ((a->d[offset >> 5] >> (offset & 0x1F)) | (a->d[(offset >> 5) + 1] << (32 - (offset & 0x1F)))) & (0xFFFFFFFF >> (32 - count)); } } diff --git a/src/secp256k1/src/scalar_low_impl.h b/src/secp256k1/src/scalar_low_impl.h index 0895db6a17..45d2f3e460 100644 --- a/src/secp256k1/src/scalar_low_impl.h +++ b/src/secp256k1/src/scalar_low_impl.h @@ -27,19 +27,21 @@ SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsig SECP256K1_SCALAR_VERIFY(r); } -SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { +SECP256K1_INLINE static uint32_t secp256k1_scalar_get_bits_limb32(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { SECP256K1_SCALAR_VERIFY(a); - if (offset < 32) - return ((*a >> offset) & ((((uint32_t)1) << count) - 1)); - else + VERIFY_CHECK(count > 0 && count <= 32); + if (offset < 32) { + return (*a >> offset) & (0xFFFFFFFF >> (32 - count)); + } else { return 0; + } } -SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { +SECP256K1_INLINE static uint32_t secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { SECP256K1_SCALAR_VERIFY(a); - return secp256k1_scalar_get_bits(a, offset, count); + return secp256k1_scalar_get_bits_limb32(a, offset, count); } SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar *a) { return *a >= EXHAUSTIVE_TEST_ORDER; } @@ -169,17 +171,22 @@ static SECP256K1_INLINE void secp256k1_scalar_cmov(secp256k1_scalar *r, const se static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar *x) { int i; - *r = 0; + uint32_t res = 0; SECP256K1_SCALAR_VERIFY(x); - for (i = 0; i < EXHAUSTIVE_TEST_ORDER; i++) - if ((i * *x) % EXHAUSTIVE_TEST_ORDER == 1) - *r = i; + for (i = 0; i < EXHAUSTIVE_TEST_ORDER; i++) { + if ((i * *x) % EXHAUSTIVE_TEST_ORDER == 1) { + res = i; + break; + } + } - SECP256K1_SCALAR_VERIFY(r); /* If this VERIFY_CHECK triggers we were given a noninvertible scalar (and thus * have a composite group order; fix it in exhaustive_tests.c). */ - VERIFY_CHECK(*r != 0); + VERIFY_CHECK(res != 0); + *r = res; + + SECP256K1_SCALAR_VERIFY(r); } static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_scalar *x) { diff --git a/src/secp256k1/src/secp256k1.c b/src/secp256k1/src/secp256k1.c index 15a5eede67..72d725a74e 100644 --- a/src/secp256k1/src/secp256k1.c +++ b/src/secp256k1/src/secp256k1.c @@ -36,6 +36,7 @@ #include "int128_impl.h" #include "scratch_impl.h" #include "selftest.h" +#include "hsort_impl.h" #ifdef SECP256K1_NO_BUILD # error "secp256k1.h processed without SECP256K1_BUILD defined while building secp256k1.c" @@ -75,7 +76,7 @@ const secp256k1_context *secp256k1_context_no_precomp = &secp256k1_context_stati /* Helper function that determines if a context is proper, i.e., is not the static context or a copy thereof. * - * This is intended for "context" functions such as secp256k1_context_clone. Function which need specific + * This is intended for "context" functions such as secp256k1_context_clone. Functions that need specific * features of a context should still check for these features directly. For example, a function that needs * ecmult_gen should directly check for the existence of the ecmult_gen context. */ static int secp256k1_context_is_proper(const secp256k1_context* ctx) { @@ -325,6 +326,34 @@ int secp256k1_ec_pubkey_cmp(const secp256k1_context* ctx, const secp256k1_pubkey return secp256k1_memcmp_var(out[0], out[1], sizeof(out[0])); } +static int secp256k1_ec_pubkey_sort_cmp(const void* pk1, const void* pk2, void *ctx) { + return secp256k1_ec_pubkey_cmp((secp256k1_context *)ctx, + *(secp256k1_pubkey **)pk1, + *(secp256k1_pubkey **)pk2); +} + +int secp256k1_ec_pubkey_sort(const secp256k1_context* ctx, const secp256k1_pubkey **pubkeys, size_t n_pubkeys) { + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(pubkeys != NULL); + + /* Suppress wrong warning (fixed in MSVC 19.33) */ + #if defined(_MSC_VER) && (_MSC_VER < 1933) + #pragma warning(push) + #pragma warning(disable: 4090) + #endif + + /* Casting away const is fine because neither secp256k1_hsort nor + * secp256k1_ec_pubkey_sort_cmp modify the data pointed to by the cmp_data + * argument. */ + secp256k1_hsort(pubkeys, n_pubkeys, sizeof(*pubkeys), secp256k1_ec_pubkey_sort_cmp, (void *)ctx); + + #if defined(_MSC_VER) && (_MSC_VER < 1933) + #pragma warning(pop) + #endif + + return 1; +} + static void secp256k1_ecdsa_signature_load(const secp256k1_context* ctx, secp256k1_scalar* r, secp256k1_scalar* s, const secp256k1_ecdsa_signature* sig) { (void)ctx; if (sizeof(secp256k1_scalar) == 32) { @@ -515,7 +544,7 @@ static int secp256k1_ecdsa_sign_inner(const secp256k1_context* ctx, secp256k1_sc break; } is_nonce_valid = secp256k1_scalar_set_b32_seckey(&non, nonce32); - /* The nonce is still secret here, but it being invalid is is less likely than 1:2^255. */ + /* The nonce is still secret here, but it being invalid is less likely than 1:2^255. */ secp256k1_declassify(ctx, &is_nonce_valid, sizeof(is_nonce_valid)); if (is_nonce_valid) { ret = secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, r, s, &sec, &msg, &non, recid); diff --git a/src/secp256k1/src/testrand.h b/src/secp256k1/src/testrand.h index 721099d039..3c1ed3d45d 100644 --- a/src/secp256k1/src/testrand.h +++ b/src/secp256k1/src/testrand.h @@ -12,37 +12,37 @@ /* A non-cryptographic RNG used only for test infrastructure. */ /** Seed the pseudorandom number generator for testing. */ -SECP256K1_INLINE static void secp256k1_testrand_seed(const unsigned char *seed16); +SECP256K1_INLINE static void testrand_seed(const unsigned char *seed16); /** Generate a pseudorandom number in the range [0..2**32-1]. */ -SECP256K1_INLINE static uint32_t secp256k1_testrand32(void); +SECP256K1_INLINE static uint32_t testrand32(void); /** Generate a pseudorandom number in the range [0..2**64-1]. */ -SECP256K1_INLINE static uint64_t secp256k1_testrand64(void); +SECP256K1_INLINE static uint64_t testrand64(void); /** Generate a pseudorandom number in the range [0..2**bits-1]. Bits must be 1 or * more. */ -SECP256K1_INLINE static uint64_t secp256k1_testrand_bits(int bits); +SECP256K1_INLINE static uint64_t testrand_bits(int bits); /** Generate a pseudorandom number in the range [0..range-1]. */ -static uint32_t secp256k1_testrand_int(uint32_t range); +static uint32_t testrand_int(uint32_t range); /** Generate a pseudorandom 32-byte array. */ -static void secp256k1_testrand256(unsigned char *b32); +static void testrand256(unsigned char *b32); /** Generate a pseudorandom 32-byte array with long sequences of zero and one bits. */ -static void secp256k1_testrand256_test(unsigned char *b32); +static void testrand256_test(unsigned char *b32); /** Generate pseudorandom bytes with long sequences of zero and one bits. */ -static void secp256k1_testrand_bytes_test(unsigned char *bytes, size_t len); +static void testrand_bytes_test(unsigned char *bytes, size_t len); /** Flip a single random bit in a byte array */ -static void secp256k1_testrand_flip(unsigned char *b, size_t len); +static void testrand_flip(unsigned char *b, size_t len); /** Initialize the test RNG using (hex encoded) array up to 16 bytes, or randomly if hexseed is NULL. */ -static void secp256k1_testrand_init(const char* hexseed); +static void testrand_init(const char* hexseed); /** Print final test information. */ -static void secp256k1_testrand_finish(void); +static void testrand_finish(void); #endif /* SECP256K1_TESTRAND_H */ diff --git a/src/secp256k1/src/testrand_impl.h b/src/secp256k1/src/testrand_impl.h index fe97620435..07564f7f3f 100644 --- a/src/secp256k1/src/testrand_impl.h +++ b/src/secp256k1/src/testrand_impl.h @@ -17,7 +17,7 @@ static uint64_t secp256k1_test_state[4]; -SECP256K1_INLINE static void secp256k1_testrand_seed(const unsigned char *seed16) { +SECP256K1_INLINE static void testrand_seed(const unsigned char *seed16) { static const unsigned char PREFIX[19] = "secp256k1 test init"; unsigned char out32[32]; secp256k1_sha256 hash; @@ -40,7 +40,7 @@ SECP256K1_INLINE static uint64_t rotl(const uint64_t x, int k) { return (x << k) | (x >> (64 - k)); } -SECP256K1_INLINE static uint64_t secp256k1_testrand64(void) { +SECP256K1_INLINE static uint64_t testrand64(void) { /* Test-only Xoshiro256++ RNG. See https://prng.di.unimi.it/ */ const uint64_t result = rotl(secp256k1_test_state[0] + secp256k1_test_state[3], 23) + secp256k1_test_state[0]; const uint64_t t = secp256k1_test_state[1] << 17; @@ -53,16 +53,16 @@ SECP256K1_INLINE static uint64_t secp256k1_testrand64(void) { return result; } -SECP256K1_INLINE static uint64_t secp256k1_testrand_bits(int bits) { +SECP256K1_INLINE static uint64_t testrand_bits(int bits) { if (bits == 0) return 0; - return secp256k1_testrand64() >> (64 - bits); + return testrand64() >> (64 - bits); } -SECP256K1_INLINE static uint32_t secp256k1_testrand32(void) { - return secp256k1_testrand64() >> 32; +SECP256K1_INLINE static uint32_t testrand32(void) { + return testrand64() >> 32; } -static uint32_t secp256k1_testrand_int(uint32_t range) { +static uint32_t testrand_int(uint32_t range) { uint32_t mask = 0; uint32_t range_copy; /* Reduce range by 1, changing its meaning to "maximum value". */ @@ -76,15 +76,15 @@ static uint32_t secp256k1_testrand_int(uint32_t range) { } /* Generation loop. */ while (1) { - uint32_t val = secp256k1_testrand64() & mask; + uint32_t val = testrand64() & mask; if (val <= range) return val; } } -static void secp256k1_testrand256(unsigned char *b32) { +static void testrand256(unsigned char *b32) { int i; for (i = 0; i < 4; ++i) { - uint64_t val = secp256k1_testrand64(); + uint64_t val = testrand64(); b32[0] = val; b32[1] = val >> 8; b32[2] = val >> 16; @@ -97,14 +97,14 @@ static void secp256k1_testrand256(unsigned char *b32) { } } -static void secp256k1_testrand_bytes_test(unsigned char *bytes, size_t len) { +static void testrand_bytes_test(unsigned char *bytes, size_t len) { size_t bits = 0; memset(bytes, 0, len); while (bits < len * 8) { int now; uint32_t val; - now = 1 + (secp256k1_testrand_bits(6) * secp256k1_testrand_bits(5) + 16) / 31; - val = secp256k1_testrand_bits(1); + now = 1 + (testrand_bits(6) * testrand_bits(5) + 16) / 31; + val = testrand_bits(1); while (now > 0 && bits < len * 8) { bytes[bits / 8] |= val << (bits % 8); now--; @@ -113,15 +113,15 @@ static void secp256k1_testrand_bytes_test(unsigned char *bytes, size_t len) { } } -static void secp256k1_testrand256_test(unsigned char *b32) { - secp256k1_testrand_bytes_test(b32, 32); +static void testrand256_test(unsigned char *b32) { + testrand_bytes_test(b32, 32); } -static void secp256k1_testrand_flip(unsigned char *b, size_t len) { - b[secp256k1_testrand_int(len)] ^= (1 << secp256k1_testrand_bits(3)); +static void testrand_flip(unsigned char *b, size_t len) { + b[testrand_int(len)] ^= (1 << testrand_bits(3)); } -static void secp256k1_testrand_init(const char* hexseed) { +static void testrand_init(const char* hexseed) { unsigned char seed16[16] = {0}; if (hexseed && strlen(hexseed) != 0) { int pos = 0; @@ -155,12 +155,12 @@ static void secp256k1_testrand_init(const char* hexseed) { } printf("random seed = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", seed16[0], seed16[1], seed16[2], seed16[3], seed16[4], seed16[5], seed16[6], seed16[7], seed16[8], seed16[9], seed16[10], seed16[11], seed16[12], seed16[13], seed16[14], seed16[15]); - secp256k1_testrand_seed(seed16); + testrand_seed(seed16); } -static void secp256k1_testrand_finish(void) { +static void testrand_finish(void) { unsigned char run32[32]; - secp256k1_testrand256(run32); + testrand256(run32); printf("random run = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", run32[0], run32[1], run32[2], run32[3], run32[4], run32[5], run32[6], run32[7], run32[8], run32[9], run32[10], run32[11], run32[12], run32[13], run32[14], run32[15]); } diff --git a/src/secp256k1/src/tests.c b/src/secp256k1/src/tests.c index 85b4881295..6b401e52c0 100644 --- a/src/secp256k1/src/tests.c +++ b/src/secp256k1/src/tests.c @@ -96,122 +96,6 @@ static void uncounting_illegal_callback_fn(const char* str, void* data) { (*p)--; } -static void random_field_element_magnitude(secp256k1_fe *fe, int m) { - secp256k1_fe zero; - int n = secp256k1_testrand_int(m + 1); - secp256k1_fe_normalize(fe); - if (n == 0) { - return; - } - secp256k1_fe_clear(&zero); - secp256k1_fe_negate(&zero, &zero, 0); - secp256k1_fe_mul_int_unchecked(&zero, n - 1); - secp256k1_fe_add(fe, &zero); -#ifdef VERIFY - CHECK(fe->magnitude == n); -#endif -} - -static void random_fe_test(secp256k1_fe *x) { - unsigned char bin[32]; - do { - secp256k1_testrand256_test(bin); - if (secp256k1_fe_set_b32_limit(x, bin)) { - return; - } - } while(1); -} - -static void random_fe_non_zero_test(secp256k1_fe *fe) { - do { - random_fe_test(fe); - } while(secp256k1_fe_is_zero(fe)); -} - -static void random_fe_magnitude(secp256k1_fe *fe) { - random_field_element_magnitude(fe, 8); -} - -static void random_ge_x_magnitude(secp256k1_ge *ge) { - random_field_element_magnitude(&ge->x, SECP256K1_GE_X_MAGNITUDE_MAX); -} - -static void random_ge_y_magnitude(secp256k1_ge *ge) { - random_field_element_magnitude(&ge->y, SECP256K1_GE_Y_MAGNITUDE_MAX); -} - -static void random_gej_x_magnitude(secp256k1_gej *gej) { - random_field_element_magnitude(&gej->x, SECP256K1_GEJ_X_MAGNITUDE_MAX); -} - -static void random_gej_y_magnitude(secp256k1_gej *gej) { - random_field_element_magnitude(&gej->y, SECP256K1_GEJ_Y_MAGNITUDE_MAX); -} - -static void random_gej_z_magnitude(secp256k1_gej *gej) { - random_field_element_magnitude(&gej->z, SECP256K1_GEJ_Z_MAGNITUDE_MAX); -} - -static void random_group_element_test(secp256k1_ge *ge) { - secp256k1_fe fe; - do { - random_fe_test(&fe); - if (secp256k1_ge_set_xo_var(ge, &fe, secp256k1_testrand_bits(1))) { - secp256k1_fe_normalize(&ge->y); - break; - } - } while(1); - ge->infinity = 0; -} - -static void random_group_element_jacobian_test(secp256k1_gej *gej, const secp256k1_ge *ge) { - secp256k1_fe z2, z3; - random_fe_non_zero_test(&gej->z); - secp256k1_fe_sqr(&z2, &gej->z); - secp256k1_fe_mul(&z3, &z2, &gej->z); - secp256k1_fe_mul(&gej->x, &ge->x, &z2); - secp256k1_fe_mul(&gej->y, &ge->y, &z3); - gej->infinity = ge->infinity; -} - -static void random_gej_test(secp256k1_gej *gej) { - secp256k1_ge ge; - random_group_element_test(&ge); - random_group_element_jacobian_test(gej, &ge); -} - -static void random_scalar_order_test(secp256k1_scalar *num) { - do { - unsigned char b32[32]; - int overflow = 0; - secp256k1_testrand256_test(b32); - secp256k1_scalar_set_b32(num, b32, &overflow); - if (overflow || secp256k1_scalar_is_zero(num)) { - continue; - } - break; - } while(1); -} - -static void random_scalar_order(secp256k1_scalar *num) { - do { - unsigned char b32[32]; - int overflow = 0; - secp256k1_testrand256(b32); - secp256k1_scalar_set_b32(num, b32, &overflow); - if (overflow || secp256k1_scalar_is_zero(num)) { - continue; - } - break; - } while(1); -} - -static void random_scalar_order_b32(unsigned char *b32) { - secp256k1_scalar num; - random_scalar_order(&num); - secp256k1_scalar_get_b32(b32, &num); -} - static void run_xoshiro256pp_tests(void) { { size_t i; @@ -233,9 +117,9 @@ static void run_xoshiro256pp_tests(void) { 0x4C, 0xCC, 0xC1, 0x18, 0xB2, 0xD8, 0x8F, 0xEF, 0x43, 0x26, 0x15, 0x57, 0x37, 0x00, 0xEF, 0x30, }; - secp256k1_testrand_seed(seed16); + testrand_seed(seed16); for (i = 0; i < 17; i++) { - secp256k1_testrand256(buf32); + testrand256(buf32); } CHECK(secp256k1_memcmp_var(buf32, buf32_expected, sizeof(buf32)) == 0); } @@ -248,8 +132,9 @@ static void run_selftest_tests(void) { static int ecmult_gen_context_eq(const secp256k1_ecmult_gen_context *a, const secp256k1_ecmult_gen_context *b) { return a->built == b->built - && secp256k1_scalar_eq(&a->blind, &b->blind) - && secp256k1_gej_eq_var(&a->initial, &b->initial); + && secp256k1_scalar_eq(&a->scalar_offset, &b->scalar_offset) + && secp256k1_ge_eq_var(&a->ge_offset, &b->ge_offset) + && secp256k1_fe_equal(&a->proj_blind, &b->proj_blind); } static int context_eq(const secp256k1_context *a, const secp256k1_context *b) { @@ -443,14 +328,14 @@ static void run_proper_context_tests(int use_prealloc) { CHECK(context_eq(my_ctx, my_ctx_fresh)); /*** attempt to use them ***/ - random_scalar_order_test(&msg); - random_scalar_order_test(&key); + testutil_random_scalar_order_test(&msg); + testutil_random_scalar_order_test(&key); secp256k1_ecmult_gen(&my_ctx->ecmult_gen_ctx, &pubj, &key); secp256k1_ge_set_gej(&pub, &pubj); /* obtain a working nonce */ do { - random_scalar_order_test(&nonce); + testutil_random_scalar_order_test(&nonce); } while(!secp256k1_ecdsa_sig_sign(&my_ctx->ecmult_gen_ctx, &sigr, &sigs, &key, &msg, &nonce, NULL)); /* try signing */ @@ -607,7 +492,7 @@ static void run_sha256_known_output_tests(void) { CHECK(secp256k1_memcmp_var(out, outputs[i], 32) == 0); /* 2. Run: split the input bytestrings randomly before writing */ if (strlen(inputs[i]) > 0) { - int split = secp256k1_testrand_int(strlen(inputs[i])); + int split = testrand_int(strlen(inputs[i])); secp256k1_sha256_initialize(&hasher); j = repeat[i]; while (j > 0) { @@ -768,7 +653,7 @@ static void run_hmac_sha256_tests(void) { secp256k1_hmac_sha256_finalize(&hasher, out); CHECK(secp256k1_memcmp_var(out, outputs[i], 32) == 0); if (strlen(inputs[i]) > 0) { - int split = secp256k1_testrand_int(strlen(inputs[i])); + int split = testrand_int(strlen(inputs[i])); secp256k1_hmac_sha256_initialize(&hasher, (const unsigned char*)(keys[i]), strlen(keys[i])); secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i]), split); secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i] + split), strlen(inputs[i]) - split); @@ -968,7 +853,7 @@ static void signed30_to_uint16(uint16_t* out, const secp256k1_modinv32_signed30* static void mutate_sign_signed30(secp256k1_modinv32_signed30* x) { int i; for (i = 0; i < 16; ++i) { - int pos = secp256k1_testrand_bits(3); + int pos = testrand_bits(3); if (x->v[pos] > 0 && x->v[pos + 1] <= 0x3fffffff) { x->v[pos] -= 0x40000000; x->v[pos + 1] += 1; @@ -1060,7 +945,7 @@ static void mutate_sign_signed62(secp256k1_modinv64_signed62* x) { static const int64_t M62 = (int64_t)(UINT64_MAX >> 2); int i; for (i = 0; i < 8; ++i) { - int pos = secp256k1_testrand_bits(2); + int pos = testrand_bits(2); if (x->v[pos] > 0 && x->v[pos + 1] <= M62) { x->v[pos] -= (M62 + 1); x->v[pos + 1] += 1; @@ -1773,8 +1658,8 @@ static void run_modinv_tests(void) { /* generate random xd and md, so that md is odd, md>1, xd<md, and gcd(xd,md)=1 */ do { /* generate random xd and md (with many subsequent 0s and 1s) */ - secp256k1_testrand256_test((unsigned char*)xd); - secp256k1_testrand256_test((unsigned char*)md); + testrand256_test((unsigned char*)xd); + testrand256_test((unsigned char*)md); md[0] |= 1; /* modulus must be odd */ /* If modulus is 1, find another one. */ ok = md[0] != 1; @@ -1906,7 +1791,7 @@ static void run_int128_test_case(void) { int i; /* Generate 32-byte random value. */ - secp256k1_testrand256_test(buf); + testrand256_test(buf); /* Convert into 4 64-bit integers. */ for (i = 0; i < 4; ++i) { uint64_t vi = 0; @@ -2132,13 +2017,13 @@ static void scalar_test(void) { unsigned char c[32]; /* Set 's' to a random scalar, with value 'snum'. */ - random_scalar_order_test(&s); + testutil_random_scalar_order_test(&s); /* Set 's1' to a random scalar, with value 's1num'. */ - random_scalar_order_test(&s1); + testutil_random_scalar_order_test(&s1); /* Set 's2' to a random scalar, with value 'snum2', and byte array representation 'c'. */ - random_scalar_order_test(&s2); + testutil_random_scalar_order_test(&s2); secp256k1_scalar_get_b32(c, &s2); { @@ -2149,7 +2034,7 @@ static void scalar_test(void) { for (i = 0; i < 256; i += 4) { secp256k1_scalar t; int j; - secp256k1_scalar_set_int(&t, secp256k1_scalar_get_bits(&s, 256 - 4 - i, 4)); + secp256k1_scalar_set_int(&t, secp256k1_scalar_get_bits_limb32(&s, 256 - 4 - i, 4)); for (j = 0; j < 4; j++) { secp256k1_scalar_add(&n, &n, &n); } @@ -2166,7 +2051,7 @@ static void scalar_test(void) { while (i < 256) { secp256k1_scalar t; int j; - int now = secp256k1_testrand_int(15) + 1; + int now = testrand_int(15) + 1; if (now + i > 256) { now = 256 - i; } @@ -2193,7 +2078,7 @@ static void scalar_test(void) { secp256k1_scalar b; int i; /* Test add_bit. */ - int bit = secp256k1_testrand_bits(8); + int bit = testrand_bits(8); secp256k1_scalar_set_int(&b, 1); CHECK(secp256k1_scalar_is_one(&b)); for (i = 0; i < bit; i++) { @@ -2286,7 +2171,7 @@ static void run_scalar_set_b32_seckey_tests(void) { secp256k1_scalar s2; /* Usually set_b32 and set_b32_seckey give the same result */ - random_scalar_order_b32(b32); + testutil_random_scalar_order_b32(b32); secp256k1_scalar_set_b32(&s1, b32, NULL); CHECK(secp256k1_scalar_set_b32_seckey(&s2, b32) == 1); CHECK(secp256k1_scalar_eq(&s1, &s2) == 1); @@ -2947,7 +2832,7 @@ static void run_scalar_tests(void) { static void random_fe_non_square(secp256k1_fe *ns) { secp256k1_fe r; - random_fe_non_zero(ns); + testutil_random_fe_non_zero(ns); if (secp256k1_fe_sqrt(&r, ns)) { secp256k1_fe_negate(ns, ns, 1); } @@ -3124,12 +3009,12 @@ static void run_field_misc(void) { for (i = 0; i < 1000 * COUNT; i++) { secp256k1_fe_storage xs, ys, zs; if (i & 1) { - random_fe(&x); + testutil_random_fe(&x); } else { - random_fe_test(&x); + testutil_random_fe_test(&x); } - random_fe_non_zero(&y); - v = secp256k1_testrand_bits(15); + testutil_random_fe_non_zero(&y); + v = testrand_bits(15); /* Test that fe_add_int is equivalent to fe_set_int + fe_add. */ secp256k1_fe_set_int(&q, v); /* q = v */ z = x; /* z = x */ @@ -3267,14 +3152,14 @@ static void run_fe_mul(void) { int i; for (i = 0; i < 100 * COUNT; ++i) { secp256k1_fe a, b, c, d; - random_fe(&a); - random_fe_magnitude(&a); - random_fe(&b); - random_fe_magnitude(&b); - random_fe_test(&c); - random_fe_magnitude(&c); - random_fe_test(&d); - random_fe_magnitude(&d); + testutil_random_fe(&a); + testutil_random_fe_magnitude(&a, 8); + testutil_random_fe(&b); + testutil_random_fe_magnitude(&b, 8); + testutil_random_fe_test(&c); + testutil_random_fe_magnitude(&c, 8); + testutil_random_fe_test(&d); + testutil_random_fe_magnitude(&d, 8); test_fe_mul(&a, &a, 1); test_fe_mul(&c, &c, 1); test_fe_mul(&a, &b, 0); @@ -3296,7 +3181,7 @@ static void run_sqr(void) { secp256k1_fe_normalize(&x); /* Check that (x+y)*(x-y) = x^2 - y*2 for some random values y */ - random_fe_test(&y); + testutil_random_fe_test(&y); lhs = x; secp256k1_fe_add(&lhs, &y); /* lhs = x+y */ @@ -3350,7 +3235,7 @@ static void run_sqrt(void) { int j; random_fe_non_square(&ns); for (j = 0; j < COUNT; j++) { - random_fe(&x); + testutil_random_fe(&x); secp256k1_fe_sqr(&s, &x); CHECK(secp256k1_fe_is_square_var(&s)); test_sqrt(&s, &x); @@ -3664,7 +3549,7 @@ static void run_inverse_tests(void) /* test 128*count random inputs; half with testrand256_test, half with testrand256 */ for (testrand = 0; testrand <= 1; ++testrand) { for (i = 0; i < 64 * COUNT; ++i) { - (testrand ? secp256k1_testrand256_test : secp256k1_testrand256)(b32); + (testrand ? testrand256_test : testrand256)(b32); secp256k1_scalar_set_b32(&x_scalar, b32, NULL); secp256k1_fe_set_b32_mod(&x_fe, b32); for (var = 0; var <= 1; ++var) { @@ -3675,6 +3560,78 @@ static void run_inverse_tests(void) } } +/***** HSORT TESTS *****/ + +static void test_heap_swap(void) { + unsigned char a[600]; + unsigned char e[sizeof(a)]; + memset(a, 21, 200); + memset(a + 200, 99, 200); + memset(a + 400, 42, 200); + memset(e, 42, 200); + memset(e + 200, 99, 200); + memset(e + 400, 21, 200); + secp256k1_heap_swap(a, 0, 2, 200); + CHECK(secp256k1_memcmp_var(a, e, sizeof(a)) == 0); +} + +static void test_hsort_is_sorted(unsigned char *elements, size_t n, size_t len) { + size_t i; + for (i = 1; i < n; i++) { + CHECK(secp256k1_memcmp_var(&elements[(i-1) * len], &elements[i * len], len) <= 0); + } +} + +struct test_hsort_cmp_data { + size_t counter; + size_t element_len; +}; + + +static int test_hsort_cmp(const void *ele1, const void *ele2, void *data) { + struct test_hsort_cmp_data *d = (struct test_hsort_cmp_data *) data; + d->counter += 1; + return secp256k1_memcmp_var((unsigned char *)ele1, (unsigned char *)ele2, d->element_len); +} + +#define NUM 65 +#define MAX_ELEMENT_LEN 65 +static void test_hsort(size_t element_len) { + unsigned char elements[NUM * MAX_ELEMENT_LEN] = { 0 }; + struct test_hsort_cmp_data data; + int i; + + VERIFY_CHECK(element_len <= MAX_ELEMENT_LEN); + data.counter = 0; + data.element_len = element_len; + + secp256k1_hsort(elements, 0, element_len, test_hsort_cmp, &data); + CHECK(data.counter == 0); + secp256k1_hsort(elements, 1, element_len, test_hsort_cmp, &data); + CHECK(data.counter == 0); + secp256k1_hsort(elements, NUM, element_len, test_hsort_cmp, &data); + CHECK(data.counter >= NUM - 1); + test_hsort_is_sorted(elements, NUM, element_len); + + /* Test hsort with array of random length n */ + for (i = 0; i < COUNT; i++) { + int n = testrand_int(NUM); + testrand_bytes_test(elements, n*element_len); + secp256k1_hsort(elements, n, element_len, test_hsort_cmp, &data); + test_hsort_is_sorted(elements, n, element_len); + } +} +#undef NUM +#undef MAX_ELEMENT_LEN + + +static void run_hsort_tests(void) { + test_heap_swap(); + test_hsort(1); + test_hsort(64); + test_hsort(65); +} + /***** GROUP TESTS *****/ /* This compares jacobian points including their Z, not just their geometric meaning. */ @@ -3719,7 +3676,7 @@ static void test_ge(void) { for (i = 0; i < runs; i++) { int j, k; secp256k1_ge g; - random_group_element_test(&g); + testutil_random_ge_test(&g); if (i >= runs - 2) { secp256k1_ge_mul_lambda(&g, &ge[1]); CHECK(!secp256k1_ge_eq_var(&g, &ge[1])); @@ -3732,15 +3689,15 @@ static void test_ge(void) { secp256k1_ge_neg(&ge[3 + 4 * i], &g); secp256k1_ge_neg(&ge[4 + 4 * i], &g); secp256k1_gej_set_ge(&gej[1 + 4 * i], &ge[1 + 4 * i]); - random_group_element_jacobian_test(&gej[2 + 4 * i], &ge[2 + 4 * i]); + testutil_random_ge_jacobian_test(&gej[2 + 4 * i], &ge[2 + 4 * i]); secp256k1_gej_set_ge(&gej[3 + 4 * i], &ge[3 + 4 * i]); - random_group_element_jacobian_test(&gej[4 + 4 * i], &ge[4 + 4 * i]); + testutil_random_ge_jacobian_test(&gej[4 + 4 * i], &ge[4 + 4 * i]); for (j = 0; j < 4; j++) { - random_ge_x_magnitude(&ge[1 + j + 4 * i]); - random_ge_y_magnitude(&ge[1 + j + 4 * i]); - random_gej_x_magnitude(&gej[1 + j + 4 * i]); - random_gej_y_magnitude(&gej[1 + j + 4 * i]); - random_gej_z_magnitude(&gej[1 + j + 4 * i]); + testutil_random_ge_x_magnitude(&ge[1 + j + 4 * i]); + testutil_random_ge_y_magnitude(&ge[1 + j + 4 * i]); + testutil_random_gej_x_magnitude(&gej[1 + j + 4 * i]); + testutil_random_gej_y_magnitude(&gej[1 + j + 4 * i]); + testutil_random_gej_z_magnitude(&gej[1 + j + 4 * i]); } for (j = 0; j < 4; ++j) { @@ -3755,14 +3712,14 @@ static void test_ge(void) { } /* Generate random zf, and zfi2 = 1/zf^2, zfi3 = 1/zf^3 */ - random_fe_non_zero_test(&zf); - random_fe_magnitude(&zf); + testutil_random_fe_non_zero_test(&zf); + testutil_random_fe_magnitude(&zf, 8); secp256k1_fe_inv_var(&zfi3, &zf); secp256k1_fe_sqr(&zfi2, &zfi3); secp256k1_fe_mul(&zfi3, &zfi3, &zfi2); /* Generate random r */ - random_fe_non_zero_test(&r); + testutil_random_fe_non_zero_test(&r); for (i1 = 0; i1 < 1 + 4 * runs; i1++) { int i2; @@ -3792,8 +3749,8 @@ static void test_ge(void) { secp256k1_ge ge2_zfi = ge[i2]; /* the second term with x and y rescaled for z = 1/zf */ secp256k1_fe_mul(&ge2_zfi.x, &ge2_zfi.x, &zfi2); secp256k1_fe_mul(&ge2_zfi.y, &ge2_zfi.y, &zfi3); - random_ge_x_magnitude(&ge2_zfi); - random_ge_y_magnitude(&ge2_zfi); + testutil_random_ge_x_magnitude(&ge2_zfi); + testutil_random_ge_y_magnitude(&ge2_zfi); secp256k1_gej_add_zinv_var(&resj, &gej[i1], &ge2_zfi, &zf); CHECK(secp256k1_gej_eq_ge_var(&resj, &ref)); } @@ -3849,7 +3806,7 @@ static void test_ge(void) { gej_shuffled[i] = gej[i]; } for (i = 0; i < 4 * runs + 1; i++) { - int swap = i + secp256k1_testrand_int(4 * runs + 1 - i); + int swap = i + testrand_int(4 * runs + 1 - i); if (swap != i) { secp256k1_gej t = gej_shuffled[i]; gej_shuffled[i] = gej_shuffled[swap]; @@ -3869,7 +3826,7 @@ static void test_ge(void) { secp256k1_ge_set_all_gej_var(ge_set_all, gej, 4 * runs + 1); for (i = 0; i < 4 * runs + 1; i++) { secp256k1_fe s; - random_fe_non_zero(&s); + testutil_random_fe_non_zero(&s); secp256k1_gej_rescale(&gej[i], &s); CHECK(secp256k1_gej_eq_ge_var(&gej[i], &ge_set_all[i])); } @@ -3902,7 +3859,7 @@ static void test_ge(void) { /* Test batch gej -> ge conversion with many infinities. */ for (i = 0; i < 4 * runs + 1; i++) { int odd; - random_group_element_test(&ge[i]); + testutil_random_ge_test(&ge[i]); odd = secp256k1_fe_is_odd(&ge[i].x); CHECK(odd == 0 || odd == 1); /* randomly set half the points to infinity */ @@ -3939,7 +3896,7 @@ static void test_intialized_inf(void) { secp256k1_fe zinv; /* Test that adding P+(-P) results in a fully initialized infinity*/ - random_group_element_test(&p); + testutil_random_ge_test(&p); secp256k1_gej_set_ge(&pj, &p); secp256k1_gej_neg(&npj, &pj); @@ -4052,14 +4009,14 @@ static void run_gej(void) { secp256k1_gej_set_infinity(&b); test_gej_cmov(&a, &b); - random_gej_test(&a); + testutil_random_gej_test(&a); test_gej_cmov(&a, &b); test_gej_cmov(&b, &a); b = a; test_gej_cmov(&a, &b); - random_gej_test(&b); + testutil_random_gej_test(&b); test_gej_cmov(&a, &b); test_gej_cmov(&b, &a); } @@ -4067,12 +4024,12 @@ static void run_gej(void) { /* Tests for secp256k1_gej_eq_var */ for (i = 0; i < COUNT; i++) { secp256k1_fe fe; - random_gej_test(&a); - random_gej_test(&b); + testutil_random_gej_test(&a); + testutil_random_gej_test(&b); CHECK(!secp256k1_gej_eq_var(&a, &b)); b = a; - random_fe_non_zero_test(&fe); + testutil_random_fe_non_zero_test(&fe); secp256k1_gej_rescale(&a, &fe); CHECK(secp256k1_gej_eq_var(&a, &b)); } @@ -4089,7 +4046,7 @@ static void test_ec_combine(void) { int i; for (i = 1; i <= 6; i++) { secp256k1_scalar s; - random_scalar_order_test(&s); + testutil_random_scalar_order_test(&s); secp256k1_scalar_add(&sum, &sum, &s); secp256k1_ecmult_gen(&CTX->ecmult_gen_ctx, &Qj, &s); secp256k1_ge_set_gej(&Q, &Qj); @@ -4149,7 +4106,7 @@ static void run_group_decompress(void) { int i; for (i = 0; i < COUNT * 4; i++) { secp256k1_fe fe; - random_fe_test(&fe); + testutil_random_fe_test(&fe); test_group_decompress(&fe); } } @@ -4297,7 +4254,7 @@ static void test_point_times_order(const secp256k1_gej *point) { secp256k1_ge res3; unsigned char pub[65]; size_t psize = 65; - random_scalar_order_test(&x); + testutil_random_scalar_order_test(&x); secp256k1_scalar_negate(&nx, &x); secp256k1_ecmult(&res1, point, &x, &x); /* calc res1 = x * point + x * G; */ secp256k1_ecmult(&res2, point, &nx, &nx); /* calc res2 = (order - x) * point + (order - x) * G; */ @@ -4358,13 +4315,13 @@ static void test_ecmult_target(const secp256k1_scalar* target, int mode) { secp256k1_gej pj, p1j, p2j, ptj; /* Generate random n1,n2 such that n1+n2 = -target. */ - random_scalar_order_test(&n1); + testutil_random_scalar_order_test(&n1); secp256k1_scalar_add(&n2, &n1, target); secp256k1_scalar_negate(&n2, &n2); /* Generate a random input point. */ if (mode != 0) { - random_group_element_test(&p); + testutil_random_ge_test(&p); secp256k1_gej_set_ge(&pj, &p); } @@ -4456,8 +4413,8 @@ static void ecmult_const_commutativity(void) { secp256k1_gej res2; secp256k1_ge mid1; secp256k1_ge mid2; - random_scalar_order_test(&a); - random_scalar_order_test(&b); + testutil_random_scalar_order_test(&a); + testutil_random_scalar_order_test(&b); secp256k1_ecmult_const(&res1, &secp256k1_ge_const_g, &a); secp256k1_ecmult_const(&res2, &secp256k1_ge_const_g, &b); @@ -4478,9 +4435,9 @@ static void ecmult_const_mult_zero_one(void) { secp256k1_ge point; secp256k1_ge inf; - random_scalar_order_test(&s); + testutil_random_scalar_order_test(&s); secp256k1_scalar_negate(&negone, &secp256k1_scalar_one); - random_group_element_test(&point); + testutil_random_ge_test(&point); secp256k1_ge_set_infinity(&inf); /* 0*point */ @@ -4533,7 +4490,7 @@ static void ecmult_const_edges(void) { secp256k1_scalar_add(&q, &q, &scalars_near_split_bounds[i - 1]); secp256k1_scalar_add(&q, &q, &scalars_near_split_bounds[i - 1]); } - random_group_element_test(&point); + testutil_random_ge_test(&point); secp256k1_ecmult_const(&res, &point, &q); ecmult_const_check_result(&point, &q, &res); } @@ -4550,12 +4507,12 @@ static void ecmult_const_mult_xonly(void) { secp256k1_scalar q; int res; /* Random base point. */ - random_group_element_test(&base); + testutil_random_ge_test(&base); /* Random scalar to multiply it with. */ - random_scalar_order_test(&q); + testutil_random_scalar_order_test(&q); /* If i is odd, n=d*base.x for random non-zero d */ if (i & 1) { - random_fe_non_zero_test(&d); + testutil_random_fe_non_zero_test(&d); secp256k1_fe_mul(&n, &base.x, &d); } else { n = base.x; @@ -4577,14 +4534,14 @@ static void ecmult_const_mult_xonly(void) { secp256k1_fe x, n, d, r; int res; secp256k1_scalar q; - random_scalar_order_test(&q); + testutil_random_scalar_order_test(&q); /* Generate random X coordinate not on the curve. */ do { - random_fe_test(&x); + testutil_random_fe_test(&x); } while (secp256k1_ge_x_on_curve_var(&x)); /* If i is odd, n=d*x for random non-zero d. */ if (i & 1) { - random_fe_non_zero_test(&d); + testutil_random_fe_non_zero_test(&d); secp256k1_fe_mul(&n, &x, &d); } else { n = x; @@ -4667,10 +4624,10 @@ static void test_ecmult_multi(secp256k1_scratch *scratch, secp256k1_ecmult_multi for (ncount = 0; ncount < COUNT; ncount++) { secp256k1_ge ptg; secp256k1_gej ptgj; - random_scalar_order(&sc[0]); - random_scalar_order(&sc[1]); + testutil_random_scalar_order(&sc[0]); + testutil_random_scalar_order(&sc[1]); - random_group_element_test(&ptg); + testutil_random_ge_test(&ptg); secp256k1_gej_set_ge(&ptgj, &ptg); pt[0] = ptg; pt[1] = secp256k1_ge_const_g; @@ -4707,7 +4664,7 @@ static void test_ecmult_multi(secp256k1_scratch *scratch, secp256k1_ecmult_multi for (j = 0; j < 3; j++) { for (i = 0; i < 32; i++) { - random_scalar_order(&sc[i]); + testutil_random_scalar_order(&sc[i]); secp256k1_ge_set_infinity(&pt[i]); } CHECK(ecmult_multi(&CTX->error_callback, scratch, &r, &secp256k1_scalar_zero, ecmult_multi_callback, &data, sizes[j])); @@ -4716,7 +4673,7 @@ static void test_ecmult_multi(secp256k1_scratch *scratch, secp256k1_ecmult_multi for (j = 0; j < 3; j++) { for (i = 0; i < 32; i++) { - random_group_element_test(&ptg); + testutil_random_ge_test(&ptg); pt[i] = ptg; secp256k1_scalar_set_int(&sc[i], 0); } @@ -4725,9 +4682,9 @@ static void test_ecmult_multi(secp256k1_scratch *scratch, secp256k1_ecmult_multi } for (j = 0; j < 3; j++) { - random_group_element_test(&ptg); + testutil_random_ge_test(&ptg); for (i = 0; i < 16; i++) { - random_scalar_order(&sc[2*i]); + testutil_random_scalar_order(&sc[2*i]); secp256k1_scalar_negate(&sc[2*i + 1], &sc[2*i]); pt[2 * i] = ptg; pt[2 * i + 1] = ptg; @@ -4736,9 +4693,9 @@ static void test_ecmult_multi(secp256k1_scratch *scratch, secp256k1_ecmult_multi CHECK(ecmult_multi(&CTX->error_callback, scratch, &r, &secp256k1_scalar_zero, ecmult_multi_callback, &data, sizes[j])); CHECK(secp256k1_gej_is_infinity(&r)); - random_scalar_order(&sc[0]); + testutil_random_scalar_order(&sc[0]); for (i = 0; i < 16; i++) { - random_group_element_test(&ptg); + testutil_random_ge_test(&ptg); sc[2*i] = sc[0]; sc[2*i+1] = sc[0]; @@ -4750,13 +4707,13 @@ static void test_ecmult_multi(secp256k1_scratch *scratch, secp256k1_ecmult_multi CHECK(secp256k1_gej_is_infinity(&r)); } - random_group_element_test(&ptg); + testutil_random_ge_test(&ptg); secp256k1_scalar_set_int(&sc[0], 0); pt[0] = ptg; for (i = 1; i < 32; i++) { pt[i] = ptg; - random_scalar_order(&sc[i]); + testutil_random_scalar_order(&sc[i]); secp256k1_scalar_add(&sc[0], &sc[0], &sc[i]); secp256k1_scalar_negate(&sc[i], &sc[i]); } @@ -4770,11 +4727,11 @@ static void test_ecmult_multi(secp256k1_scratch *scratch, secp256k1_ecmult_multi size_t i; secp256k1_gej_set_infinity(&r); - random_scalar_order(&sc[0]); + testutil_random_scalar_order(&sc[0]); for (i = 0; i < 20; i++) { secp256k1_ge ptg; sc[i] = sc[0]; - random_group_element_test(&ptg); + testutil_random_ge_test(&ptg); pt[i] = ptg; secp256k1_gej_add_ge_var(&r, &r, &pt[i], NULL); } @@ -4792,9 +4749,9 @@ static void test_ecmult_multi(secp256k1_scratch *scratch, secp256k1_ecmult_multi secp256k1_scalar rs; secp256k1_scalar_set_int(&rs, 0); - random_group_element_test(&ptg); + testutil_random_ge_test(&ptg); for (i = 0; i < 20; i++) { - random_scalar_order(&sc[i]); + testutil_random_scalar_order(&sc[i]); pt[i] = ptg; secp256k1_scalar_add(&rs, &rs, &sc[i]); } @@ -4807,8 +4764,8 @@ static void test_ecmult_multi(secp256k1_scratch *scratch, secp256k1_ecmult_multi /* Sanity check that zero scalars don't cause problems */ for (ncount = 0; ncount < 20; ncount++) { - random_scalar_order(&sc[ncount]); - random_group_element_test(&pt[ncount]); + testutil_random_scalar_order(&sc[ncount]); + testutil_random_ge_test(&pt[ncount]); } secp256k1_scalar_clear(&sc[0]); @@ -4829,7 +4786,7 @@ static void test_ecmult_multi(secp256k1_scratch *scratch, secp256k1_ecmult_multi secp256k1_ge ptg; secp256k1_gej ptgj; - random_group_element_test(&ptg); + testutil_random_ge_test(&ptg); secp256k1_gej_set_ge(&ptgj, &ptg); for(t0i = 0; t0i < TOP; t0i++) { @@ -4900,29 +4857,29 @@ static int test_ecmult_multi_random(secp256k1_scratch *scratch) { int i; /* Which multiplication function to use */ - int fn = secp256k1_testrand_int(3); + int fn = testrand_int(3); secp256k1_ecmult_multi_func ecmult_multi = fn == 0 ? secp256k1_ecmult_multi_var : fn == 1 ? secp256k1_ecmult_strauss_batch_single : secp256k1_ecmult_pippenger_batch_single; /* Simulate exponentially distributed num. */ - int num_bits = 2 + secp256k1_testrand_int(6); + int num_bits = 2 + testrand_int(6); /* Number of (scalar, point) inputs (excluding g). */ - int num = secp256k1_testrand_int((1 << num_bits) + 1); + int num = testrand_int((1 << num_bits) + 1); /* Number of those which are nonzero. */ - int num_nonzero = secp256k1_testrand_int(num + 1); + int num_nonzero = testrand_int(num + 1); /* Whether we're aiming to create an input with nonzero expected result. */ - int nonzero_result = secp256k1_testrand_bits(1); + int nonzero_result = testrand_bits(1); /* Whether we will provide nonzero g multiplicand. In some cases our hand * is forced here based on num_nonzero and nonzero_result. */ int g_nonzero = num_nonzero == 0 ? nonzero_result : num_nonzero == 1 && !nonzero_result ? 1 : - (int)secp256k1_testrand_bits(1); + (int)testrand_bits(1); /* Which g_scalar pointer to pass into ecmult_multi(). */ - const secp256k1_scalar* g_scalar_ptr = (g_nonzero || secp256k1_testrand_bits(1)) ? &g_scalar : NULL; + const secp256k1_scalar* g_scalar_ptr = (g_nonzero || testrand_bits(1)) ? &g_scalar : NULL; /* How many EC multiplications were performed in this function. */ int mults = 0; /* How many randomization steps to apply to the input list. */ - int rands = (int)secp256k1_testrand_bits(3); + int rands = (int)testrand_bits(3); if (rands > num_nonzero) rands = num_nonzero; secp256k1_gej_set_infinity(&expected); @@ -4931,11 +4888,11 @@ static int test_ecmult_multi_random(secp256k1_scratch *scratch) { if (g_nonzero) { /* If g_nonzero, set g_scalar to nonzero value r. */ - random_scalar_order_test(&g_scalar); + testutil_random_scalar_order_test(&g_scalar); if (!nonzero_result) { /* If expected=0 is desired, add a (a*r, -(1/a)*g) term to compensate. */ CHECK(num_nonzero > filled); - random_scalar_order_test(&sc_tmp); + testutil_random_scalar_order_test(&sc_tmp); secp256k1_scalar_mul(&scalars[filled], &sc_tmp, &g_scalar); secp256k1_scalar_inverse_var(&sc_tmp, &sc_tmp); secp256k1_scalar_negate(&sc_tmp, &sc_tmp); @@ -4947,8 +4904,8 @@ static int test_ecmult_multi_random(secp256k1_scratch *scratch) { if (nonzero_result && filled < num_nonzero) { /* If a nonzero result is desired, and there is space, add a random nonzero term. */ - random_scalar_order_test(&scalars[filled]); - random_group_element_test(&ge_tmp); + testutil_random_scalar_order_test(&scalars[filled]); + testutil_random_ge_test(&ge_tmp); secp256k1_gej_set_ge(&gejs[filled], &ge_tmp); ++filled; } @@ -4967,12 +4924,12 @@ static int test_ecmult_multi_random(secp256k1_scratch *scratch) { /* Add entries to scalars,gejs so that there are num of them. All the added entries * either have scalar=0 or point=infinity, so these do not change the expected result. */ while (filled < num) { - if (secp256k1_testrand_bits(1)) { + if (testrand_bits(1)) { secp256k1_gej_set_infinity(&gejs[filled]); - random_scalar_order_test(&scalars[filled]); + testutil_random_scalar_order_test(&scalars[filled]); } else { secp256k1_scalar_set_int(&scalars[filled], 0); - random_group_element_test(&ge_tmp); + testutil_random_ge_test(&ge_tmp); secp256k1_gej_set_ge(&gejs[filled], &ge_tmp); } ++filled; @@ -4986,7 +4943,7 @@ static int test_ecmult_multi_random(secp256k1_scratch *scratch) { secp256k1_scalar v, iv; /* Shuffle the entries. */ for (j = 0; j < num_nonzero; ++j) { - int k = secp256k1_testrand_int(num_nonzero - j); + int k = testrand_int(num_nonzero - j); if (k != 0) { secp256k1_gej gej = gejs[j]; secp256k1_scalar sc = scalars[j]; @@ -5006,7 +4963,7 @@ static int test_ecmult_multi_random(secp256k1_scratch *scratch) { } /* Transform the last input: a*P -> (v*a) * ((1/v)*P). */ CHECK(num_nonzero >= 1); - random_scalar_order_test(&v); + testutil_random_scalar_order_test(&v); secp256k1_scalar_inverse(&iv, &v); secp256k1_scalar_mul(&scalars[num_nonzero - 1], &scalars[num_nonzero - 1], &v); secp256k1_ecmult(&gejs[num_nonzero - 1], &gejs[num_nonzero - 1], &iv, NULL); @@ -5015,7 +4972,7 @@ static int test_ecmult_multi_random(secp256k1_scratch *scratch) { /* Shuffle all entries (0..num-1). */ for (i = 0; i < num; ++i) { - int j = secp256k1_testrand_int(num - i); + int j = testrand_int(num - i); if (j != 0) { secp256k1_gej gej = gejs[i]; secp256k1_scalar sc = scalars[i]; @@ -5045,8 +5002,8 @@ static void test_ecmult_multi_batch_single(secp256k1_ecmult_multi_func ecmult_mu ecmult_multi_data data; secp256k1_scratch *scratch_empty; - random_group_element_test(&pt); - random_scalar_order(&sc); + testutil_random_ge_test(&pt); + testutil_random_scalar_order(&sc); data.sc = ≻ data.pt = &pt; @@ -5077,7 +5034,7 @@ static void test_secp256k1_pippenger_bucket_window_inv(void) { * for a given scratch space. */ static void test_ecmult_multi_pippenger_max_points(void) { - size_t scratch_size = secp256k1_testrand_bits(8); + size_t scratch_size = testrand_bits(8); size_t max_size = secp256k1_pippenger_scratch_size(secp256k1_pippenger_bucket_window_inv(PIPPENGER_MAX_BUCKET_WINDOW-1)+512, 12); secp256k1_scratch *scratch; size_t n_points_supported; @@ -5171,15 +5128,15 @@ static void test_ecmult_multi_batching(void) { secp256k1_gej_set_infinity(&r2); /* Get random scalars and group elements and compute result */ - random_scalar_order(&scG); + testutil_random_scalar_order(&scG); secp256k1_ecmult(&r2, &r2, &secp256k1_scalar_zero, &scG); for(i = 0; i < n_points; i++) { secp256k1_ge ptg; secp256k1_gej ptgj; - random_group_element_test(&ptg); + testutil_random_ge_test(&ptg); secp256k1_gej_set_ge(&ptgj, &ptg); pt[i] = ptg; - random_scalar_order(&sc[i]); + testutil_random_scalar_order(&sc[i]); secp256k1_ecmult(&ptgj, &ptgj, &sc[i], NULL); secp256k1_gej_add_var(&r2, &r2, &ptgj, NULL); } @@ -5391,7 +5348,7 @@ static void run_wnaf(void) { test_fixed_wnaf_small(); /* Random tests */ for (i = 0; i < COUNT; i++) { - random_scalar_order(&n); + testutil_random_scalar_order(&n); test_wnaf(&n, 4+(i%10)); test_fixed_wnaf(&n, 4 + (i % 10)); } @@ -5421,8 +5378,8 @@ static void test_ecmult_accumulate(secp256k1_sha256* acc, const secp256k1_scalar secp256k1_ecmult_gen(&CTX->ecmult_gen_ctx, &rj1, x); secp256k1_ecmult(&rj2, &gj, x, &secp256k1_scalar_zero); secp256k1_ecmult(&rj3, &infj, &secp256k1_scalar_zero, x); - secp256k1_ecmult_multi_var(NULL, scratch, &rj4, x, NULL, NULL, 0); - secp256k1_ecmult_multi_var(NULL, scratch, &rj5, &secp256k1_scalar_zero, test_ecmult_accumulate_cb, (void*)x, 1); + CHECK(secp256k1_ecmult_multi_var(&CTX->error_callback, scratch, &rj4, x, NULL, NULL, 0)); + CHECK(secp256k1_ecmult_multi_var(&CTX->error_callback, scratch, &rj5, &secp256k1_scalar_zero, test_ecmult_accumulate_cb, (void*)x, 1)); secp256k1_ecmult_const(&rj6, &secp256k1_ge_const_g, x); secp256k1_ge_set_gej_var(&r, &rj1); CHECK(secp256k1_gej_eq_ge_var(&rj2, &r)); @@ -5570,18 +5527,18 @@ static void test_ecmult_gen_blind(void) { unsigned char seed32[32]; secp256k1_gej pgej; secp256k1_gej pgej2; - secp256k1_gej i; + secp256k1_ge p; secp256k1_ge pge; - random_scalar_order_test(&key); + testutil_random_scalar_order_test(&key); secp256k1_ecmult_gen(&CTX->ecmult_gen_ctx, &pgej, &key); - secp256k1_testrand256(seed32); - b = CTX->ecmult_gen_ctx.blind; - i = CTX->ecmult_gen_ctx.initial; + testrand256(seed32); + b = CTX->ecmult_gen_ctx.scalar_offset; + p = CTX->ecmult_gen_ctx.ge_offset; secp256k1_ecmult_gen_blind(&CTX->ecmult_gen_ctx, seed32); - CHECK(!secp256k1_scalar_eq(&b, &CTX->ecmult_gen_ctx.blind)); + CHECK(!secp256k1_scalar_eq(&b, &CTX->ecmult_gen_ctx.scalar_offset)); secp256k1_ecmult_gen(&CTX->ecmult_gen_ctx, &pgej2, &key); CHECK(!gej_xyz_equals_gej(&pgej, &pgej2)); - CHECK(!gej_xyz_equals_gej(&i, &CTX->ecmult_gen_ctx.initial)); + CHECK(!secp256k1_ge_eq_var(&p, &CTX->ecmult_gen_ctx.ge_offset)); secp256k1_ge_set_gej(&pge, &pgej); CHECK(secp256k1_gej_eq_ge_var(&pgej2, &pge)); } @@ -5589,18 +5546,39 @@ static void test_ecmult_gen_blind(void) { static void test_ecmult_gen_blind_reset(void) { /* Test ecmult_gen() blinding reset and confirm that the blinding is consistent. */ secp256k1_scalar b; - secp256k1_gej initial; + secp256k1_ge p1, p2; secp256k1_ecmult_gen_blind(&CTX->ecmult_gen_ctx, 0); - b = CTX->ecmult_gen_ctx.blind; - initial = CTX->ecmult_gen_ctx.initial; + b = CTX->ecmult_gen_ctx.scalar_offset; + p1 = CTX->ecmult_gen_ctx.ge_offset; secp256k1_ecmult_gen_blind(&CTX->ecmult_gen_ctx, 0); - CHECK(secp256k1_scalar_eq(&b, &CTX->ecmult_gen_ctx.blind)); - CHECK(gej_xyz_equals_gej(&initial, &CTX->ecmult_gen_ctx.initial)); + CHECK(secp256k1_scalar_eq(&b, &CTX->ecmult_gen_ctx.scalar_offset)); + p2 = CTX->ecmult_gen_ctx.ge_offset; + CHECK(secp256k1_ge_eq_var(&p1, &p2)); +} + +/* Verify that ecmult_gen for scalars gn for which gn + scalar_offset = {-1,0,1}. */ +static void test_ecmult_gen_edge_cases(void) { + int i; + secp256k1_gej res1, res2, res3; + secp256k1_scalar gn = secp256k1_scalar_one; /* gn = 1 */ + secp256k1_scalar_add(&gn, &gn, &CTX->ecmult_gen_ctx.scalar_offset); /* gn = 1 + scalar_offset */ + secp256k1_scalar_negate(&gn, &gn); /* gn = -1 - scalar_offset */ + + for (i = -1; i < 2; ++i) { + /* Run test with gn = i - scalar_offset (so that the ecmult_gen recoded value represents i). */ + secp256k1_ecmult_gen(&CTX->ecmult_gen_ctx, &res1, &gn); + secp256k1_ecmult(&res2, NULL, &secp256k1_scalar_zero, &gn); + secp256k1_ecmult_const(&res3, &secp256k1_ge_const_g, &gn); + CHECK(secp256k1_gej_eq_var(&res1, &res2)); + CHECK(secp256k1_gej_eq_var(&res1, &res3)); + secp256k1_scalar_add(&gn, &gn, &secp256k1_scalar_one); + } } static void run_ecmult_gen_blind(void) { int i; test_ecmult_gen_blind_reset(); + test_ecmult_gen_edge_cases(); for (i = 0; i < 10; i++) { test_ecmult_gen_blind(); } @@ -5647,7 +5625,7 @@ static void run_endomorphism_tests(void) { for (i = 0; i < 100U * COUNT; ++i) { secp256k1_scalar full; - random_scalar_order_test(&full); + testutil_random_scalar_order_test(&full); test_scalar_split(&full); } for (i = 0; i < sizeof(scalars_near_split_bounds) / sizeof(scalars_near_split_bounds[0]); ++i) { @@ -6233,7 +6211,7 @@ static void run_eckey_negate_test(void) { unsigned char seckey[32]; unsigned char seckey_tmp[32]; - random_scalar_order_b32(seckey); + testutil_random_scalar_order_b32(seckey); memcpy(seckey_tmp, seckey, 32); /* Verify negation changes the key and changes it back */ @@ -6257,7 +6235,7 @@ static void run_eckey_negate_test(void) { /* Negating an overflowing seckey fails and the seckey is zeroed. In this * test, the seckey has 16 random bytes to ensure that ec_seckey_negate * doesn't just set seckey to a constant value in case of failure. */ - random_scalar_order_b32(seckey); + testutil_random_scalar_order_b32(seckey); memset(seckey, 0xFF, 16); memset(seckey_tmp, 0, 32); CHECK(secp256k1_ec_seckey_negate(CTX, seckey) == 0); @@ -6267,7 +6245,7 @@ static void run_eckey_negate_test(void) { static void random_sign(secp256k1_scalar *sigr, secp256k1_scalar *sigs, const secp256k1_scalar *key, const secp256k1_scalar *msg, int *recid) { secp256k1_scalar nonce; do { - random_scalar_order_test(&nonce); + testutil_random_scalar_order_test(&nonce); } while(!secp256k1_ecdsa_sig_sign(&CTX->ecmult_gen_ctx, sigr, sigs, key, msg, &nonce, recid)); } @@ -6279,11 +6257,11 @@ static void test_ecdsa_sign_verify(void) { secp256k1_scalar sigr, sigs; int getrec; int recid; - random_scalar_order_test(&msg); - random_scalar_order_test(&key); + testutil_random_scalar_order_test(&msg); + testutil_random_scalar_order_test(&key); secp256k1_ecmult_gen(&CTX->ecmult_gen_ctx, &pubj, &key); secp256k1_ge_set_gej(&pub, &pubj); - getrec = secp256k1_testrand_bits(1); + getrec = testrand_bits(1); /* The specific way in which this conditional is written sidesteps a potential bug in clang. See the commit messages of the commit that introduced this comment for details. */ if (getrec) { @@ -6376,8 +6354,8 @@ static void test_ecdsa_end_to_end(void) { /* Generate a random key and message. */ { secp256k1_scalar msg, key; - random_scalar_order_test(&msg); - random_scalar_order_test(&key); + testutil_random_scalar_order_test(&msg); + testutil_random_scalar_order_test(&key); secp256k1_scalar_get_b32(privkey, &key); secp256k1_scalar_get_b32(message, &msg); } @@ -6387,7 +6365,7 @@ static void test_ecdsa_end_to_end(void) { CHECK(secp256k1_ec_pubkey_create(CTX, &pubkey, privkey) == 1); /* Verify exporting and importing public key. */ - CHECK(secp256k1_ec_pubkey_serialize(CTX, pubkeyc, &pubkeyclen, &pubkey, secp256k1_testrand_bits(1) == 1 ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED)); + CHECK(secp256k1_ec_pubkey_serialize(CTX, pubkeyc, &pubkeyclen, &pubkey, testrand_bits(1) == 1 ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED)); memset(&pubkey, 0, sizeof(pubkey)); CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkey, pubkeyc, pubkeyclen) == 1); @@ -6399,19 +6377,19 @@ static void test_ecdsa_end_to_end(void) { CHECK(secp256k1_memcmp_var(&pubkey_tmp, &pubkey, sizeof(pubkey)) == 0); /* Verify private key import and export. */ - CHECK(ec_privkey_export_der(CTX, seckey, &seckeylen, privkey, secp256k1_testrand_bits(1) == 1)); + CHECK(ec_privkey_export_der(CTX, seckey, &seckeylen, privkey, testrand_bits(1) == 1)); CHECK(ec_privkey_import_der(CTX, privkey2, seckey, seckeylen) == 1); CHECK(secp256k1_memcmp_var(privkey, privkey2, 32) == 0); /* Optionally tweak the keys using addition. */ - if (secp256k1_testrand_int(3) == 0) { + if (testrand_int(3) == 0) { int ret1; int ret2; int ret3; unsigned char rnd[32]; unsigned char privkey_tmp[32]; secp256k1_pubkey pubkey2; - secp256k1_testrand256_test(rnd); + testrand256_test(rnd); memcpy(privkey_tmp, privkey, 32); ret1 = secp256k1_ec_seckey_tweak_add(CTX, privkey, rnd); ret2 = secp256k1_ec_pubkey_tweak_add(CTX, &pubkey, rnd); @@ -6428,14 +6406,14 @@ static void test_ecdsa_end_to_end(void) { } /* Optionally tweak the keys using multiplication. */ - if (secp256k1_testrand_int(3) == 0) { + if (testrand_int(3) == 0) { int ret1; int ret2; int ret3; unsigned char rnd[32]; unsigned char privkey_tmp[32]; secp256k1_pubkey pubkey2; - secp256k1_testrand256_test(rnd); + testrand256_test(rnd); memcpy(privkey_tmp, privkey, 32); ret1 = secp256k1_ec_seckey_tweak_mul(CTX, privkey, rnd); ret2 = secp256k1_ec_pubkey_tweak_mul(CTX, &pubkey, rnd); @@ -6497,7 +6475,7 @@ static void test_ecdsa_end_to_end(void) { /* Serialize/destroy/parse DER and verify again. */ siglen = 74; CHECK(secp256k1_ecdsa_signature_serialize_der(CTX, sig, &siglen, &signature[0]) == 1); - sig[secp256k1_testrand_int(siglen)] += 1 + secp256k1_testrand_int(255); + sig[testrand_int(siglen)] += 1 + testrand_int(255); CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &signature[0], sig, siglen) == 0 || secp256k1_ecdsa_verify(CTX, &signature[0], message, &pubkey) == 0); } @@ -6507,23 +6485,23 @@ static void test_random_pubkeys(void) { secp256k1_ge elem2; unsigned char in[65]; /* Generate some randomly sized pubkeys. */ - size_t len = secp256k1_testrand_bits(2) == 0 ? 65 : 33; - if (secp256k1_testrand_bits(2) == 0) { - len = secp256k1_testrand_bits(6); + size_t len = testrand_bits(2) == 0 ? 65 : 33; + if (testrand_bits(2) == 0) { + len = testrand_bits(6); } if (len == 65) { - in[0] = secp256k1_testrand_bits(1) ? 4 : (secp256k1_testrand_bits(1) ? 6 : 7); + in[0] = testrand_bits(1) ? 4 : (testrand_bits(1) ? 6 : 7); } else { - in[0] = secp256k1_testrand_bits(1) ? 2 : 3; + in[0] = testrand_bits(1) ? 2 : 3; } - if (secp256k1_testrand_bits(3) == 0) { - in[0] = secp256k1_testrand_bits(8); + if (testrand_bits(3) == 0) { + in[0] = testrand_bits(8); } if (len > 1) { - secp256k1_testrand256(&in[1]); + testrand256(&in[1]); } if (len > 33) { - secp256k1_testrand256(&in[33]); + testrand256(&in[33]); } if (secp256k1_eckey_pubkey_parse(&elem, in, len)) { unsigned char out[65]; @@ -6545,7 +6523,7 @@ static void test_random_pubkeys(void) { CHECK(secp256k1_eckey_pubkey_parse(&elem2, in, size)); CHECK(secp256k1_ge_eq_var(&elem2, &elem)); /* Check that the X9.62 hybrid type is checked. */ - in[0] = secp256k1_testrand_bits(1) ? 6 : 7; + in[0] = testrand_bits(1) ? 6 : 7; res = secp256k1_eckey_pubkey_parse(&elem2, in, size); if (firstb == 2 || firstb == 3) { if (in[0] == firstb + 4) { @@ -6607,6 +6585,161 @@ static void run_pubkey_comparison(void) { CHECK(secp256k1_ec_pubkey_cmp(CTX, &pk2, &pk1) > 0); } +static void test_sort_helper(secp256k1_pubkey *pk, size_t *pk_order, size_t n_pk) { + size_t i; + const secp256k1_pubkey *pk_test[5]; + + for (i = 0; i < n_pk; i++) { + pk_test[i] = &pk[pk_order[i]]; + } + secp256k1_ec_pubkey_sort(CTX, pk_test, n_pk); + for (i = 0; i < n_pk; i++) { + CHECK(secp256k1_memcmp_var(pk_test[i], &pk[i], sizeof(*pk_test[i])) == 0); + } +} + +static void permute(size_t *arr, size_t n) { + size_t i; + for (i = n - 1; i >= 1; i--) { + size_t tmp, j; + j = testrand_int(i + 1); + tmp = arr[i]; + arr[i] = arr[j]; + arr[j] = tmp; + } +} + +static void rand_pk(secp256k1_pubkey *pk) { + unsigned char seckey[32]; + secp256k1_keypair keypair; + testrand256(seckey); + CHECK(secp256k1_keypair_create(CTX, &keypair, seckey) == 1); + CHECK(secp256k1_keypair_pub(CTX, pk, &keypair) == 1); +} + +static void test_sort_api(void) { + secp256k1_pubkey pks[2]; + const secp256k1_pubkey *pks_ptr[2]; + + pks_ptr[0] = &pks[0]; + pks_ptr[1] = &pks[1]; + + rand_pk(&pks[0]); + rand_pk(&pks[1]); + + CHECK(secp256k1_ec_pubkey_sort(CTX, pks_ptr, 2) == 1); + CHECK_ILLEGAL(CTX, secp256k1_ec_pubkey_sort(CTX, NULL, 2)); + CHECK(secp256k1_ec_pubkey_sort(CTX, pks_ptr, 0) == 1); + /* Test illegal public keys */ + memset(&pks[0], 0, sizeof(pks[0])); + CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_ec_pubkey_sort(CTX, pks_ptr, 2) == 1)); + memset(&pks[1], 0, sizeof(pks[1])); + { + int32_t ecount = 0; + secp256k1_context_set_illegal_callback(CTX, counting_callback_fn, &ecount); + CHECK(secp256k1_ec_pubkey_sort(CTX, pks_ptr, 2) == 1); + CHECK(ecount == 2); + secp256k1_context_set_illegal_callback(CTX, NULL, NULL); + } +} + +static void test_sort(void) { + secp256k1_pubkey pk[5]; + unsigned char pk_ser[5][33] = { + { 0x02, 0x08 }, + { 0x02, 0x0b }, + { 0x02, 0x0c }, + { 0x03, 0x05 }, + { 0x03, 0x0a }, + }; + int i; + size_t pk_order[5] = { 0, 1, 2, 3, 4 }; + + for (i = 0; i < 5; i++) { + CHECK(secp256k1_ec_pubkey_parse(CTX, &pk[i], pk_ser[i], sizeof(pk_ser[i]))); + } + + permute(pk_order, 1); + test_sort_helper(pk, pk_order, 1); + permute(pk_order, 2); + test_sort_helper(pk, pk_order, 2); + permute(pk_order, 3); + test_sort_helper(pk, pk_order, 3); + for (i = 0; i < COUNT; i++) { + permute(pk_order, 4); + test_sort_helper(pk, pk_order, 4); + } + for (i = 0; i < COUNT; i++) { + permute(pk_order, 5); + test_sort_helper(pk, pk_order, 5); + } + /* Check that sorting also works for random pubkeys */ + for (i = 0; i < COUNT; i++) { + int j; + const secp256k1_pubkey *pk_ptr[5]; + for (j = 0; j < 5; j++) { + rand_pk(&pk[j]); + pk_ptr[j] = &pk[j]; + } + secp256k1_ec_pubkey_sort(CTX, pk_ptr, 5); + for (j = 1; j < 5; j++) { + CHECK(secp256k1_ec_pubkey_sort_cmp(&pk_ptr[j - 1], &pk_ptr[j], CTX) <= 0); + } + } +} + +/* Test vectors from BIP-MuSig2 */ +static void test_sort_vectors(void) { + enum { N_PUBKEYS = 6 }; + unsigned char pk_ser[N_PUBKEYS][33] = { + { 0x02, 0xDD, 0x30, 0x8A, 0xFE, 0xC5, 0x77, 0x7E, 0x13, 0x12, 0x1F, + 0xA7, 0x2B, 0x9C, 0xC1, 0xB7, 0xCC, 0x01, 0x39, 0x71, 0x53, 0x09, + 0xB0, 0x86, 0xC9, 0x60, 0xE1, 0x8F, 0xD9, 0x69, 0x77, 0x4E, 0xB8 }, + { 0x02, 0xF9, 0x30, 0x8A, 0x01, 0x92, 0x58, 0xC3, 0x10, 0x49, 0x34, + 0x4F, 0x85, 0xF8, 0x9D, 0x52, 0x29, 0xB5, 0x31, 0xC8, 0x45, 0x83, + 0x6F, 0x99, 0xB0, 0x86, 0x01, 0xF1, 0x13, 0xBC, 0xE0, 0x36, 0xF9 }, + { 0x03, 0xDF, 0xF1, 0xD7, 0x7F, 0x2A, 0x67, 0x1C, 0x5F, 0x36, 0x18, + 0x37, 0x26, 0xDB, 0x23, 0x41, 0xBE, 0x58, 0xFE, 0xAE, 0x1D, 0xA2, + 0xDE, 0xCE, 0xD8, 0x43, 0x24, 0x0F, 0x7B, 0x50, 0x2B, 0xA6, 0x59 }, + { 0x02, 0x35, 0x90, 0xA9, 0x4E, 0x76, 0x8F, 0x8E, 0x18, 0x15, 0xC2, + 0xF2, 0x4B, 0x4D, 0x80, 0xA8, 0xE3, 0x14, 0x93, 0x16, 0xC3, 0x51, + 0x8C, 0xE7, 0xB7, 0xAD, 0x33, 0x83, 0x68, 0xD0, 0x38, 0xCA, 0x66 }, + { 0x02, 0xDD, 0x30, 0x8A, 0xFE, 0xC5, 0x77, 0x7E, 0x13, 0x12, 0x1F, + 0xA7, 0x2B, 0x9C, 0xC1, 0xB7, 0xCC, 0x01, 0x39, 0x71, 0x53, 0x09, + 0xB0, 0x86, 0xC9, 0x60, 0xE1, 0x8F, 0xD9, 0x69, 0x77, 0x4E, 0xFF }, + { 0x02, 0xDD, 0x30, 0x8A, 0xFE, 0xC5, 0x77, 0x7E, 0x13, 0x12, 0x1F, + 0xA7, 0x2B, 0x9C, 0xC1, 0xB7, 0xCC, 0x01, 0x39, 0x71, 0x53, 0x09, + 0xB0, 0x86, 0xC9, 0x60, 0xE1, 0x8F, 0xD9, 0x69, 0x77, 0x4E, 0xB8 } + }; + secp256k1_pubkey pubkeys[N_PUBKEYS]; + secp256k1_pubkey *sorted[N_PUBKEYS]; + const secp256k1_pubkey *pks_ptr[N_PUBKEYS]; + int i; + + sorted[0] = &pubkeys[3]; + sorted[1] = &pubkeys[0]; + sorted[2] = &pubkeys[0]; + sorted[3] = &pubkeys[4]; + sorted[4] = &pubkeys[1]; + sorted[5] = &pubkeys[2]; + + for (i = 0; i < N_PUBKEYS; i++) { + CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkeys[i], pk_ser[i], sizeof(pk_ser[i]))); + pks_ptr[i] = &pubkeys[i]; + } + CHECK(secp256k1_ec_pubkey_sort(CTX, pks_ptr, N_PUBKEYS) == 1); + for (i = 0; i < N_PUBKEYS; i++) { + CHECK(secp256k1_memcmp_var(pks_ptr[i], sorted[i], sizeof(secp256k1_pubkey)) == 0); + } +} + +static void run_pubkey_sort(void) { + test_sort_api(); + test_sort(); + test_sort_vectors(); +} + + static void run_random_pubkeys(void) { int i; for (i = 0; i < 10*COUNT; i++) { @@ -6695,27 +6828,27 @@ static void assign_big_endian(unsigned char *ptr, size_t ptrlen, uint32_t val) { static void damage_array(unsigned char *sig, size_t *len) { int pos; - int action = secp256k1_testrand_bits(3); + int action = testrand_bits(3); if (action < 1 && *len > 3) { /* Delete a byte. */ - pos = secp256k1_testrand_int(*len); + pos = testrand_int(*len); memmove(sig + pos, sig + pos + 1, *len - pos - 1); (*len)--; return; } else if (action < 2 && *len < 2048) { /* Insert a byte. */ - pos = secp256k1_testrand_int(1 + *len); + pos = testrand_int(1 + *len); memmove(sig + pos + 1, sig + pos, *len - pos); - sig[pos] = secp256k1_testrand_bits(8); + sig[pos] = testrand_bits(8); (*len)++; return; } else if (action < 4) { /* Modify a byte. */ - sig[secp256k1_testrand_int(*len)] += 1 + secp256k1_testrand_int(255); + sig[testrand_int(*len)] += 1 + testrand_int(255); return; } else { /* action < 8 */ /* Modify a bit. */ - sig[secp256k1_testrand_int(*len)] ^= 1 << secp256k1_testrand_bits(3); + sig[testrand_int(*len)] ^= 1 << testrand_bits(3); return; } } @@ -6728,23 +6861,23 @@ static void random_ber_signature(unsigned char *sig, size_t *len, int* certainly int n; *len = 0; - der = secp256k1_testrand_bits(2) == 0; + der = testrand_bits(2) == 0; *certainly_der = der; *certainly_not_der = 0; - indet = der ? 0 : secp256k1_testrand_int(10) == 0; + indet = der ? 0 : testrand_int(10) == 0; for (n = 0; n < 2; n++) { /* We generate two classes of numbers: nlow==1 "low" ones (up to 32 bytes), nlow==0 "high" ones (32 bytes with 129 top bits set, or larger than 32 bytes) */ - nlow[n] = der ? 1 : (secp256k1_testrand_bits(3) != 0); + nlow[n] = der ? 1 : (testrand_bits(3) != 0); /* The length of the number in bytes (the first byte of which will always be nonzero) */ - nlen[n] = nlow[n] ? secp256k1_testrand_int(33) : 32 + secp256k1_testrand_int(200) * secp256k1_testrand_bits(3) / 8; + nlen[n] = nlow[n] ? testrand_int(33) : 32 + testrand_int(200) * testrand_bits(3) / 8; CHECK(nlen[n] <= 232); /* The top bit of the number. */ - nhbit[n] = (nlow[n] == 0 && nlen[n] == 32) ? 1 : (nlen[n] == 0 ? 0 : secp256k1_testrand_bits(1)); + nhbit[n] = (nlow[n] == 0 && nlen[n] == 32) ? 1 : (nlen[n] == 0 ? 0 : testrand_bits(1)); /* The top byte of the number (after the potential hardcoded 16 0xFF characters for "high" 32 bytes numbers) */ - nhbyte[n] = nlen[n] == 0 ? 0 : (nhbit[n] ? 128 + secp256k1_testrand_bits(7) : 1 + secp256k1_testrand_int(127)); + nhbyte[n] = nlen[n] == 0 ? 0 : (nhbit[n] ? 128 + testrand_bits(7) : 1 + testrand_int(127)); /* The number of zero bytes in front of the number (which is 0 or 1 in case of DER, otherwise we extend up to 300 bytes) */ - nzlen[n] = der ? ((nlen[n] == 0 || nhbit[n]) ? 1 : 0) : (nlow[n] ? secp256k1_testrand_int(3) : secp256k1_testrand_int(300 - nlen[n]) * secp256k1_testrand_bits(3) / 8); + nzlen[n] = der ? ((nlen[n] == 0 || nhbit[n]) ? 1 : 0) : (nlow[n] ? testrand_int(3) : testrand_int(300 - nlen[n]) * testrand_bits(3) / 8); if (nzlen[n] > ((nlen[n] == 0 || nhbit[n]) ? 1 : 0)) { *certainly_not_der = 1; } @@ -6753,7 +6886,7 @@ static void random_ber_signature(unsigned char *sig, size_t *len, int* certainly nlenlen[n] = nlen[n] + nzlen[n] < 128 ? 0 : (nlen[n] + nzlen[n] < 256 ? 1 : 2); if (!der) { /* nlenlen[n] max 127 bytes */ - int add = secp256k1_testrand_int(127 - nlenlen[n]) * secp256k1_testrand_bits(4) * secp256k1_testrand_bits(4) / 256; + int add = testrand_int(127 - nlenlen[n]) * testrand_bits(4) * testrand_bits(4) / 256; nlenlen[n] += add; if (add != 0) { *certainly_not_der = 1; @@ -6767,7 +6900,7 @@ static void random_ber_signature(unsigned char *sig, size_t *len, int* certainly CHECK(tlen <= 856); /* The length of the garbage inside the tuple. */ - elen = (der || indet) ? 0 : secp256k1_testrand_int(980 - tlen) * secp256k1_testrand_bits(3) / 8; + elen = (der || indet) ? 0 : testrand_int(980 - tlen) * testrand_bits(3) / 8; if (elen != 0) { *certainly_not_der = 1; } @@ -6775,7 +6908,7 @@ static void random_ber_signature(unsigned char *sig, size_t *len, int* certainly CHECK(tlen <= 980); /* The length of the garbage after the end of the tuple. */ - glen = der ? 0 : secp256k1_testrand_int(990 - tlen) * secp256k1_testrand_bits(3) / 8; + glen = der ? 0 : testrand_int(990 - tlen) * testrand_bits(3) / 8; if (glen != 0) { *certainly_not_der = 1; } @@ -6790,7 +6923,7 @@ static void random_ber_signature(unsigned char *sig, size_t *len, int* certainly } else { int tlenlen = tlen < 128 ? 0 : (tlen < 256 ? 1 : 2); if (!der) { - int add = secp256k1_testrand_int(127 - tlenlen) * secp256k1_testrand_bits(4) * secp256k1_testrand_bits(4) / 256; + int add = testrand_int(127 - tlenlen) * testrand_bits(4) * testrand_bits(4) / 256; tlenlen += add; if (add != 0) { *certainly_not_der = 1; @@ -6841,13 +6974,13 @@ static void random_ber_signature(unsigned char *sig, size_t *len, int* certainly nlen[n]--; } /* Generate remaining random bytes of number */ - secp256k1_testrand_bytes_test(sig + *len, nlen[n]); + testrand_bytes_test(sig + *len, nlen[n]); *len += nlen[n]; nlen[n] = 0; } /* Generate random garbage inside tuple. */ - secp256k1_testrand_bytes_test(sig + *len, elen); + testrand_bytes_test(sig + *len, elen); *len += elen; /* Generate end-of-contents bytes. */ @@ -6859,7 +6992,7 @@ static void random_ber_signature(unsigned char *sig, size_t *len, int* certainly CHECK(tlen + glen <= 1121); /* Generate random garbage outside tuple. */ - secp256k1_testrand_bytes_test(sig + *len, glen); + testrand_bytes_test(sig + *len, glen); *len += glen; tlen += glen; CHECK(tlen <= 1121); @@ -7522,7 +7655,7 @@ int main(int argc, char **argv) { run_xoshiro256pp_tests(); /* find random seed */ - secp256k1_testrand_init(argc > 2 ? argv[2] : NULL); + testrand_init(argc > 2 ? argv[2] : NULL); /*** Setup test environment ***/ @@ -7531,9 +7664,9 @@ int main(int argc, char **argv) { /* Randomize the context only with probability 15/16 to make sure we test without context randomization from time to time. TODO Reconsider this when recalibrating the tests. */ - if (secp256k1_testrand_bits(4)) { + if (testrand_bits(4)) { unsigned char rand32[32]; - secp256k1_testrand256(rand32); + testrand256(rand32); CHECK(secp256k1_context_randomize(CTX, rand32)); } /* Make a writable copy of secp256k1_context_static in order to test the effect of API functions @@ -7566,6 +7699,9 @@ int main(int argc, char **argv) { run_modinv_tests(); run_inverse_tests(); + /* sorting tests */ + run_hsort_tests(); + /* hash tests */ run_sha256_known_output_tests(); run_sha256_counter_tests(); @@ -7622,6 +7758,7 @@ int main(int argc, char **argv) { /* ecdsa tests */ run_ec_illegal_argument_tests(); run_pubkey_comparison(); + run_pubkey_sort(); run_random_pubkeys(); run_ecdsa_der_parse(); run_ecdsa_sign_verify(); @@ -7656,7 +7793,7 @@ int main(int argc, char **argv) { free(STATIC_CTX); secp256k1_context_destroy(CTX); - secp256k1_testrand_finish(); + testrand_finish(); printf("no problems found\n"); return 0; diff --git a/src/secp256k1/src/tests_exhaustive.c b/src/secp256k1/src/tests_exhaustive.c index 1a8be57d07..6efa88982e 100644 --- a/src/secp256k1/src/tests_exhaustive.c +++ b/src/secp256k1/src/tests_exhaustive.c @@ -171,7 +171,7 @@ static void test_exhaustive_ecmult(const secp256k1_ge *group, const secp256k1_ge CHECK(secp256k1_fe_equal(&tmpf, &group[(i * j) % EXHAUSTIVE_TEST_ORDER].x)); /* Test secp256k1_ecmult_const_xonly with all curve X coordinates, with random xd. */ - random_fe_non_zero(&xd); + testutil_random_fe_non_zero(&xd); secp256k1_fe_mul(&xn, &xd, &group[i].x); ret = secp256k1_ecmult_const_xonly(&tmpf, &xn, &xd, &ng, 0); CHECK(ret); @@ -375,7 +375,7 @@ int main(int argc, char** argv) { printf("test count = %i\n", count); /* find random seed */ - secp256k1_testrand_init(argc > 2 ? argv[2] : NULL); + testrand_init(argc > 2 ? argv[2] : NULL); /* set up split processing */ if (argc > 4) { @@ -389,13 +389,13 @@ int main(int argc, char** argv) { } /* Recreate the ecmult{,_gen} tables using the right generator (as selected via EXHAUSTIVE_TEST_ORDER) */ - secp256k1_ecmult_gen_compute_table(&secp256k1_ecmult_gen_prec_table[0][0], &secp256k1_ge_const_g, ECMULT_GEN_PREC_BITS); + secp256k1_ecmult_gen_compute_table(&secp256k1_ecmult_gen_prec_table[0][0], &secp256k1_ge_const_g, COMB_BLOCKS, COMB_TEETH, COMB_SPACING); secp256k1_ecmult_compute_two_tables(secp256k1_pre_g, secp256k1_pre_g_128, WINDOW_G, &secp256k1_ge_const_g); while (count--) { /* Build context */ ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); - secp256k1_testrand256(rand32); + testrand256(rand32); CHECK(secp256k1_context_randomize(ctx, rand32)); /* Generate the entire group */ @@ -408,7 +408,7 @@ int main(int argc, char** argv) { /* Set a different random z-value for each Jacobian point, except z=1 is used in the last iteration. */ secp256k1_fe z; - random_fe(&z); + testutil_random_fe(&z); secp256k1_gej_rescale(&groupj[i], &z); } @@ -459,7 +459,7 @@ int main(int argc, char** argv) { secp256k1_context_destroy(ctx); } - secp256k1_testrand_finish(); + testrand_finish(); printf("no problems found\n"); return 0; diff --git a/src/secp256k1/src/testutil.h b/src/secp256k1/src/testutil.h index 4e2cb7d5b3..8296a5fb99 100644 --- a/src/secp256k1/src/testutil.h +++ b/src/secp256k1/src/testutil.h @@ -7,23 +7,136 @@ #define SECP256K1_TESTUTIL_H #include "field.h" +#include "group.h" #include "testrand.h" #include "util.h" -static void random_fe(secp256k1_fe *x) { +static void testutil_random_fe(secp256k1_fe *x) { unsigned char bin[32]; do { - secp256k1_testrand256(bin); + testrand256(bin); if (secp256k1_fe_set_b32_limit(x, bin)) { return; } } while(1); } -static void random_fe_non_zero(secp256k1_fe *nz) { +static void testutil_random_fe_non_zero(secp256k1_fe *nz) { do { - random_fe(nz); + testutil_random_fe(nz); } while (secp256k1_fe_is_zero(nz)); } +static void testutil_random_fe_magnitude(secp256k1_fe *fe, int m) { + secp256k1_fe zero; + int n = testrand_int(m + 1); + secp256k1_fe_normalize(fe); + if (n == 0) { + return; + } + secp256k1_fe_clear(&zero); + secp256k1_fe_negate(&zero, &zero, 0); + secp256k1_fe_mul_int_unchecked(&zero, n - 1); + secp256k1_fe_add(fe, &zero); +#ifdef VERIFY + CHECK(fe->magnitude == n); +#endif +} + +static void testutil_random_fe_test(secp256k1_fe *x) { + unsigned char bin[32]; + do { + testrand256_test(bin); + if (secp256k1_fe_set_b32_limit(x, bin)) { + return; + } + } while(1); +} + +static void testutil_random_fe_non_zero_test(secp256k1_fe *fe) { + do { + testutil_random_fe_test(fe); + } while(secp256k1_fe_is_zero(fe)); +} + +static void testutil_random_ge_x_magnitude(secp256k1_ge *ge) { + testutil_random_fe_magnitude(&ge->x, SECP256K1_GE_X_MAGNITUDE_MAX); +} + +static void testutil_random_ge_y_magnitude(secp256k1_ge *ge) { + testutil_random_fe_magnitude(&ge->y, SECP256K1_GE_Y_MAGNITUDE_MAX); +} + +static void testutil_random_gej_x_magnitude(secp256k1_gej *gej) { + testutil_random_fe_magnitude(&gej->x, SECP256K1_GEJ_X_MAGNITUDE_MAX); +} + +static void testutil_random_gej_y_magnitude(secp256k1_gej *gej) { + testutil_random_fe_magnitude(&gej->y, SECP256K1_GEJ_Y_MAGNITUDE_MAX); +} + +static void testutil_random_gej_z_magnitude(secp256k1_gej *gej) { + testutil_random_fe_magnitude(&gej->z, SECP256K1_GEJ_Z_MAGNITUDE_MAX); +} + +static void testutil_random_ge_test(secp256k1_ge *ge) { + secp256k1_fe fe; + do { + testutil_random_fe_test(&fe); + if (secp256k1_ge_set_xo_var(ge, &fe, testrand_bits(1))) { + secp256k1_fe_normalize(&ge->y); + break; + } + } while(1); + ge->infinity = 0; +} + +static void testutil_random_ge_jacobian_test(secp256k1_gej *gej, const secp256k1_ge *ge) { + secp256k1_fe z2, z3; + testutil_random_fe_non_zero_test(&gej->z); + secp256k1_fe_sqr(&z2, &gej->z); + secp256k1_fe_mul(&z3, &z2, &gej->z); + secp256k1_fe_mul(&gej->x, &ge->x, &z2); + secp256k1_fe_mul(&gej->y, &ge->y, &z3); + gej->infinity = ge->infinity; +} + +static void testutil_random_gej_test(secp256k1_gej *gej) { + secp256k1_ge ge; + testutil_random_ge_test(&ge); + testutil_random_ge_jacobian_test(gej, &ge); +} + +static void testutil_random_scalar_order_test(secp256k1_scalar *num) { + do { + unsigned char b32[32]; + int overflow = 0; + testrand256_test(b32); + secp256k1_scalar_set_b32(num, b32, &overflow); + if (overflow || secp256k1_scalar_is_zero(num)) { + continue; + } + break; + } while(1); +} + +static void testutil_random_scalar_order(secp256k1_scalar *num) { + do { + unsigned char b32[32]; + int overflow = 0; + testrand256(b32); + secp256k1_scalar_set_b32(num, b32, &overflow); + if (overflow || secp256k1_scalar_is_zero(num)) { + continue; + } + break; + } while(1); +} + +static void testutil_random_scalar_order_b32(unsigned char *b32) { + secp256k1_scalar num; + testutil_random_scalar_order(&num); + secp256k1_scalar_get_b32(b32, &num); +} + #endif /* SECP256K1_TESTUTIL_H */ diff --git a/src/secp256k1/src/util.h b/src/secp256k1/src/util.h index 154d9ebcf1..ca73752ccc 100644 --- a/src/secp256k1/src/util.h +++ b/src/secp256k1/src/util.h @@ -170,7 +170,10 @@ static SECP256K1_INLINE void *checked_malloc(const secp256k1_callback* cb, size_ #define ALIGNMENT 16 #endif -#define ROUND_TO_ALIGN(size) ((((size) + ALIGNMENT - 1) / ALIGNMENT) * ALIGNMENT) +/* ceil(x/y) for integers x > 0 and y > 0. Here, / denotes rational division. */ +#define CEIL_DIV(x, y) (1 + ((x) - 1) / (y)) + +#define ROUND_TO_ALIGN(size) (CEIL_DIV(size, ALIGNMENT) * ALIGNMENT) /* Macro for restrict, when available and not in a VERIFY build. */ #if defined(SECP256K1_BUILD) && defined(VERIFY) @@ -391,4 +394,16 @@ SECP256K1_INLINE static void secp256k1_write_be64(unsigned char* p, uint64_t x) p[0] = x >> 56; } +/* Rotate a uint32_t to the right. */ +SECP256K1_INLINE static uint32_t secp256k1_rotr32(const uint32_t x, const unsigned int by) { +#if defined(_MSC_VER) + return _rotr(x, by); /* needs <stdlib.h> */ +#else + /* Reduce rotation amount to avoid UB when shifting. */ + const unsigned int mask = CHAR_BIT * sizeof(x) - 1; + /* Turned into a rot instruction by GCC and clang. */ + return (x >> (by & mask)) | (x << ((-by) & mask)); +#endif +} + #endif /* SECP256K1_UTIL_H */ diff --git a/src/secp256k1/tools/check-abi.sh b/src/secp256k1/tools/check-abi.sh index 55c945ac16..94a98831e1 100755 --- a/src/secp256k1/tools/check-abi.sh +++ b/src/secp256k1/tools/check-abi.sh @@ -49,7 +49,7 @@ checkout_and_build() { -DSECP256K1_BUILD_CTIME_TESTS=OFF \ -DSECP256K1_BUILD_EXAMPLES=OFF cmake --build . -j "$(nproc)" - abi-dumper src/libsecp256k1.so -o ABI.dump -lver "$2" + abi-dumper src/libsecp256k1.so -o ABI.dump -lver "$2" -public-headers ../include/ cd "$_orig_dir" } diff --git a/src/serialize.h b/src/serialize.h index 2f13fba582..35519056a5 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -182,9 +182,8 @@ const Out& AsBase(const In& x) static void SerializationOps(Type& obj, Stream& s, Operation ser_action) /** - * Variant of FORMATTER_METHODS that supports a declared parameter type. - * - * If a formatter has a declared parameter type, it must be invoked directly or + * Formatter methods can retrieve parameters attached to a stream using the + * SER_PARAMS(type) macro as long as the stream is created directly or * indirectly with a parameter of that type. This permits making serialization * depend on run-time context in a type-safe way. * @@ -192,7 +191,8 @@ const Out& AsBase(const In& x) * struct BarParameter { bool fancy; ... }; * struct Bar { ... }; * struct FooFormatter { - * FORMATTER_METHODS(Bar, obj, BarParameter, param) { + * FORMATTER_METHODS(Bar, obj) { + * auto& param = SER_PARAMS(BarParameter); * if (param.fancy) { * READWRITE(VARINT(obj.value)); * } else { @@ -214,13 +214,7 @@ const Out& AsBase(const In& x) * Compilation will fail in any context where serialization is invoked but * no parameter of a type convertible to BarParameter is provided. */ -#define FORMATTER_METHODS_PARAMS(cls, obj, paramcls, paramobj) \ - template <typename Stream> \ - static void Ser(Stream& s, const cls& obj) { SerializationOps(obj, s, ActionSerialize{}, s.GetParams()); } \ - template <typename Stream> \ - static void Unser(Stream& s, cls& obj) { SerializationOps(obj, s, ActionUnserialize{}, s.GetParams()); } \ - template <typename Stream, typename Type, typename Operation> \ - static void SerializationOps(Type& obj, Stream& s, Operation ser_action, const paramcls& paramobj) +#define SER_PARAMS(type) (s.template GetParams<type>()) #define BASE_SERIALIZE_METHODS(cls) \ template <typename Stream> \ @@ -247,15 +241,6 @@ const Out& AsBase(const In& x) BASE_SERIALIZE_METHODS(cls) \ FORMATTER_METHODS(cls, obj) -/** - * Variant of SERIALIZE_METHODS that supports a declared parameter type. - * - * See FORMATTER_METHODS_PARAMS for more information on parameters. - */ -#define SERIALIZE_METHODS_PARAMS(cls, obj, paramcls, paramobj) \ - BASE_SERIALIZE_METHODS(cls) \ - FORMATTER_METHODS_PARAMS(cls, obj, paramcls, paramobj) - // Templates for serializing to anything that looks like a stream, // i.e. anything that supports .read(Span<std::byte>) and .write(Span<const std::byte>) // @@ -1118,27 +1103,85 @@ size_t GetSerializeSize(const T& t) return (SizeComputer() << t).size(); } -/** Wrapper that overrides the GetParams() function of a stream (and hides GetVersion/GetType). */ -template <typename Params, typename SubStream> +//! Check if type contains a stream by seeing if has a GetStream() method. +template<typename T> +concept ContainsStream = requires(T t) { t.GetStream(); }; + +/** Wrapper that overrides the GetParams() function of a stream. */ +template <typename SubStream, typename Params> class ParamsStream { const Params& m_params; - SubStream& m_substream; // private to avoid leaking version/type into serialization code that shouldn't see it + // If ParamsStream constructor is passed an lvalue argument, Substream will + // be a reference type, and m_substream will reference that argument. + // Otherwise m_substream will be a substream instance and move from the + // argument. Letting ParamsStream contain a substream instance instead of + // just a reference is useful to make the ParamsStream object self contained + // and let it do cleanup when destroyed, for example by closing files if + // SubStream is a file stream. + SubStream m_substream; public: - ParamsStream(const Params& params LIFETIMEBOUND, SubStream& substream LIFETIMEBOUND) : m_params{params}, m_substream{substream} {} + ParamsStream(SubStream&& substream, const Params& params LIFETIMEBOUND) : m_params{params}, m_substream{std::forward<SubStream>(substream)} {} + + template <typename NestedSubstream, typename Params1, typename Params2, typename... NestedParams> + ParamsStream(NestedSubstream&& s, const Params1& params1 LIFETIMEBOUND, const Params2& params2 LIFETIMEBOUND, const NestedParams&... params LIFETIMEBOUND) + : ParamsStream{::ParamsStream{std::forward<NestedSubstream>(s), params2, params...}, params1} {} + template <typename U> ParamsStream& operator<<(const U& obj) { ::Serialize(*this, obj); return *this; } template <typename U> ParamsStream& operator>>(U&& obj) { ::Unserialize(*this, obj); return *this; } - void write(Span<const std::byte> src) { m_substream.write(src); } - void read(Span<std::byte> dst) { m_substream.read(dst); } - void ignore(size_t num) { m_substream.ignore(num); } - bool eof() const { return m_substream.eof(); } - size_t size() const { return m_substream.size(); } - const Params& GetParams() const { return m_params; } - int GetVersion() = delete; // Deprecated with Params usage - int GetType() = delete; // Deprecated with Params usage + void write(Span<const std::byte> src) { GetStream().write(src); } + void read(Span<std::byte> dst) { GetStream().read(dst); } + void ignore(size_t num) { GetStream().ignore(num); } + bool eof() const { return GetStream().eof(); } + size_t size() const { return GetStream().size(); } + + //! Get reference to stream parameters. + template <typename P> + const auto& GetParams() const + { + if constexpr (std::is_convertible_v<Params, P>) { + return m_params; + } else { + return m_substream.template GetParams<P>(); + } + } + + //! Get reference to underlying stream. + auto& GetStream() + { + if constexpr (ContainsStream<SubStream>) { + return m_substream.GetStream(); + } else { + return m_substream; + } + } + const auto& GetStream() const + { + if constexpr (ContainsStream<SubStream>) { + return m_substream.GetStream(); + } else { + return m_substream; + } + } }; +/** + * Explicit template deduction guide is required for single-parameter + * constructor so Substream&& is treated as a forwarding reference, and + * SubStream is deduced as reference type for lvalue arguments. + */ +template <typename Substream, typename Params> +ParamsStream(Substream&&, const Params&) -> ParamsStream<Substream, Params>; + +/** + * Template deduction guide for multiple params arguments that creates a nested + * ParamsStream. + */ +template <typename Substream, typename Params1, typename Params2, typename... Params> +ParamsStream(Substream&& s, const Params1& params1, const Params2& params2, const Params&... params) -> + ParamsStream<decltype(ParamsStream{std::forward<Substream>(s), params2, params...}), Params1>; + /** Wrapper that serializes objects with the specified parameters. */ template <typename Params, typename T> class ParamsWrapper @@ -1152,13 +1195,13 @@ public: template <typename Stream> void Serialize(Stream& s) const { - ParamsStream ss{m_params, s}; + ParamsStream ss{s, m_params}; ::Serialize(ss, m_object); } template <typename Stream> void Unserialize(Stream& s) { - ParamsStream ss{m_params, s}; + ParamsStream ss{s, m_params}; ::Unserialize(ss, m_object); } }; @@ -1176,7 +1219,7 @@ public: /** \ * Return a wrapper around t that (de)serializes it with specified parameter params. \ * \ - * See FORMATTER_METHODS_PARAMS for more information on serialization parameters. \ + * See SER_PARAMS for more information on serialization parameters. \ */ \ template <typename T> \ auto operator()(T&& t) const \ diff --git a/src/signet.cpp b/src/signet.cpp index ebf0de09d3..7c193a1d77 100644 --- a/src/signet.cpp +++ b/src/signet.cpp @@ -68,13 +68,13 @@ static uint256 ComputeModifiedMerkleRoot(const CMutableTransaction& cb, const CB std::optional<SignetTxs> SignetTxs::Create(const CBlock& block, const CScript& challenge) { CMutableTransaction tx_to_spend; - tx_to_spend.nVersion = 0; + tx_to_spend.version = 0; tx_to_spend.nLockTime = 0; tx_to_spend.vin.emplace_back(COutPoint(), CScript(OP_0), 0); tx_to_spend.vout.emplace_back(0, challenge); CMutableTransaction tx_spending; - tx_spending.nVersion = 0; + tx_spending.version = 0; tx_spending.nLockTime = 0; tx_spending.vin.emplace_back(COutPoint(), CScript(), 0); tx_spending.vout.emplace_back(0, CScript(OP_RETURN)); diff --git a/src/streams.cpp b/src/streams.cpp index 6921dad677..cdd36a86fe 100644 --- a/src/streams.cpp +++ b/src/streams.cpp @@ -21,6 +21,28 @@ std::size_t AutoFile::detail_fread(Span<std::byte> dst) } } +void AutoFile::seek(int64_t offset, int origin) +{ + if (IsNull()) { + throw std::ios_base::failure("AutoFile::seek: file handle is nullptr"); + } + if (std::fseek(m_file, offset, origin) != 0) { + throw std::ios_base::failure(feof() ? "AutoFile::seek: end of file" : "AutoFile::seek: fseek failed"); + } +} + +int64_t AutoFile::tell() +{ + if (IsNull()) { + throw std::ios_base::failure("AutoFile::tell: file handle is nullptr"); + } + int64_t r{std::ftell(m_file)}; + if (r < 0) { + throw std::ios_base::failure("AutoFile::tell: ftell failed"); + } + return r; +} + void AutoFile::read(Span<std::byte> dst) { if (detail_fread(dst) != dst.size()) { diff --git a/src/streams.h b/src/streams.h index bc04a2babd..57fc600646 100644 --- a/src/streams.h +++ b/src/streams.h @@ -435,6 +435,9 @@ public: /** Implementation detail, only used internally. */ std::size_t detail_fread(Span<std::byte> dst); + void seek(int64_t offset, int origin); + int64_t tell(); + // // Stream subset // diff --git a/src/sync.cpp b/src/sync.cpp index a8bdfc1dea..93c9194541 100644 --- a/src/sync.cpp +++ b/src/sync.cpp @@ -37,11 +37,11 @@ struct CLockLocation { const char* pszFile, int nLine, bool fTryIn, - const std::string& thread_name) + std::string&& thread_name) : fTry(fTryIn), mutexName(pszName), sourceFile(pszFile), - m_thread_name(thread_name), + m_thread_name(std::move(thread_name)), sourceLine(nLine) {} std::string ToString() const @@ -60,7 +60,7 @@ private: bool fTry; std::string mutexName; std::string sourceFile; - const std::string& m_thread_name; + const std::string m_thread_name; int sourceLine; }; diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp index 9668a85484..e5d25637bd 100644 --- a/src/test/addrman_tests.cpp +++ b/src/test/addrman_tests.cpp @@ -22,6 +22,7 @@ using namespace std::literals; using node::NodeContext; +using util::ToString; static NetGroupManager EMPTY_NETGROUPMAN{std::vector<bool>()}; static const bool DETERMINISTIC{true}; diff --git a/src/test/argsman_tests.cpp b/src/test/argsman_tests.cpp index 340208a1c9..5f0318e8c4 100644 --- a/src/test/argsman_tests.cpp +++ b/src/test/argsman_tests.cpp @@ -20,6 +20,8 @@ #include <boost/test/unit_test.hpp> +using util::ToString; + BOOST_FIXTURE_TEST_SUITE(argsman_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(util_datadir) diff --git a/src/test/blockchain_tests.cpp b/src/test/blockchain_tests.cpp index be515a9eac..9b8f419290 100644 --- a/src/test/blockchain_tests.cpp +++ b/src/test/blockchain_tests.cpp @@ -11,6 +11,8 @@ #include <cstdlib> +using util::ToString; + /* Equality between doubles is imprecise. Comparison should be done * with a small threshold of tolerance, rather than exact equality. */ diff --git a/src/test/blockfilter_index_tests.cpp b/src/test/blockfilter_index_tests.cpp index d44d84af93..067a32d6a4 100644 --- a/src/test/blockfilter_index_tests.cpp +++ b/src/test/blockfilter_index_tests.cpp @@ -67,7 +67,8 @@ CBlock BuildChainTestingSetup::CreateBlock(const CBlockIndex* prev, const std::vector<CMutableTransaction>& txns, const CScript& scriptPubKey) { - std::unique_ptr<CBlockTemplate> pblocktemplate = BlockAssembler{m_node.chainman->ActiveChainstate(), m_node.mempool.get()}.CreateNewBlock(scriptPubKey); + BlockAssembler::Options options; + std::unique_ptr<CBlockTemplate> pblocktemplate = BlockAssembler{m_node.chainman->ActiveChainstate(), m_node.mempool.get(), options}.CreateNewBlock(scriptPubKey); CBlock& block = pblocktemplate->block; block.hashPrevBlock = prev->GetBlockHash(); block.nTime = prev->nTime + 1; diff --git a/src/test/blockmanager_tests.cpp b/src/test/blockmanager_tests.cpp index d7ac0bf823..9eb7acc3ca 100644 --- a/src/test/blockmanager_tests.cpp +++ b/src/test/blockmanager_tests.cpp @@ -27,7 +27,7 @@ BOOST_FIXTURE_TEST_SUITE(blockmanager_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(blockmanager_find_block_pos) { const auto params {CreateChainParams(ArgsManager{}, ChainType::MAIN)}; - KernelNotifications notifications{*Assert(m_node.shutdown), m_node.exit_status}; + KernelNotifications notifications{*Assert(m_node.shutdown), m_node.exit_status, *Assert(m_node.warnings)}; const BlockManager::Options blockman_opts{ .chainparams = *params, .blocks_dir = m_args.GetBlocksDirPath(), @@ -35,20 +35,20 @@ BOOST_AUTO_TEST_CASE(blockmanager_find_block_pos) }; BlockManager blockman{*Assert(m_node.shutdown), blockman_opts}; // simulate adding a genesis block normally - BOOST_CHECK_EQUAL(blockman.SaveBlockToDisk(params->GenesisBlock(), 0, nullptr).nPos, BLOCK_SERIALIZATION_HEADER_SIZE); + BOOST_CHECK_EQUAL(blockman.SaveBlockToDisk(params->GenesisBlock(), 0).nPos, BLOCK_SERIALIZATION_HEADER_SIZE); // simulate what happens during reindex // simulate a well-formed genesis block being found at offset 8 in the blk00000.dat file // the block is found at offset 8 because there is an 8 byte serialization header // consisting of 4 magic bytes + 4 length bytes before each block in a well-formed blk file. - FlatFilePos pos{0, BLOCK_SERIALIZATION_HEADER_SIZE}; - BOOST_CHECK_EQUAL(blockman.SaveBlockToDisk(params->GenesisBlock(), 0, &pos).nPos, BLOCK_SERIALIZATION_HEADER_SIZE); + const FlatFilePos pos{0, BLOCK_SERIALIZATION_HEADER_SIZE}; + blockman.UpdateBlockInfo(params->GenesisBlock(), 0, pos); // now simulate what happens after reindex for the first new block processed // the actual block contents don't matter, just that it's a block. // verify that the write position is at offset 0x12d. // this is a check to make sure that https://github.com/bitcoin/bitcoin/issues/21379 does not recur // 8 bytes (for serialization header) + 285 (for serialized genesis block) = 293 // add another 8 bytes for the second block's serialization header and we get 293 + 8 = 301 - FlatFilePos actual{blockman.SaveBlockToDisk(params->GenesisBlock(), 1, nullptr)}; + FlatFilePos actual{blockman.SaveBlockToDisk(params->GenesisBlock(), 1)}; BOOST_CHECK_EQUAL(actual.nPos, BLOCK_SERIALIZATION_HEADER_SIZE + ::GetSerializeSize(TX_WITH_WITNESS(params->GenesisBlock())) + BLOCK_SERIALIZATION_HEADER_SIZE); } @@ -134,7 +134,7 @@ BOOST_FIXTURE_TEST_CASE(blockmanager_block_data_availability, TestChain100Setup) BOOST_AUTO_TEST_CASE(blockmanager_flush_block_file) { - KernelNotifications notifications{*Assert(m_node.shutdown), m_node.exit_status}; + KernelNotifications notifications{*Assert(m_node.shutdown), m_node.exit_status, *Assert(m_node.warnings)}; node::BlockManager::Options blockman_opts{ .chainparams = Params(), .blocks_dir = m_args.GetBlocksDirPath(), @@ -156,12 +156,11 @@ BOOST_AUTO_TEST_CASE(blockmanager_flush_block_file) // Blockstore is empty BOOST_CHECK_EQUAL(blockman.CalculateCurrentUsage(), 0); - // Write the first block; dbp=nullptr means this block doesn't already have a disk - // location, so allocate a free location and write it there. - FlatFilePos pos1{blockman.SaveBlockToDisk(block1, /*nHeight=*/1, /*dbp=*/nullptr)}; + // Write the first block to a new location. + FlatFilePos pos1{blockman.SaveBlockToDisk(block1, /*nHeight=*/1)}; // Write second block - FlatFilePos pos2{blockman.SaveBlockToDisk(block2, /*nHeight=*/2, /*dbp=*/nullptr)}; + FlatFilePos pos2{blockman.SaveBlockToDisk(block2, /*nHeight=*/2)}; // Two blocks in the file BOOST_CHECK_EQUAL(blockman.CalculateCurrentUsage(), (TEST_BLOCK_SIZE + BLOCK_SERIALIZATION_HEADER_SIZE) * 2); @@ -181,22 +180,19 @@ BOOST_AUTO_TEST_CASE(blockmanager_flush_block_file) BOOST_CHECK_EQUAL(read_block.nVersion, 2); } - // When FlatFilePos* dbp is given, SaveBlockToDisk() will not write or - // overwrite anything to the flat file block storage. It will, however, - // update the blockfile metadata. This is to facilitate reindexing - // when the user has the blocks on disk but the metadata is being rebuilt. + // During reindex, the flat file block storage will not be written to. + // UpdateBlockInfo will, however, update the blockfile metadata. // Verify this behavior by attempting (and failing) to write block 3 data // to block 2 location. CBlockFileInfo* block_data = blockman.GetBlockFileInfo(0); BOOST_CHECK_EQUAL(block_data->nBlocks, 2); - BOOST_CHECK(blockman.SaveBlockToDisk(block3, /*nHeight=*/3, /*dbp=*/&pos2) == pos2); + blockman.UpdateBlockInfo(block3, /*nHeight=*/3, /*pos=*/pos2); // Metadata is updated... BOOST_CHECK_EQUAL(block_data->nBlocks, 3); // ...but there are still only two blocks in the file BOOST_CHECK_EQUAL(blockman.CalculateCurrentUsage(), (TEST_BLOCK_SIZE + BLOCK_SERIALIZATION_HEADER_SIZE) * 2); // Block 2 was not overwritten: - // SaveBlockToDisk() did not call WriteBlockToDisk() because `FlatFilePos* dbp` was non-null blockman.ReadBlockFromDisk(read_block, pos2); BOOST_CHECK_EQUAL(read_block.nVersion, 2); } diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json index a47bc8f366..486469ddef 100644 --- a/src/test/data/tx_invalid.json +++ b/src/test/data/tx_invalid.json @@ -246,7 +246,7 @@ [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x7c17aff532f22beb54069942f9bf567a66133eaf EQUAL"]], "0200000001000100000000000000000000000000000000000000000000000000000000000000000000030251b2000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], -["Failure due to insufficient tx.nVersion (<2)"], +["Failure due to insufficient tx.version (<2)"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKSEQUENCEVERIFY 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "CHECKSEQUENCEVERIFY"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194304 CHECKSEQUENCEVERIFY"]], diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp index 723a1ceee3..167e4be288 100644 --- a/src/test/dbwrapper_tests.cpp +++ b/src/test/dbwrapper_tests.cpp @@ -12,6 +12,8 @@ #include <boost/test/unit_test.hpp> +using util::ToString; + // Test if a string consists entirely of null characters static bool is_null_key(const std::vector<unsigned char>& key) { bool isnull = true; diff --git a/src/test/denialofservice_tests.cpp b/src/test/denialofservice_tests.cpp index 5e9ae78681..42db28daf5 100644 --- a/src/test/denialofservice_tests.cpp +++ b/src/test/denialofservice_tests.cpp @@ -141,7 +141,7 @@ BOOST_AUTO_TEST_CASE(stale_tip_peer_management) { NodeId id{0}; auto connman = std::make_unique<ConnmanTestMsg>(0x1337, 0x1337, *m_node.addrman, *m_node.netgroupman, Params()); - auto peerLogic = PeerManager::make(*connman, *m_node.addrman, nullptr, *m_node.chainman, *m_node.mempool, {}); + auto peerLogic = PeerManager::make(*connman, *m_node.addrman, nullptr, *m_node.chainman, *m_node.mempool, *m_node.warnings, {}); constexpr int max_outbound_full_relay = MAX_OUTBOUND_FULL_RELAY_CONNECTIONS; CConnman::Options options; @@ -239,7 +239,7 @@ BOOST_AUTO_TEST_CASE(block_relay_only_eviction) { NodeId id{0}; auto connman = std::make_unique<ConnmanTestMsg>(0x1337, 0x1337, *m_node.addrman, *m_node.netgroupman, Params()); - auto peerLogic = PeerManager::make(*connman, *m_node.addrman, nullptr, *m_node.chainman, *m_node.mempool, {}); + auto peerLogic = PeerManager::make(*connman, *m_node.addrman, nullptr, *m_node.chainman, *m_node.mempool, *m_node.warnings, {}); constexpr int max_outbound_block_relay{MAX_BLOCK_RELAY_ONLY_CONNECTIONS}; constexpr int64_t MINIMUM_CONNECT_TIME{30}; @@ -300,7 +300,7 @@ BOOST_AUTO_TEST_CASE(peer_discouragement) auto banman = std::make_unique<BanMan>(m_args.GetDataDirBase() / "banlist", nullptr, DEFAULT_MISBEHAVING_BANTIME); auto connman = std::make_unique<ConnmanTestMsg>(0x1337, 0x1337, *m_node.addrman, *m_node.netgroupman, Params()); - auto peerLogic = PeerManager::make(*connman, *m_node.addrman, banman.get(), *m_node.chainman, *m_node.mempool, {}); + auto peerLogic = PeerManager::make(*connman, *m_node.addrman, banman.get(), *m_node.chainman, *m_node.mempool, *m_node.warnings, {}); CNetAddr tor_netaddr; BOOST_REQUIRE( @@ -330,7 +330,7 @@ BOOST_AUTO_TEST_CASE(peer_discouragement) peerLogic->InitializeNode(*nodes[0], NODE_NETWORK); nodes[0]->fSuccessfullyConnected = true; connman->AddTestNode(*nodes[0]); - peerLogic->UnitTestMisbehaving(nodes[0]->GetId(), DISCOURAGEMENT_THRESHOLD); // Should be discouraged + peerLogic->UnitTestMisbehaving(nodes[0]->GetId()); // Should be discouraged BOOST_CHECK(peerLogic->SendMessages(nodes[0])); BOOST_CHECK(banman->IsDiscouraged(addr[0])); @@ -350,7 +350,6 @@ BOOST_AUTO_TEST_CASE(peer_discouragement) peerLogic->InitializeNode(*nodes[1], NODE_NETWORK); nodes[1]->fSuccessfullyConnected = true; connman->AddTestNode(*nodes[1]); - peerLogic->UnitTestMisbehaving(nodes[1]->GetId(), DISCOURAGEMENT_THRESHOLD - 1); BOOST_CHECK(peerLogic->SendMessages(nodes[1])); // [0] is still discouraged/disconnected. BOOST_CHECK(banman->IsDiscouraged(addr[0])); @@ -358,7 +357,7 @@ BOOST_AUTO_TEST_CASE(peer_discouragement) // [1] is not discouraged/disconnected yet. BOOST_CHECK(!banman->IsDiscouraged(addr[1])); BOOST_CHECK(!nodes[1]->fDisconnect); - peerLogic->UnitTestMisbehaving(nodes[1]->GetId(), 1); // [1] reaches discouragement threshold + peerLogic->UnitTestMisbehaving(nodes[1]->GetId()); BOOST_CHECK(peerLogic->SendMessages(nodes[1])); // Expect both [0] and [1] to be discouraged/disconnected now. BOOST_CHECK(banman->IsDiscouraged(addr[0])); @@ -381,7 +380,7 @@ BOOST_AUTO_TEST_CASE(peer_discouragement) peerLogic->InitializeNode(*nodes[2], NODE_NETWORK); nodes[2]->fSuccessfullyConnected = true; connman->AddTestNode(*nodes[2]); - peerLogic->UnitTestMisbehaving(nodes[2]->GetId(), DISCOURAGEMENT_THRESHOLD); + peerLogic->UnitTestMisbehaving(nodes[2]->GetId()); BOOST_CHECK(peerLogic->SendMessages(nodes[2])); BOOST_CHECK(banman->IsDiscouraged(addr[0])); BOOST_CHECK(banman->IsDiscouraged(addr[1])); @@ -402,7 +401,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime) auto banman = std::make_unique<BanMan>(m_args.GetDataDirBase() / "banlist", nullptr, DEFAULT_MISBEHAVING_BANTIME); auto connman = std::make_unique<CConnman>(0x1337, 0x1337, *m_node.addrman, *m_node.netgroupman, Params()); - auto peerLogic = PeerManager::make(*connman, *m_node.addrman, banman.get(), *m_node.chainman, *m_node.mempool, {}); + auto peerLogic = PeerManager::make(*connman, *m_node.addrman, banman.get(), *m_node.chainman, *m_node.mempool, *m_node.warnings, {}); banman->ClearBanned(); int64_t nStartTime = GetTime(); @@ -423,7 +422,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime) peerLogic->InitializeNode(dummyNode, NODE_NETWORK); dummyNode.fSuccessfullyConnected = true; - peerLogic->UnitTestMisbehaving(dummyNode.GetId(), DISCOURAGEMENT_THRESHOLD); + peerLogic->UnitTestMisbehaving(dummyNode.GetId()); BOOST_CHECK(peerLogic->SendMessages(&dummyNode)); BOOST_CHECK(banman->IsDiscouraged(addr)); diff --git a/src/test/descriptor_tests.cpp b/src/test/descriptor_tests.cpp index c779bf6f73..e6821dd321 100644 --- a/src/test/descriptor_tests.cpp +++ b/src/test/descriptor_tests.cpp @@ -7,6 +7,7 @@ #include <script/sign.h> #include <test/util/setup_common.h> #include <util/strencodings.h> +#include <util/string.h> #include <boost/test/unit_test.hpp> @@ -14,6 +15,8 @@ #include <string> #include <vector> +using util::Split; + namespace { void CheckUnparsable(const std::string& prv, const std::string& pub, const std::string& expected_error) @@ -400,7 +403,6 @@ void CheckInferDescriptor(const std::string& script_hex, const std::string& expe provider.pubkeys.emplace(origin_pubkey.GetID(), origin_pubkey); if (!origin_str.empty()) { - using namespace spanparsing; KeyOriginInfo info; Span<const char> origin_sp{origin_str}; std::vector<Span<const char>> origin_split = Split(origin_sp, "/"); diff --git a/src/test/fuzz/base_encode_decode.cpp b/src/test/fuzz/base_encode_decode.cpp index d322416d34..0cc8cb5886 100644 --- a/src/test/fuzz/base_encode_decode.cpp +++ b/src/test/fuzz/base_encode_decode.cpp @@ -14,6 +14,9 @@ #include <string> #include <vector> +using util::TrimString; +using util::TrimStringView; + FUZZ_TARGET(base_encode_decode) { const std::string random_encoded_string(buffer.begin(), buffer.end()); diff --git a/src/test/fuzz/bip324.cpp b/src/test/fuzz/bip324.cpp index 37c41f3895..8210e75cee 100644 --- a/src/test/fuzz/bip324.cpp +++ b/src/test/fuzz/bip324.cpp @@ -17,7 +17,7 @@ namespace { void Initialize() { - ECC_Start(); + static ECC_Context ecc_context{}; SelectParams(ChainType::MAIN); } diff --git a/src/test/fuzz/bitset.cpp b/src/test/fuzz/bitset.cpp new file mode 100644 index 0000000000..7684337729 --- /dev/null +++ b/src/test/fuzz/bitset.cpp @@ -0,0 +1,316 @@ +// Copyright (c) The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <span.h> +#include <test/fuzz/util.h> +#include <test/util/xoroshiro128plusplus.h> +#include <util/bitset.h> + +#include <bitset> +#include <vector> + +namespace { + +/** Pop the first byte from a byte-span, and return it. */ +uint8_t ReadByte(FuzzBufferType& buffer) +{ + if (buffer.empty()) return 0; + uint8_t ret = buffer.front(); + buffer = buffer.subspan(1); + return ret; +} + +/** Perform a simulation fuzz test on BitSet type S. */ +template<typename S> +void TestType(FuzzBufferType buffer) +{ + /** This fuzz test's design is based on the assumption that the actual bits stored in the + * bitsets and their simulations do not matter for the purpose of detecting edge cases, thus + * these are taken from a deterministically-seeded RNG instead. To provide some level of + * variation however, pick the seed based on the buffer size and size of the chosen bitset. */ + XoRoShiRo128PlusPlus rng(buffer.size() + 0x10000 * S::Size()); + + using Sim = std::bitset<S::Size()>; + // Up to 4 real BitSets (initially 2). + std::vector<S> real(2); + // Up to 4 std::bitsets with the same corresponding contents. + std::vector<Sim> sim(2); + + /* Compare sim[idx] with real[idx], using all inspector operations. */ + auto compare_fn = [&](unsigned idx) { + /* iterators and operator[] */ + auto it = real[idx].begin(); + unsigned first = S::Size(); + unsigned last = S::Size(); + for (unsigned i = 0; i < S::Size(); ++i) { + bool match = (it != real[idx].end()) && *it == i; + assert(sim[idx][i] == real[idx][i]); + assert(match == real[idx][i]); + assert((it == real[idx].end()) != (it != real[idx].end())); + if (match) { + ++it; + if (first == S::Size()) first = i; + last = i; + } + } + assert(it == real[idx].end()); + assert(!(it != real[idx].end())); + /* Any / None */ + assert(sim[idx].any() == real[idx].Any()); + assert(sim[idx].none() == real[idx].None()); + /* First / Last */ + if (sim[idx].any()) { + assert(first == real[idx].First()); + assert(last == real[idx].Last()); + } + /* Count */ + assert(sim[idx].count() == real[idx].Count()); + }; + + LIMITED_WHILE(buffer.size() > 0, 1000) { + // Read one byte to determine which operation to execute on the BitSets. + int command = ReadByte(buffer) % 64; + // Read another byte that determines which bitsets will be involved. + unsigned args = ReadByte(buffer); + unsigned dest = ((args & 7) * sim.size()) >> 3; + unsigned src = (((args >> 3) & 7) * sim.size()) >> 3; + unsigned aux = (((args >> 6) & 3) * sim.size()) >> 2; + // Args are in range for non-empty sim, or sim is completely empty and will be grown + assert((sim.empty() && dest == 0 && src == 0 && aux == 0) || + (!sim.empty() && dest < sim.size() && src < sim.size() && aux < sim.size())); + + // Pick one operation based on value of command. Not all operations are always applicable. + // Loop through the applicable ones until command reaches 0 (which avoids the need to + // compute the number of applicable commands ahead of time). + while (true) { + if (dest < sim.size() && command-- == 0) { + /* Set() (true) */ + unsigned val = ReadByte(buffer) % S::Size(); + assert(sim[dest][val] == real[dest][val]); + sim[dest].set(val); + real[dest].Set(val); + break; + } else if (dest < sim.size() && command-- == 0) { + /* Reset() */ + unsigned val = ReadByte(buffer) % S::Size(); + assert(sim[dest][val] == real[dest][val]); + sim[dest].reset(val); + real[dest].Reset(val); + break; + } else if (dest < sim.size() && command-- == 0) { + /* Set() (conditional) */ + unsigned val = ReadByte(buffer) % S::Size(); + assert(sim[dest][val] == real[dest][val]); + sim[dest].set(val, args >> 7); + real[dest].Set(val, args >> 7); + break; + } else if (sim.size() < 4 && command-- == 0) { + /* Construct empty. */ + sim.resize(sim.size() + 1); + real.resize(real.size() + 1); + break; + } else if (sim.size() < 4 && command-- == 0) { + /* Construct singleton. */ + unsigned val = ReadByte(buffer) % S::Size(); + std::bitset<S::Size()> newset; + newset[val] = true; + sim.push_back(newset); + real.push_back(S::Singleton(val)); + break; + } else if (dest < sim.size() && command-- == 0) { + /* Make random. */ + compare_fn(dest); + sim[dest].reset(); + real[dest] = S{}; + for (unsigned i = 0; i < S::Size(); ++i) { + if (rng() & 1) { + sim[dest][i] = true; + real[dest].Set(i); + } + } + break; + } else if (dest < sim.size() && command-- == 0) { + /* Assign initializer list. */ + unsigned r1 = rng() % S::Size(); + unsigned r2 = rng() % S::Size(); + unsigned r3 = rng() % S::Size(); + compare_fn(dest); + sim[dest].reset(); + real[dest] = {r1, r2, r3}; + sim[dest].set(r1); + sim[dest].set(r2); + sim[dest].set(r3); + break; + } else if (!sim.empty() && command-- == 0) { + /* Destruct. */ + compare_fn(sim.size() - 1); + sim.pop_back(); + real.pop_back(); + break; + } else if (sim.size() < 4 && src < sim.size() && command-- == 0) { + /* Copy construct. */ + sim.emplace_back(sim[src]); + real.emplace_back(real[src]); + break; + } else if (src < sim.size() && dest < sim.size() && command-- == 0) { + /* Copy assign. */ + compare_fn(dest); + sim[dest] = sim[src]; + real[dest] = real[src]; + break; + } else if (src < sim.size() && dest < sim.size() && command-- == 0) { + /* swap() function. */ + swap(sim[dest], sim[src]); + swap(real[dest], real[src]); + break; + } else if (sim.size() < 4 && command-- == 0) { + /* Construct with initializer list. */ + unsigned r1 = rng() % S::Size(); + unsigned r2 = rng() % S::Size(); + sim.emplace_back(); + sim.back().set(r1); + sim.back().set(r2); + real.push_back(S{r1, r2}); + break; + } else if (dest < sim.size() && command-- == 0) { + /* Fill() + copy assign. */ + unsigned len = ReadByte(buffer) % S::Size(); + compare_fn(dest); + sim[dest].reset(); + for (unsigned i = 0; i < len; ++i) sim[dest][i] = true; + real[dest] = S::Fill(len); + break; + } else if (src < sim.size() && command-- == 0) { + /* Iterator copy based compare. */ + unsigned val = ReadByte(buffer) % S::Size(); + /* In a first loop, compare begin..end, and copy to it_copy at some point. */ + auto it = real[src].begin(), it_copy = it; + for (unsigned i = 0; i < S::Size(); ++i) { + if (i == val) it_copy = it; + bool match = (it != real[src].end()) && *it == i; + assert(match == sim[src][i]); + if (match) ++it; + } + assert(it == real[src].end()); + /* Then compare from the copied point again to end. */ + for (unsigned i = val; i < S::Size(); ++i) { + bool match = (it_copy != real[src].end()) && *it_copy == i; + assert(match == sim[src][i]); + if (match) ++it_copy; + } + assert(it_copy == real[src].end()); + break; + } else if (src < sim.size() && dest < sim.size() && command-- == 0) { + /* operator|= */ + compare_fn(dest); + sim[dest] |= sim[src]; + real[dest] |= real[src]; + break; + } else if (src < sim.size() && dest < sim.size() && command-- == 0) { + /* operator&= */ + compare_fn(dest); + sim[dest] &= sim[src]; + real[dest] &= real[src]; + break; + } else if (src < sim.size() && dest < sim.size() && command-- == 0) { + /* operator-= */ + compare_fn(dest); + sim[dest] &= ~sim[src]; + real[dest] -= real[src]; + break; + } else if (src < sim.size() && dest < sim.size() && command-- == 0) { + /* operator^= */ + compare_fn(dest); + sim[dest] ^= sim[src]; + real[dest] ^= real[src]; + break; + } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) { + /* operator| */ + compare_fn(dest); + sim[dest] = sim[src] | sim[aux]; + real[dest] = real[src] | real[aux]; + break; + } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) { + /* operator& */ + compare_fn(dest); + sim[dest] = sim[src] & sim[aux]; + real[dest] = real[src] & real[aux]; + break; + } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) { + /* operator- */ + compare_fn(dest); + sim[dest] = sim[src] & ~sim[aux]; + real[dest] = real[src] - real[aux]; + break; + } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) { + /* operator^ */ + compare_fn(dest); + sim[dest] = sim[src] ^ sim[aux]; + real[dest] = real[src] ^ real[aux]; + break; + } else if (src < sim.size() && aux < sim.size() && command-- == 0) { + /* IsSupersetOf() and IsSubsetOf() */ + bool is_superset = (sim[aux] & ~sim[src]).none(); + bool is_subset = (sim[src] & ~sim[aux]).none(); + assert(real[src].IsSupersetOf(real[aux]) == is_superset); + assert(real[src].IsSubsetOf(real[aux]) == is_subset); + assert(real[aux].IsSupersetOf(real[src]) == is_subset); + assert(real[aux].IsSubsetOf(real[src]) == is_superset); + break; + } else if (src < sim.size() && aux < sim.size() && command-- == 0) { + /* operator== and operator!= */ + assert((sim[src] == sim[aux]) == (real[src] == real[aux])); + assert((sim[src] != sim[aux]) == (real[src] != real[aux])); + break; + } else if (src < sim.size() && aux < sim.size() && command-- == 0) { + /* Overlaps() */ + assert((sim[src] & sim[aux]).any() == real[src].Overlaps(real[aux])); + assert((sim[src] & sim[aux]).any() == real[aux].Overlaps(real[src])); + break; + } + } + } + /* Fully compare the final state. */ + for (unsigned i = 0; i < sim.size(); ++i) { + compare_fn(i); + } +} + +} // namespace + +FUZZ_TARGET(bitset) +{ + unsigned typdat = ReadByte(buffer) % 8; + if (typdat == 0) { + /* 16 bits */ + TestType<bitset_detail::IntBitSet<uint16_t>>(buffer); + TestType<bitset_detail::MultiIntBitSet<uint16_t, 1>>(buffer); + } else if (typdat == 1) { + /* 32 bits */ + TestType<bitset_detail::MultiIntBitSet<uint16_t, 2>>(buffer); + TestType<bitset_detail::IntBitSet<uint32_t>>(buffer); + } else if (typdat == 2) { + /* 48 bits */ + TestType<bitset_detail::MultiIntBitSet<uint16_t, 3>>(buffer); + } else if (typdat == 3) { + /* 64 bits */ + TestType<bitset_detail::IntBitSet<uint64_t>>(buffer); + TestType<bitset_detail::MultiIntBitSet<uint64_t, 1>>(buffer); + TestType<bitset_detail::MultiIntBitSet<uint32_t, 2>>(buffer); + TestType<bitset_detail::MultiIntBitSet<uint16_t, 4>>(buffer); + } else if (typdat == 4) { + /* 96 bits */ + TestType<bitset_detail::MultiIntBitSet<uint32_t, 3>>(buffer); + } else if (typdat == 5) { + /* 128 bits */ + TestType<bitset_detail::MultiIntBitSet<uint64_t, 2>>(buffer); + TestType<bitset_detail::MultiIntBitSet<uint32_t, 4>>(buffer); + } else if (typdat == 6) { + /* 192 bits */ + TestType<bitset_detail::MultiIntBitSet<uint64_t, 3>>(buffer); + } else if (typdat == 7) { + /* 256 bits */ + TestType<bitset_detail::MultiIntBitSet<uint64_t, 4>>(buffer); + } +} diff --git a/src/test/fuzz/descriptor_parse.cpp b/src/test/fuzz/descriptor_parse.cpp index 6ea315d4e2..b9a5560ffb 100644 --- a/src/test/fuzz/descriptor_parse.cpp +++ b/src/test/fuzz/descriptor_parse.cpp @@ -55,7 +55,7 @@ static void TestDescriptor(const Descriptor& desc, FlatSigningProvider& sig_prov void initialize_descriptor_parse() { - ECC_Start(); + static ECC_Context ecc_context{}; SelectParams(ChainType::MAIN); } diff --git a/src/test/fuzz/deserialize.cpp b/src/test/fuzz/deserialize.cpp index c9a3bc86ac..6623edcf99 100644 --- a/src/test/fuzz/deserialize.cpp +++ b/src/test/fuzz/deserialize.cpp @@ -316,7 +316,8 @@ FUZZ_TARGET_DESERIALIZE(blocktransactionsrequest_deserialize, { DeserializeFromFuzzingInput(buffer, btr); }) FUZZ_TARGET_DESERIALIZE(snapshotmetadata_deserialize, { - SnapshotMetadata snapshot_metadata; + auto msg_start = Params().MessageStart(); + SnapshotMetadata snapshot_metadata{msg_start}; DeserializeFromFuzzingInput(buffer, snapshot_metadata); }) FUZZ_TARGET_DESERIALIZE(uint160_deserialize, { diff --git a/src/test/fuzz/fees.cpp b/src/test/fuzz/fees.cpp index 38a8c6798e..5c760be13d 100644 --- a/src/test/fuzz/fees.cpp +++ b/src/test/fuzz/fees.cpp @@ -2,17 +2,19 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <common/messages.h> #include <consensus/amount.h> #include <policy/fees.h> #include <test/fuzz/FuzzedDataProvider.h> #include <test/fuzz/fuzz.h> #include <test/fuzz/util.h> -#include <util/fees.h> #include <cstdint> #include <string> #include <vector> +using common::StringForFeeReason; + FUZZ_TARGET(fees) { FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); diff --git a/src/test/fuzz/fuzz.cpp b/src/test/fuzz/fuzz.cpp index f9915187bd..c1c9945a04 100644 --- a/src/test/fuzz/fuzz.cpp +++ b/src/test/fuzz/fuzz.cpp @@ -79,10 +79,31 @@ void FuzzFrameworkRegisterTarget(std::string_view name, TypeTestOneInput target, static std::string_view g_fuzz_target; static const TypeTestOneInput* g_test_one_input{nullptr}; + +#if defined(__clang__) && defined(__linux__) +extern "C" void __llvm_profile_reset_counters(void) __attribute__((weak)); +extern "C" void __gcov_reset(void) __attribute__((weak)); + +void ResetCoverageCounters() +{ + if (__llvm_profile_reset_counters) { + __llvm_profile_reset_counters(); + } + + if (__gcov_reset) { + __gcov_reset(); + } +} +#else +void ResetCoverageCounters() {} +#endif + + void initialize() { - // Terminate immediately if a fuzzing harness ever tries to create a TCP socket. - CreateSock = [](const sa_family_t&) -> std::unique_ptr<Sock> { std::terminate(); }; + // Terminate immediately if a fuzzing harness ever tries to create a socket. + // Individual tests can override this by pointing CreateSock to a mocked alternative. + CreateSock = [](int, int, int) -> std::unique_ptr<Sock> { std::terminate(); }; // Terminate immediately if a fuzzing harness ever tries to perform a DNS lookup. g_dns_lookup = [](const std::string& name, bool allow_lookup) { @@ -129,6 +150,8 @@ void initialize() Assert(!g_test_one_input); g_test_one_input = &it->second.test_one_input; it->second.opts.init(); + + ResetCoverageCounters(); } #if defined(PROVIDE_FUZZ_MAIN_FUNCTION) diff --git a/src/test/fuzz/fuzz.h b/src/test/fuzz/fuzz.h index ca74d53de7..c468cd39e3 100644 --- a/src/test/fuzz/fuzz.h +++ b/src/test/fuzz/fuzz.h @@ -5,10 +5,9 @@ #ifndef BITCOIN_TEST_FUZZ_FUZZ_H #define BITCOIN_TEST_FUZZ_FUZZ_H -#include <span.h> - #include <cstdint> #include <functional> +#include <span> #include <string_view> /** @@ -23,7 +22,7 @@ #define LIMITED_WHILE(condition, limit) \ for (unsigned _count{limit}; (condition) && _count; --_count) -using FuzzBufferType = Span<const uint8_t>; +using FuzzBufferType = std::span<const uint8_t>; using TypeTestOneInput = std::function<void(FuzzBufferType)>; struct FuzzTargetOptions { diff --git a/src/test/fuzz/i2p.cpp b/src/test/fuzz/i2p.cpp new file mode 100644 index 0000000000..51517187a0 --- /dev/null +++ b/src/test/fuzz/i2p.cpp @@ -0,0 +1,63 @@ +// Copyright (c) The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <common/args.h> +#include <i2p.h> +#include <netaddress.h> +#include <netbase.h> +#include <test/fuzz/FuzzedDataProvider.h> +#include <test/fuzz/fuzz.h> +#include <test/fuzz/util.h> +#include <test/fuzz/util/net.h> +#include <test/util/setup_common.h> +#include <util/fs_helpers.h> +#include <util/threadinterrupt.h> + +void initialize_i2p() +{ + static const auto testing_setup = MakeNoLogFileContext<>(); +} + +FUZZ_TARGET(i2p, .init = initialize_i2p) +{ + FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; + + SetMockTime(ConsumeTime(fuzzed_data_provider)); + + // Mock CreateSock() to create FuzzedSock. + auto CreateSockOrig = CreateSock; + CreateSock = [&fuzzed_data_provider](int, int, int) { + return std::make_unique<FuzzedSock>(fuzzed_data_provider); + }; + + const fs::path private_key_path = gArgs.GetDataDirNet() / "fuzzed_i2p_private_key"; + const CService addr{in6_addr(IN6ADDR_LOOPBACK_INIT), 7656}; + const Proxy sam_proxy{addr, false}; + CThreadInterrupt interrupt; + + i2p::sam::Session session{private_key_path, sam_proxy, &interrupt}; + i2p::Connection conn; + + if (session.Listen(conn)) { + if (session.Accept(conn)) { + try { + (void)conn.sock->RecvUntilTerminator('\n', 10ms, interrupt, i2p::sam::MAX_MSG_SIZE); + } catch (const std::runtime_error&) { + } + } + } + + bool proxy_error; + + if (session.Connect(CService{}, conn, proxy_error)) { + try { + conn.sock->SendComplete("verack\n", 10ms, interrupt); + } catch (const std::runtime_error&) { + } + } + + fs::remove_all(private_key_path); + + CreateSock = CreateSockOrig; +} diff --git a/src/test/fuzz/integer.cpp b/src/test/fuzz/integer.cpp index db246bb84e..8f1d7b6d45 100644 --- a/src/test/fuzz/integer.cpp +++ b/src/test/fuzz/integer.cpp @@ -40,6 +40,8 @@ #include <set> #include <vector> +using util::ToString; + void initialize_integer() { SelectParams(ChainType::REGTEST); diff --git a/src/test/fuzz/key.cpp b/src/test/fuzz/key.cpp index 9e1e318e02..82973803f8 100644 --- a/src/test/fuzz/key.cpp +++ b/src/test/fuzz/key.cpp @@ -32,7 +32,7 @@ void initialize_key() { - ECC_Start(); + static ECC_Context ecc_context{}; SelectParams(ChainType::REGTEST); } @@ -78,16 +78,6 @@ FUZZ_TARGET(key, .init = initialize_key) assert(copied_key == key); } - { - CKey negated_key = key; - negated_key.Negate(); - assert(negated_key.IsValid()); - assert(!(negated_key == key)); - - negated_key.Negate(); - assert(negated_key == key); - } - const uint256 random_uint256 = Hash(buffer); { diff --git a/src/test/fuzz/key_io.cpp b/src/test/fuzz/key_io.cpp index 5f98f2b7f1..aefdefe233 100644 --- a/src/test/fuzz/key_io.cpp +++ b/src/test/fuzz/key_io.cpp @@ -14,7 +14,7 @@ void initialize_key_io() { - ECC_Start(); + static ECC_Context ecc_context{}; SelectParams(ChainType::MAIN); } diff --git a/src/test/fuzz/kitchen_sink.cpp b/src/test/fuzz/kitchen_sink.cpp index 82f3a306c5..4468f358d9 100644 --- a/src/test/fuzz/kitchen_sink.cpp +++ b/src/test/fuzz/kitchen_sink.cpp @@ -2,13 +2,14 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <common/messages.h> #include <merkleblock.h> +#include <node/types.h> #include <policy/fees.h> #include <rpc/util.h> #include <test/fuzz/FuzzedDataProvider.h> #include <test/fuzz/fuzz.h> #include <test/fuzz/util.h> -#include <util/error.h> #include <util/translation.h> #include <array> @@ -16,17 +17,15 @@ #include <optional> #include <vector> +using common::TransactionErrorString; +using node::TransactionError; + namespace { constexpr TransactionError ALL_TRANSACTION_ERROR[] = { - TransactionError::OK, TransactionError::MISSING_INPUTS, TransactionError::ALREADY_IN_CHAIN, - TransactionError::P2P_DISABLED, TransactionError::MEMPOOL_REJECTED, TransactionError::MEMPOOL_ERROR, - TransactionError::INVALID_PSBT, - TransactionError::PSBT_MISMATCH, - TransactionError::SIGHASH_MISMATCH, TransactionError::MAX_FEE_EXCEEDED, }; }; // namespace diff --git a/src/test/fuzz/locale.cpp b/src/test/fuzz/locale.cpp index 0f2985b504..68db842247 100644 --- a/src/test/fuzz/locale.cpp +++ b/src/test/fuzz/locale.cpp @@ -51,7 +51,7 @@ FUZZ_TARGET(locale) int64_t parseint64_out_without_locale; const bool parseint64_without_locale = ParseInt64(random_string, &parseint64_out_without_locale); const int64_t random_int64 = fuzzed_data_provider.ConsumeIntegral<int64_t>(); - const std::string tostring_without_locale = ToString(random_int64); + const std::string tostring_without_locale = util::ToString(random_int64); // The variable `random_int32` is no longer used, but the harness still needs to // consume the same data that it did previously to not invalidate existing seeds. const int32_t random_int32 = fuzzed_data_provider.ConsumeIntegral<int32_t>(); @@ -75,7 +75,7 @@ FUZZ_TARGET(locale) if (parseint64_without_locale) { assert(parseint64_out_without_locale == parseint64_out_with_locale); } - const std::string tostring_with_locale = ToString(random_int64); + const std::string tostring_with_locale = util::ToString(random_int64); assert(tostring_without_locale == tostring_with_locale); const std::string strprintf_int_with_locale = strprintf("%d", random_int64); assert(strprintf_int_without_locale == strprintf_int_with_locale); diff --git a/src/test/fuzz/message.cpp b/src/test/fuzz/message.cpp index b5c95441f8..6763206f72 100644 --- a/src/test/fuzz/message.cpp +++ b/src/test/fuzz/message.cpp @@ -3,12 +3,12 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <chainparams.h> +#include <common/signmessage.h> #include <key_io.h> #include <test/fuzz/FuzzedDataProvider.h> #include <test/fuzz/fuzz.h> #include <test/fuzz/util.h> #include <util/chaintype.h> -#include <util/message.h> #include <util/strencodings.h> #include <cassert> @@ -19,7 +19,7 @@ void initialize_message() { - ECC_Start(); + static ECC_Context ecc_context{}; SelectParams(ChainType::REGTEST); } diff --git a/src/test/fuzz/mini_miner.cpp b/src/test/fuzz/mini_miner.cpp index 84f9bb4ad0..3a1663364f 100644 --- a/src/test/fuzz/mini_miner.cpp +++ b/src/test/fuzz/mini_miner.cpp @@ -7,11 +7,13 @@ #include <test/util/txmempool.h> #include <test/util/mining.h> -#include <node/mini_miner.h> #include <node/miner.h> +#include <node/mini_miner.h> #include <primitives/transaction.h> #include <random.h> #include <txmempool.h> +#include <util/check.h> +#include <util/translation.h> #include <deque> #include <vector> @@ -33,7 +35,9 @@ void initialize_miner() FUZZ_TARGET(mini_miner, .init = initialize_miner) { FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; - CTxMemPool pool{CTxMemPool::Options{}}; + bilingual_str error; + CTxMemPool pool{CTxMemPool::Options{}, error}; + Assert(error.empty()); std::vector<COutPoint> outpoints; std::deque<COutPoint> available_coins = g_available_coins; LOCK2(::cs_main, pool.cs); @@ -109,7 +113,9 @@ FUZZ_TARGET(mini_miner, .init = initialize_miner) FUZZ_TARGET(mini_miner_selection, .init = initialize_miner) { FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; - CTxMemPool pool{CTxMemPool::Options{}}; + bilingual_str error; + CTxMemPool pool{CTxMemPool::Options{}, error}; + Assert(error.empty()); // Make a copy to preserve determinism. std::deque<COutPoint> available_coins = g_available_coins; std::vector<CTransactionRef> transactions; diff --git a/src/test/fuzz/miniscript.cpp b/src/test/fuzz/miniscript.cpp index 947424c4ac..7e71af7c44 100644 --- a/src/test/fuzz/miniscript.cpp +++ b/src/test/fuzz/miniscript.cpp @@ -309,9 +309,6 @@ const struct KeyComparator { // A dummy scriptsig to pass to VerifyScript (we always use Segwit v0). const CScript DUMMY_SCRIPTSIG; -//! Public key to be used as internal key for dummy Taproot spends. -const std::vector<unsigned char> NUMS_PK{ParseHex("50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0")}; - //! Construct a miniscript node as a shared_ptr. template<typename... Args> NodeRef MakeNodeRef(Args&&... args) { return miniscript::MakeNodeRef<CPubKey>(miniscript::internal::NoDupCheck{}, std::forward<Args>(args)...); @@ -1018,7 +1015,7 @@ CScript ScriptPubKey(MsCtx ctx, const CScript& script, TaprootBuilder& builder) // For Taproot outputs we always use a tree with a single script and a dummy internal key. builder.Add(0, script, TAPROOT_LEAF_TAPSCRIPT); - builder.Finalize(XOnlyPubKey{NUMS_PK}); + builder.Finalize(XOnlyPubKey::NUMS_H); return GetScriptForDestination(builder.GetOutput()); } @@ -1201,7 +1198,7 @@ void TestNode(const MsCtx script_ctx, const NodeRef& node, FuzzedDataProvider& p void FuzzInit() { - ECC_Start(); + static ECC_Context ecc_context{}; TEST_DATA.Init(); } diff --git a/src/test/fuzz/muhash.cpp b/src/test/fuzz/muhash.cpp index 8304e6fdb8..dd34c465ed 100644 --- a/src/test/fuzz/muhash.cpp +++ b/src/test/fuzz/muhash.cpp @@ -43,7 +43,19 @@ FUZZ_TARGET(muhash) }, [&] { // Test that dividing a MuHash by itself brings it back to it's initial state + + // See note about clang + self-assignment in test/uint256_tests.cpp + #if defined(__clang__) + # pragma clang diagnostic push + # pragma clang diagnostic ignored "-Wself-assign-overloaded" + #endif + muhash /= muhash; + + #if defined(__clang__) + # pragma clang diagnostic pop + #endif + muhash.Finalize(out); out2 = uint256S(initial_state_hash); }, diff --git a/src/test/fuzz/p2p_transport_serialization.cpp b/src/test/fuzz/p2p_transport_serialization.cpp index 1b7a732260..767238d103 100644 --- a/src/test/fuzz/p2p_transport_serialization.cpp +++ b/src/test/fuzz/p2p_transport_serialization.cpp @@ -21,13 +21,12 @@ namespace { -std::vector<std::string> g_all_messages; +auto g_all_messages = ALL_NET_MESSAGE_TYPES; void initialize_p2p_transport_serialization() { - ECC_Start(); + static ECC_Context ecc_context{}; SelectParams(ChainType::REGTEST); - g_all_messages = getAllNetMessageTypes(); std::sort(g_all_messages.begin(), g_all_messages.end()); } diff --git a/src/test/fuzz/package_eval.cpp b/src/test/fuzz/package_eval.cpp index c201118bce..53aedf23ea 100644 --- a/src/test/fuzz/package_eval.cpp +++ b/src/test/fuzz/package_eval.cpp @@ -15,7 +15,9 @@ #include <test/util/script.h> #include <test/util/setup_common.h> #include <test/util/txmempool.h> +#include <util/check.h> #include <util/rbf.h> +#include <util/translation.h> #include <validation.h> #include <validationinterface.h> @@ -107,7 +109,7 @@ void MockTime(FuzzedDataProvider& fuzzed_data_provider, const Chainstate& chains SetMockTime(time); } -CTxMemPool MakeMempool(FuzzedDataProvider& fuzzed_data_provider, const NodeContext& node) +std::unique_ptr<CTxMemPool> MakeMempool(FuzzedDataProvider& fuzzed_data_provider, const NodeContext& node) { // Take the default options for tests... CTxMemPool::Options mempool_opts{MemPoolOptionsForTest(node)}; @@ -126,8 +128,13 @@ CTxMemPool MakeMempool(FuzzedDataProvider& fuzzed_data_provider, const NodeConte mempool_opts.check_ratio = 1; mempool_opts.require_standard = fuzzed_data_provider.ConsumeBool(); + bilingual_str error; // ...and construct a CTxMemPool from it - return CTxMemPool{mempool_opts}; + auto mempool{std::make_unique<CTxMemPool>(std::move(mempool_opts), error)}; + // ... ignore the error since it might be beneficial to fuzz even when the + // mempool size is unreasonably small + Assert(error.empty() || error.original.starts_with("-maxmempool must be at least ")); + return mempool; } FUZZ_TARGET(tx_package_eval, .init = initialize_tx_pool) @@ -149,8 +156,8 @@ FUZZ_TARGET(tx_package_eval, .init = initialize_tx_pool) auto outpoints_updater = std::make_shared<OutpointsUpdater>(mempool_outpoints); node.validation_signals->RegisterSharedValidationInterface(outpoints_updater); - CTxMemPool tx_pool_{MakeMempool(fuzzed_data_provider, node)}; - MockedTxPool& tx_pool = *static_cast<MockedTxPool*>(&tx_pool_); + auto tx_pool_{MakeMempool(fuzzed_data_provider, node)}; + MockedTxPool& tx_pool = *static_cast<MockedTxPool*>(tx_pool_.get()); chainstate.SetMempool(&tx_pool); @@ -173,7 +180,7 @@ FUZZ_TARGET(tx_package_eval, .init = initialize_tx_pool) // Create transaction to add to the mempool const CTransactionRef tx = [&] { CMutableTransaction tx_mut; - tx_mut.nVersion = fuzzed_data_provider.ConsumeBool() ? 3 : CTransaction::CURRENT_VERSION; + tx_mut.version = fuzzed_data_provider.ConsumeBool() ? TRUC_VERSION : CTransaction::CURRENT_VERSION; tx_mut.nLockTime = fuzzed_data_provider.ConsumeBool() ? 0 : fuzzed_data_provider.ConsumeIntegral<uint32_t>(); // Last tx will sweep all outpoints in package const auto num_in = last_tx ? package_outpoints.size() : fuzzed_data_provider.ConsumeIntegralInRange<int>(1, mempool_outpoints.size()); @@ -307,7 +314,7 @@ FUZZ_TARGET(tx_package_eval, .init = initialize_tx_pool) // just use result_package.m_state here. This makes the expect_valid check meaningless, but // we can still verify that the contents of m_tx_results are consistent with m_state. const bool expect_valid{result_package.m_state.IsValid()}; - Assert(!CheckPackageMempoolAcceptResult(txs, result_package, expect_valid, nullptr)); + Assert(!CheckPackageMempoolAcceptResult(txs, result_package, expect_valid, &tx_pool)); } else { // This is empty if it fails early checks, or "full" if transactions are looked at deeper Assert(result_package.m_tx_results.size() == txs.size() || result_package.m_tx_results.empty()); diff --git a/src/test/fuzz/partially_downloaded_block.cpp b/src/test/fuzz/partially_downloaded_block.cpp index 2bf47930f4..791d457710 100644 --- a/src/test/fuzz/partially_downloaded_block.cpp +++ b/src/test/fuzz/partially_downloaded_block.cpp @@ -10,6 +10,8 @@ #include <test/util/setup_common.h> #include <test/util/txmempool.h> #include <txmempool.h> +#include <util/check.h> +#include <util/translation.h> #include <cstddef> #include <cstdint> @@ -52,7 +54,9 @@ FUZZ_TARGET(partially_downloaded_block, .init = initialize_pdb) CBlockHeaderAndShortTxIDs cmpctblock{*block}; - CTxMemPool pool{MemPoolOptionsForTest(g_setup->m_node)}; + bilingual_str error; + CTxMemPool pool{MemPoolOptionsForTest(g_setup->m_node), error}; + Assert(error.empty()); PartiallyDownloadedBlock pdb{&pool}; // Set of available transactions (mempool or extra_txn) diff --git a/src/test/fuzz/process_message.cpp b/src/test/fuzz/process_message.cpp index a467fd5382..d10d9dafe8 100644 --- a/src/test/fuzz/process_message.cpp +++ b/src/test/fuzz/process_message.cpp @@ -37,7 +37,7 @@ void initialize_process_message() { if (const auto val{std::getenv("LIMIT_TO_MESSAGE_TYPE")}) { LIMIT_TO_MESSAGE_TYPE = val; - Assert(std::count(getAllNetMessageTypes().begin(), getAllNetMessageTypes().end(), LIMIT_TO_MESSAGE_TYPE)); // Unknown message type passed + Assert(std::count(ALL_NET_MESSAGE_TYPES.begin(), ALL_NET_MESSAGE_TYPES.end(), LIMIT_TO_MESSAGE_TYPE)); // Unknown message type passed } static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>( diff --git a/src/test/fuzz/rbf.cpp b/src/test/fuzz/rbf.cpp index 64785948f6..eb981352ec 100644 --- a/src/test/fuzz/rbf.cpp +++ b/src/test/fuzz/rbf.cpp @@ -13,6 +13,8 @@ #include <test/util/setup_common.h> #include <test/util/txmempool.h> #include <txmempool.h> +#include <util/check.h> +#include <util/translation.h> #include <cstdint> #include <optional> @@ -56,7 +58,9 @@ FUZZ_TARGET(rbf, .init = initialize_rbf) return; } - CTxMemPool pool{MemPoolOptionsForTest(g_setup->m_node)}; + bilingual_str error; + CTxMemPool pool{MemPoolOptionsForTest(g_setup->m_node), error}; + Assert(error.empty()); LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), NUM_ITERS) { @@ -87,10 +91,14 @@ FUZZ_TARGET(package_rbf, .init = initialize_package_rbf) FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); SetMockTime(ConsumeTime(fuzzed_data_provider)); - std::optional<CMutableTransaction> child = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider, TX_WITH_WITNESS); - if (!child) return; + // "Real" virtual size is not important for this test since ConsumeTxMemPoolEntry generates its own virtual size values + // so we construct small transactions for performance reasons. Child simply needs an input for later to perhaps connect to parent. + CMutableTransaction child; + child.vin.resize(1); - CTxMemPool pool{MemPoolOptionsForTest(g_setup->m_node)}; + bilingual_str error; + CTxMemPool pool{MemPoolOptionsForTest(g_setup->m_node), error}; + Assert(error.empty()); // Add a bunch of parent-child pairs to the mempool, and remember them. std::vector<CTransaction> mempool_txs; @@ -107,15 +115,13 @@ FUZZ_TARGET(package_rbf, .init = initialize_package_rbf) LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), NUM_ITERS) { // Make sure txns only have one input, and that a unique input is given to avoid circular references - std::optional<CMutableTransaction> parent = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider, TX_WITH_WITNESS); - if (!parent) { - return; - } + CMutableTransaction parent; assert(iter <= g_outpoints.size()); - parent->vin.resize(1); - parent->vin[0].prevout = g_outpoints[iter++]; + parent.vin.resize(1); + parent.vin[0].prevout = g_outpoints[iter++]; + parent.vout.emplace_back(0, CScript()); - mempool_txs.emplace_back(*parent); + mempool_txs.emplace_back(parent); const auto parent_entry = ConsumeTxMemPoolEntry(fuzzed_data_provider, mempool_txs.back()); running_vsize_total += parent_entry.GetTxSize(); if (running_vsize_total > std::numeric_limits<int32_t>::max()) { @@ -124,10 +130,10 @@ FUZZ_TARGET(package_rbf, .init = initialize_package_rbf) break; } pool.addUnchecked(parent_entry); - if (fuzzed_data_provider.ConsumeBool() && !child->vin.empty()) { - child->vin[0].prevout = COutPoint{mempool_txs.back().GetHash(), 0}; + if (fuzzed_data_provider.ConsumeBool()) { + child.vin[0].prevout = COutPoint{mempool_txs.back().GetHash(), 0}; } - mempool_txs.emplace_back(*child); + mempool_txs.emplace_back(child); const auto child_entry = ConsumeTxMemPoolEntry(fuzzed_data_provider, mempool_txs.back()); running_vsize_total += child_entry.GetTxSize(); if (running_vsize_total > std::numeric_limits<int32_t>::max()) { diff --git a/src/test/fuzz/rpc.cpp b/src/test/fuzz/rpc.cpp index 2325bf0941..4e52c1c091 100644 --- a/src/test/fuzz/rpc.cpp +++ b/src/test/fuzz/rpc.cpp @@ -36,6 +36,9 @@ #include <vector> enum class ChainType; +using util::Join; +using util::ToString; + namespace { struct RPCFuzzTestingSetup : public TestingSetup { RPCFuzzTestingSetup(const ChainType chain_type, const std::vector<const char*>& extra_args) : TestingSetup{chain_type, extra_args} diff --git a/src/test/fuzz/script_assets_test_minimizer.cpp b/src/test/fuzz/script_assets_test_minimizer.cpp index 511b581f60..5a8b599df6 100644 --- a/src/test/fuzz/script_assets_test_minimizer.cpp +++ b/src/test/fuzz/script_assets_test_minimizer.cpp @@ -17,6 +17,8 @@ #include <string> #include <vector> +using util::SplitString; + // This fuzz "test" can be used to minimize test cases for script_assets_test in // src/test/script_tests.cpp. While it written as a fuzz test, and can be used as such, // fuzzing the inputs is unlikely to construct useful test cases. diff --git a/src/test/fuzz/spanparsing.cpp b/src/test/fuzz/script_parsing.cpp index b8996632bc..d29a6ea90c 100644 --- a/src/test/fuzz/spanparsing.cpp +++ b/src/test/fuzz/script_parsing.cpp @@ -2,11 +2,14 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <script/parsing.h> #include <test/fuzz/FuzzedDataProvider.h> #include <test/fuzz/fuzz.h> -#include <util/spanparsing.h> +#include <util/string.h> -FUZZ_TARGET(spanparsing) +using util::Split; + +FUZZ_TARGET(script_parsing) { FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); const size_t query_size = fuzzed_data_provider.ConsumeIntegral<size_t>(); @@ -15,16 +18,16 @@ FUZZ_TARGET(spanparsing) const Span<const char> const_span{span_str}; Span<const char> mut_span = const_span; - (void)spanparsing::Const(query, mut_span); + (void)script::Const(query, mut_span); mut_span = const_span; - (void)spanparsing::Func(query, mut_span); + (void)script::Func(query, mut_span); mut_span = const_span; - (void)spanparsing::Expr(mut_span); + (void)script::Expr(mut_span); if (!query.empty()) { mut_span = const_span; - (void)spanparsing::Split(mut_span, query.front()); + (void)Split(mut_span, query.front()); } } diff --git a/src/test/fuzz/script_sign.cpp b/src/test/fuzz/script_sign.cpp index 9ae150e553..4695bc611b 100644 --- a/src/test/fuzz/script_sign.cpp +++ b/src/test/fuzz/script_sign.cpp @@ -26,7 +26,7 @@ void initialize_script_sign() { - ECC_Start(); + static ECC_Context ecc_context{}; SelectParams(ChainType::REGTEST); } diff --git a/src/test/fuzz/secp256k1_ecdsa_signature_parse_der_lax.cpp b/src/test/fuzz/secp256k1_ecdsa_signature_parse_der_lax.cpp index 74ef6bfd4e..ae0c8479cb 100644 --- a/src/test/fuzz/secp256k1_ecdsa_signature_parse_der_lax.cpp +++ b/src/test/fuzz/secp256k1_ecdsa_signature_parse_der_lax.cpp @@ -24,8 +24,7 @@ FUZZ_TARGET(secp256k1_ecdsa_signature_parse_der_lax) secp256k1_ecdsa_signature sig_der_lax; const bool parsed_der_lax = ecdsa_signature_parse_der_lax(&sig_der_lax, signature_bytes.data(), signature_bytes.size()) == 1; if (parsed_der_lax) { - ECC_Start(); + ECC_Context ecc_context{}; (void)SigHasLowR(&sig_der_lax); - ECC_Stop(); } } diff --git a/src/test/fuzz/string.cpp b/src/test/fuzz/string.cpp index 631da13803..5b822b03f6 100644 --- a/src/test/fuzz/string.cpp +++ b/src/test/fuzz/string.cpp @@ -5,6 +5,7 @@ #include <blockfilter.h> #include <clientversion.h> #include <common/args.h> +#include <common/messages.h> #include <common/settings.h> #include <common/system.h> #include <common/url.h> @@ -21,8 +22,6 @@ #include <test/fuzz/FuzzedDataProvider.h> #include <test/fuzz/fuzz.h> #include <test/fuzz/util.h> -#include <util/error.h> -#include <util/fees.h> #include <util/strencodings.h> #include <util/string.h> #include <util/translation.h> @@ -37,6 +36,16 @@ enum class FeeEstimateMode; +using common::AmountErrMsg; +using common::AmountHighWarn; +using common::FeeModeFromString; +using common::ResolveErrMsg; +using util::ContainsNoNUL; +using util::Join; +using util::RemovePrefix; +using util::SplitString; +using util::TrimString; + FUZZ_TARGET(string) { FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); diff --git a/src/test/fuzz/timeoffsets.cpp b/src/test/fuzz/timeoffsets.cpp index 019337a94a..dfa4dd705d 100644 --- a/src/test/fuzz/timeoffsets.cpp +++ b/src/test/fuzz/timeoffsets.cpp @@ -3,6 +3,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <node/timeoffsets.h> +#include <node/warnings.h> #include <test/fuzz/FuzzedDataProvider.h> #include <test/fuzz/fuzz.h> #include <test/util/setup_common.h> @@ -19,7 +20,8 @@ void initialize_timeoffsets() FUZZ_TARGET(timeoffsets, .init = initialize_timeoffsets) { FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); - TimeOffsets offsets{}; + node::Warnings warnings{}; + TimeOffsets offsets{warnings}; LIMITED_WHILE(fuzzed_data_provider.remaining_bytes() > 0, 4'000) { (void)offsets.Median(); offsets.Add(std::chrono::seconds{fuzzed_data_provider.ConsumeIntegral<std::chrono::seconds::rep>()}); diff --git a/src/test/fuzz/tx_pool.cpp b/src/test/fuzz/tx_pool.cpp index 9f0aedf29b..b6b91445f9 100644 --- a/src/test/fuzz/tx_pool.cpp +++ b/src/test/fuzz/tx_pool.cpp @@ -15,12 +15,15 @@ #include <test/util/script.h> #include <test/util/setup_common.h> #include <test/util/txmempool.h> +#include <util/check.h> #include <util/rbf.h> +#include <util/translation.h> #include <validation.h> #include <validationinterface.h> using node::BlockAssembler; using node::NodeContext; +using util::ToString; namespace { @@ -116,7 +119,7 @@ void MockTime(FuzzedDataProvider& fuzzed_data_provider, const Chainstate& chains SetMockTime(time); } -CTxMemPool MakeMempool(FuzzedDataProvider& fuzzed_data_provider, const NodeContext& node) +std::unique_ptr<CTxMemPool> MakeMempool(FuzzedDataProvider& fuzzed_data_provider, const NodeContext& node) { // Take the default options for tests... CTxMemPool::Options mempool_opts{MemPoolOptionsForTest(node)}; @@ -126,7 +129,12 @@ CTxMemPool MakeMempool(FuzzedDataProvider& fuzzed_data_provider, const NodeConte mempool_opts.require_standard = fuzzed_data_provider.ConsumeBool(); // ...and construct a CTxMemPool from it - return CTxMemPool{mempool_opts}; + bilingual_str error; + auto mempool{std::make_unique<CTxMemPool>(std::move(mempool_opts), error)}; + // ... ignore the error since it might be beneficial to fuzz even when the + // mempool size is unreasonably small + Assert(error.empty() || error.original.starts_with("-maxmempool must be at least ")); + return mempool; } void CheckATMPInvariants(const MempoolAcceptResult& res, bool txid_in_mempool, bool wtxid_in_mempool) @@ -198,8 +206,8 @@ FUZZ_TARGET(tx_pool_standard, .init = initialize_tx_pool) constexpr CAmount SUPPLY_TOTAL{COINBASE_MATURITY * 50 * COIN}; SetMempoolConstraints(*node.args, fuzzed_data_provider); - CTxMemPool tx_pool_{MakeMempool(fuzzed_data_provider, node)}; - MockedTxPool& tx_pool = *static_cast<MockedTxPool*>(&tx_pool_); + auto tx_pool_{MakeMempool(fuzzed_data_provider, node)}; + MockedTxPool& tx_pool = *static_cast<MockedTxPool*>(tx_pool_.get()); chainstate.SetMempool(&tx_pool); @@ -226,7 +234,7 @@ FUZZ_TARGET(tx_pool_standard, .init = initialize_tx_pool) // Create transaction to add to the mempool const CTransactionRef tx = [&] { CMutableTransaction tx_mut; - tx_mut.nVersion = fuzzed_data_provider.ConsumeBool() ? 3 : CTransaction::CURRENT_VERSION; + tx_mut.version = fuzzed_data_provider.ConsumeBool() ? TRUC_VERSION : CTransaction::CURRENT_VERSION; tx_mut.nLockTime = fuzzed_data_provider.ConsumeBool() ? 0 : fuzzed_data_provider.ConsumeIntegral<uint32_t>(); const auto num_in = fuzzed_data_provider.ConsumeIntegralInRange<int>(1, outpoints_rbf.size()); const auto num_out = fuzzed_data_provider.ConsumeIntegralInRange<int>(1, outpoints_rbf.size() * 2); @@ -376,8 +384,8 @@ FUZZ_TARGET(tx_pool, .init = initialize_tx_pool) } SetMempoolConstraints(*node.args, fuzzed_data_provider); - CTxMemPool tx_pool_{MakeMempool(fuzzed_data_provider, node)}; - MockedTxPool& tx_pool = *static_cast<MockedTxPool*>(&tx_pool_); + auto tx_pool_{MakeMempool(fuzzed_data_provider, node)}; + MockedTxPool& tx_pool = *static_cast<MockedTxPool*>(tx_pool_.get()); chainstate.SetMempool(&tx_pool); diff --git a/src/test/fuzz/txorphan.cpp b/src/test/fuzz/txorphan.cpp index a44f47b00d..7bebb987b1 100644 --- a/src/test/fuzz/txorphan.cpp +++ b/src/test/fuzz/txorphan.cpp @@ -37,13 +37,12 @@ FUZZ_TARGET(txorphan, .init = initialize_orphanage) SetMockTime(ConsumeTime(fuzzed_data_provider)); TxOrphanage orphanage; - std::vector<COutPoint> outpoints; + std::set<COutPoint> outpoints; + // initial outpoints used to construct transactions later for (uint8_t i = 0; i < 4; i++) { - outpoints.emplace_back(Txid::FromUint256(uint256{i}), 0); + outpoints.emplace(Txid::FromUint256(uint256{i}), 0); } - // if true, allow duplicate input when constructing tx - const bool duplicate_input = fuzzed_data_provider.ConsumeBool(); CTransactionRef ptx_potential_parent = nullptr; @@ -53,29 +52,22 @@ FUZZ_TARGET(txorphan, .init = initialize_orphanage) const CTransactionRef tx = [&] { CMutableTransaction tx_mut; const auto num_in = fuzzed_data_provider.ConsumeIntegralInRange<uint32_t>(1, outpoints.size()); - const auto num_out = fuzzed_data_provider.ConsumeIntegralInRange<uint32_t>(1, outpoints.size()); - // pick unique outpoints from outpoints as input + const auto num_out = fuzzed_data_provider.ConsumeIntegralInRange<uint32_t>(1, 256); + // pick outpoints from outpoints as input. We allow input duplicates on purpose, given we are not + // running any transaction validation logic before adding transactions to the orphanage for (uint32_t i = 0; i < num_in; i++) { auto& prevout = PickValue(fuzzed_data_provider, outpoints); - tx_mut.vin.emplace_back(prevout); - // pop the picked outpoint if duplicate input is not allowed - if (!duplicate_input) { - std::swap(prevout, outpoints.back()); - outpoints.pop_back(); - } + // try making transactions unique by setting a random nSequence, but allow duplicate transactions if they happen + tx_mut.vin.emplace_back(prevout, CScript{}, fuzzed_data_provider.ConsumeIntegralInRange<uint32_t>(0, CTxIn::SEQUENCE_FINAL)); } // output amount will not affect txorphanage for (uint32_t i = 0; i < num_out; i++) { tx_mut.vout.emplace_back(CAmount{0}, CScript{}); } - // restore previously popped outpoints - for (auto& in : tx_mut.vin) { - outpoints.push_back(in.prevout); - } auto new_tx = MakeTransactionRef(tx_mut); - // add newly constructed transaction to outpoints + // add newly constructed outpoints to the coin pool for (uint32_t i = 0; i < num_out; i++) { - outpoints.emplace_back(new_tx->GetHash(), i); + outpoints.emplace(new_tx->GetHash(), i); } return new_tx; }(); @@ -112,13 +104,12 @@ FUZZ_TARGET(txorphan, .init = initialize_orphanage) { CTransactionRef ref = orphanage.GetTxToReconsider(peer_id); if (ref) { - bool have_tx = orphanage.HaveTx(GenTxid::Txid(ref->GetHash())) || orphanage.HaveTx(GenTxid::Wtxid(ref->GetWitnessHash())); - Assert(have_tx); + Assert(orphanage.HaveTx(ref->GetWitnessHash())); } } }, [&] { - bool have_tx = orphanage.HaveTx(GenTxid::Txid(tx->GetHash())) || orphanage.HaveTx(GenTxid::Wtxid(tx->GetWitnessHash())); + bool have_tx = orphanage.HaveTx(tx->GetWitnessHash()); // AddTx should return false if tx is too big or already have it // tx weight is unknown, we only check when tx is already in orphanage { @@ -126,7 +117,7 @@ FUZZ_TARGET(txorphan, .init = initialize_orphanage) // have_tx == true -> add_tx == false Assert(!have_tx || !add_tx); } - have_tx = orphanage.HaveTx(GenTxid::Txid(tx->GetHash())) || orphanage.HaveTx(GenTxid::Wtxid(tx->GetWitnessHash())); + have_tx = orphanage.HaveTx(tx->GetWitnessHash()); { bool add_tx = orphanage.AddTx(tx, peer_id); // if have_tx is still false, it must be too big @@ -135,15 +126,15 @@ FUZZ_TARGET(txorphan, .init = initialize_orphanage) } }, [&] { - bool have_tx = orphanage.HaveTx(GenTxid::Txid(tx->GetHash())) || orphanage.HaveTx(GenTxid::Wtxid(tx->GetWitnessHash())); + bool have_tx = orphanage.HaveTx(tx->GetWitnessHash()); // EraseTx should return 0 if m_orphans doesn't have the tx { - Assert(have_tx == orphanage.EraseTx(tx->GetHash())); + Assert(have_tx == orphanage.EraseTx(tx->GetWitnessHash())); } - have_tx = orphanage.HaveTx(GenTxid::Txid(tx->GetHash())) || orphanage.HaveTx(GenTxid::Wtxid(tx->GetWitnessHash())); + have_tx = orphanage.HaveTx(tx->GetWitnessHash()); // have_tx should be false and EraseTx should fail { - Assert(!have_tx && !orphanage.EraseTx(tx->GetHash())); + Assert(!have_tx && !orphanage.EraseTx(tx->GetWitnessHash())); } }, [&] { diff --git a/src/test/fuzz/util.cpp b/src/test/fuzz/util.cpp index 259b00fcae..92ded99917 100644 --- a/src/test/fuzz/util.cpp +++ b/src/test/fuzz/util.cpp @@ -43,9 +43,9 @@ CMutableTransaction ConsumeTransaction(FuzzedDataProvider& fuzzed_data_provider, { CMutableTransaction tx_mut; const auto p2wsh_op_true = fuzzed_data_provider.ConsumeBool(); - tx_mut.nVersion = fuzzed_data_provider.ConsumeBool() ? + tx_mut.version = fuzzed_data_provider.ConsumeBool() ? CTransaction::CURRENT_VERSION : - fuzzed_data_provider.ConsumeIntegral<int32_t>(); + fuzzed_data_provider.ConsumeIntegral<uint32_t>(); tx_mut.nLockTime = fuzzed_data_provider.ConsumeIntegral<uint32_t>(); const auto num_in = fuzzed_data_provider.ConsumeIntegralInRange<int>(0, max_num_in); const auto num_out = fuzzed_data_provider.ConsumeIntegralInRange<int>(0, max_num_out); diff --git a/src/test/fuzz/util/net.cpp b/src/test/fuzz/util/net.cpp index 99151bb84d..5e7aae670e 100644 --- a/src/test/fuzz/util/net.cpp +++ b/src/test/fuzz/util/net.cpp @@ -193,21 +193,20 @@ ssize_t FuzzedSock::Recv(void* buf, size_t len, int flags) const bool pad_to_len_bytes{m_fuzzed_data_provider.ConsumeBool()}; if (m_peek_data.has_value()) { // `MSG_PEEK` was used in the preceding `Recv()` call, return `m_peek_data`. - random_bytes.assign({m_peek_data.value()}); + random_bytes = m_peek_data.value(); if ((flags & MSG_PEEK) == 0) { m_peek_data.reset(); } pad_to_len_bytes = false; } else if ((flags & MSG_PEEK) != 0) { // New call with `MSG_PEEK`. - random_bytes = m_fuzzed_data_provider.ConsumeBytes<uint8_t>(1); + random_bytes = ConsumeRandomLengthByteVector(m_fuzzed_data_provider, len); if (!random_bytes.empty()) { - m_peek_data = random_bytes[0]; + m_peek_data = random_bytes; pad_to_len_bytes = false; } } else { - random_bytes = m_fuzzed_data_provider.ConsumeBytes<uint8_t>( - m_fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, len)); + random_bytes = ConsumeRandomLengthByteVector(m_fuzzed_data_provider, len); } if (random_bytes.empty()) { const ssize_t r = m_fuzzed_data_provider.ConsumeBool() ? 0 : -1; @@ -216,7 +215,11 @@ ssize_t FuzzedSock::Recv(void* buf, size_t len, int flags) const } return r; } - std::memcpy(buf, random_bytes.data(), random_bytes.size()); + // `random_bytes` might exceed the size of `buf` if e.g. Recv is called with + // len=N and MSG_PEEK first and afterwards called with len=M (M < N) and + // without MSG_PEEK. + size_t recv_len{std::min(random_bytes.size(), len)}; + std::memcpy(buf, random_bytes.data(), recv_len); if (pad_to_len_bytes) { if (len > random_bytes.size()) { std::memset((char*)buf + random_bytes.size(), 0, len - random_bytes.size()); @@ -226,7 +229,7 @@ ssize_t FuzzedSock::Recv(void* buf, size_t len, int flags) const if (m_fuzzed_data_provider.ConsumeBool() && std::getenv("FUZZED_SOCKET_FAKE_LATENCY") != nullptr) { std::this_thread::sleep_for(std::chrono::milliseconds{2}); } - return random_bytes.size(); + return recv_len; } int FuzzedSock::Connect(const sockaddr*, socklen_t) const @@ -380,7 +383,10 @@ bool FuzzedSock::Wait(std::chrono::milliseconds timeout, Event requested, Event* return false; } if (occurred != nullptr) { - *occurred = m_fuzzed_data_provider.ConsumeBool() ? requested : 0; + // We simulate the requested event as occured when ConsumeBool() + // returns false. This avoids simulating endless waiting if the + // FuzzedDataProvider runs out of data. + *occurred = m_fuzzed_data_provider.ConsumeBool() ? 0 : requested; } return true; } @@ -389,7 +395,10 @@ bool FuzzedSock::WaitMany(std::chrono::milliseconds timeout, EventsPerSock& even { for (auto& [sock, events] : events_per_sock) { (void)sock; - events.occurred = m_fuzzed_data_provider.ConsumeBool() ? events.requested : 0; + // We simulate the requested event as occured when ConsumeBool() + // returns false. This avoids simulating endless waiting if the + // FuzzedDataProvider runs out of data. + events.occurred = m_fuzzed_data_provider.ConsumeBool() ? 0 : events.requested; } return true; } diff --git a/src/test/fuzz/util/net.h b/src/test/fuzz/util/net.h index a6c9e23f2e..ed02680676 100644 --- a/src/test/fuzz/util/net.h +++ b/src/test/fuzz/util/net.h @@ -43,7 +43,7 @@ class FuzzedSock : public Sock * If `MSG_PEEK` is used, then our `Recv()` returns some random data as usual, but on the next * `Recv()` call we must return the same data, thus we remember it here. */ - mutable std::optional<uint8_t> m_peek_data; + mutable std::optional<std::vector<uint8_t>> m_peek_data; /** * Whether to pretend that the socket is select(2)-able. This is randomly set in the diff --git a/src/test/fuzz/utxo_snapshot.cpp b/src/test/fuzz/utxo_snapshot.cpp index dce728d96b..8c9c67a91c 100644 --- a/src/test/fuzz/utxo_snapshot.cpp +++ b/src/test/fuzz/utxo_snapshot.cpp @@ -47,7 +47,8 @@ FUZZ_TARGET(utxo_snapshot, .init = initialize_chain) const auto ActivateFuzzedSnapshot{[&] { AutoFile infile{fsbridge::fopen(snapshot_path, "rb")}; - SnapshotMetadata metadata; + auto msg_start = Params().MessageStart(); + SnapshotMetadata metadata{msg_start}; try { infile >> metadata; } catch (const std::ios_base::failure&) { diff --git a/src/test/fuzz/validation_load_mempool.cpp b/src/test/fuzz/validation_load_mempool.cpp index 00678742c9..51140ae039 100644 --- a/src/test/fuzz/validation_load_mempool.cpp +++ b/src/test/fuzz/validation_load_mempool.cpp @@ -13,7 +13,9 @@ #include <test/util/setup_common.h> #include <test/util/txmempool.h> #include <txmempool.h> +#include <util/check.h> #include <util/time.h> +#include <util/translation.h> #include <validation.h> #include <cstdint> @@ -40,7 +42,9 @@ FUZZ_TARGET(validation_load_mempool, .init = initialize_validation_load_mempool) SetMockTime(ConsumeTime(fuzzed_data_provider)); FuzzedFileProvider fuzzed_file_provider{fuzzed_data_provider}; - CTxMemPool pool{MemPoolOptionsForTest(g_setup->m_node)}; + bilingual_str error; + CTxMemPool pool{MemPoolOptionsForTest(g_setup->m_node), error}; + Assert(error.empty()); auto& chainstate{static_cast<DummyChainState&>(g_setup->m_node.chainman->ActiveChainstate())}; chainstate.SetMempool(&pool); diff --git a/src/test/fuzz/vecdeque.cpp b/src/test/fuzz/vecdeque.cpp new file mode 100644 index 0000000000..1d9a98931f --- /dev/null +++ b/src/test/fuzz/vecdeque.cpp @@ -0,0 +1,491 @@ +// Copyright (c) The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <span.h> +#include <test/fuzz/util.h> +#include <test/util/xoroshiro128plusplus.h> +#include <util/vecdeque.h> + +#include <deque> +#include <stdint.h> + +namespace { + +/** The maximum number of simultaneous buffers kept by the test. */ +static constexpr size_t MAX_BUFFERS{3}; +/** How many elements are kept in a buffer at most. */ +static constexpr size_t MAX_BUFFER_SIZE{48}; +/** How many operations are performed at most on the buffers in one test. */ +static constexpr size_t MAX_OPERATIONS{1024}; + +/** Perform a simulation fuzz test on VecDeque type T. + * + * T must be constructible from a uint64_t seed, comparable to other T, copyable, and movable. + */ +template<typename T, bool CheckNoneLeft> +void TestType(Span<const uint8_t> buffer, uint64_t rng_tweak) +{ + FuzzedDataProvider provider(buffer.data(), buffer.size()); + // Local RNG, only used for the seeds to initialize T objects with. + XoRoShiRo128PlusPlus rng(provider.ConsumeIntegral<uint64_t>() ^ rng_tweak); + + // Real circular buffers. + std::vector<VecDeque<T>> real; + real.reserve(MAX_BUFFERS); + // Simulated circular buffers. + std::vector<std::deque<T>> sim; + sim.reserve(MAX_BUFFERS); + // Temporary object of type T. + std::optional<T> tmp; + + // Compare a real and a simulated buffer. + auto compare_fn = [](const VecDeque<T>& r, const std::deque<T>& s) { + assert(r.size() == s.size()); + assert(r.empty() == s.empty()); + assert(r.capacity() >= r.size()); + if (s.size() == 0) return; + assert(r.front() == s.front()); + assert(r.back() == s.back()); + for (size_t i = 0; i < s.size(); ++i) { + assert(r[i] == s[i]); + } + }; + + LIMITED_WHILE(provider.remaining_bytes(), MAX_OPERATIONS) { + int command = provider.ConsumeIntegral<uint8_t>() % 64; + unsigned idx = real.empty() ? 0 : provider.ConsumeIntegralInRange<unsigned>(0, real.size() - 1); + const size_t num_buffers = sim.size(); + // Pick one operation based on value of command. Not all operations are always applicable. + // Loop through the applicable ones until command reaches 0 (which avoids the need to + // compute the number of applicable commands ahead of time). + const bool non_empty{num_buffers != 0}; + const bool non_full{num_buffers < MAX_BUFFERS}; + const bool partially_full{non_empty && non_full}; + const bool multiple_exist{num_buffers > 1}; + const bool existing_buffer_non_full{non_empty && sim[idx].size() < MAX_BUFFER_SIZE}; + const bool existing_buffer_non_empty{non_empty && !sim[idx].empty()}; + assert(non_full || non_empty); + while (true) { + if (non_full && command-- == 0) { + /* Default construct. */ + real.emplace_back(); + sim.emplace_back(); + break; + } + if (non_empty && command-- == 0) { + /* resize() */ + compare_fn(real[idx], sim[idx]); + size_t new_size = provider.ConsumeIntegralInRange<size_t>(0, MAX_BUFFER_SIZE); + real[idx].resize(new_size); + sim[idx].resize(new_size); + assert(real[idx].size() == new_size); + break; + } + if (non_empty && command-- == 0) { + /* clear() */ + compare_fn(real[idx], sim[idx]); + real[idx].clear(); + sim[idx].clear(); + assert(real[idx].empty()); + break; + } + if (non_empty && command-- == 0) { + /* Copy construct default. */ + compare_fn(real[idx], sim[idx]); + real[idx] = VecDeque<T>(); + sim[idx].clear(); + assert(real[idx].size() == 0); + break; + } + if (non_empty && command-- == 0) { + /* Destruct. */ + compare_fn(real.back(), sim.back()); + real.pop_back(); + sim.pop_back(); + break; + } + if (partially_full && command-- == 0) { + /* Copy construct. */ + real.emplace_back(real[idx]); + sim.emplace_back(sim[idx]); + break; + } + if (partially_full && command-- == 0) { + /* Move construct. */ + VecDeque<T> copy(real[idx]); + real.emplace_back(std::move(copy)); + sim.emplace_back(sim[idx]); + break; + } + if (multiple_exist && command-- == 0) { + /* swap() */ + swap(real[idx], real[(idx + 1) % num_buffers]); + swap(sim[idx], sim[(idx + 1) % num_buffers]); + break; + } + if (multiple_exist && command-- == 0) { + /* Copy assign. */ + compare_fn(real[idx], sim[idx]); + real[idx] = real[(idx + 1) % num_buffers]; + sim[idx] = sim[(idx + 1) % num_buffers]; + break; + } + if (multiple_exist && command-- == 0) { + /* Move assign. */ + VecDeque<T> copy(real[(idx + 1) % num_buffers]); + compare_fn(real[idx], sim[idx]); + real[idx] = std::move(copy); + sim[idx] = sim[(idx + 1) % num_buffers]; + break; + } + if (non_empty && command-- == 0) { + /* Self swap() */ + swap(real[idx], real[idx]); + break; + } + if (non_empty && command-- == 0) { + /* Self-copy assign. */ + real[idx] = real[idx]; + break; + } + if (non_empty && command-- == 0) { + /* Self-move assign. */ + // Do not use std::move(real[idx]) here: -Wself-move correctly warns about that. + real[idx] = static_cast<VecDeque<T>&&>(real[idx]); + break; + } + if (non_empty && command-- == 0) { + /* reserve() */ + size_t res_size = provider.ConsumeIntegralInRange<size_t>(0, MAX_BUFFER_SIZE); + size_t old_cap = real[idx].capacity(); + size_t old_size = real[idx].size(); + real[idx].reserve(res_size); + assert(real[idx].size() == old_size); + assert(real[idx].capacity() == std::max(old_cap, res_size)); + break; + } + if (non_empty && command-- == 0) { + /* shrink_to_fit() */ + size_t old_size = real[idx].size(); + real[idx].shrink_to_fit(); + assert(real[idx].size() == old_size); + assert(real[idx].capacity() == old_size); + break; + } + if (existing_buffer_non_full && command-- == 0) { + /* push_back() (copying) */ + tmp = T(rng()); + size_t old_size = real[idx].size(); + size_t old_cap = real[idx].capacity(); + real[idx].push_back(*tmp); + sim[idx].push_back(*tmp); + assert(real[idx].size() == old_size + 1); + if (old_cap > old_size) { + assert(real[idx].capacity() == old_cap); + } else { + assert(real[idx].capacity() > old_cap); + assert(real[idx].capacity() <= 2 * (old_cap + 1)); + } + break; + } + if (existing_buffer_non_full && command-- == 0) { + /* push_back() (moving) */ + tmp = T(rng()); + size_t old_size = real[idx].size(); + size_t old_cap = real[idx].capacity(); + sim[idx].push_back(*tmp); + real[idx].push_back(std::move(*tmp)); + assert(real[idx].size() == old_size + 1); + if (old_cap > old_size) { + assert(real[idx].capacity() == old_cap); + } else { + assert(real[idx].capacity() > old_cap); + assert(real[idx].capacity() <= 2 * (old_cap + 1)); + } + break; + } + if (existing_buffer_non_full && command-- == 0) { + /* emplace_back() */ + uint64_t seed{rng()}; + size_t old_size = real[idx].size(); + size_t old_cap = real[idx].capacity(); + sim[idx].emplace_back(seed); + real[idx].emplace_back(seed); + assert(real[idx].size() == old_size + 1); + if (old_cap > old_size) { + assert(real[idx].capacity() == old_cap); + } else { + assert(real[idx].capacity() > old_cap); + assert(real[idx].capacity() <= 2 * (old_cap + 1)); + } + break; + } + if (existing_buffer_non_full && command-- == 0) { + /* push_front() (copying) */ + tmp = T(rng()); + size_t old_size = real[idx].size(); + size_t old_cap = real[idx].capacity(); + real[idx].push_front(*tmp); + sim[idx].push_front(*tmp); + assert(real[idx].size() == old_size + 1); + if (old_cap > old_size) { + assert(real[idx].capacity() == old_cap); + } else { + assert(real[idx].capacity() > old_cap); + assert(real[idx].capacity() <= 2 * (old_cap + 1)); + } + break; + } + if (existing_buffer_non_full && command-- == 0) { + /* push_front() (moving) */ + tmp = T(rng()); + size_t old_size = real[idx].size(); + size_t old_cap = real[idx].capacity(); + sim[idx].push_front(*tmp); + real[idx].push_front(std::move(*tmp)); + assert(real[idx].size() == old_size + 1); + if (old_cap > old_size) { + assert(real[idx].capacity() == old_cap); + } else { + assert(real[idx].capacity() > old_cap); + assert(real[idx].capacity() <= 2 * (old_cap + 1)); + } + break; + } + if (existing_buffer_non_full && command-- == 0) { + /* emplace_front() */ + uint64_t seed{rng()}; + size_t old_size = real[idx].size(); + size_t old_cap = real[idx].capacity(); + sim[idx].emplace_front(seed); + real[idx].emplace_front(seed); + assert(real[idx].size() == old_size + 1); + if (old_cap > old_size) { + assert(real[idx].capacity() == old_cap); + } else { + assert(real[idx].capacity() > old_cap); + assert(real[idx].capacity() <= 2 * (old_cap + 1)); + } + break; + } + if (existing_buffer_non_empty && command-- == 0) { + /* front() [modifying] */ + tmp = T(rng()); + size_t old_size = real[idx].size(); + assert(sim[idx].front() == real[idx].front()); + sim[idx].front() = *tmp; + real[idx].front() = std::move(*tmp); + assert(real[idx].size() == old_size); + break; + } + if (existing_buffer_non_empty && command-- == 0) { + /* back() [modifying] */ + tmp = T(rng()); + size_t old_size = real[idx].size(); + assert(sim[idx].back() == real[idx].back()); + sim[idx].back() = *tmp; + real[idx].back() = *tmp; + assert(real[idx].size() == old_size); + break; + } + if (existing_buffer_non_empty && command-- == 0) { + /* operator[] [modifying] */ + tmp = T(rng()); + size_t pos = provider.ConsumeIntegralInRange<size_t>(0, sim[idx].size() - 1); + size_t old_size = real[idx].size(); + assert(sim[idx][pos] == real[idx][pos]); + sim[idx][pos] = *tmp; + real[idx][pos] = std::move(*tmp); + assert(real[idx].size() == old_size); + break; + } + if (existing_buffer_non_empty && command-- == 0) { + /* pop_front() */ + assert(sim[idx].front() == real[idx].front()); + size_t old_size = real[idx].size(); + sim[idx].pop_front(); + real[idx].pop_front(); + assert(real[idx].size() == old_size - 1); + break; + } + if (existing_buffer_non_empty && command-- == 0) { + /* pop_back() */ + assert(sim[idx].back() == real[idx].back()); + size_t old_size = real[idx].size(); + sim[idx].pop_back(); + real[idx].pop_back(); + assert(real[idx].size() == old_size - 1); + break; + } + } + } + + /* Fully compare the final state. */ + for (unsigned i = 0; i < sim.size(); ++i) { + // Make sure const getters work. + const VecDeque<T>& realbuf = real[i]; + const std::deque<T>& simbuf = sim[i]; + compare_fn(realbuf, simbuf); + for (unsigned j = 0; j < sim.size(); ++j) { + assert((realbuf == real[j]) == (simbuf == sim[j])); + assert(((realbuf <=> real[j]) >= 0) == (simbuf >= sim[j])); + assert(((realbuf <=> real[j]) <= 0) == (simbuf <= sim[j])); + } + // Clear out the buffers so we can check below that no objects exist anymore. + sim[i].clear(); + real[i].clear(); + } + + if constexpr (CheckNoneLeft) { + tmp = std::nullopt; + T::CheckNoneExist(); + } +} + +/** Data structure with built-in tracking of all existing objects. */ +template<size_t Size> +class TrackedObj +{ + static_assert(Size > 0); + + /* Data type for map that actually stores the object data. + * + * The key is a pointer to the TrackedObj, the value is the uint64_t it was initialized with. + * Default-constructed and moved-from objects hold an std::nullopt. + */ + using track_map_type = std::map<const TrackedObj<Size>*, std::optional<uint64_t>>; + +private: + + /** Actual map. */ + static inline track_map_type g_tracker; + + /** Iterators into the tracker map for this object. + * + * This is an array of size Size, all holding the same value, to give the object configurable + * size. The value is g_tracker.end() if this object is not fully initialized. */ + typename track_map_type::iterator m_track_entry[Size]; + + void Check() const + { + auto it = g_tracker.find(this); + for (size_t i = 0; i < Size; ++i) { + assert(m_track_entry[i] == it); + } + } + + /** Create entry for this object in g_tracker and populate m_track_entry. */ + void Register() + { + auto [it, inserted] = g_tracker.emplace(this, std::nullopt); + assert(inserted); + for (size_t i = 0; i < Size; ++i) { + m_track_entry[i] = it; + } + } + + void Deregister() + { + Check(); + assert(m_track_entry[0] != g_tracker.end()); + g_tracker.erase(m_track_entry[0]); + for (size_t i = 0; i < Size; ++i) { + m_track_entry[i] = g_tracker.end(); + } + } + + /** Get value corresponding to this object in g_tracker. */ + std::optional<uint64_t>& Deref() + { + Check(); + assert(m_track_entry[0] != g_tracker.end()); + return m_track_entry[0]->second; + } + + /** Get value corresponding to this object in g_tracker. */ + const std::optional<uint64_t>& Deref() const + { + Check(); + assert(m_track_entry[0] != g_tracker.end()); + return m_track_entry[0]->second; + } + +public: + ~TrackedObj() { Deregister(); } + TrackedObj() { Register(); } + + TrackedObj(uint64_t value) + { + Register(); + Deref() = value; + } + + TrackedObj(const TrackedObj& other) + { + Register(); + Deref() = other.Deref(); + } + + TrackedObj(TrackedObj&& other) + { + Register(); + Deref() = other.Deref(); + other.Deref() = std::nullopt; + } + + TrackedObj& operator=(const TrackedObj& other) + { + if (this == &other) return *this; + Deref() = other.Deref(); + return *this; + } + + TrackedObj& operator=(TrackedObj&& other) + { + if (this == &other) return *this; + Deref() = other.Deref(); + other.Deref() = std::nullopt; + return *this; + } + + friend bool operator==(const TrackedObj& a, const TrackedObj& b) + { + return a.Deref() == b.Deref(); + } + + friend std::strong_ordering operator<=>(const TrackedObj& a, const TrackedObj& b) + { + // Libc++ 15 & 16 do not support std::optional<T>::operator<=> yet. See + // https://reviews.llvm.org/D146392. + if (!a.Deref().has_value() || !b.Deref().has_value()) { + return a.Deref().has_value() <=> b.Deref().has_value(); + } + return *a.Deref() <=> *b.Deref(); + } + + static void CheckNoneExist() + { + assert(g_tracker.empty()); + } +}; + +} // namespace + +FUZZ_TARGET(vecdeque) +{ + // Run the test with simple uints (which satisfy all the trivial properties). + static_assert(std::is_trivially_copyable_v<uint32_t>); + static_assert(std::is_trivially_destructible_v<uint64_t>); + TestType<uint8_t, false>(buffer, 1); + TestType<uint16_t, false>(buffer, 2); + TestType<uint32_t, false>(buffer, 3); + TestType<uint64_t, false>(buffer, 4); + + // Run the test with TrackedObjs (which do not). + static_assert(!std::is_trivially_copyable_v<TrackedObj<3>>); + static_assert(!std::is_trivially_destructible_v<TrackedObj<17>>); + TestType<TrackedObj<1>, true>(buffer, 5); + TestType<TrackedObj<3>, true>(buffer, 6); + TestType<TrackedObj<17>, true>(buffer, 7); +} diff --git a/src/test/getarg_tests.cpp b/src/test/getarg_tests.cpp index c73b675388..8734735fd5 100644 --- a/src/test/getarg_tests.cpp +++ b/src/test/getarg_tests.cpp @@ -16,6 +16,8 @@ #include <boost/test/unit_test.hpp> +using util::SplitString; + BOOST_FIXTURE_TEST_SUITE(getarg_tests, BasicTestingSetup) void ResetArgs(ArgsManager& local_args, const std::string& strArg) diff --git a/src/test/hash_tests.cpp b/src/test/hash_tests.cpp index f0d2b9ed72..51f1d4c840 100644 --- a/src/test/hash_tests.cpp +++ b/src/test/hash_tests.cpp @@ -124,9 +124,9 @@ BOOST_AUTO_TEST_CASE(siphash) HashWriter ss{}; CMutableTransaction tx; - // Note these tests were originally written with tx.nVersion=1 + // Note these tests were originally written with tx.version=1 // and the test would be affected by default tx version bumps if not fixed. - tx.nVersion = 1; + tx.version = 1; ss << TX_WITH_WITNESS(tx); BOOST_CHECK_EQUAL(SipHashUint256(1, 2, ss.GetHash()), 0x79751e980c2a0a35ULL); diff --git a/src/test/i2p_tests.cpp b/src/test/i2p_tests.cpp index d7249d88f4..0512c6134f 100644 --- a/src/test/i2p_tests.cpp +++ b/src/test/i2p_tests.cpp @@ -39,15 +39,14 @@ public: private: const BCLog::Level m_prev_log_level; - const std::function<std::unique_ptr<Sock>(const sa_family_t&)> m_create_sock_orig; + const decltype(CreateSock) m_create_sock_orig; }; BOOST_FIXTURE_TEST_SUITE(i2p_tests, EnvTestingSetup) BOOST_AUTO_TEST_CASE(unlimited_recv) { - // Mock CreateSock() to create MockSock. - CreateSock = [](const sa_family_t&) { + CreateSock = [](int, int, int) { return std::make_unique<StaticContentsSock>(std::string(i2p::sam::MAX_MSG_SIZE + 1, 'a')); }; @@ -69,7 +68,7 @@ BOOST_AUTO_TEST_CASE(unlimited_recv) BOOST_AUTO_TEST_CASE(listen_ok_accept_fail) { size_t num_sockets{0}; - CreateSock = [&num_sockets](const sa_family_t&) { + CreateSock = [&num_sockets](int, int, int) { // clang-format off ++num_sockets; // First socket is the control socket for creating the session. @@ -133,9 +132,7 @@ BOOST_AUTO_TEST_CASE(listen_ok_accept_fail) BOOST_AUTO_TEST_CASE(damaged_private_key) { - const auto CreateSockOrig = CreateSock; - - CreateSock = [](const sa_family_t&) { + CreateSock = [](int, int, int) { return std::make_unique<StaticContentsSock>("HELLO REPLY RESULT=OK VERSION=3.1\n" "SESSION STATUS RESULT=OK DESTINATION=\n"); }; @@ -172,8 +169,6 @@ BOOST_AUTO_TEST_CASE(damaged_private_key) BOOST_CHECK(!session.Connect(CService{}, conn, proxy_error)); } } - - CreateSock = CreateSockOrig; } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp index 86a8d17a76..b897a0a153 100644 --- a/src/test/key_tests.cpp +++ b/src/test/key_tests.cpp @@ -6,6 +6,7 @@ #include <common/system.h> #include <key_io.h> +#include <span.h> #include <streams.h> #include <test/util/random.h> #include <test/util/setup_common.h> @@ -18,6 +19,8 @@ #include <boost/test/unit_test.hpp> +using util::ToString; + static const std::string strSecret1 = "5HxWvvfubhXpYYpS3tJkw6fq9jE9j18THftkZjHHfmFiWtmAbrj"; static const std::string strSecret2 = "5KC4ejrDjv152FGwP386VD1i2NYc5KkfSMyv1nGy1VGDxGHqVY3"; static const std::string strSecret1C = "Kwr371tjA9u2rFSMZjTNun2PXXP3WPZu2afRHTcta6KxEUdm1vEw"; @@ -200,37 +203,6 @@ BOOST_AUTO_TEST_CASE(key_signature_tests) BOOST_CHECK(found_small); } -BOOST_AUTO_TEST_CASE(key_key_negation) -{ - // create a dummy hash for signature comparison - unsigned char rnd[8]; - std::string str = "Bitcoin key verification\n"; - GetRandBytes(rnd); - uint256 hash{Hash(str, rnd)}; - - // import the static test key - CKey key = DecodeSecret(strSecret1C); - - // create a signature - std::vector<unsigned char> vch_sig; - std::vector<unsigned char> vch_sig_cmp; - key.Sign(hash, vch_sig); - - // negate the key twice - BOOST_CHECK(key.GetPubKey().data()[0] == 0x03); - key.Negate(); - // after the first negation, the signature must be different - key.Sign(hash, vch_sig_cmp); - BOOST_CHECK(vch_sig_cmp != vch_sig); - BOOST_CHECK(key.GetPubKey().data()[0] == 0x02); - key.Negate(); - // after the second negation, we should have the original key and thus the - // same signature - key.Sign(hash, vch_sig_cmp); - BOOST_CHECK(vch_sig_cmp == vch_sig); - BOOST_CHECK(key.GetPubKey().data()[0] == 0x03); -} - static CPubKey UnserializePubkey(const std::vector<uint8_t>& data) { DataStream stream{}; @@ -364,4 +336,13 @@ BOOST_AUTO_TEST_CASE(key_ellswift) } } +BOOST_AUTO_TEST_CASE(bip341_test_h) +{ + std::vector<unsigned char> G_uncompressed = ParseHex("0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8"); + HashWriter hw; + hw.write(MakeByteSpan(G_uncompressed)); + XOnlyPubKey H{hw.GetSHA256()}; + BOOST_CHECK(XOnlyPubKey::NUMS_H == H); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/logging_tests.cpp b/src/test/logging_tests.cpp index 88e3ec94b7..cebd000df8 100644 --- a/src/test/logging_tests.cpp +++ b/src/test/logging_tests.cpp @@ -17,6 +17,9 @@ #include <boost/test/unit_test.hpp> +using util::SplitString; +using util::TrimString; + BOOST_FIXTURE_TEST_SUITE(logging_tests, BasicTestingSetup) static void ResetLogger() diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index d50af4c175..c4cf6f8a40 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -14,8 +14,10 @@ #include <test/util/txmempool.h> #include <txmempool.h> #include <uint256.h> +#include <util/check.h> #include <util/strencodings.h> #include <util/time.h> +#include <util/translation.h> #include <validation.h> #include <versionbits.h> @@ -46,7 +48,9 @@ struct MinerTestingSetup : public TestingSetup { // pointer is not accessed, when the new one should be accessed // instead. m_node.mempool.reset(); - m_node.mempool = std::make_unique<CTxMemPool>(MemPoolOptionsForTest(m_node)); + bilingual_str error; + m_node.mempool = std::make_unique<CTxMemPool>(MemPoolOptionsForTest(m_node), error); + Assert(error.empty()); return *m_node.mempool; } BlockAssembler AssemblerForTest(CTxMemPool& tx_mempool); @@ -421,7 +425,7 @@ void MinerTestingSetup::TestBasicMining(const CScript& scriptPubKey, const std:: std::vector<int> prevheights; // relative height locked - tx.nVersion = 2; + tx.version = 2; tx.vin.resize(1); prevheights.resize(1); tx.vin[0].prevout.hash = txFirst[0]->GetHash(); // only 1 transaction @@ -622,7 +626,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) pblock->nVersion = VERSIONBITS_TOP_BITS; pblock->nTime = m_node.chainman->ActiveChain().Tip()->GetMedianTimePast()+1; CMutableTransaction txCoinbase(*pblock->vtx[0]); - txCoinbase.nVersion = 1; + txCoinbase.version = 1; txCoinbase.vin[0].scriptSig = CScript{} << (m_node.chainman->ActiveChain().Height() + 1) << bi.extranonce; txCoinbase.vout.resize(1); // Ignore the (optional) segwit commitment added by CreateNewBlock (as the hardcoded nonces don't account for this) txCoinbase.vout[0].scriptPubKey = CScript(); diff --git a/src/test/miniscript_tests.cpp b/src/test/miniscript_tests.cpp index a3699f84b6..7e39e9e4de 100644 --- a/src/test/miniscript_tests.cpp +++ b/src/test/miniscript_tests.cpp @@ -288,9 +288,6 @@ public: } }; -//! Public key to be used as internal key for dummy Taproot spends. -const std::vector<unsigned char> NUMS_PK{ParseHex("50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0")}; - using Fragment = miniscript::Fragment; using NodeRef = miniscript::NodeRef<CPubKey>; using miniscript::operator"" _mst; @@ -330,7 +327,7 @@ CScript ScriptPubKey(miniscript::MiniscriptContext ctx, const CScript& script, T // For Taproot outputs we always use a tree with a single script and a dummy internal key. builder.Add(0, script, TAPROOT_LEAF_TAPSCRIPT); - builder.Finalize(XOnlyPubKey{NUMS_PK}); + builder.Finalize(XOnlyPubKey::NUMS_H); return GetScriptForDestination(builder.GetOutput()); } diff --git a/src/test/net_peer_connection_tests.cpp b/src/test/net_peer_connection_tests.cpp index 58cbe9eb72..5f38ce112c 100644 --- a/src/test/net_peer_connection_tests.cpp +++ b/src/test/net_peer_connection_tests.cpp @@ -84,7 +84,7 @@ static void AddPeer(NodeId& id, std::vector<CNode*>& nodes, PeerManager& peerman BOOST_AUTO_TEST_CASE(test_addnode_getaddednodeinfo_and_connection_detection) { auto connman = std::make_unique<ConnmanTestMsg>(0x1337, 0x1337, *m_node.addrman, *m_node.netgroupman, Params()); - auto peerman = PeerManager::make(*connman, *m_node.addrman, nullptr, *m_node.chainman, *m_node.mempool, {}); + auto peerman = PeerManager::make(*connman, *m_node.addrman, nullptr, *m_node.chainman, *m_node.mempool, *m_node.warnings, {}); NodeId id{0}; std::vector<CNode*> nodes; @@ -108,6 +108,12 @@ BOOST_AUTO_TEST_CASE(test_addnode_getaddednodeinfo_and_connection_detection) AddPeer(id, nodes, *peerman, *connman, ConnectionType::BLOCK_RELAY, /*onion_peer=*/true); AddPeer(id, nodes, *peerman, *connman, ConnectionType::INBOUND); + // Add a CJDNS peer connection. + AddPeer(id, nodes, *peerman, *connman, ConnectionType::INBOUND, /*onion_peer=*/false, + /*address=*/"[fc00:3344:5566:7788:9900:aabb:ccdd:eeff]:1234"); + BOOST_CHECK(nodes.back()->IsInboundConn()); + BOOST_CHECK_EQUAL(nodes.back()->ConnectedThroughNetwork(), Network::NET_CJDNS); + BOOST_TEST_MESSAGE("Call AddNode() for all the peers"); for (auto node : connman->TestNodes()) { BOOST_CHECK(connman->AddNode({/*m_added_node=*/node->addr.ToStringAddrPort(), /*m_use_v2transport=*/true})); diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp index b9dff96610..46a6a33b34 100644 --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -32,6 +32,7 @@ #include <string> using namespace std::literals; +using util::ToString; BOOST_FIXTURE_TEST_SUITE(net_tests, RegTestingSetup) diff --git a/src/test/node_warnings_tests.cpp b/src/test/node_warnings_tests.cpp new file mode 100644 index 0000000000..2bcc2c95ed --- /dev/null +++ b/src/test/node_warnings_tests.cpp @@ -0,0 +1,52 @@ +// Copyright (c) 2024-present The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// + +#include <node/warnings.h> +#include <util/translation.h> + +#include <test/util/setup_common.h> + +#include <boost/test/unit_test.hpp> + +BOOST_FIXTURE_TEST_SUITE(node_warnings_tests, BasicTestingSetup) + +BOOST_AUTO_TEST_CASE(warnings) +{ + node::Warnings warnings; + // On pre-release builds, a warning is generated automatically + warnings.Unset(node::Warning::PRE_RELEASE_TEST_BUILD); + + // For these tests, we don't care what the exact warnings are, so + // just refer to them as warning_1 and warning_2 + const auto warning_1{node::Warning::CLOCK_OUT_OF_SYNC}; + const auto warning_2{node::Warning::FATAL_INTERNAL_ERROR}; + + // Ensure we start without any warnings + BOOST_CHECK(warnings.GetMessages().size() == 0); + // Add two warnings + BOOST_CHECK(warnings.Set(warning_1, _("warning 1"))); + BOOST_CHECK(warnings.Set(warning_2, _("warning 2"))); + // Unset the second one + BOOST_CHECK(warnings.Unset(warning_2)); + // Since it's already been unset, this should return false + BOOST_CHECK(!warnings.Unset(warning_2)); + // We should now be able to set w2 again + BOOST_CHECK(warnings.Set(warning_2, _("warning 2 - revision 1"))); + // Setting w2 again should return false since it's already set + BOOST_CHECK(!warnings.Set(warning_2, _("warning 2 - revision 2"))); + + // Verify messages are correct + const auto messages{warnings.GetMessages()}; + BOOST_CHECK(messages.size() == 2); + BOOST_CHECK(messages[0].original == "warning 1"); + BOOST_CHECK(messages[1].original == "warning 2 - revision 1"); + + // Clearing all warnings should also clear all messages + BOOST_CHECK(warnings.Unset(warning_1)); + BOOST_CHECK(warnings.Unset(warning_2)); + BOOST_CHECK(warnings.GetMessages().size() == 0); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/orphanage_tests.cpp b/src/test/orphanage_tests.cpp index b2643cf678..450bf6a4fc 100644 --- a/src/test/orphanage_tests.cpp +++ b/src/test/orphanage_tests.cpp @@ -30,8 +30,8 @@ public: CTransactionRef RandomOrphan() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex) { LOCK(m_mutex); - std::map<Txid, OrphanTx>::iterator it; - it = m_orphans.lower_bound(Txid::FromUint256(InsecureRand256())); + std::map<Wtxid, OrphanTx>::iterator it; + it = m_orphans.lower_bound(Wtxid::FromUint256(InsecureRand256())); if (it == m_orphans.end()) it = m_orphans.begin(); return it->second.tx; @@ -70,6 +70,16 @@ static CTransactionRef MakeTransactionSpending(const std::vector<COutPoint>& out return MakeTransactionRef(tx); } +// Make another (not necessarily valid) tx with the same txid but different wtxid. +static CTransactionRef MakeMutation(const CTransactionRef& ptx) +{ + CMutableTransaction tx(*ptx); + tx.vin[0].scriptWitness.stack.push_back({5}); + auto mutated_tx = MakeTransactionRef(tx); + assert(ptx->GetHash() == mutated_tx->GetHash()); + return mutated_tx; +} + static bool EqualTxns(const std::set<CTransactionRef>& set_txns, const std::vector<CTransactionRef>& vec_txns) { if (vec_txns.size() != set_txns.size()) return false; @@ -180,6 +190,49 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans) BOOST_CHECK(orphanage.CountOrphans() == 0); } +BOOST_AUTO_TEST_CASE(same_txid_diff_witness) +{ + FastRandomContext det_rand{true}; + TxOrphanage orphanage; + NodeId peer{0}; + + std::vector<COutPoint> empty_outpoints; + auto parent = MakeTransactionSpending(empty_outpoints, det_rand); + + // Create children to go into orphanage. + auto child_normal = MakeTransactionSpending({{parent->GetHash(), 0}}, det_rand); + auto child_mutated = MakeMutation(child_normal); + + const auto& normal_wtxid = child_normal->GetWitnessHash(); + const auto& mutated_wtxid = child_mutated->GetWitnessHash(); + BOOST_CHECK(normal_wtxid != mutated_wtxid); + + BOOST_CHECK(orphanage.AddTx(child_normal, peer)); + // EraseTx fails as transaction by this wtxid doesn't exist. + BOOST_CHECK_EQUAL(orphanage.EraseTx(mutated_wtxid), 0); + BOOST_CHECK(orphanage.HaveTx(normal_wtxid)); + BOOST_CHECK(!orphanage.HaveTx(mutated_wtxid)); + + // Must succeed. Both transactions should be present in orphanage. + BOOST_CHECK(orphanage.AddTx(child_mutated, peer)); + BOOST_CHECK(orphanage.HaveTx(normal_wtxid)); + BOOST_CHECK(orphanage.HaveTx(mutated_wtxid)); + + // Outpoints map should track all entries: check that both are returned as children of the parent. + std::set<CTransactionRef> expected_children{child_normal, child_mutated}; + BOOST_CHECK(EqualTxns(expected_children, orphanage.GetChildrenFromSamePeer(parent, peer))); + + // Erase by wtxid: mutated first + BOOST_CHECK_EQUAL(orphanage.EraseTx(mutated_wtxid), 1); + BOOST_CHECK(orphanage.HaveTx(normal_wtxid)); + BOOST_CHECK(!orphanage.HaveTx(mutated_wtxid)); + + BOOST_CHECK_EQUAL(orphanage.EraseTx(normal_wtxid), 1); + BOOST_CHECK(!orphanage.HaveTx(normal_wtxid)); + BOOST_CHECK(!orphanage.HaveTx(mutated_wtxid)); +} + + BOOST_AUTO_TEST_CASE(get_children) { FastRandomContext det_rand{true}; diff --git a/src/test/peerman_tests.cpp b/src/test/peerman_tests.cpp index 28866695bc..6de373eef2 100644 --- a/src/test/peerman_tests.cpp +++ b/src/test/peerman_tests.cpp @@ -20,7 +20,8 @@ static void mineBlock(const node::NodeContext& node, std::chrono::seconds block_ { auto curr_time = GetTime<std::chrono::seconds>(); SetMockTime(block_time); // update time so the block is created with it - CBlock block = node::BlockAssembler{node.chainman->ActiveChainstate(), nullptr}.CreateNewBlock(CScript() << OP_TRUE)->block; + node::BlockAssembler::Options options; + CBlock block = node::BlockAssembler{node.chainman->ActiveChainstate(), nullptr, options}.CreateNewBlock(CScript() << OP_TRUE)->block; while (!CheckProofOfWork(block.GetHash(), block.nBits, node.chainman->GetConsensus())) ++block.nNonce; block.fChecked = true; // little speedup SetMockTime(curr_time); // process block at current time @@ -31,7 +32,7 @@ static void mineBlock(const node::NodeContext& node, std::chrono::seconds block_ // Verifying when network-limited peer connections are desirable based on the node's proximity to the tip BOOST_AUTO_TEST_CASE(connections_desirable_service_flags) { - std::unique_ptr<PeerManager> peerman = PeerManager::make(*m_node.connman, *m_node.addrman, nullptr, *m_node.chainman, *m_node.mempool, {}); + std::unique_ptr<PeerManager> peerman = PeerManager::make(*m_node.connman, *m_node.addrman, nullptr, *m_node.chainman, *m_node.mempool, *m_node.warnings, {}); auto consensus = m_node.chainman->GetParams().GetConsensus(); // Check we start connecting to full nodes diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index acacb6257d..5089f3e8e3 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -17,6 +17,8 @@ #include <boost/test/unit_test.hpp> +using util::SplitString; + static UniValue JSON(std::string_view json) { UniValue value; @@ -552,7 +554,7 @@ BOOST_AUTO_TEST_CASE(help_example) // test different argument types const RPCArgList& args = {{"foo", "bar"}, {"b", true}, {"n", 1}}; BOOST_CHECK_EQUAL(HelpExampleCliNamed("test", args), "> bitcoin-cli -named test foo=bar b=true n=1\n"); - BOOST_CHECK_EQUAL(HelpExampleRpcNamed("test", args), "> curl --user myusername --data-binary '{\"jsonrpc\": \"1.0\", \"id\": \"curltest\", \"method\": \"test\", \"params\": {\"foo\":\"bar\",\"b\":true,\"n\":1}}' -H 'content-type: text/plain;' http://127.0.0.1:8332/\n"); + BOOST_CHECK_EQUAL(HelpExampleRpcNamed("test", args), "> curl --user myusername --data-binary '{\"jsonrpc\": \"2.0\", \"id\": \"curltest\", \"method\": \"test\", \"params\": {\"foo\":\"bar\",\"b\":true,\"n\":1}}' -H 'content-type: application/json' http://127.0.0.1:8332/\n"); // test shell escape BOOST_CHECK_EQUAL(HelpExampleCliNamed("test", {{"foo", "b'ar"}}), "> bitcoin-cli -named test foo='b'''ar'\n"); @@ -565,7 +567,7 @@ BOOST_AUTO_TEST_CASE(help_example) obj_value.pushKV("b", false); obj_value.pushKV("n", 1); BOOST_CHECK_EQUAL(HelpExampleCliNamed("test", {{"name", obj_value}}), "> bitcoin-cli -named test name='{\"foo\":\"bar\",\"b\":false,\"n\":1}'\n"); - BOOST_CHECK_EQUAL(HelpExampleRpcNamed("test", {{"name", obj_value}}), "> curl --user myusername --data-binary '{\"jsonrpc\": \"1.0\", \"id\": \"curltest\", \"method\": \"test\", \"params\": {\"name\":{\"foo\":\"bar\",\"b\":false,\"n\":1}}}' -H 'content-type: text/plain;' http://127.0.0.1:8332/\n"); + BOOST_CHECK_EQUAL(HelpExampleRpcNamed("test", {{"name", obj_value}}), "> curl --user myusername --data-binary '{\"jsonrpc\": \"2.0\", \"id\": \"curltest\", \"method\": \"test\", \"params\": {\"name\":{\"foo\":\"bar\",\"b\":false,\"n\":1}}}' -H 'content-type: application/json' http://127.0.0.1:8332/\n"); // test array params UniValue arr_value(UniValue::VARR); @@ -573,7 +575,7 @@ BOOST_AUTO_TEST_CASE(help_example) arr_value.push_back(false); arr_value.push_back(1); BOOST_CHECK_EQUAL(HelpExampleCliNamed("test", {{"name", arr_value}}), "> bitcoin-cli -named test name='[\"bar\",false,1]'\n"); - BOOST_CHECK_EQUAL(HelpExampleRpcNamed("test", {{"name", arr_value}}), "> curl --user myusername --data-binary '{\"jsonrpc\": \"1.0\", \"id\": \"curltest\", \"method\": \"test\", \"params\": {\"name\":[\"bar\",false,1]}}' -H 'content-type: text/plain;' http://127.0.0.1:8332/\n"); + BOOST_CHECK_EQUAL(HelpExampleRpcNamed("test", {{"name", arr_value}}), "> curl --user myusername --data-binary '{\"jsonrpc\": \"2.0\", \"id\": \"curltest\", \"method\": \"test\", \"params\": {\"name\":[\"bar\",false,1]}}' -H 'content-type: application/json' http://127.0.0.1:8332/\n"); // test types don't matter for shell BOOST_CHECK_EQUAL(HelpExampleCliNamed("foo", {{"arg", true}}), HelpExampleCliNamed("foo", {{"arg", "true"}})); @@ -614,40 +616,26 @@ BOOST_AUTO_TEST_CASE(rpc_arg_helper) //! Check that `self.Arg` returns the same value as the `request.params` accessors RPCHelpMan::RPCMethodImpl check_positional = [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - BOOST_CHECK_EQUAL(self.Arg<int>(0), request.params[0].getInt<int>()); - BOOST_CHECK_EQUAL(self.Arg<std::string>(1), request.params[1].get_str()); - BOOST_CHECK_EQUAL(self.Arg<uint64_t>(2), request.params[2].isNull() ? DEFAULT_UINT64_T : request.params[2].getInt<uint64_t>()); - BOOST_CHECK_EQUAL(self.Arg<std::string>(3), request.params[3].isNull() ? DEFAULT_STRING : request.params[3].get_str()); - BOOST_CHECK_EQUAL(self.Arg<bool>(4), request.params[4].isNull() ? DEFAULT_BOOL : request.params[4].get_bool()); + BOOST_CHECK_EQUAL(self.Arg<int>("req_int"), request.params[0].getInt<int>()); + BOOST_CHECK_EQUAL(self.Arg<std::string>("req_str"), request.params[1].get_str()); + BOOST_CHECK_EQUAL(self.Arg<uint64_t>("def_uint64_t"), request.params[2].isNull() ? DEFAULT_UINT64_T : request.params[2].getInt<uint64_t>()); + BOOST_CHECK_EQUAL(self.Arg<std::string>("def_string"), request.params[3].isNull() ? DEFAULT_STRING : request.params[3].get_str()); + BOOST_CHECK_EQUAL(self.Arg<bool>("def_bool"), request.params[4].isNull() ? DEFAULT_BOOL : request.params[4].get_bool()); if (!request.params[5].isNull()) { - BOOST_CHECK_EQUAL(self.MaybeArg<double>(5).value(), request.params[5].get_real()); + BOOST_CHECK_EQUAL(self.MaybeArg<double>("opt_double").value(), request.params[5].get_real()); } else { - BOOST_CHECK(!self.MaybeArg<double>(5)); + BOOST_CHECK(!self.MaybeArg<double>("opt_double")); } if (!request.params[6].isNull()) { - BOOST_CHECK(self.MaybeArg<std::string>(6)); - BOOST_CHECK_EQUAL(*self.MaybeArg<std::string>(6), request.params[6].get_str()); + BOOST_CHECK(self.MaybeArg<std::string>("opt_string")); + BOOST_CHECK_EQUAL(*self.MaybeArg<std::string>("opt_string"), request.params[6].get_str()); } else { - BOOST_CHECK(!self.MaybeArg<std::string>(6)); + BOOST_CHECK(!self.MaybeArg<std::string>("opt_string")); } return UniValue{}; }; CheckRpc(params, UniValue{JSON(R"([5, "hello", null, null, null, null, null])")}, check_positional); CheckRpc(params, UniValue{JSON(R"([5, "hello", 4, "test", true, 1.23, "world"])")}, check_positional); - - //! Check that `self.Arg` returns the same value when using index and key - RPCHelpMan::RPCMethodImpl check_named = [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - BOOST_CHECK_EQUAL(self.Arg<int>(0), self.Arg<int>("req_int")); - BOOST_CHECK_EQUAL(self.Arg<std::string>(1), self.Arg<std::string>("req_str")); - BOOST_CHECK_EQUAL(self.Arg<uint64_t>(2), self.Arg<uint64_t>("def_uint64_t")); - BOOST_CHECK_EQUAL(self.Arg<std::string>(3), self.Arg<std::string>("def_string")); - BOOST_CHECK_EQUAL(self.Arg<bool>(4), self.Arg<bool>("def_bool")); - BOOST_CHECK(self.MaybeArg<double>(5) == self.MaybeArg<double>("opt_double")); - BOOST_CHECK(self.MaybeArg<std::string>(6) == self.MaybeArg<std::string>("opt_string")); - return UniValue{}; - }; - CheckRpc(params, UniValue{JSON(R"([5, "hello", null, null, null, null, null])")}, check_named); - CheckRpc(params, UniValue{JSON(R"([5, "hello", 4, "test", true, 1.23, "world"])")}, check_named); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index e4142e203c..39b53295e7 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -396,7 +396,7 @@ public: wit.push_back(HexStr(scriptWitness.stack[i])); } wit.push_back(ValueFromAmount(nValue)); - array.push_back(wit); + array.push_back(std::move(wit)); } array.push_back(FormatScript(spendTx.vin[0].scriptSig)); array.push_back(FormatScript(creditTx->vout[0].scriptPubKey)); @@ -1268,8 +1268,7 @@ BOOST_AUTO_TEST_CASE(sign_invalid_miniscript) const auto invalid_pubkey{ParseHex("173d36c8c9c9c9ffffffffffff0200000000021e1e37373721361818181818181e1e1e1e19000000000000000000b19292929292926b006c9b9b9292")}; TaprootBuilder builder; builder.Add(0, {invalid_pubkey}, 0xc0); - XOnlyPubKey nums{ParseHex("50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0")}; - builder.Finalize(nums); + builder.Finalize(XOnlyPubKey::NUMS_H); prev.vout.emplace_back(0, GetScriptForDestination(builder.GetOutput())); curr.vin.emplace_back(COutPoint{prev.GetHash(), 0}); sig_data.tr_spenddata = builder.GetSpendData(); diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp index d75eb499b4..b28e1b4196 100644 --- a/src/test/serialize_tests.cpp +++ b/src/test/serialize_tests.cpp @@ -15,6 +15,18 @@ BOOST_FIXTURE_TEST_SUITE(serialize_tests, BasicTestingSetup) +// For testing move-semantics, declare a version of datastream that can be moved +// but is not copyable. +class UncopyableStream : public DataStream +{ +public: + using DataStream::DataStream; + UncopyableStream(const UncopyableStream&) = delete; + UncopyableStream& operator=(const UncopyableStream&) = delete; + UncopyableStream(UncopyableStream&&) noexcept = default; + UncopyableStream& operator=(UncopyableStream&&) noexcept = default; +}; + class CSerializeMethodsTestSingle { protected: @@ -289,7 +301,7 @@ public: template <typename Stream> void Serialize(Stream& s) const { - if (s.GetParams().m_base_format == BaseFormat::RAW) { + if (s.template GetParams<BaseFormat>().m_base_format == BaseFormat::RAW) { s << m_base_data; } else { s << Span{HexStr(Span{&m_base_data, 1})}; @@ -299,7 +311,7 @@ public: template <typename Stream> void Unserialize(Stream& s) { - if (s.GetParams().m_base_format == BaseFormat::RAW) { + if (s.template GetParams<BaseFormat>().m_base_format == BaseFormat::RAW) { s >> m_base_data; } else { std::string hex{"aa"}; @@ -327,8 +339,9 @@ class Derived : public Base public: std::string m_derived_data; - SERIALIZE_METHODS_PARAMS(Derived, obj, DerivedAndBaseFormat, fmt) + SERIALIZE_METHODS(Derived, obj) { + auto& fmt = SER_PARAMS(DerivedAndBaseFormat); READWRITE(fmt.m_base_format(AsBase<Base>(obj))); if (ser_action.ForRead()) { @@ -343,6 +356,76 @@ public: } }; +struct OtherParam { + uint8_t param; + SER_PARAMS_OPFUNC +}; + +//! Checker for value of OtherParam. When being serialized, serializes the +//! param to the stream. When being unserialized, verifies the value in the +//! stream matches the param. +class OtherParamChecker +{ +public: + template <typename Stream> + void Serialize(Stream& s) const + { + const uint8_t param = s.template GetParams<OtherParam>().param; + s << param; + } + + template <typename Stream> + void Unserialize(Stream& s) const + { + const uint8_t param = s.template GetParams<OtherParam>().param; + uint8_t value; + s >> value; + BOOST_CHECK_EQUAL(value, param); + } +}; + +//! Test creating a stream with multiple parameters and making sure +//! serialization code requiring different parameters can retrieve them. Also +//! test that earlier parameters take precedence if the same parameter type is +//! specified twice. (Choice of whether earlier or later values take precedence +//! or multiple values of the same type are allowed was arbitrary, and just +//! decided based on what would require smallest amount of ugly C++ template +//! code. Intent of the test is to just ensure there is no unexpected behavior.) +BOOST_AUTO_TEST_CASE(with_params_multi) +{ + const OtherParam other_param_used{.param = 0x10}; + const OtherParam other_param_ignored{.param = 0x11}; + const OtherParam other_param_override{.param = 0x12}; + const OtherParamChecker check; + DataStream stream; + ParamsStream pstream{stream, RAW, other_param_used, other_param_ignored}; + + Base base1{0x20}; + pstream << base1 << check << other_param_override(check); + BOOST_CHECK_EQUAL(stream.str(), "\x20\x10\x12"); + + Base base2; + pstream >> base2 >> check >> other_param_override(check); + BOOST_CHECK_EQUAL(base2.m_base_data, 0x20); +} + +//! Test creating a ParamsStream that moves from a stream argument. +BOOST_AUTO_TEST_CASE(with_params_move) +{ + UncopyableStream stream{MakeByteSpan(std::string_view{"abc"})}; + ParamsStream pstream{std::move(stream), RAW, HEX, RAW}; + BOOST_CHECK_EQUAL(pstream.GetStream().str(), "abc"); + pstream.GetStream().clear(); + + Base base1{0x20}; + pstream << base1; + BOOST_CHECK_EQUAL(pstream.GetStream().str(), "\x20"); + + Base base2; + pstream >> base2; + BOOST_CHECK_EQUAL(base2.m_base_data, 0x20); +} + BOOST_AUTO_TEST_CASE(with_params_base) { Base b{0x0F}; diff --git a/src/test/settings_tests.cpp b/src/test/settings_tests.cpp index 41190b3579..95f38fc0ce 100644 --- a/src/test/settings_tests.cpp +++ b/src/test/settings_tests.cpp @@ -21,6 +21,8 @@ #include <system_error> #include <vector> +using util::ToString; + inline bool operator==(const common::SettingsValue& a, const common::SettingsValue& b) { return a.write() == b.write(); diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index d08d5519a1..70a18835d2 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -92,7 +92,7 @@ void static RandomScript(CScript &script) { void static RandomTransaction(CMutableTransaction& tx, bool fSingle) { - tx.nVersion = int(InsecureRand32()); + tx.version = InsecureRand32(); tx.vin.clear(); tx.vout.clear(); tx.nLockTime = (InsecureRandBool()) ? InsecureRand32() : 0; diff --git a/src/test/sigopcount_tests.cpp b/src/test/sigopcount_tests.cpp index 2081acdf4d..aed67d5f3c 100644 --- a/src/test/sigopcount_tests.cpp +++ b/src/test/sigopcount_tests.cpp @@ -86,7 +86,7 @@ static ScriptError VerifyWithFlag(const CTransaction& output, const CMutableTran */ static void BuildTxs(CMutableTransaction& spendingTx, CCoinsViewCache& coins, CMutableTransaction& creationTx, const CScript& scriptPubKey, const CScript& scriptSig, const CScriptWitness& witness) { - creationTx.nVersion = 1; + creationTx.version = 1; creationTx.vin.resize(1); creationTx.vin[0].prevout.SetNull(); creationTx.vin[0].scriptSig = CScript(); @@ -94,7 +94,7 @@ static void BuildTxs(CMutableTransaction& spendingTx, CCoinsViewCache& coins, CM creationTx.vout[0].nValue = 1; creationTx.vout[0].scriptPubKey = scriptPubKey; - spendingTx.nVersion = 1; + spendingTx.version = 1; spendingTx.vin.resize(1); spendingTx.vin[0].prevout.hash = creationTx.GetHash(); spendingTx.vin[0].prevout.n = 0; diff --git a/src/test/timeoffsets_tests.cpp b/src/test/timeoffsets_tests.cpp index 008f1a9db9..5f85a5feeb 100644 --- a/src/test/timeoffsets_tests.cpp +++ b/src/test/timeoffsets_tests.cpp @@ -4,6 +4,7 @@ // #include <node/timeoffsets.h> +#include <node/warnings.h> #include <test/util/setup_common.h> #include <boost/test/unit_test.hpp> @@ -24,7 +25,8 @@ BOOST_FIXTURE_TEST_SUITE(timeoffsets_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(timeoffsets) { - TimeOffsets offsets{}; + node::Warnings warnings{}; + TimeOffsets offsets{warnings}; BOOST_CHECK(offsets.Median() == 0s); AddMulti(offsets, {{0s, -1s, -2s, -3s}}); @@ -50,7 +52,8 @@ BOOST_AUTO_TEST_CASE(timeoffsets) static bool IsWarningRaised(const std::vector<std::chrono::seconds>& check_offsets) { - TimeOffsets offsets{}; + node::Warnings warnings{}; + TimeOffsets offsets{warnings}; AddMulti(offsets, check_offsets); return offsets.WarnIfOutOfSync(); } diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index e6cf64611e..34176626f0 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -38,6 +38,9 @@ #include <univalue.h> +using util::SplitString; +using util::ToString; + typedef std::vector<unsigned char> valtype; static CFeeRate g_dust{DUST_RELAY_TX_FEE}; @@ -69,17 +72,16 @@ static std::map<std::string, unsigned int> mapFlagNames = { unsigned int ParseScriptFlags(std::string strFlags) { - if (strFlags.empty() || strFlags == "NONE") return 0; - unsigned int flags = 0; - std::vector<std::string> words = SplitString(strFlags, ','); + unsigned int flags = SCRIPT_VERIFY_NONE; + if (strFlags.empty() || strFlags == "NONE") return flags; + std::vector<std::string> words = SplitString(strFlags, ','); for (const std::string& word : words) { if (!mapFlagNames.count(word)) BOOST_ERROR("Bad test: unknown verification flag '" << word << "'"); flags |= mapFlagNames[word]; } - return flags; } @@ -95,7 +97,7 @@ bool CheckMapFlagNames() std::string FormatScriptFlags(unsigned int flags) { - if (flags == 0) { + if (flags == SCRIPT_VERIFY_NONE) { return ""; } std::string ret; @@ -367,6 +369,41 @@ BOOST_AUTO_TEST_CASE(tx_invalid) } } +BOOST_AUTO_TEST_CASE(tx_no_inputs) +{ + CMutableTransaction empty; + + TxValidationState state; + BOOST_CHECK_MESSAGE(!CheckTransaction(CTransaction(empty), state), "Transaction with no inputs should be invalid."); + BOOST_CHECK(state.GetRejectReason() == "bad-txns-vin-empty"); +} + +BOOST_AUTO_TEST_CASE(tx_oversized) +{ + auto createTransaction =[](size_t payloadSize) { + CMutableTransaction tx; + tx.vin.resize(1); + tx.vout.emplace_back(1, CScript() << OP_RETURN << std::vector<unsigned char>(payloadSize)); + return CTransaction(tx); + }; + const auto maxTransactionSize = MAX_BLOCK_WEIGHT / WITNESS_SCALE_FACTOR; + const auto oversizedTransactionBaseSize = ::GetSerializeSize(TX_NO_WITNESS(createTransaction(maxTransactionSize))) - maxTransactionSize; + + auto maxPayloadSize = maxTransactionSize - oversizedTransactionBaseSize; + { + TxValidationState state; + CheckTransaction(createTransaction(maxPayloadSize), state); + BOOST_CHECK(state.GetRejectReason() != "bad-txns-oversize"); + } + + maxPayloadSize += 1; + { + TxValidationState state; + BOOST_CHECK_MESSAGE(!CheckTransaction(createTransaction(maxPayloadSize), state), "Oversized transaction should be invalid"); + BOOST_CHECK(state.GetRejectReason() == "bad-txns-oversize"); + } +} + BOOST_AUTO_TEST_CASE(basic_transaction_tests) { // Random real transaction (e2769b09e784f32f62ef849763d4f45b98e07ba658647343b915ff832b110436) @@ -412,7 +449,7 @@ BOOST_AUTO_TEST_CASE(test_Get) static void CreateCreditAndSpend(const FillableSigningProvider& keystore, const CScript& outscript, CTransactionRef& output, CMutableTransaction& input, bool success = true) { CMutableTransaction outputm; - outputm.nVersion = 1; + outputm.version = 1; outputm.vin.resize(1); outputm.vin[0].prevout.SetNull(); outputm.vin[0].scriptSig = CScript(); @@ -428,7 +465,7 @@ static void CreateCreditAndSpend(const FillableSigningProvider& keystore, const assert(output->vout[0] == outputm.vout[0]); CMutableTransaction inputm; - inputm.nVersion = 1; + inputm.version = 1; inputm.vin.resize(1); inputm.vin[0].prevout.hash = output->GetHash(); inputm.vin[0].prevout.n = 0; @@ -485,7 +522,7 @@ static void ReplaceRedeemScript(CScript& script, const CScript& redeemScript) BOOST_AUTO_TEST_CASE(test_big_witness_transaction) { CMutableTransaction mtx; - mtx.nVersion = 1; + mtx.version = 1; CKey key = GenerateRandomKey(); // Need to use compressed keys in segwit or the signing will fail FillableSigningProvider keystore; @@ -612,11 +649,11 @@ BOOST_AUTO_TEST_CASE(test_witness) // Normal pay-to-compressed-pubkey. CreateCreditAndSpend(keystore, scriptPubkey1, output1, input1); CreateCreditAndSpend(keystore, scriptPubkey2, output2, input2); - CheckWithFlag(output1, input1, 0, true); + CheckWithFlag(output1, input1, SCRIPT_VERIFY_NONE, true); CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true); CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true); CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true); - CheckWithFlag(output1, input2, 0, false); + CheckWithFlag(output1, input2, SCRIPT_VERIFY_NONE, false); CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, false); CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false); CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false); @@ -625,11 +662,11 @@ BOOST_AUTO_TEST_CASE(test_witness) CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(scriptPubkey1)), output1, input1); CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(scriptPubkey2)), output2, input2); ReplaceRedeemScript(input2.vin[0].scriptSig, scriptPubkey1); - CheckWithFlag(output1, input1, 0, true); + CheckWithFlag(output1, input1, SCRIPT_VERIFY_NONE, true); CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true); CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true); CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true); - CheckWithFlag(output1, input2, 0, true); + CheckWithFlag(output1, input2, SCRIPT_VERIFY_NONE, true); CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, false); CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false); CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false); @@ -637,11 +674,11 @@ BOOST_AUTO_TEST_CASE(test_witness) // Witness pay-to-compressed-pubkey (v0). CreateCreditAndSpend(keystore, destination_script_1, output1, input1); CreateCreditAndSpend(keystore, destination_script_2, output2, input2); - CheckWithFlag(output1, input1, 0, true); + CheckWithFlag(output1, input1, SCRIPT_VERIFY_NONE, true); CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true); CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true); CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true); - CheckWithFlag(output1, input2, 0, true); + CheckWithFlag(output1, input2, SCRIPT_VERIFY_NONE, true); CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, true); CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false); CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false); @@ -650,11 +687,11 @@ BOOST_AUTO_TEST_CASE(test_witness) CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(destination_script_1)), output1, input1); CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(destination_script_2)), output2, input2); ReplaceRedeemScript(input2.vin[0].scriptSig, destination_script_1); - CheckWithFlag(output1, input1, 0, true); + CheckWithFlag(output1, input1, SCRIPT_VERIFY_NONE, true); CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true); CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true); CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true); - CheckWithFlag(output1, input2, 0, true); + CheckWithFlag(output1, input2, SCRIPT_VERIFY_NONE, true); CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, true); CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false); CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false); @@ -662,11 +699,11 @@ BOOST_AUTO_TEST_CASE(test_witness) // Normal pay-to-uncompressed-pubkey. CreateCreditAndSpend(keystore, scriptPubkey1L, output1, input1); CreateCreditAndSpend(keystore, scriptPubkey2L, output2, input2); - CheckWithFlag(output1, input1, 0, true); + CheckWithFlag(output1, input1, SCRIPT_VERIFY_NONE, true); CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true); CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true); CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true); - CheckWithFlag(output1, input2, 0, false); + CheckWithFlag(output1, input2, SCRIPT_VERIFY_NONE, false); CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, false); CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false); CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false); @@ -675,11 +712,11 @@ BOOST_AUTO_TEST_CASE(test_witness) CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(scriptPubkey1L)), output1, input1); CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(scriptPubkey2L)), output2, input2); ReplaceRedeemScript(input2.vin[0].scriptSig, scriptPubkey1L); - CheckWithFlag(output1, input1, 0, true); + CheckWithFlag(output1, input1, SCRIPT_VERIFY_NONE, true); CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true); CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true); CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true); - CheckWithFlag(output1, input2, 0, true); + CheckWithFlag(output1, input2, SCRIPT_VERIFY_NONE, true); CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, false); CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false); CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false); @@ -694,19 +731,19 @@ BOOST_AUTO_TEST_CASE(test_witness) // Normal 2-of-2 multisig CreateCreditAndSpend(keystore, scriptMulti, output1, input1, false); - CheckWithFlag(output1, input1, 0, false); + CheckWithFlag(output1, input1, SCRIPT_VERIFY_NONE, false); CreateCreditAndSpend(keystore2, scriptMulti, output2, input2, false); - CheckWithFlag(output2, input2, 0, false); + CheckWithFlag(output2, input2, SCRIPT_VERIFY_NONE, false); BOOST_CHECK(*output1 == *output2); UpdateInput(input1.vin[0], CombineSignatures(input1, input2, output1)); CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true); // P2SH 2-of-2 multisig CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(scriptMulti)), output1, input1, false); - CheckWithFlag(output1, input1, 0, true); + CheckWithFlag(output1, input1, SCRIPT_VERIFY_NONE, true); CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, false); CreateCreditAndSpend(keystore2, GetScriptForDestination(ScriptHash(scriptMulti)), output2, input2, false); - CheckWithFlag(output2, input2, 0, true); + CheckWithFlag(output2, input2, SCRIPT_VERIFY_NONE, true); CheckWithFlag(output2, input2, SCRIPT_VERIFY_P2SH, false); BOOST_CHECK(*output1 == *output2); UpdateInput(input1.vin[0], CombineSignatures(input1, input2, output1)); @@ -715,10 +752,10 @@ BOOST_AUTO_TEST_CASE(test_witness) // Witness 2-of-2 multisig CreateCreditAndSpend(keystore, destination_script_multi, output1, input1, false); - CheckWithFlag(output1, input1, 0, true); + CheckWithFlag(output1, input1, SCRIPT_VERIFY_NONE, true); CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false); CreateCreditAndSpend(keystore2, destination_script_multi, output2, input2, false); - CheckWithFlag(output2, input2, 0, true); + CheckWithFlag(output2, input2, SCRIPT_VERIFY_NONE, true); CheckWithFlag(output2, input2, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false); BOOST_CHECK(*output1 == *output2); UpdateInput(input1.vin[0], CombineSignatures(input1, input2, output1)); @@ -779,21 +816,21 @@ BOOST_AUTO_TEST_CASE(test_IsStandard) t.vout[0].nValue = nDustThreshold; CheckIsStandard(t); - // Disallowed nVersion - t.nVersion = -1; + // Disallowed version + t.version = std::numeric_limits<uint32_t>::max(); CheckIsNotStandard(t, "version"); - t.nVersion = 0; + t.version = 0; CheckIsNotStandard(t, "version"); - t.nVersion = TX_MAX_STANDARD_VERSION + 1; + t.version = TX_MAX_STANDARD_VERSION + 1; CheckIsNotStandard(t, "version"); - // Allowed nVersion - t.nVersion = 1; + // Allowed version + t.version = 1; CheckIsStandard(t); - t.nVersion = 2; + t.version = 2; CheckIsStandard(t); // Check dust with odd relay fee to verify rounding: @@ -904,15 +941,15 @@ BOOST_AUTO_TEST_CASE(test_IsStandard) t.vin.clear(); t.vin.resize(2438); // size per input (empty scriptSig): 41 bytes t.vout[0].scriptPubKey = CScript() << OP_RETURN << std::vector<unsigned char>(19, 0); // output size: 30 bytes - // tx header: 12 bytes => 48 vbytes - // 2438 inputs: 2438*41 = 99958 bytes => 399832 vbytes - // 1 output: 30 bytes => 120 vbytes - // =============================== - // total: 400000 vbytes + // tx header: 12 bytes => 48 weight units + // 2438 inputs: 2438*41 = 99958 bytes => 399832 weight units + // 1 output: 30 bytes => 120 weight units + // ====================================== + // total: 400000 weight units BOOST_CHECK_EQUAL(GetTransactionWeight(CTransaction(t)), 400000); CheckIsStandard(t); - // increase output size by one byte, so we end up with 400004 vbytes + // increase output size by one byte, so we end up with 400004 weight units t.vout[0].scriptPubKey = CScript() << OP_RETURN << std::vector<unsigned char>(20, 0); // output size: 31 bytes BOOST_CHECK_EQUAL(GetTransactionWeight(CTransaction(t)), 400004); CheckIsNotStandard(t, "tx-size"); diff --git a/src/test/txpackage_tests.cpp b/src/test/txpackage_tests.cpp index 8112f5f685..478121cc6f 100644 --- a/src/test/txpackage_tests.cpp +++ b/src/test/txpackage_tests.cpp @@ -6,6 +6,7 @@ #include <key_io.h> #include <policy/packages.h> #include <policy/policy.h> +#include <policy/rbf.h> #include <primitives/transaction.h> #include <script/script.h> #include <serialize.h> @@ -523,7 +524,7 @@ BOOST_FIXTURE_TEST_CASE(package_witness_swap_tests, TestChain100Setup) CKey child_key = GenerateRandomKey(); CScript child_locking_script = GetScriptForDestination(WitnessV0KeyHash(child_key.GetPubKey())); CMutableTransaction mtx_child1; - mtx_child1.nVersion = 1; + mtx_child1.version = 1; mtx_child1.vin.resize(1); mtx_child1.vin[0].prevout.hash = ptx_parent->GetHash(); mtx_child1.vin[0].prevout.n = 0; @@ -651,7 +652,7 @@ BOOST_FIXTURE_TEST_CASE(package_witness_swap_tests, TestChain100Setup) CTransactionRef ptx_grandparent2 = MakeTransactionRef(mtx_grandparent2); CMutableTransaction mtx_parent2_v1; - mtx_parent2_v1.nVersion = 1; + mtx_parent2_v1.version = 1; mtx_parent2_v1.vin.resize(1); mtx_parent2_v1.vin[0].prevout.hash = ptx_grandparent2->GetHash(); mtx_parent2_v1.vin[0].prevout.n = 0; @@ -679,7 +680,7 @@ BOOST_FIXTURE_TEST_CASE(package_witness_swap_tests, TestChain100Setup) CTransactionRef ptx_parent3 = MakeTransactionRef(mtx_parent3); package_mixed.push_back(ptx_parent3); BOOST_CHECK(m_node.mempool->GetMinFee().GetFee(GetVirtualTransactionSize(*ptx_parent3)) > low_fee_amt); - BOOST_CHECK(m_node.mempool->m_min_relay_feerate.GetFee(GetVirtualTransactionSize(*ptx_parent3)) <= low_fee_amt); + BOOST_CHECK(m_node.mempool->m_opts.min_relay_feerate.GetFee(GetVirtualTransactionSize(*ptx_parent3)) <= low_fee_amt); // child spends parent1, parent2, and parent3 CKey mixed_grandchild_key = GenerateRandomKey(); @@ -825,7 +826,7 @@ BOOST_FIXTURE_TEST_CASE(package_cpfp_tests, TestChain100Setup) CTransactionRef tx_parent_cheap = MakeTransactionRef(mtx_parent_cheap); package_still_too_low.push_back(tx_parent_cheap); BOOST_CHECK(m_node.mempool->GetMinFee().GetFee(GetVirtualTransactionSize(*tx_parent_cheap)) > parent_fee); - BOOST_CHECK(m_node.mempool->m_min_relay_feerate.GetFee(GetVirtualTransactionSize(*tx_parent_cheap)) <= parent_fee); + BOOST_CHECK(m_node.mempool->m_opts.min_relay_feerate.GetFee(GetVirtualTransactionSize(*tx_parent_cheap)) <= parent_fee); auto mtx_child_cheap = CreateValidMempoolTransaction(/*input_transaction=*/tx_parent_cheap, /*input_vout=*/0, /*input_height=*/101, /*input_signing_key=*/child_key, @@ -938,4 +939,147 @@ BOOST_FIXTURE_TEST_CASE(package_cpfp_tests, TestChain100Setup) BOOST_CHECK_EQUAL(m_node.mempool->size(), expected_pool_size); } } + +BOOST_FIXTURE_TEST_CASE(package_rbf_tests, TestChain100Setup) +{ + mineBlocks(5); + LOCK(::cs_main); + size_t expected_pool_size = m_node.mempool->size(); + CKey child_key{GenerateRandomKey()}; + CScript parent_spk = GetScriptForDestination(WitnessV0KeyHash(child_key.GetPubKey())); + CKey grandchild_key{GenerateRandomKey()}; + CScript child_spk = GetScriptForDestination(WitnessV0KeyHash(grandchild_key.GetPubKey())); + + const CAmount coinbase_value{50 * COIN}; + // Test that de-duplication works. This is not actually package rbf. + { + // 1 parent paying 200sat, 1 child paying 300sat + Package package1; + // 1 parent paying 200sat, 1 child paying 500sat + Package package2; + // Package1 and package2 have the same parent. The children conflict. + auto mtx_parent = CreateValidMempoolTransaction(/*input_transaction=*/m_coinbase_txns[0], /*input_vout=*/0, + /*input_height=*/0, /*input_signing_key=*/coinbaseKey, + /*output_destination=*/parent_spk, + /*output_amount=*/coinbase_value - low_fee_amt, /*submit=*/false); + CTransactionRef tx_parent = MakeTransactionRef(mtx_parent); + package1.push_back(tx_parent); + package2.push_back(tx_parent); + + CTransactionRef tx_child_1 = MakeTransactionRef(CreateValidMempoolTransaction(tx_parent, 0, 101, child_key, child_spk, coinbase_value - low_fee_amt - 300, false)); + package1.push_back(tx_child_1); + CTransactionRef tx_child_2 = MakeTransactionRef(CreateValidMempoolTransaction(tx_parent, 0, 101, child_key, child_spk, coinbase_value - low_fee_amt - 500, false)); + package2.push_back(tx_child_2); + + LOCK(m_node.mempool->cs); + const auto submit1 = ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, package1, /*test_accept=*/false, std::nullopt); + if (auto err_1{CheckPackageMempoolAcceptResult(package1, submit1, /*expect_valid=*/true, m_node.mempool.get())}) { + BOOST_ERROR(err_1.value()); + } + + // Check precise ResultTypes and mempool size. We know it_parent_1 and it_child_1 exist from above call + auto it_parent_1 = submit1.m_tx_results.find(tx_parent->GetWitnessHash()); + auto it_child_1 = submit1.m_tx_results.find(tx_child_1->GetWitnessHash()); + BOOST_CHECK_EQUAL(it_parent_1->second.m_result_type, MempoolAcceptResult::ResultType::VALID); + BOOST_CHECK_EQUAL(it_child_1->second.m_result_type, MempoolAcceptResult::ResultType::VALID); + expected_pool_size += 2; + BOOST_CHECK_EQUAL(m_node.mempool->size(), expected_pool_size); + + const auto submit2 = ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, package2, /*test_accept=*/false, std::nullopt); + if (auto err_2{CheckPackageMempoolAcceptResult(package2, submit2, /*expect_valid=*/true, m_node.mempool.get())}) { + BOOST_ERROR(err_2.value()); + } + + // Check precise ResultTypes and mempool size. We know it_parent_2 and it_child_2 exist from above call + auto it_parent_2 = submit2.m_tx_results.find(tx_parent->GetWitnessHash()); + auto it_child_2 = submit2.m_tx_results.find(tx_child_2->GetWitnessHash()); + BOOST_CHECK_EQUAL(it_parent_2->second.m_result_type, MempoolAcceptResult::ResultType::MEMPOOL_ENTRY); + BOOST_CHECK_EQUAL(it_child_2->second.m_result_type, MempoolAcceptResult::ResultType::VALID); + BOOST_CHECK_EQUAL(m_node.mempool->size(), expected_pool_size); + + // child1 has been replaced + BOOST_CHECK(!m_node.mempool->exists(GenTxid::Txid(tx_child_1->GetHash()))); + } + + // Test package rbf. + { + CTransactionRef tx_parent_1 = MakeTransactionRef(CreateValidMempoolTransaction( + m_coinbase_txns[1], /*input_vout=*/0, /*input_height=*/0, + coinbaseKey, parent_spk, coinbase_value - 200, /*submit=*/false)); + CTransactionRef tx_child_1 = MakeTransactionRef(CreateValidMempoolTransaction( + tx_parent_1, /*input_vout=*/0, /*input_height=*/101, + child_key, child_spk, coinbase_value - 400, /*submit=*/false)); + + CTransactionRef tx_parent_2 = MakeTransactionRef(CreateValidMempoolTransaction( + m_coinbase_txns[1], /*input_vout=*/0, /*input_height=*/0, + coinbaseKey, parent_spk, coinbase_value - 800, /*submit=*/false)); + CTransactionRef tx_child_2 = MakeTransactionRef(CreateValidMempoolTransaction( + tx_parent_2, /*input_vout=*/0, /*input_height=*/101, + child_key, child_spk, coinbase_value - 800 - 200, /*submit=*/false)); + + CTransactionRef tx_parent_3 = MakeTransactionRef(CreateValidMempoolTransaction( + m_coinbase_txns[1], /*input_vout=*/0, /*input_height=*/0, + coinbaseKey, parent_spk, coinbase_value - 199, /*submit=*/false)); + CTransactionRef tx_child_3 = MakeTransactionRef(CreateValidMempoolTransaction( + tx_parent_3, /*input_vout=*/0, /*input_height=*/101, + child_key, child_spk, coinbase_value - 199 - 1300, /*submit=*/false)); + + // In all packages, the parents conflict with each other + BOOST_CHECK(tx_parent_1->GetHash() != tx_parent_2->GetHash() && tx_parent_2->GetHash() != tx_parent_3->GetHash()); + + // 1 parent paying 200sat, 1 child paying 200sat. + Package package1{tx_parent_1, tx_child_1}; + // 1 parent paying 800sat, 1 child paying 200sat. + Package package2{tx_parent_2, tx_child_2}; + // 1 parent paying 199sat, 1 child paying 1300sat. + Package package3{tx_parent_3, tx_child_3}; + + const auto submit1 = ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, package1, false, std::nullopt); + if (auto err_1{CheckPackageMempoolAcceptResult(package1, submit1, /*expect_valid=*/true, m_node.mempool.get())}) { + BOOST_ERROR(err_1.value()); + } + auto it_parent_1 = submit1.m_tx_results.find(tx_parent_1->GetWitnessHash()); + auto it_child_1 = submit1.m_tx_results.find(tx_child_1->GetWitnessHash()); + BOOST_CHECK_EQUAL(it_parent_1->second.m_result_type, MempoolAcceptResult::ResultType::VALID); + BOOST_CHECK_EQUAL(it_child_1->second.m_result_type, MempoolAcceptResult::ResultType::VALID); + expected_pool_size += 2; + BOOST_CHECK_EQUAL(m_node.mempool->size(), expected_pool_size); + + // This replacement is actually not package rbf; the parent carries enough fees + // to replace the entire package on its own. + const auto submit2 = ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, package2, false, std::nullopt); + if (auto err_2{CheckPackageMempoolAcceptResult(package2, submit2, /*expect_valid=*/true, m_node.mempool.get())}) { + BOOST_ERROR(err_2.value()); + } + auto it_parent_2 = submit2.m_tx_results.find(tx_parent_2->GetWitnessHash()); + auto it_child_2 = submit2.m_tx_results.find(tx_child_2->GetWitnessHash()); + BOOST_CHECK_EQUAL(it_parent_2->second.m_result_type, MempoolAcceptResult::ResultType::VALID); + BOOST_CHECK_EQUAL(it_child_2->second.m_result_type, MempoolAcceptResult::ResultType::VALID); + BOOST_CHECK_EQUAL(m_node.mempool->size(), expected_pool_size); + + // Package RBF, in which the replacement transaction's child sponsors the fees to meet RBF feerate rules + const auto submit3 = ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, package3, false, std::nullopt); + if (auto err_3{CheckPackageMempoolAcceptResult(package3, submit3, /*expect_valid=*/true, m_node.mempool.get())}) { + BOOST_ERROR(err_3.value()); + } + auto it_parent_3 = submit3.m_tx_results.find(tx_parent_3->GetWitnessHash()); + auto it_child_3 = submit3.m_tx_results.find(tx_child_3->GetWitnessHash()); + BOOST_CHECK_EQUAL(it_parent_3->second.m_result_type, MempoolAcceptResult::ResultType::VALID); + BOOST_CHECK_EQUAL(it_child_3->second.m_result_type, MempoolAcceptResult::ResultType::VALID); + + // package3 was considered as a package to replace both package2 transactions + BOOST_CHECK(it_parent_3->second.m_replaced_transactions.size() == 2); + BOOST_CHECK(it_child_3->second.m_replaced_transactions.empty()); + + std::vector<Wtxid> expected_package3_wtxids({tx_parent_3->GetWitnessHash(), tx_child_3->GetWitnessHash()}); + const auto package3_total_vsize{GetVirtualTransactionSize(*tx_parent_3) + GetVirtualTransactionSize(*tx_child_3)}; + BOOST_CHECK(it_parent_3->second.m_wtxids_fee_calculations.value() == expected_package3_wtxids); + BOOST_CHECK(it_child_3->second.m_wtxids_fee_calculations.value() == expected_package3_wtxids); + BOOST_CHECK_EQUAL(it_parent_3->second.m_effective_feerate.value().GetFee(package3_total_vsize), 199 + 1300); + BOOST_CHECK_EQUAL(it_child_3->second.m_effective_feerate.value().GetFee(package3_total_vsize), 199 + 1300); + + BOOST_CHECK_EQUAL(m_node.mempool->size(), expected_pool_size); + } + +} BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/txvalidation_tests.cpp b/src/test/txvalidation_tests.cpp index 95583b53bf..f429f94a2f 100644 --- a/src/test/txvalidation_tests.cpp +++ b/src/test/txvalidation_tests.cpp @@ -27,7 +27,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_reject_coinbase, TestChain100Setup) CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG; CMutableTransaction coinbaseTx; - coinbaseTx.nVersion = 1; + coinbaseTx.version = 1; coinbaseTx.vin.resize(1); coinbaseTx.vout.resize(1); coinbaseTx.vin[0].scriptSig = CScript() << OP_11 << OP_EQUAL; @@ -72,11 +72,11 @@ static inline std::vector<CPubKey> random_keys(size_t num_keys) { return keys; } -// Creates a placeholder tx (not valid) with 25 outputs. Specify the nVersion and the inputs. +// Creates a placeholder tx (not valid) with 25 outputs. Specify the version and the inputs. static inline CTransactionRef make_tx(const std::vector<COutPoint>& inputs, int32_t version) { CMutableTransaction mtx = CMutableTransaction{}; - mtx.nVersion = version; + mtx.version = version; mtx.vin.resize(inputs.size()); mtx.vout.resize(25); for (size_t i{0}; i < inputs.size(); ++i) { @@ -286,7 +286,7 @@ BOOST_FIXTURE_TEST_CASE(version3_tests, RegTestingSetup) script_multisig << OP_2 << OP_CHECKMULTISIG; { CMutableTransaction mtx_many_sigops = CMutableTransaction{}; - mtx_many_sigops.nVersion = 3; + mtx_many_sigops.version = TRUC_VERSION; for (const auto& outpoint : multisig_outpoints) { mtx_many_sigops.vin.emplace_back(outpoint); mtx_many_sigops.vin.back().scriptWitness.stack.emplace_back(script_multisig.begin(), script_multisig.end()); diff --git a/src/test/txvalidationcache_tests.cpp b/src/test/txvalidationcache_tests.cpp index 790eabc7c1..78ef96a15d 100644 --- a/src/test/txvalidationcache_tests.cpp +++ b/src/test/txvalidationcache_tests.cpp @@ -46,7 +46,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, Dersig100Setup) spends.resize(2); for (int i = 0; i < 2; i++) { - spends[i].nVersion = 1; + spends[i].version = 1; spends[i].vin.resize(1); spends[i].vin[0].prevout.hash = m_coinbase_txns[0]->GetHash(); spends[i].vin[0].prevout.n = 0; @@ -181,7 +181,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, Dersig100Setup) // coinbase tx. CMutableTransaction spend_tx; - spend_tx.nVersion = 1; + spend_tx.version = 1; spend_tx.vin.resize(1); spend_tx.vin[0].prevout.hash = m_coinbase_txns[0]->GetHash(); spend_tx.vin[0].prevout.n = 0; @@ -243,7 +243,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, Dersig100Setup) // then test validity with P2SH. { CMutableTransaction invalid_under_p2sh_tx; - invalid_under_p2sh_tx.nVersion = 1; + invalid_under_p2sh_tx.version = 1; invalid_under_p2sh_tx.vin.resize(1); invalid_under_p2sh_tx.vin[0].prevout.hash = spend_tx.GetHash(); invalid_under_p2sh_tx.vin[0].prevout.n = 0; @@ -259,7 +259,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, Dersig100Setup) // Test CHECKLOCKTIMEVERIFY { CMutableTransaction invalid_with_cltv_tx; - invalid_with_cltv_tx.nVersion = 1; + invalid_with_cltv_tx.version = 1; invalid_with_cltv_tx.nLockTime = 100; invalid_with_cltv_tx.vin.resize(1); invalid_with_cltv_tx.vin[0].prevout.hash = spend_tx.GetHash(); @@ -288,7 +288,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, Dersig100Setup) // TEST CHECKSEQUENCEVERIFY { CMutableTransaction invalid_with_csv_tx; - invalid_with_csv_tx.nVersion = 2; + invalid_with_csv_tx.version = 2; invalid_with_csv_tx.vin.resize(1); invalid_with_csv_tx.vin[0].prevout.hash = spend_tx.GetHash(); invalid_with_csv_tx.vin[0].prevout.n = 3; @@ -319,7 +319,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, Dersig100Setup) // for the same tx with a different witness. { CMutableTransaction valid_with_witness_tx; - valid_with_witness_tx.nVersion = 1; + valid_with_witness_tx.version = 1; valid_with_witness_tx.vin.resize(1); valid_with_witness_tx.vin[0].prevout.hash = spend_tx.GetHash(); valid_with_witness_tx.vin[0].prevout.n = 1; @@ -344,7 +344,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, Dersig100Setup) // Test a transaction with multiple inputs. CMutableTransaction tx; - tx.nVersion = 1; + tx.version = 1; tx.vin.resize(2); tx.vin[0].prevout.hash = spend_tx.GetHash(); tx.vin[0].prevout.n = 0; diff --git a/src/test/uint256_tests.cpp b/src/test/uint256_tests.cpp index 5746961550..b7892a2139 100644 --- a/src/test/uint256_tests.cpp +++ b/src/test/uint256_tests.cpp @@ -267,6 +267,22 @@ BOOST_AUTO_TEST_CASE( conversion ) BOOST_AUTO_TEST_CASE( operator_with_self ) { + +/* Clang 16 and earlier detects v -= v and v /= v as self-assignments + to 0 and 1 respectively. + See: https://github.com/llvm/llvm-project/issues/42469 + and the fix in commit c5302325b2a62d77cf13dd16cd5c19141862fed0 . + + This makes some sense for arithmetic classes, but could be considered a bug + elsewhere. Disable the warning here so that the code can be tested, but the + warning should remain on as there will likely always be a better way to + express this. +*/ + +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wself-assign-overloaded" +#endif arith_uint256 v = UintToArith256(uint256S("02")); v *= v; BOOST_CHECK(v == UintToArith256(uint256S("04"))); @@ -276,6 +292,9 @@ BOOST_AUTO_TEST_CASE( operator_with_self ) BOOST_CHECK(v == UintToArith256(uint256S("02"))); v -= v; BOOST_CHECK(v == UintToArith256(uint256S("0"))); +#if defined(__clang__) +# pragma clang diagnostic pop +#endif } BOOST_AUTO_TEST_CASE(parse) diff --git a/src/test/util/chainstate.h b/src/test/util/chainstate.h index ff95e64b7e..03b44fc894 100644 --- a/src/test/util/chainstate.h +++ b/src/test/util/chainstate.h @@ -56,7 +56,7 @@ CreateAndActivateUTXOSnapshot( // FILE* infile{fsbridge::fopen(snapshot_path, "rb")}; AutoFile auto_infile{infile}; - node::SnapshotMetadata metadata; + node::SnapshotMetadata metadata{node.chainman->GetParams().MessageStart()}; auto_infile >> metadata; malleation(auto_infile, metadata); diff --git a/src/test/util/random.h b/src/test/util/random.h index c910bd6a3a..18ab425e48 100644 --- a/src/test/util/random.h +++ b/src/test/util/random.h @@ -14,9 +14,8 @@ /** * This global and the helpers that use it are not thread-safe. * - * If thread-safety is needed, the global could be made thread_local (given - * that thread_local is supported on all architectures we support) or a - * per-thread instance could be used in the multi-threaded test. + * If thread-safety is needed, a per-thread instance could be + * used in the multi-threaded test. */ extern FastRandomContext g_insecure_rand_ctx; diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index 0fb5e4eb45..cc7b2d6546 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -31,6 +31,7 @@ #include <node/miner.h> #include <node/peerman_args.h> #include <node/validation_cache_args.h> +#include <node/warnings.h> #include <noui.h> #include <policy/fees.h> #include <policy/fees_args.h> @@ -182,7 +183,9 @@ BasicTestingSetup::BasicTestingSetup(const ChainType chainType, const std::vecto InitLogging(*m_node.args); AppInitParameterInteraction(*m_node.args); LogInstance().StartLogging(); + m_node.warnings = std::make_unique<node::Warnings>(); m_node.kernel = std::make_unique<kernel::Context>(); + m_node.ecc_context = std::make_unique<ECC_Context>(); SetupEnvironment(); ValidationCacheSizes validation_cache_sizes{}; @@ -200,6 +203,7 @@ BasicTestingSetup::BasicTestingSetup(const ChainType chainType, const std::vecto BasicTestingSetup::~BasicTestingSetup() { + m_node.ecc_context.reset(); m_node.kernel.reset(); SetMockTime(0s); // Reset mocktime for following tests LogInstance().DisconnectTestLogger(); @@ -225,16 +229,19 @@ ChainTestingSetup::ChainTestingSetup(const ChainType chainType, const std::vecto m_node.validation_signals = std::make_unique<ValidationSignals>(std::make_unique<SerialTaskRunner>(*m_node.scheduler)); m_node.fee_estimator = std::make_unique<CBlockPolicyEstimator>(FeeestPath(*m_node.args), DEFAULT_ACCEPT_STALE_FEE_ESTIMATES); - m_node.mempool = std::make_unique<CTxMemPool>(MemPoolOptionsForTest(m_node)); + bilingual_str error{}; + m_node.mempool = std::make_unique<CTxMemPool>(MemPoolOptionsForTest(m_node), error); + Assert(error.empty()); + m_node.warnings = std::make_unique<node::Warnings>(); m_cache_sizes = CalculateCacheSizes(m_args); - m_node.notifications = std::make_unique<KernelNotifications>(*Assert(m_node.shutdown), m_node.exit_status); + m_node.notifications = std::make_unique<KernelNotifications>(*Assert(m_node.shutdown), m_node.exit_status, *Assert(m_node.warnings)); const ChainstateManager::Options chainman_opts{ .chainparams = chainparams, .datadir = m_args.GetDataDirNet(), - .check_block_index = true, + .check_block_index = 1, .notifications = *m_node.notifications, .signals = m_node.validation_signals.get(), .worker_threads_num = 2, @@ -274,8 +281,8 @@ void ChainTestingSetup::LoadVerifyActivateChainstate() options.mempool = Assert(m_node.mempool.get()); options.block_tree_db_in_memory = m_block_tree_db_in_memory; options.coins_db_in_memory = m_coins_db_in_memory; - options.reindex = node::fReindex; - options.reindex_chainstate = m_args.GetBoolArg("-reindex-chainstate", false); + options.wipe_block_tree_db = m_args.GetBoolArg("-reindex", false); + options.wipe_chainstate_db = m_args.GetBoolArg("-reindex", false) || m_args.GetBoolArg("-reindex-chainstate", false); options.prune = chainman.m_blockman.IsPruneMode(); options.check_blocks = m_args.GetIntArg("-checkblocks", DEFAULT_CHECKBLOCKS); options.check_level = m_args.GetIntArg("-checklevel", DEFAULT_CHECKLEVEL); @@ -318,7 +325,8 @@ TestingSetup::TestingSetup( peerman_opts.deterministic_rng = true; m_node.peerman = PeerManager::make(*m_node.connman, *m_node.addrman, m_node.banman.get(), *m_node.chainman, - *m_node.mempool, peerman_opts); + *m_node.mempool, *m_node.warnings, + peerman_opts); { CConnman::Options options; @@ -366,7 +374,8 @@ CBlock TestChain100Setup::CreateBlock( const CScript& scriptPubKey, Chainstate& chainstate) { - CBlock block = BlockAssembler{chainstate, nullptr}.CreateNewBlock(scriptPubKey)->block; + BlockAssembler::Options options; + CBlock block = BlockAssembler{chainstate, nullptr, options}.CreateNewBlock(scriptPubKey)->block; Assert(block.vtx.size() == 1); for (const CMutableTransaction& tx : txns) { @@ -550,9 +559,9 @@ void TestChain100Setup::MockMempoolMinFee(const CFeeRate& target_feerate) assert(m_node.mempool->size() == 0); // The target feerate cannot be too low... // ...otherwise the transaction's feerate will need to be negative. - assert(target_feerate > m_node.mempool->m_incremental_relay_feerate); + assert(target_feerate > m_node.mempool->m_opts.incremental_relay_feerate); // ...otherwise this is not meaningful. The feerate policy uses the maximum of both feerates. - assert(target_feerate > m_node.mempool->m_min_relay_feerate); + assert(target_feerate > m_node.mempool->m_opts.min_relay_feerate); // Manually create an invalid transaction. Manually set the fee in the CTxMemPoolEntry to // achieve the exact target feerate. @@ -563,7 +572,7 @@ void TestChain100Setup::MockMempoolMinFee(const CFeeRate& target_feerate) LockPoints lp; // The new mempool min feerate is equal to the removed package's feerate + incremental feerate. const auto tx_fee = target_feerate.GetFee(GetVirtualTransactionSize(*tx)) - - m_node.mempool->m_incremental_relay_feerate.GetFee(GetVirtualTransactionSize(*tx)); + m_node.mempool->m_opts.incremental_relay_feerate.GetFee(GetVirtualTransactionSize(*tx)); m_node.mempool->addUnchecked(CTxMemPoolEntry(tx, /*fee=*/tx_fee, /*time=*/0, /*entry_height=*/1, /*entry_sequence=*/0, /*spends_coinbase=*/true, /*sigops_cost=*/1, lp)); diff --git a/src/test/util/setup_common.h b/src/test/util/setup_common.h index 8ccf9b571c..dbd66e3585 100644 --- a/src/test/util/setup_common.h +++ b/src/test/util/setup_common.h @@ -6,6 +6,7 @@ #define BITCOIN_TEST_UTIL_SETUP_COMMON_H #include <common/args.h> // IWYU pragma: export +#include <kernel/context.h> #include <key.h> #include <node/caches.h> #include <node/context.h> // IWYU pragma: export @@ -15,6 +16,7 @@ #include <util/chaintype.h> // IWYU pragma: export #include <util/check.h> #include <util/fs.h> +#include <util/signalinterrupt.h> #include <util/string.h> #include <util/vector.h> diff --git a/src/test/util/transaction_utils.cpp b/src/test/util/transaction_utils.cpp index 7e5bb30a2c..300caa577c 100644 --- a/src/test/util/transaction_utils.cpp +++ b/src/test/util/transaction_utils.cpp @@ -9,7 +9,7 @@ CMutableTransaction BuildCreditingTransaction(const CScript& scriptPubKey, int nValue) { CMutableTransaction txCredit; - txCredit.nVersion = 1; + txCredit.version = 1; txCredit.nLockTime = 0; txCredit.vin.resize(1); txCredit.vout.resize(1); @@ -25,7 +25,7 @@ CMutableTransaction BuildCreditingTransaction(const CScript& scriptPubKey, int n CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CScriptWitness& scriptWitness, const CTransaction& txCredit) { CMutableTransaction txSpend; - txSpend.nVersion = 1; + txSpend.version = 1; txSpend.nLockTime = 0; txSpend.vin.resize(1); txSpend.vout.resize(1); diff --git a/src/test/util/txmempool.cpp b/src/test/util/txmempool.cpp index 870cdd0b32..94d50bba50 100644 --- a/src/test/util/txmempool.cpp +++ b/src/test/util/txmempool.cpp @@ -7,6 +7,7 @@ #include <chainparams.h> #include <node/context.h> #include <node/mempool_args.h> +#include <policy/rbf.h> #include <policy/v3_policy.h> #include <txmempool.h> #include <util/check.h> @@ -68,6 +69,28 @@ std::optional<std::string> CheckPackageMempoolAcceptResult(const Package& txns, return strprintf("tx %s unexpectedly failed: %s", wtxid.ToString(), atmp_result.m_state.ToString()); } + // Each subpackage is allowed MAX_REPLACEMENT_CANDIDATES replacements (only checking individually here) + if (atmp_result.m_replaced_transactions.size() > MAX_REPLACEMENT_CANDIDATES) { + return strprintf("tx %s result replaced too many transactions", + wtxid.ToString()); + } + + // Replacements can't happen for subpackages larger than 2 + if (!atmp_result.m_replaced_transactions.empty() && + atmp_result.m_wtxids_fee_calculations.has_value() && atmp_result.m_wtxids_fee_calculations.value().size() > 2) { + return strprintf("tx %s was part of a too-large package RBF subpackage", + wtxid.ToString()); + } + + if (!atmp_result.m_replaced_transactions.empty() && mempool) { + LOCK(mempool->cs); + // If replacements occurred and it used 2 transactions, this is a package RBF and should result in a cluster of size 2 + if (atmp_result.m_wtxids_fee_calculations.has_value() && atmp_result.m_wtxids_fee_calculations.value().size() == 2) { + const auto cluster = mempool->GatherClusters({tx->GetHash()}); + if (cluster.size() != 2) return strprintf("tx %s has too many ancestors or descendants for a package rbf", wtxid.ToString()); + } + } + // m_vsize and m_base_fees should exist iff the result was VALID or MEMPOOL_ENTRY const bool mempool_entry{atmp_result.m_result_type == MempoolAcceptResult::ResultType::MEMPOOL_ENTRY}; if (atmp_result.m_base_fees.has_value() != (valid || mempool_entry)) { @@ -108,6 +131,11 @@ std::optional<std::string> CheckPackageMempoolAcceptResult(const Package& txns, return strprintf("wtxid %s should not be in mempool", wtxid.ToString()); } } + for (const auto& tx_ref : atmp_result.m_replaced_transactions) { + if (mempool->exists(GenTxid::Txid(tx_ref->GetHash()))) { + return strprintf("tx %s should not be in mempool as it was replaced", tx_ref->GetWitnessHash().ToString()); + } + } } } return std::nullopt; @@ -118,21 +146,27 @@ void CheckMempoolV3Invariants(const CTxMemPool& tx_pool) LOCK(tx_pool.cs); for (const auto& tx_info : tx_pool.infoAll()) { const auto& entry = *Assert(tx_pool.GetEntry(tx_info.tx->GetHash())); - if (tx_info.tx->nVersion == 3) { + if (tx_info.tx->version == TRUC_VERSION) { + // Check that special maximum virtual size is respected + Assert(entry.GetTxSize() <= V3_MAX_VSIZE); + // Check that special v3 ancestor/descendant limits and rules are always respected Assert(entry.GetCountWithDescendants() <= V3_DESCENDANT_LIMIT); Assert(entry.GetCountWithAncestors() <= V3_ANCESTOR_LIMIT); + Assert(entry.GetSizeWithDescendants() <= V3_MAX_VSIZE + V3_CHILD_MAX_VSIZE); + Assert(entry.GetSizeWithAncestors() <= V3_MAX_VSIZE + V3_CHILD_MAX_VSIZE); + // If this transaction has at least 1 ancestor, it's a "child" and has restricted weight. if (entry.GetCountWithAncestors() > 1) { Assert(entry.GetTxSize() <= V3_CHILD_MAX_VSIZE); // All v3 transactions must only have v3 unconfirmed parents. const auto& parents = entry.GetMemPoolParentsConst(); - Assert(parents.begin()->get().GetSharedTx()->nVersion == 3); + Assert(parents.begin()->get().GetSharedTx()->version == TRUC_VERSION); } } else if (entry.GetCountWithAncestors() > 1) { // All non-v3 transactions must only have non-v3 unconfirmed parents. for (const auto& parent : entry.GetMemPoolParentsConst()) { - Assert(parent.get().GetSharedTx()->nVersion != 3); + Assert(parent.get().GetSharedTx()->version != TRUC_VERSION); } } } diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 9a2add748e..a371753adf 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -3,8 +3,10 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <clientversion.h> +#include <common/signmessage.h> // For MessageSign(), MessageVerify(), MESSAGE_MAGIC #include <hash.h> // For Hash() #include <key.h> // For CKey +#include <script/parsing.h> #include <sync.h> #include <test/util/random.h> #include <test/util/setup_common.h> @@ -12,11 +14,9 @@ #include <util/bitdeque.h> #include <util/fs.h> #include <util/fs_helpers.h> -#include <util/message.h> // For MessageSign(), MessageVerify(), MESSAGE_MAGIC #include <util/moneystr.h> #include <util/overflow.h> #include <util/readwritefile.h> -#include <util/spanparsing.h> #include <util/strencodings.h> #include <util/string.h> #include <util/time.h> @@ -45,6 +45,15 @@ #include <boost/test/unit_test.hpp> using namespace std::literals; +using util::Join; +using util::RemovePrefix; +using util::RemovePrefixView; +using util::ReplaceAll; +using util::Split; +using util::SplitString; +using util::TrimString; +using util::TrimStringView; + static const std::string STRING_WITH_EMBEDDED_NULL_CHAR{"1"s "\0" "1"s}; /* defined in logging.cpp */ @@ -1292,9 +1301,9 @@ static std::string SpanToStr(const Span<const char>& span) return std::string(span.begin(), span.end()); } -BOOST_AUTO_TEST_CASE(test_spanparsing) +BOOST_AUTO_TEST_CASE(test_script_parsing) { - using namespace spanparsing; + using namespace script; std::string input; Span<const char> sp; bool success; diff --git a/src/test/util_threadnames_tests.cpp b/src/test/util_threadnames_tests.cpp index df5b1a4461..efa0b2736b 100644 --- a/src/test/util_threadnames_tests.cpp +++ b/src/test/util_threadnames_tests.cpp @@ -11,10 +11,10 @@ #include <thread> #include <vector> -#include <config/bitcoin-config.h> // IWYU pragma: keep - #include <boost/test/unit_test.hpp> +using util::ToString; + BOOST_AUTO_TEST_SUITE(util_threadnames_tests) const std::string TEST_THREAD_NAME_BASE = "test_thread."; @@ -52,11 +52,6 @@ std::set<std::string> RenameEnMasse(int num_threads) */ BOOST_AUTO_TEST_CASE(util_threadnames_test_rename_threaded) { -#if !defined(HAVE_THREAD_LOCAL) - // This test doesn't apply to platforms where we don't have thread_local. - return; -#endif - std::set<std::string> names = RenameEnMasse(100); BOOST_CHECK_EQUAL(names.size(), 100U); diff --git a/src/test/validation_block_tests.cpp b/src/test/validation_block_tests.cpp index 69f4e305ab..588ac60498 100644 --- a/src/test/validation_block_tests.cpp +++ b/src/test/validation_block_tests.cpp @@ -65,7 +65,8 @@ std::shared_ptr<CBlock> MinerTestingSetup::Block(const uint256& prev_hash) static int i = 0; static uint64_t time = Params().GenesisBlock().nTime; - auto ptemplate = BlockAssembler{m_node.chainman->ActiveChainstate(), m_node.mempool.get()}.CreateNewBlock(CScript{} << i++ << OP_TRUE); + BlockAssembler::Options options; + auto ptemplate = BlockAssembler{m_node.chainman->ActiveChainstate(), m_node.mempool.get(), options}.CreateNewBlock(CScript{} << i++ << OP_TRUE); auto pblock = std::make_shared<CBlock>(ptemplate->block); pblock->hashPrevBlock = prev_hash; pblock->nTime = ++time; @@ -329,7 +330,8 @@ BOOST_AUTO_TEST_CASE(witness_commitment_index) LOCK(Assert(m_node.chainman)->GetMutex()); CScript pubKey; pubKey << 1 << OP_TRUE; - auto ptemplate = BlockAssembler{m_node.chainman->ActiveChainstate(), m_node.mempool.get()}.CreateNewBlock(pubKey); + BlockAssembler::Options options; + auto ptemplate = BlockAssembler{m_node.chainman->ActiveChainstate(), m_node.mempool.get(), options}.CreateNewBlock(pubKey); CBlock pblock = ptemplate->block; CTxOut witness; diff --git a/src/test/validation_chainstatemanager_tests.cpp b/src/test/validation_chainstatemanager_tests.cpp index 4bf66a55eb..1641c4cd22 100644 --- a/src/test/validation_chainstatemanager_tests.cpp +++ b/src/test/validation_chainstatemanager_tests.cpp @@ -226,10 +226,13 @@ struct SnapshotTestSetup : TestChain100Setup { // A UTXO is missing but count is correct metadata.m_coins_count -= 1; - COutPoint outpoint; + Txid txid; + auto_infile >> txid; + // coins size + (void)ReadCompactSize(auto_infile); + // vout index + (void)ReadCompactSize(auto_infile); Coin coin; - - auto_infile >> outpoint; auto_infile >> coin; })); @@ -375,7 +378,7 @@ struct SnapshotTestSetup : TestChain100Setup { LOCK(::cs_main); chainman.ResetChainstates(); BOOST_CHECK_EQUAL(chainman.GetAll().size(), 0); - m_node.notifications = std::make_unique<KernelNotifications>(*Assert(m_node.shutdown), m_node.exit_status); + m_node.notifications = std::make_unique<KernelNotifications>(*Assert(m_node.shutdown), m_node.exit_status, *Assert(m_node.warnings)); const ChainstateManager::Options chainman_opts{ .chainparams = ::Params(), .datadir = chainman.m_options.datadir, diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 442c1c4d42..4f79644c8d 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -42,6 +42,10 @@ #include <event2/thread.h> #include <event2/util.h> +using util::ReplaceAll; +using util::SplitString; +using util::ToString; + /** Default control ip and port */ const std::string DEFAULT_TOR_CONTROL = "127.0.0.1:" + ToString(DEFAULT_TOR_CONTROL_PORT); /** Tor cookie size (from control-spec.txt) */ diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 06066e38b2..10674c07ac 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -16,6 +16,7 @@ #include <policy/settings.h> #include <random.h> #include <reverse_iterator.h> +#include <tinyformat.h> #include <util/check.h> #include <util/feefrac.h> #include <util/moneystr.h> @@ -26,6 +27,7 @@ #include <util/translation.h> #include <validationinterface.h> +#include <algorithm> #include <cmath> #include <numeric> #include <optional> @@ -92,7 +94,7 @@ void CTxMemPool::UpdateForDescendants(txiter updateIt, cacheMap& cachedDescendan // Don't directly remove the transaction here -- doing so would // invalidate iterators in cachedDescendants. Mark it for removal // by inserting into descendants_to_remove. - if (descendant.GetCountWithAncestors() > uint64_t(m_limits.ancestor_count) || descendant.GetSizeWithAncestors() > m_limits.ancestor_size_vbytes) { + if (descendant.GetCountWithAncestors() > uint64_t(m_opts.limits.ancestor_count) || descendant.GetSizeWithAncestors() > m_opts.limits.ancestor_size_vbytes) { descendants_to_remove.insert(descendant.GetTx().GetHash()); } } @@ -203,14 +205,14 @@ util::Result<void> CTxMemPool::CheckPackageLimits(const Package& package, size_t pack_count = package.size(); // Package itself is busting mempool limits; should be rejected even if no staged_ancestors exist - if (pack_count > static_cast<uint64_t>(m_limits.ancestor_count)) { - return util::Error{Untranslated(strprintf("package count %u exceeds ancestor count limit [limit: %u]", pack_count, m_limits.ancestor_count))}; - } else if (pack_count > static_cast<uint64_t>(m_limits.descendant_count)) { - return util::Error{Untranslated(strprintf("package count %u exceeds descendant count limit [limit: %u]", pack_count, m_limits.descendant_count))}; - } else if (total_vsize > m_limits.ancestor_size_vbytes) { - return util::Error{Untranslated(strprintf("package size %u exceeds ancestor size limit [limit: %u]", total_vsize, m_limits.ancestor_size_vbytes))}; - } else if (total_vsize > m_limits.descendant_size_vbytes) { - return util::Error{Untranslated(strprintf("package size %u exceeds descendant size limit [limit: %u]", total_vsize, m_limits.descendant_size_vbytes))}; + if (pack_count > static_cast<uint64_t>(m_opts.limits.ancestor_count)) { + return util::Error{Untranslated(strprintf("package count %u exceeds ancestor count limit [limit: %u]", pack_count, m_opts.limits.ancestor_count))}; + } else if (pack_count > static_cast<uint64_t>(m_opts.limits.descendant_count)) { + return util::Error{Untranslated(strprintf("package count %u exceeds descendant count limit [limit: %u]", pack_count, m_opts.limits.descendant_count))}; + } else if (total_vsize > m_opts.limits.ancestor_size_vbytes) { + return util::Error{Untranslated(strprintf("package size %u exceeds ancestor size limit [limit: %u]", total_vsize, m_opts.limits.ancestor_size_vbytes))}; + } else if (total_vsize > m_opts.limits.descendant_size_vbytes) { + return util::Error{Untranslated(strprintf("package size %u exceeds descendant size limit [limit: %u]", total_vsize, m_opts.limits.descendant_size_vbytes))}; } CTxMemPoolEntry::Parents staged_ancestors; @@ -219,8 +221,8 @@ util::Result<void> CTxMemPool::CheckPackageLimits(const Package& package, std::optional<txiter> piter = GetIter(input.prevout.hash); if (piter) { staged_ancestors.insert(**piter); - if (staged_ancestors.size() + package.size() > static_cast<uint64_t>(m_limits.ancestor_count)) { - return util::Error{Untranslated(strprintf("too many unconfirmed parents [limit: %u]", m_limits.ancestor_count))}; + if (staged_ancestors.size() + package.size() > static_cast<uint64_t>(m_opts.limits.ancestor_count)) { + return util::Error{Untranslated(strprintf("too many unconfirmed parents [limit: %u]", m_opts.limits.ancestor_count))}; } } } @@ -229,7 +231,7 @@ util::Result<void> CTxMemPool::CheckPackageLimits(const Package& package, // considered together must be within limits even if they are not interdependent. This may be // stricter than the limits for each individual transaction. const auto ancestors{CalculateAncestorsAndCheckLimits(total_vsize, package.size(), - staged_ancestors, m_limits)}; + staged_ancestors, m_opts.limits)}; // It's possible to overestimate the ancestor/descendant totals. if (!ancestors.has_value()) return util::Error{Untranslated("possibly " + util::ErrorString(ancestors).original)}; return {}; @@ -395,20 +397,19 @@ void CTxMemPoolEntry::UpdateAncestorState(int32_t modifySize, CAmount modifyFee, assert(int(nSigOpCostWithAncestors) >= 0); } -CTxMemPool::CTxMemPool(const Options& opts) - : m_check_ratio{opts.check_ratio}, - m_max_size_bytes{opts.max_size_bytes}, - m_expiry{opts.expiry}, - m_incremental_relay_feerate{opts.incremental_relay_feerate}, - m_min_relay_feerate{opts.min_relay_feerate}, - m_dust_relay_feerate{opts.dust_relay_feerate}, - m_permit_bare_multisig{opts.permit_bare_multisig}, - m_max_datacarrier_bytes{opts.max_datacarrier_bytes}, - m_require_standard{opts.require_standard}, - m_full_rbf{opts.full_rbf}, - m_persist_v1_dat{opts.persist_v1_dat}, - m_limits{opts.limits}, - m_signals{opts.signals} +//! Clamp option values and populate the error if options are not valid. +static CTxMemPool::Options&& Flatten(CTxMemPool::Options&& opts, bilingual_str& error) +{ + opts.check_ratio = std::clamp<int>(opts.check_ratio, 0, 1'000'000); + int64_t descendant_limit_bytes = opts.limits.descendant_size_vbytes * 40; + if (opts.max_size_bytes < 0 || opts.max_size_bytes < descendant_limit_bytes) { + error = strprintf(_("-maxmempool must be at least %d MB"), std::ceil(descendant_limit_bytes / 1'000'000.0)); + } + return std::move(opts); +} + +CTxMemPool::CTxMemPool(Options opts, bilingual_str& error) + : m_opts{Flatten(std::move(opts), error)} { } @@ -489,12 +490,12 @@ void CTxMemPool::removeUnchecked(txiter it, MemPoolRemovalReason reason) // even if not directly reported below. uint64_t mempool_sequence = GetAndIncrementSequence(); - if (reason != MemPoolRemovalReason::BLOCK && m_signals) { + if (reason != MemPoolRemovalReason::BLOCK && m_opts.signals) { // Notify clients that a transaction has been removed from the mempool // for any reason except being included in a block. Clients interested // in transactions included in blocks can subscribe to the BlockConnected // notification. - m_signals->TransactionRemovedFromMempool(it->GetSharedTx(), reason, mempool_sequence); + m_opts.signals->TransactionRemovedFromMempool(it->GetSharedTx(), reason, mempool_sequence); } TRACE5(mempool, removed, it->GetTx().GetHash().data(), @@ -645,8 +646,8 @@ void CTxMemPool::removeForBlock(const std::vector<CTransactionRef>& vtx, unsigne removeConflicts(*tx); ClearPrioritisation(tx->GetHash()); } - if (m_signals) { - m_signals->MempoolTransactionsRemovedForBlock(txs_removed_for_block, nBlockHeight); + if (m_opts.signals) { + m_opts.signals->MempoolTransactionsRemovedForBlock(txs_removed_for_block, nBlockHeight); } lastRollingFeeUpdate = GetTime(); blockSinceLastRollingFeeBump = true; @@ -654,9 +655,9 @@ void CTxMemPool::removeForBlock(const std::vector<CTransactionRef>& vtx, unsigne void CTxMemPool::check(const CCoinsViewCache& active_coins_tip, int64_t spendheight) const { - if (m_check_ratio == 0) return; + if (m_opts.check_ratio == 0) return; - if (GetRand(m_check_ratio) >= 1) return; + if (GetRand(m_opts.check_ratio) >= 1) return; AssertLockHeld(::cs_main); LOCK(cs); @@ -1108,12 +1109,12 @@ CFeeRate CTxMemPool::GetMinFee(size_t sizelimit) const { rollingMinimumFeeRate = rollingMinimumFeeRate / pow(2.0, (time - lastRollingFeeUpdate) / halflife); lastRollingFeeUpdate = time; - if (rollingMinimumFeeRate < (double)m_incremental_relay_feerate.GetFeePerK() / 2) { + if (rollingMinimumFeeRate < (double)m_opts.incremental_relay_feerate.GetFeePerK() / 2) { rollingMinimumFeeRate = 0; return CFeeRate(0); } } - return std::max(CFeeRate(llround(rollingMinimumFeeRate)), m_incremental_relay_feerate); + return std::max(CFeeRate(llround(rollingMinimumFeeRate)), m_opts.incremental_relay_feerate); } void CTxMemPool::trackPackageRemoved(const CFeeRate& rate) { @@ -1137,7 +1138,7 @@ void CTxMemPool::TrimToSize(size_t sizelimit, std::vector<COutPoint>* pvNoSpends // to have 0 fee). This way, we don't allow txn to enter mempool with feerate // equal to txn which were removed with no block in between. CFeeRate removed(it->GetModFeesWithDescendants(), it->GetSizeWithDescendants()); - removed += m_incremental_relay_feerate; + removed += m_opts.incremental_relay_feerate; trackPackageRemoved(removed); maxFeeRateRemoved = std::max(maxFeeRateRemoved, removed); diff --git a/src/txmempool.h b/src/txmempool.h index 52a3dc2d7d..52f186f0ff 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -43,6 +43,8 @@ class CChain; class ValidationSignals; +struct bilingual_str; + /** Fake height value used in Coin to signify they are only in the memory pool (since 0.8) */ static const uint32_t MEMPOOL_HEIGHT = 0x7FFFFFFF; @@ -301,7 +303,6 @@ struct TxMempoolInfo class CTxMemPool { protected: - const int m_check_ratio; //!< Value n means that 1 times in n we check. std::atomic<unsigned int> nTransactionsUpdated{0}; //!< Used by getblocktemplate to trigger CreateNewBlock() invocation uint64_t totalTxSize GUARDED_BY(cs){0}; //!< sum of all mempool tx's virtual sizes. Differs from serialized tx size since witness data is discounted. Defined in BIP 141. @@ -436,27 +437,14 @@ public: using Options = kernel::MemPoolOptions; - const int64_t m_max_size_bytes; - const std::chrono::seconds m_expiry; - const CFeeRate m_incremental_relay_feerate; - const CFeeRate m_min_relay_feerate; - const CFeeRate m_dust_relay_feerate; - const bool m_permit_bare_multisig; - const std::optional<unsigned> m_max_datacarrier_bytes; - const bool m_require_standard; - const bool m_full_rbf; - const bool m_persist_v1_dat; - - const Limits m_limits; - - ValidationSignals* const m_signals; + const Options m_opts; /** Create a new CTxMemPool. * Sanity checks will be off by default for performance, because otherwise * accepting transactions becomes O(N^2) where N is the number of transactions * in the pool. */ - explicit CTxMemPool(const Options& opts); + explicit CTxMemPool(Options opts, bilingual_str& error); /** * If sanity-checking is turned on, check makes sure the pool is @@ -625,7 +613,7 @@ public: * would otherwise be half of this, it is set to 0 instead. */ CFeeRate GetMinFee() const { - return GetMinFee(m_max_size_bytes); + return GetMinFee(m_opts.max_size_bytes); } /** Remove transactions from the mempool until its dynamic size is <= sizelimit. diff --git a/src/txorphanage.cpp b/src/txorphanage.cpp index 92055ded72..3eaf53939d 100644 --- a/src/txorphanage.cpp +++ b/src/txorphanage.cpp @@ -8,13 +8,14 @@ #include <logging.h> #include <policy/policy.h> #include <primitives/transaction.h> +#include <util/time.h> #include <cassert> -/** Expiration time for orphan transactions in seconds */ -static constexpr int64_t ORPHAN_TX_EXPIRE_TIME = 20 * 60; -/** Minimum time between orphan transactions expire time checks in seconds */ -static constexpr int64_t ORPHAN_TX_EXPIRE_INTERVAL = 5 * 60; +/** Expiration time for orphan transactions */ +static constexpr auto ORPHAN_TX_EXPIRE_TIME{20min}; +/** Minimum time between orphan transactions expire time checks */ +static constexpr auto ORPHAN_TX_EXPIRE_INTERVAL{5min}; bool TxOrphanage::AddTx(const CTransactionRef& tx, NodeId peer) @@ -23,7 +24,7 @@ bool TxOrphanage::AddTx(const CTransactionRef& tx, NodeId peer) const Txid& hash = tx->GetHash(); const Wtxid& wtxid = tx->GetWitnessHash(); - if (m_orphans.count(hash)) + if (m_orphans.count(wtxid)) return false; // Ignore big transactions, to avoid a @@ -40,30 +41,28 @@ bool TxOrphanage::AddTx(const CTransactionRef& tx, NodeId peer) return false; } - auto ret = m_orphans.emplace(hash, OrphanTx{tx, peer, GetTime() + ORPHAN_TX_EXPIRE_TIME, m_orphan_list.size()}); + auto ret = m_orphans.emplace(wtxid, OrphanTx{tx, peer, Now<NodeSeconds>() + ORPHAN_TX_EXPIRE_TIME, m_orphan_list.size()}); assert(ret.second); m_orphan_list.push_back(ret.first); - // Allow for lookups in the orphan pool by wtxid, as well as txid - m_wtxid_to_orphan_it.emplace(tx->GetWitnessHash(), ret.first); for (const CTxIn& txin : tx->vin) { m_outpoint_to_orphan_it[txin.prevout].insert(ret.first); } - LogPrint(BCLog::TXPACKAGES, "stored orphan tx %s (wtxid=%s) (mapsz %u outsz %u)\n", hash.ToString(), wtxid.ToString(), + LogPrint(BCLog::TXPACKAGES, "stored orphan tx %s (wtxid=%s), weight: %u (mapsz %u outsz %u)\n", hash.ToString(), wtxid.ToString(), sz, m_orphans.size(), m_outpoint_to_orphan_it.size()); return true; } -int TxOrphanage::EraseTx(const Txid& txid) +int TxOrphanage::EraseTx(const Wtxid& wtxid) { LOCK(m_mutex); - return EraseTxNoLock(txid); + return EraseTxNoLock(wtxid); } -int TxOrphanage::EraseTxNoLock(const Txid& txid) +int TxOrphanage::EraseTxNoLock(const Wtxid& wtxid) { AssertLockHeld(m_mutex); - std::map<Txid, OrphanTx>::iterator it = m_orphans.find(txid); + std::map<Wtxid, OrphanTx>::iterator it = m_orphans.find(wtxid); if (it == m_orphans.end()) return 0; for (const CTxIn& txin : it->second.tx->vin) @@ -85,10 +84,12 @@ int TxOrphanage::EraseTxNoLock(const Txid& txid) m_orphan_list[old_pos] = it_last; it_last->second.list_pos = old_pos; } - const auto& wtxid = it->second.tx->GetWitnessHash(); - LogPrint(BCLog::TXPACKAGES, " removed orphan tx %s (wtxid=%s)\n", txid.ToString(), wtxid.ToString()); + const auto& txid = it->second.tx->GetHash(); + // Time spent in orphanage = difference between current and entry time. + // Entry time is equal to ORPHAN_TX_EXPIRE_TIME earlier than entry's expiry. + LogPrint(BCLog::TXPACKAGES, " removed orphan tx %s (wtxid=%s) after %ds\n", txid.ToString(), wtxid.ToString(), + Ticks<std::chrono::seconds>(NodeClock::now() + ORPHAN_TX_EXPIRE_TIME - it->second.nTimeExpire)); m_orphan_list.pop_back(); - m_wtxid_to_orphan_it.erase(it->second.tx->GetWitnessHash()); m_orphans.erase(it); return 1; @@ -101,16 +102,16 @@ void TxOrphanage::EraseForPeer(NodeId peer) m_peer_work_set.erase(peer); int nErased = 0; - std::map<Txid, OrphanTx>::iterator iter = m_orphans.begin(); + std::map<Wtxid, OrphanTx>::iterator iter = m_orphans.begin(); while (iter != m_orphans.end()) { - std::map<Txid, OrphanTx>::iterator maybeErase = iter++; // increment to avoid iterator becoming invalid - if (maybeErase->second.fromPeer == peer) - { - nErased += EraseTxNoLock(maybeErase->second.tx->GetHash()); + // increment to avoid iterator becoming invalid after erasure + const auto& [wtxid, orphan] = *iter++; + if (orphan.fromPeer == peer) { + nErased += EraseTxNoLock(wtxid); } } - if (nErased > 0) LogPrint(BCLog::TXPACKAGES, "Erased %d orphan tx from peer=%d\n", nErased, peer); + if (nErased > 0) LogPrint(BCLog::TXPACKAGES, "Erased %d orphan transaction(s) from peer=%d\n", nErased, peer); } void TxOrphanage::LimitOrphans(unsigned int max_orphans, FastRandomContext& rng) @@ -118,31 +119,30 @@ void TxOrphanage::LimitOrphans(unsigned int max_orphans, FastRandomContext& rng) LOCK(m_mutex); unsigned int nEvicted = 0; - static int64_t nNextSweep; - int64_t nNow = GetTime(); - if (nNextSweep <= nNow) { + auto nNow{Now<NodeSeconds>()}; + if (m_next_sweep <= nNow) { // Sweep out expired orphan pool entries: int nErased = 0; - int64_t nMinExpTime = nNow + ORPHAN_TX_EXPIRE_TIME - ORPHAN_TX_EXPIRE_INTERVAL; - std::map<Txid, OrphanTx>::iterator iter = m_orphans.begin(); + auto nMinExpTime{nNow + ORPHAN_TX_EXPIRE_TIME - ORPHAN_TX_EXPIRE_INTERVAL}; + std::map<Wtxid, OrphanTx>::iterator iter = m_orphans.begin(); while (iter != m_orphans.end()) { - std::map<Txid, OrphanTx>::iterator maybeErase = iter++; + std::map<Wtxid, OrphanTx>::iterator maybeErase = iter++; if (maybeErase->second.nTimeExpire <= nNow) { - nErased += EraseTxNoLock(maybeErase->second.tx->GetHash()); + nErased += EraseTxNoLock(maybeErase->second.tx->GetWitnessHash()); } else { nMinExpTime = std::min(maybeErase->second.nTimeExpire, nMinExpTime); } } // Sweep again 5 minutes after the next entry that expires in order to batch the linear scan. - nNextSweep = nMinExpTime + ORPHAN_TX_EXPIRE_INTERVAL; + m_next_sweep = nMinExpTime + ORPHAN_TX_EXPIRE_INTERVAL; if (nErased > 0) LogPrint(BCLog::TXPACKAGES, "Erased %d orphan tx due to expiration\n", nErased); } while (m_orphans.size() > max_orphans) { // Evict a random orphan: size_t randompos = rng.randrange(m_orphan_list.size()); - EraseTxNoLock(m_orphan_list[randompos]->first); + EraseTxNoLock(m_orphan_list[randompos]->second.tx->GetWitnessHash()); ++nEvicted; } if (nEvicted > 0) LogPrint(BCLog::TXPACKAGES, "orphanage overflow, removed %u tx\n", nEvicted); @@ -159,7 +159,7 @@ void TxOrphanage::AddChildrenToWorkSet(const CTransaction& tx) for (const auto& elem : it_by_prev->second) { // Get this source peer's work set, emplacing an empty set if it didn't exist // (note: if this peer wasn't still connected, we would have removed the orphan tx already) - std::set<Txid>& orphan_work_set = m_peer_work_set.try_emplace(elem->second.fromPeer).first->second; + std::set<Wtxid>& orphan_work_set = m_peer_work_set.try_emplace(elem->second.fromPeer).first->second; // Add this tx to the work set orphan_work_set.insert(elem->first); LogPrint(BCLog::TXPACKAGES, "added %s (wtxid=%s) to peer %d workset\n", @@ -169,14 +169,10 @@ void TxOrphanage::AddChildrenToWorkSet(const CTransaction& tx) } } -bool TxOrphanage::HaveTx(const GenTxid& gtxid) const +bool TxOrphanage::HaveTx(const Wtxid& wtxid) const { LOCK(m_mutex); - if (gtxid.IsWtxid()) { - return m_wtxid_to_orphan_it.count(Wtxid::FromUint256(gtxid.GetHash())); - } else { - return m_orphans.count(Txid::FromUint256(gtxid.GetHash())); - } + return m_orphans.count(wtxid); } CTransactionRef TxOrphanage::GetTxToReconsider(NodeId peer) @@ -187,10 +183,10 @@ CTransactionRef TxOrphanage::GetTxToReconsider(NodeId peer) if (work_set_it != m_peer_work_set.end()) { auto& work_set = work_set_it->second; while (!work_set.empty()) { - Txid txid = *work_set.begin(); + Wtxid wtxid = *work_set.begin(); work_set.erase(work_set.begin()); - const auto orphan_it = m_orphans.find(txid); + const auto orphan_it = m_orphans.find(wtxid); if (orphan_it != m_orphans.end()) { return orphan_it->second.tx; } @@ -215,7 +211,7 @@ void TxOrphanage::EraseForBlock(const CBlock& block) { LOCK(m_mutex); - std::vector<Txid> vOrphanErase; + std::vector<Wtxid> vOrphanErase; for (const CTransactionRef& ptx : block.vtx) { const CTransaction& tx = *ptx; @@ -226,8 +222,7 @@ void TxOrphanage::EraseForBlock(const CBlock& block) if (itByPrev == m_outpoint_to_orphan_it.end()) continue; for (auto mi = itByPrev->second.begin(); mi != itByPrev->second.end(); ++mi) { const CTransaction& orphanTx = *(*mi)->second.tx; - const auto& orphanHash = orphanTx.GetHash(); - vOrphanErase.push_back(orphanHash); + vOrphanErase.push_back(orphanTx.GetWitnessHash()); } } } @@ -238,7 +233,7 @@ void TxOrphanage::EraseForBlock(const CBlock& block) for (const auto& orphanHash : vOrphanErase) { nErased += EraseTxNoLock(orphanHash); } - LogPrint(BCLog::TXPACKAGES, "Erased %d orphan tx included or conflicted by block\n", nErased); + LogPrint(BCLog::TXPACKAGES, "Erased %d orphan transaction(s) included or conflicted by block\n", nErased); } } diff --git a/src/txorphanage.h b/src/txorphanage.h index a3c8edaa2a..3054396b2d 100644 --- a/src/txorphanage.h +++ b/src/txorphanage.h @@ -9,6 +9,7 @@ #include <primitives/block.h> #include <primitives/transaction.h> #include <sync.h> +#include <util/time.h> #include <map> #include <set> @@ -23,8 +24,8 @@ public: /** Add a new orphan transaction */ bool AddTx(const CTransactionRef& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex); - /** Check if we already have an orphan transaction (by txid or wtxid) */ - bool HaveTx(const GenTxid& gtxid) const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex); + /** Check if we already have an orphan transaction (by wtxid only) */ + bool HaveTx(const Wtxid& wtxid) const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex); /** Extract a transaction from a peer's work set * Returns nullptr if there are no transactions to work on. @@ -33,8 +34,8 @@ public: */ CTransactionRef GetTxToReconsider(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex); - /** Erase an orphan by txid */ - int EraseTx(const Txid& txid) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex); + /** Erase an orphan by wtxid */ + int EraseTx(const Wtxid& wtxid) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex); /** Erase all orphans announced by a peer (eg, after that peer disconnects) */ void EraseForPeer(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex); @@ -73,16 +74,16 @@ protected: struct OrphanTx { CTransactionRef tx; NodeId fromPeer; - int64_t nTimeExpire; + NodeSeconds nTimeExpire; size_t list_pos; }; - /** Map from txid to orphan transaction record. Limited by + /** Map from wtxid to orphan transaction record. Limited by * -maxorphantx/DEFAULT_MAX_ORPHAN_TRANSACTIONS */ - std::map<Txid, OrphanTx> m_orphans GUARDED_BY(m_mutex); + std::map<Wtxid, OrphanTx> m_orphans GUARDED_BY(m_mutex); /** Which peer provided the orphans that need to be reconsidered */ - std::map<NodeId, std::set<Txid>> m_peer_work_set GUARDED_BY(m_mutex); + std::map<NodeId, std::set<Wtxid>> m_peer_work_set GUARDED_BY(m_mutex); using OrphanMap = decltype(m_orphans); @@ -102,12 +103,11 @@ protected: /** Orphan transactions in vector for quick random eviction */ std::vector<OrphanMap::iterator> m_orphan_list GUARDED_BY(m_mutex); - /** Index from wtxid into the m_orphans to lookup orphan - * transactions using their witness ids. */ - std::map<Wtxid, OrphanMap::iterator> m_wtxid_to_orphan_it GUARDED_BY(m_mutex); + /** Erase an orphan by wtxid */ + int EraseTxNoLock(const Wtxid& wtxid) EXCLUSIVE_LOCKS_REQUIRED(m_mutex); - /** Erase an orphan by txid */ - int EraseTxNoLock(const Txid& txid) EXCLUSIVE_LOCKS_REQUIRED(m_mutex); + /** Timestamp for the next scheduled sweep of expired orphans */ + NodeSeconds m_next_sweep GUARDED_BY(m_mutex){0s}; }; #endif // BITCOIN_TXORPHANAGE_H diff --git a/src/util/bitset.h b/src/util/bitset.h new file mode 100644 index 0000000000..6f9e808c37 --- /dev/null +++ b/src/util/bitset.h @@ -0,0 +1,527 @@ +// Copyright (c) The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_UTIL_BITSET_H +#define BITCOIN_UTIL_BITSET_H + +#include <util/check.h> + +#include <array> +#include <bit> +#include <cstdint> +#include <limits> +#include <type_traits> + +/* This file provides data types similar to std::bitset, but adds the following functionality: + * + * - Efficient iteration over all set bits (compatible with range-based for loops). + * - Efficient search for the first and last set bit (First() and Last()). + * - Efficient set subtraction: (a - b) implements "a and not b". + * - Efficient non-strict subset/superset testing: IsSubsetOf() and IsSupersetOf(). + * - Efficient set overlap testing: a.Overlaps(b) + * - Efficient construction of set containing 0..N-1 (S::Fill). + * - Efficient construction of a single set (S::Singleton). + * - Construction from initializer lists. + * + * Other differences: + * - BitSet<N> is a bitset that supports at least N elements, but may support more (Size() reports + * the actual number). Because the actual number is unpredictable, there are no operations that + * affect all positions (like std::bitset's operator~, flip(), or all()). + * - Various other unimplemented features. + */ + +namespace bitset_detail { + +/** Count the number of bits set in an unsigned integer type. */ +template<typename I> +unsigned inline constexpr PopCount(I v) +{ + static_assert(std::is_integral_v<I> && std::is_unsigned_v<I> && std::numeric_limits<I>::radix == 2); + constexpr auto BITS = std::numeric_limits<I>::digits; + // Algorithms from https://en.wikipedia.org/wiki/Hamming_weight#Efficient_implementation. + // These seem to be faster than std::popcount when compiling for non-SSE4 on x86_64. + if constexpr (BITS <= 32) { + v -= (v >> 1) & 0x55555555; + v = (v & 0x33333333) + ((v >> 2) & 0x33333333); + v = (v + (v >> 4)) & 0x0f0f0f0f; + if constexpr (BITS > 8) v += v >> 8; + if constexpr (BITS > 16) v += v >> 16; + return v & 0x3f; + } else { + static_assert(BITS <= 64); + v -= (v >> 1) & 0x5555555555555555; + v = (v & 0x3333333333333333) + ((v >> 2) & 0x3333333333333333); + v = (v + (v >> 4)) & 0x0f0f0f0f0f0f0f0f; + return (v * uint64_t{0x0101010101010101}) >> 56; + } +} + +/** A bitset implementation backed by a single integer of type I. */ +template<typename I> +class IntBitSet +{ + // Only binary, unsigned, integer, types allowed. + static_assert(std::is_integral_v<I> && std::is_unsigned_v<I> && std::numeric_limits<I>::radix == 2); + /** The maximum number of bits this bitset supports. */ + static constexpr unsigned MAX_SIZE = std::numeric_limits<I>::digits; + /** Integer whose bits represent this bitset. */ + I m_val; + /** Internal constructor with a given integer as contents. */ + IntBitSet(I val) noexcept : m_val{val} {} + /** Dummy type to return using end(). Only used for comparing with Iterator. */ + class IteratorEnd + { + friend class IntBitSet; + constexpr IteratorEnd() = default; + public: + constexpr IteratorEnd(const IteratorEnd&) = default; + }; + /** Iterator type returned by begin(), which efficiently iterates all 1 positions. */ + class Iterator + { + friend class IntBitSet; + I m_val; /**< The original integer's remaining bits. */ + unsigned m_pos; /** Last reported 1 position (if m_pos != 0). */ + constexpr Iterator(I val) noexcept : m_val(val), m_pos(0) + { + if (m_val != 0) m_pos = std::countr_zero(m_val); + } + public: + /** Do not allow external code to construct an Iterator. */ + Iterator() = delete; + // Copying is allowed. + constexpr Iterator(const Iterator&) noexcept = default; + constexpr Iterator& operator=(const Iterator&) noexcept = default; + /** Test whether we are done (can only compare with IteratorEnd). */ + constexpr friend bool operator==(const Iterator& a, const IteratorEnd&) noexcept + { + return a.m_val == 0; + } + /** Progress to the next 1 bit (only if != IteratorEnd). */ + constexpr Iterator& operator++() noexcept + { + Assume(m_val != 0); + m_val &= m_val - I{1U}; + if (m_val != 0) m_pos = std::countr_zero(m_val); + return *this; + } + /** Get the current bit position (only if != IteratorEnd). */ + constexpr unsigned operator*() const noexcept + { + Assume(m_val != 0); + return m_pos; + } + }; + +public: + /** Construct an all-zero bitset. */ + constexpr IntBitSet() noexcept : m_val{0} {} + /** Copy construct a bitset. */ + constexpr IntBitSet(const IntBitSet&) noexcept = default; + /** Construct from a list of values. */ + constexpr IntBitSet(std::initializer_list<unsigned> ilist) noexcept : m_val(0) + { + for (auto pos : ilist) Set(pos); + } + /** Copy assign a bitset. */ + constexpr IntBitSet& operator=(const IntBitSet&) noexcept = default; + /** Assign from a list of positions (which will be made true, all others false). */ + constexpr IntBitSet& operator=(std::initializer_list<unsigned> ilist) noexcept + { + m_val = 0; + for (auto pos : ilist) Set(pos); + return *this; + } + /** Construct a bitset with the singleton i. */ + static constexpr IntBitSet Singleton(unsigned i) noexcept + { + Assume(i < MAX_SIZE); + return IntBitSet(I(1U) << i); + } + /** Construct a bitset with bits 0..count-1 (inclusive) set to 1. */ + static constexpr IntBitSet Fill(unsigned count) noexcept + { + IntBitSet ret; + Assume(count <= MAX_SIZE); + if (count) ret.m_val = I(~I{0}) >> (MAX_SIZE - count); + return ret; + } + /** Set a bit to 1. */ + constexpr void Set(unsigned pos) noexcept + { + Assume(pos < MAX_SIZE); + m_val |= I{1U} << pos; + } + /** Set a bit to the specified value. */ + constexpr void Set(unsigned pos, bool val) noexcept + { + Assume(pos < MAX_SIZE); + m_val = (m_val & ~I(I{1U} << pos)) | (I(val) << pos); + } + /** Set a bit to 0. */ + constexpr void Reset(unsigned pos) noexcept + { + Assume(pos < MAX_SIZE); + m_val &= ~I(I{1U} << pos); + } + /** Retrieve a bit at the given position. */ + constexpr bool operator[](unsigned pos) const noexcept + { + Assume(pos < MAX_SIZE); + return (m_val >> pos) & 1U; + } + /** Compute the number of 1 bits in the bitset. */ + constexpr unsigned Count() const noexcept { return PopCount(m_val); } + /** Return the number of bits that this object holds. */ + static constexpr unsigned Size() noexcept { return MAX_SIZE; } + /** Check if all bits are 0. */ + constexpr bool None() const noexcept { return m_val == 0; } + /** Check if any bits are 1. */ + constexpr bool Any() const noexcept { return !None(); } + /** Return an object that iterates over all 1 bits (++ and * only allowed when != end()). */ + constexpr Iterator begin() const noexcept { return Iterator(m_val); } + /** Return a dummy object to compare Iterators with. */ + constexpr IteratorEnd end() const noexcept { return IteratorEnd(); } + /** Find the first element (requires Any()). */ + constexpr unsigned First() const noexcept + { + Assume(m_val != 0); + return std::countr_zero(m_val); + } + /** Find the last element (requires Any()). */ + constexpr unsigned Last() const noexcept + { + Assume(m_val != 0); + return std::bit_width(m_val) - 1; + } + /** Set this object's bits to be the binary AND between respective bits from this and a. */ + constexpr IntBitSet& operator|=(const IntBitSet& a) noexcept { m_val |= a.m_val; return *this; } + /** Set this object's bits to be the binary OR between respective bits from this and a. */ + constexpr IntBitSet& operator&=(const IntBitSet& a) noexcept { m_val &= a.m_val; return *this; } + /** Set this object's bits to be the binary AND NOT between respective bits from this and a. */ + constexpr IntBitSet& operator-=(const IntBitSet& a) noexcept { m_val &= ~a.m_val; return *this; } + /** Set this object's bits to be the binary XOR between respective bits from this as a. */ + constexpr IntBitSet& operator^=(const IntBitSet& a) noexcept { m_val ^= a.m_val; return *this; } + /** Check if the intersection between two sets is non-empty. */ + constexpr bool Overlaps(const IntBitSet& a) const noexcept { return m_val & a.m_val; } + /** Return an object with the binary AND between respective bits from a and b. */ + friend constexpr IntBitSet operator&(const IntBitSet& a, const IntBitSet& b) noexcept { return I(a.m_val & b.m_val); } + /** Return an object with the binary OR between respective bits from a and b. */ + friend constexpr IntBitSet operator|(const IntBitSet& a, const IntBitSet& b) noexcept { return I(a.m_val | b.m_val); } + /** Return an object with the binary AND NOT between respective bits from a and b. */ + friend constexpr IntBitSet operator-(const IntBitSet& a, const IntBitSet& b) noexcept { return I(a.m_val & ~b.m_val); } + /** Return an object with the binary XOR between respective bits from a and b. */ + friend constexpr IntBitSet operator^(const IntBitSet& a, const IntBitSet& b) noexcept { return I(a.m_val ^ b.m_val); } + /** Check if bitset a and bitset b are identical. */ + friend constexpr bool operator==(const IntBitSet& a, const IntBitSet& b) noexcept = default; + /** Check if bitset a is a superset of bitset b (= every 1 bit in b is also in a). */ + constexpr bool IsSupersetOf(const IntBitSet& a) const noexcept { return (a.m_val & ~m_val) == 0; } + /** Check if bitset a is a subset of bitset b (= every 1 bit in a is also in b). */ + constexpr bool IsSubsetOf(const IntBitSet& a) const noexcept { return (m_val & ~a.m_val) == 0; } + /** Swap two bitsets. */ + friend constexpr void swap(IntBitSet& a, IntBitSet& b) noexcept { std::swap(a.m_val, b.m_val); } +}; + +/** A bitset implementation backed by N integers of type I. */ +template<typename I, unsigned N> +class MultiIntBitSet +{ + // Only binary, unsigned, integer, types allowed. + static_assert(std::is_integral_v<I> && std::is_unsigned_v<I> && std::numeric_limits<I>::radix == 2); + // Cannot be empty. + static_assert(N > 0); + /** The number of bits per integer. */ + static constexpr unsigned LIMB_BITS = std::numeric_limits<I>::digits; + /** Number of elements this set type supports. */ + static constexpr unsigned MAX_SIZE = LIMB_BITS * N; + // No overflow allowed here. + static_assert(MAX_SIZE / LIMB_BITS == N); + /** Array whose member integers store the bits of the set. */ + std::array<I, N> m_val; + /** Dummy type to return using end(). Only used for comparing with Iterator. */ + class IteratorEnd + { + friend class MultiIntBitSet; + constexpr IteratorEnd() = default; + public: + constexpr IteratorEnd(const IteratorEnd&) = default; + }; + /** Iterator type returned by begin(), which efficiently iterates all 1 positions. */ + class Iterator + { + friend class MultiIntBitSet; + const std::array<I, N>* m_ptr; /**< Pointer to array to fetch bits from. */ + I m_val; /**< The remaining bits of (*m_ptr)[m_idx]. */ + unsigned m_pos; /**< The last reported position. */ + unsigned m_idx; /**< The index in *m_ptr currently being iterated over. */ + constexpr Iterator(const std::array<I, N>& ref) noexcept : m_ptr(&ref), m_idx(0) + { + do { + m_val = (*m_ptr)[m_idx]; + if (m_val) { + m_pos = std::countr_zero(m_val) + m_idx * LIMB_BITS; + break; + } + ++m_idx; + } while(m_idx < N); + } + + public: + /** Do not allow external code to construct an Iterator. */ + Iterator() = delete; + // Copying is allowed. + constexpr Iterator(const Iterator&) noexcept = default; + constexpr Iterator& operator=(const Iterator&) noexcept = default; + /** Test whether we are done (can only compare with IteratorEnd). */ + friend constexpr bool operator==(const Iterator& a, const IteratorEnd&) noexcept + { + return a.m_idx == N; + } + /** Progress to the next 1 bit (only if != IteratorEnd). */ + constexpr Iterator& operator++() noexcept + { + Assume(m_idx < N); + m_val &= m_val - I{1U}; + if (m_val == 0) { + while (true) { + ++m_idx; + if (m_idx == N) break; + m_val = (*m_ptr)[m_idx]; + if (m_val) { + m_pos = std::countr_zero(m_val) + m_idx * LIMB_BITS; + break; + } + } + } else { + m_pos = std::countr_zero(m_val) + m_idx * LIMB_BITS; + } + return *this; + } + /** Get the current bit position (only if != IteratorEnd). */ + constexpr unsigned operator*() const noexcept + { + Assume(m_idx < N); + return m_pos; + } + }; + +public: + /** Construct an all-zero bitset. */ + constexpr MultiIntBitSet() noexcept : m_val{} {} + /** Copy construct a bitset. */ + constexpr MultiIntBitSet(const MultiIntBitSet&) noexcept = default; + /** Copy assign a bitset. */ + constexpr MultiIntBitSet& operator=(const MultiIntBitSet&) noexcept = default; + /** Set a bit to 1. */ + void constexpr Set(unsigned pos) noexcept + { + Assume(pos < MAX_SIZE); + m_val[pos / LIMB_BITS] |= I{1U} << (pos % LIMB_BITS); + } + /** Set a bit to the specified value. */ + void constexpr Set(unsigned pos, bool val) noexcept + { + Assume(pos < MAX_SIZE); + m_val[pos / LIMB_BITS] = (m_val[pos / LIMB_BITS] & ~I(I{1U} << (pos % LIMB_BITS))) | + (I{val} << (pos % LIMB_BITS)); + } + /** Construct a bitset from a list of values. */ + constexpr MultiIntBitSet(std::initializer_list<unsigned> ilist) noexcept : m_val{} + { + for (auto pos : ilist) Set(pos); + } + /** Set a bitset to a list of values. */ + constexpr MultiIntBitSet& operator=(std::initializer_list<unsigned> ilist) noexcept + { + m_val.fill(0); + for (auto pos : ilist) Set(pos); + return *this; + } + /** Set a bit to 0. */ + void constexpr Reset(unsigned pos) noexcept + { + Assume(pos < MAX_SIZE); + m_val[pos / LIMB_BITS] &= ~I(I{1U} << (pos % LIMB_BITS)); + } + /** Retrieve a bit at the given position. */ + bool constexpr operator[](unsigned pos) const noexcept + { + Assume(pos < MAX_SIZE); + return (m_val[pos / LIMB_BITS] >> (pos % LIMB_BITS)) & 1U; + } + /** Construct a bitset with the singleton pos. */ + static constexpr MultiIntBitSet Singleton(unsigned pos) noexcept + { + Assume(pos < MAX_SIZE); + MultiIntBitSet ret; + ret.m_val[pos / LIMB_BITS] = I{1U} << (pos % LIMB_BITS); + return ret; + } + /** Construct a bitset with bits 0..count-1 (inclusive) set to 1. */ + static constexpr MultiIntBitSet Fill(unsigned count) noexcept + { + Assume(count <= MAX_SIZE); + MultiIntBitSet ret; + if (count) { + unsigned i = 0; + while (count > LIMB_BITS) { + ret.m_val[i++] = ~I{0}; + count -= LIMB_BITS; + } + ret.m_val[i] = I(~I{0}) >> (LIMB_BITS - count); + } + return ret; + } + /** Return the number of bits that this object holds. */ + static constexpr unsigned Size() noexcept { return MAX_SIZE; } + /** Compute the number of 1 bits in the bitset. */ + unsigned constexpr Count() const noexcept + { + unsigned ret{0}; + for (I v : m_val) ret += PopCount(v); + return ret; + } + /** Check if all bits are 0. */ + bool constexpr None() const noexcept + { + for (auto v : m_val) { + if (v != 0) return false; + } + return true; + } + /** Check if any bits are 1. */ + bool constexpr Any() const noexcept { return !None(); } + /** Return an object that iterates over all 1 bits (++ and * only allowed when != end()). */ + Iterator constexpr begin() const noexcept { return Iterator(m_val); } + /** Return a dummy object to compare Iterators with. */ + IteratorEnd constexpr end() const noexcept { return IteratorEnd(); } + /** Find the first element (requires Any()). */ + unsigned constexpr First() const noexcept + { + unsigned p = 0; + while (m_val[p] == 0) { + ++p; + Assume(p < N); + } + return std::countr_zero(m_val[p]) + p * LIMB_BITS; + } + /** Find the last element (requires Any()). */ + unsigned constexpr Last() const noexcept + { + unsigned p = N - 1; + while (m_val[p] == 0) { + Assume(p > 0); + --p; + } + return std::bit_width(m_val[p]) - 1 + p * LIMB_BITS; + } + /** Set this object's bits to be the binary OR between respective bits from this and a. */ + constexpr MultiIntBitSet& operator|=(const MultiIntBitSet& a) noexcept + { + for (unsigned i = 0; i < N; ++i) { + m_val[i] |= a.m_val[i]; + } + return *this; + } + /** Set this object's bits to be the binary AND between respective bits from this and a. */ + constexpr MultiIntBitSet& operator&=(const MultiIntBitSet& a) noexcept + { + for (unsigned i = 0; i < N; ++i) { + m_val[i] &= a.m_val[i]; + } + return *this; + } + /** Set this object's bits to be the binary AND NOT between respective bits from this and a. */ + constexpr MultiIntBitSet& operator-=(const MultiIntBitSet& a) noexcept + { + for (unsigned i = 0; i < N; ++i) { + m_val[i] &= ~a.m_val[i]; + } + return *this; + } + /** Set this object's bits to be the binary XOR between respective bits from this and a. */ + constexpr MultiIntBitSet& operator^=(const MultiIntBitSet& a) noexcept + { + for (unsigned i = 0; i < N; ++i) { + m_val[i] ^= a.m_val[i]; + } + return *this; + } + /** Check whether the intersection between two sets is non-empty. */ + constexpr bool Overlaps(const MultiIntBitSet& a) const noexcept + { + for (unsigned i = 0; i < N; ++i) { + if (m_val[i] & a.m_val[i]) return true; + } + return false; + } + /** Return an object with the binary AND between respective bits from a and b. */ + friend constexpr MultiIntBitSet operator&(const MultiIntBitSet& a, const MultiIntBitSet& b) noexcept + { + MultiIntBitSet r; + for (unsigned i = 0; i < N; ++i) { + r.m_val[i] = a.m_val[i] & b.m_val[i]; + } + return r; + } + /** Return an object with the binary OR between respective bits from a and b. */ + friend constexpr MultiIntBitSet operator|(const MultiIntBitSet& a, const MultiIntBitSet& b) noexcept + { + MultiIntBitSet r; + for (unsigned i = 0; i < N; ++i) { + r.m_val[i] = a.m_val[i] | b.m_val[i]; + } + return r; + } + /** Return an object with the binary AND NOT between respective bits from a and b. */ + friend constexpr MultiIntBitSet operator-(const MultiIntBitSet& a, const MultiIntBitSet& b) noexcept + { + MultiIntBitSet r; + for (unsigned i = 0; i < N; ++i) { + r.m_val[i] = a.m_val[i] & ~b.m_val[i]; + } + return r; + } + /** Return an object with the binary XOR between respective bits from a and b. */ + friend constexpr MultiIntBitSet operator^(const MultiIntBitSet& a, const MultiIntBitSet& b) noexcept + { + MultiIntBitSet r; + for (unsigned i = 0; i < N; ++i) { + r.m_val[i] = a.m_val[i] ^ b.m_val[i]; + } + return r; + } + /** Check if bitset a is a superset of bitset b (= every 1 bit in b is also in a). */ + constexpr bool IsSupersetOf(const MultiIntBitSet& a) const noexcept + { + for (unsigned i = 0; i < N; ++i) { + if (a.m_val[i] & ~m_val[i]) return false; + } + return true; + } + /** Check if bitset a is a subset of bitset b (= every 1 bit in a is also in b). */ + constexpr bool IsSubsetOf(const MultiIntBitSet& a) const noexcept + { + for (unsigned i = 0; i < N; ++i) { + if (m_val[i] & ~a.m_val[i]) return false; + } + return true; + } + /** Check if bitset a and bitset b are identical. */ + friend constexpr bool operator==(const MultiIntBitSet& a, const MultiIntBitSet& b) noexcept = default; + /** Swap two bitsets. */ + friend constexpr void swap(MultiIntBitSet& a, MultiIntBitSet& b) noexcept { std::swap(a.m_val, b.m_val); } +}; + +} // namespace bitset_detail + +// BitSet dispatches to IntBitSet or MultiIntBitSet as appropriate for the requested minimum number +// of bits. Use IntBitSet up to 32-bit, or up to 64-bit on 64-bit platforms; above that, use a +// MultiIntBitSet of size_t. +template<unsigned BITS> +using BitSet = std::conditional_t<(BITS <= 32), bitset_detail::IntBitSet<uint32_t>, + std::conditional_t<(BITS <= std::numeric_limits<size_t>::digits), bitset_detail::IntBitSet<size_t>, + bitset_detail::MultiIntBitSet<size_t, (BITS + std::numeric_limits<size_t>::digits - 1) / std::numeric_limits<size_t>::digits>>>; + +#endif // BITCOIN_UTIL_BITSET_H diff --git a/src/util/error.cpp b/src/util/error.cpp deleted file mode 100644 index 309877d067..0000000000 --- a/src/util/error.cpp +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) 2010-2022 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include <util/error.h> - -#include <tinyformat.h> -#include <util/translation.h> - -#include <cassert> -#include <string> - -bilingual_str TransactionErrorString(const TransactionError err) -{ - switch (err) { - case TransactionError::OK: - return Untranslated("No error"); - case TransactionError::MISSING_INPUTS: - return Untranslated("Inputs missing or spent"); - case TransactionError::ALREADY_IN_CHAIN: - return Untranslated("Transaction already in block chain"); - case TransactionError::P2P_DISABLED: - return Untranslated("Peer-to-peer functionality missing or disabled"); - case TransactionError::MEMPOOL_REJECTED: - return Untranslated("Transaction rejected by mempool"); - case TransactionError::MEMPOOL_ERROR: - return Untranslated("Mempool internal error"); - case TransactionError::INVALID_PSBT: - return Untranslated("PSBT is not well-formed"); - case TransactionError::PSBT_MISMATCH: - return Untranslated("PSBTs not compatible (different transactions)"); - case TransactionError::SIGHASH_MISMATCH: - return Untranslated("Specified sighash value does not match value stored in PSBT"); - case TransactionError::MAX_FEE_EXCEEDED: - return Untranslated("Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)"); - case TransactionError::MAX_BURN_EXCEEDED: - return Untranslated("Unspendable output exceeds maximum configured by user (maxburnamount)"); - case TransactionError::EXTERNAL_SIGNER_NOT_FOUND: - return Untranslated("External signer not found"); - case TransactionError::EXTERNAL_SIGNER_FAILED: - return Untranslated("External signer failed to sign"); - case TransactionError::INVALID_PACKAGE: - return Untranslated("Transaction rejected due to invalid package"); - // no default case, so the compiler can warn about missing cases - } - assert(false); -} - -bilingual_str ResolveErrMsg(const std::string& optname, const std::string& strBind) -{ - return strprintf(_("Cannot resolve -%s address: '%s'"), optname, strBind); -} - -bilingual_str InvalidPortErrMsg(const std::string& optname, const std::string& invalid_value) -{ - return strprintf(_("Invalid port specified in %s: '%s'"), optname, invalid_value); -} - -bilingual_str AmountHighWarn(const std::string& optname) -{ - return strprintf(_("%s is set very high!"), optname); -} - -bilingual_str AmountErrMsg(const std::string& optname, const std::string& strValue) -{ - return strprintf(_("Invalid amount for -%s=<amount>: '%s'"), optname, strValue); -} diff --git a/src/util/error.h b/src/util/error.h deleted file mode 100644 index a52a8f47de..0000000000 --- a/src/util/error.h +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) 2010-2021 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef BITCOIN_UTIL_ERROR_H -#define BITCOIN_UTIL_ERROR_H - -/** - * util/error.h is a common place for definitions of simple error types and - * string functions. Types and functions defined here should not require any - * outside dependencies. - * - * Error types defined here can be used in different parts of the - * codebase, to avoid the need to write boilerplate code catching and - * translating errors passed across wallet/node/rpc/gui code boundaries. - */ - -#include <string> - -struct bilingual_str; - -enum class TransactionError { - OK, //!< No error - MISSING_INPUTS, - ALREADY_IN_CHAIN, - P2P_DISABLED, - MEMPOOL_REJECTED, - MEMPOOL_ERROR, - INVALID_PSBT, - PSBT_MISMATCH, - SIGHASH_MISMATCH, - MAX_FEE_EXCEEDED, - MAX_BURN_EXCEEDED, - EXTERNAL_SIGNER_NOT_FOUND, - EXTERNAL_SIGNER_FAILED, - INVALID_PACKAGE, -}; - -bilingual_str TransactionErrorString(const TransactionError error); - -bilingual_str ResolveErrMsg(const std::string& optname, const std::string& strBind); - -bilingual_str InvalidPortErrMsg(const std::string& optname, const std::string& strPort); - -bilingual_str AmountHighWarn(const std::string& optname); - -bilingual_str AmountErrMsg(const std::string& optname, const std::string& strValue); - -#endif // BITCOIN_UTIL_ERROR_H diff --git a/src/util/fees.cpp b/src/util/fees.cpp deleted file mode 100644 index 8ada02ce54..0000000000 --- a/src/util/fees.cpp +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2020 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include <util/fees.h> - -#include <policy/fees.h> -#include <util/strencodings.h> -#include <util/string.h> - -#include <map> -#include <string> -#include <vector> -#include <utility> - -std::string StringForFeeReason(FeeReason reason) -{ - static const std::map<FeeReason, std::string> fee_reason_strings = { - {FeeReason::NONE, "None"}, - {FeeReason::HALF_ESTIMATE, "Half Target 60% Threshold"}, - {FeeReason::FULL_ESTIMATE, "Target 85% Threshold"}, - {FeeReason::DOUBLE_ESTIMATE, "Double Target 95% Threshold"}, - {FeeReason::CONSERVATIVE, "Conservative Double Target longer horizon"}, - {FeeReason::MEMPOOL_MIN, "Mempool Min Fee"}, - {FeeReason::PAYTXFEE, "PayTxFee set"}, - {FeeReason::FALLBACK, "Fallback fee"}, - {FeeReason::REQUIRED, "Minimum Required Fee"}, - }; - auto reason_string = fee_reason_strings.find(reason); - - if (reason_string == fee_reason_strings.end()) return "Unknown"; - - return reason_string->second; -} - -const std::vector<std::pair<std::string, FeeEstimateMode>>& FeeModeMap() -{ - static const std::vector<std::pair<std::string, FeeEstimateMode>> FEE_MODES = { - {"unset", FeeEstimateMode::UNSET}, - {"economical", FeeEstimateMode::ECONOMICAL}, - {"conservative", FeeEstimateMode::CONSERVATIVE}, - }; - return FEE_MODES; -} - -std::string FeeModes(const std::string& delimiter) -{ - return Join(FeeModeMap(), delimiter, [&](const std::pair<std::string, FeeEstimateMode>& i) { return i.first; }); -} - -std::string InvalidEstimateModeErrorMessage() -{ - return "Invalid estimate_mode parameter, must be one of: \"" + FeeModes("\", \"") + "\""; -} - -bool FeeModeFromString(const std::string& mode_string, FeeEstimateMode& fee_estimate_mode) -{ - auto searchkey = ToUpper(mode_string); - for (const auto& pair : FeeModeMap()) { - if (ToUpper(pair.first) == searchkey) { - fee_estimate_mode = pair.second; - return true; - } - } - return false; -} diff --git a/src/util/fees.h b/src/util/fees.h deleted file mode 100644 index 10ba1e4f85..0000000000 --- a/src/util/fees.h +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2020 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. -#ifndef BITCOIN_UTIL_FEES_H -#define BITCOIN_UTIL_FEES_H - -#include <string> - -enum class FeeEstimateMode; -enum class FeeReason; - -bool FeeModeFromString(const std::string& mode_string, FeeEstimateMode& fee_estimate_mode); -std::string StringForFeeReason(FeeReason reason); -std::string FeeModes(const std::string& delimiter); -std::string InvalidEstimateModeErrorMessage(); - -#endif // BITCOIN_UTIL_FEES_H diff --git a/src/util/moneystr.cpp b/src/util/moneystr.cpp index 9181329afc..1ed3b2ac96 100644 --- a/src/util/moneystr.cpp +++ b/src/util/moneystr.cpp @@ -13,6 +13,9 @@ #include <cstdint> #include <optional> +using util::ContainsNoNUL; +using util::TrimString; + std::string FormatMoney(const CAmount n) { // Note: not using straight sprintf here because we do NOT want diff --git a/src/util/spanparsing.h b/src/util/spanparsing.h deleted file mode 100644 index 765fe13aca..0000000000 --- a/src/util/spanparsing.h +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) 2018-2022 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef BITCOIN_UTIL_SPANPARSING_H -#define BITCOIN_UTIL_SPANPARSING_H - -#include <span.h> - -#include <string> -#include <string_view> -#include <vector> - -namespace spanparsing { - -/** Parse a constant. - * - * If sp's initial part matches str, sp is updated to skip that part, and true is returned. - * Otherwise sp is unmodified and false is returned. - */ -bool Const(const std::string& str, Span<const char>& sp); - -/** Parse a function call. - * - * If sp's initial part matches str + "(", and sp ends with ")", sp is updated to be the - * section between the braces, and true is returned. Otherwise sp is unmodified and false - * is returned. - */ -bool Func(const std::string& str, Span<const char>& sp); - -/** Extract the expression that sp begins with. - * - * This function will return the initial part of sp, up to (but not including) the first - * comma or closing brace, skipping ones that are surrounded by braces. So for example, - * for "foo(bar(1),2),3" the initial part "foo(bar(1),2)" will be returned. sp will be - * updated to skip the initial part that is returned. - */ -Span<const char> Expr(Span<const char>& sp); - -/** Split a string on any char found in separators, returning a vector. - * - * If sep does not occur in sp, a singleton with the entirety of sp is returned. - * - * Note that this function does not care about braces, so splitting - * "foo(bar(1),2),3) on ',' will return {"foo(bar(1)", "2)", "3)"}. - */ -template <typename T = Span<const char>> -std::vector<T> Split(const Span<const char>& sp, std::string_view separators) -{ - std::vector<T> ret; - auto it = sp.begin(); - auto start = it; - while (it != sp.end()) { - if (separators.find(*it) != std::string::npos) { - ret.emplace_back(start, it); - start = it + 1; - } - ++it; - } - ret.emplace_back(start, it); - return ret; -} - -/** Split a string on every instance of sep, returning a vector. - * - * If sep does not occur in sp, a singleton with the entirety of sp is returned. - * - * Note that this function does not care about braces, so splitting - * "foo(bar(1),2),3) on ',' will return {"foo(bar(1)", "2)", "3)"}. - */ -template <typename T = Span<const char>> -std::vector<T> Split(const Span<const char>& sp, char sep) -{ - return Split<T>(sp, std::string_view{&sep, 1}); -} - -} // namespace spanparsing - -#endif // BITCOIN_UTIL_SPANPARSING_H diff --git a/src/util/strencodings.cpp b/src/util/strencodings.cpp index 7b5ded2975..e030262a32 100644 --- a/src/util/strencodings.cpp +++ b/src/util/strencodings.cpp @@ -3,9 +3,11 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include <span.h> #include <util/strencodings.h> +#include <crypto/hex_base.h> +#include <span.h> + #include <array> #include <cassert> #include <cstring> @@ -36,29 +38,6 @@ std::string SanitizeString(std::string_view str, int rule) return result; } -const signed char p_util_hexdigit[256] = -{ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - 0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1, - -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, }; - -signed char HexDigit(char c) -{ - return p_util_hexdigit[(unsigned char)c]; -} - bool IsHex(std::string_view str) { for (char c : str) { @@ -466,40 +445,6 @@ std::string Capitalize(std::string str) return str; } -namespace { - -using ByteAsHex = std::array<char, 2>; - -constexpr std::array<ByteAsHex, 256> CreateByteToHexMap() -{ - constexpr char hexmap[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; - - std::array<ByteAsHex, 256> byte_to_hex{}; - for (size_t i = 0; i < byte_to_hex.size(); ++i) { - byte_to_hex[i][0] = hexmap[i >> 4]; - byte_to_hex[i][1] = hexmap[i & 15]; - } - return byte_to_hex; -} - -} // namespace - -std::string HexStr(const Span<const uint8_t> s) -{ - std::string rv(s.size() * 2, '\0'); - static constexpr auto byte_to_hex = CreateByteToHexMap(); - static_assert(sizeof(byte_to_hex) == 512); - - char* it = rv.data(); - for (uint8_t v : s) { - std::memcpy(it, byte_to_hex[v].data(), 2); - it += 2; - } - - assert(it == rv.data() + rv.size()); - return rv; -} - std::optional<uint64_t> ParseByteUnits(std::string_view str, ByteUnit default_multiplier) { if (str.empty()) { diff --git a/src/util/strencodings.h b/src/util/strencodings.h index 439678c24a..e5c2d3ddf2 100644 --- a/src/util/strencodings.h +++ b/src/util/strencodings.h @@ -9,6 +9,7 @@ #ifndef BITCOIN_UTIL_STRENCODINGS_H #define BITCOIN_UTIL_STRENCODINGS_H +#include <crypto/hex_base.h> // IWYU pragma: export #include <span.h> #include <util/string.h> @@ -66,7 +67,6 @@ std::vector<Byte> ParseHex(std::string_view hex_str) { return TryParseHex<Byte>(hex_str).value_or(std::vector<Byte>{}); } -signed char HexDigit(char c); /* Returns true if each character in str is a hex character, and has an even * number of hex digits.*/ bool IsHex(std::string_view str); @@ -122,7 +122,7 @@ T LocaleIndependentAtoi(std::string_view str) static_assert(std::is_integral<T>::value); T result; // Emulate atoi(...) handling of white space and leading +/-. - std::string_view s = TrimStringView(str); + std::string_view s = util::TrimStringView(str); if (!s.empty() && s[0] == '+') { if (s.length() >= 2 && s[1] == '-') { return 0; @@ -232,13 +232,6 @@ std::optional<T> ToIntegral(std::string_view str) [[nodiscard]] bool ParseUInt64(std::string_view str, uint64_t *out); /** - * Convert a span of bytes to a lower-case hexadecimal string. - */ -std::string HexStr(const Span<const uint8_t> s); -inline std::string HexStr(const Span<const char> s) { return HexStr(MakeUCharSpan(s)); } -inline std::string HexStr(const Span<const std::byte> s) { return HexStr(MakeUCharSpan(s)); } - -/** * Format a paragraph of text to a fixed width, adding spaces for * indentation to any added line. */ diff --git a/src/util/string.cpp b/src/util/string.cpp index 3d31849745..47c6b74d4f 100644 --- a/src/util/string.cpp +++ b/src/util/string.cpp @@ -7,8 +7,10 @@ #include <regex> #include <string> +namespace util { void ReplaceAll(std::string& in_out, const std::string& search, const std::string& substitute) { if (search.empty()) return; in_out = std::regex_replace(in_out, std::regex(search), substitute); } +} // namespace util diff --git a/src/util/string.h b/src/util/string.h index dab92942fb..e2e470f4ab 100644 --- a/src/util/string.h +++ b/src/util/string.h @@ -5,7 +5,7 @@ #ifndef BITCOIN_UTIL_STRING_H #define BITCOIN_UTIL_STRING_H -#include <util/spanparsing.h> +#include <span.h> #include <array> #include <cstdint> @@ -16,16 +16,54 @@ #include <string_view> // IWYU pragma: export #include <vector> +namespace util { void ReplaceAll(std::string& in_out, const std::string& search, const std::string& substitute); +/** Split a string on any char found in separators, returning a vector. + * + * If sep does not occur in sp, a singleton with the entirety of sp is returned. + * + * Note that this function does not care about braces, so splitting + * "foo(bar(1),2),3) on ',' will return {"foo(bar(1)", "2)", "3)"}. + */ +template <typename T = Span<const char>> +std::vector<T> Split(const Span<const char>& sp, std::string_view separators) +{ + std::vector<T> ret; + auto it = sp.begin(); + auto start = it; + while (it != sp.end()) { + if (separators.find(*it) != std::string::npos) { + ret.emplace_back(start, it); + start = it + 1; + } + ++it; + } + ret.emplace_back(start, it); + return ret; +} + +/** Split a string on every instance of sep, returning a vector. + * + * If sep does not occur in sp, a singleton with the entirety of sp is returned. + * + * Note that this function does not care about braces, so splitting + * "foo(bar(1),2),3) on ',' will return {"foo(bar(1)", "2)", "3)"}. + */ +template <typename T = Span<const char>> +std::vector<T> Split(const Span<const char>& sp, char sep) +{ + return Split<T>(sp, std::string_view{&sep, 1}); +} + [[nodiscard]] inline std::vector<std::string> SplitString(std::string_view str, char sep) { - return spanparsing::Split<std::string>(str, sep); + return Split<std::string>(str, sep); } [[nodiscard]] inline std::vector<std::string> SplitString(std::string_view str, std::string_view separators) { - return spanparsing::Split<std::string>(str, separators); + return Split<std::string>(str, separators); } [[nodiscard]] inline std::string_view TrimStringView(std::string_view str, std::string_view pattern = " \f\n\r\t\v") @@ -125,5 +163,6 @@ template <typename T1, size_t PREFIX_LEN> return obj.size() >= PREFIX_LEN && std::equal(std::begin(prefix), std::end(prefix), std::begin(obj)); } +} // namespace util #endif // BITCOIN_UTIL_STRING_H diff --git a/src/util/subprocess.h b/src/util/subprocess.h index af408b31d4..e76ced687c 100644 --- a/src/util/subprocess.h +++ b/src/util/subprocess.h @@ -902,17 +902,9 @@ private: * Command provided in a single string. * wait() - Wait for the child to exit. * retcode() - The return code of the exited child. - * pid() - PID of the spawned child. - * poll() - Check the status of the running child. * send(...) - Send input to the input channel of the child. * communicate(...) - Get the output/error from the child and close the channels * from the parent side. - * input() - Get the input channel/File pointer. Can be used for - * customizing the way of sending input to child. - * output() - Get the output channel/File pointer. Usually used - in case of redirection. See piping examples. - * error() - Get the error channel/File pointer. Usually used - in case of redirection. */ class Popen { @@ -956,14 +948,10 @@ public: execute_process(); } - int pid() const noexcept { return child_pid_; } - int retcode() const noexcept { return retcode_; } int wait() noexcept(false); - int poll() noexcept(false); - void set_out_buf_cap(size_t cap) { stream_.set_out_buf_cap(cap); } void set_err_buf_cap(size_t cap) { stream_.set_err_buf_cap(cap); } @@ -1001,15 +989,6 @@ public: return communicate(nullptr, 0); } - FILE* input() { return stream_.input(); } - FILE* output() { return stream_.output();} - FILE* error() { return stream_.error(); } - - /// Stream close APIs - void close_input() { stream_.input_.reset(); } - void close_output() { stream_.output_.reset(); } - void close_error() { stream_.error_.reset(); } - private: template <typename F, typename... Args> void init_args(F&& farg, Args&&... args); @@ -1033,7 +1012,6 @@ private: std::vector<std::string> vargs_; std::vector<char*> cargv_; - bool child_created_ = false; // Pid of the child process int child_pid_ = -1; @@ -1068,7 +1046,7 @@ inline int Popen::wait() noexcept(false) return 0; #else int ret, status; - std::tie(ret, status) = util::wait_for_child_exit(pid()); + std::tie(ret, status) = util::wait_for_child_exit(child_pid_); if (ret == -1) { if (errno != ECHILD) throw OSError("waitpid failed", errno); return 0; @@ -1081,56 +1059,6 @@ inline int Popen::wait() noexcept(false) #endif } -inline int Popen::poll() noexcept(false) -{ -#ifdef __USING_WINDOWS__ - int ret = WaitForSingleObject(process_handle_, 0); - if (ret != WAIT_OBJECT_0) return -1; - - DWORD dretcode_; - if (FALSE == GetExitCodeProcess(process_handle_, &dretcode_)) - throw OSError("GetExitCodeProcess", 0); - - retcode_ = (int)dretcode_; - CloseHandle(process_handle_); - - return retcode_; -#else - if (!child_created_) return -1; // TODO: ?? - - int status; - - // Returns zero if child is still running - int ret = waitpid(child_pid_, &status, WNOHANG); - if (ret == 0) return -1; - - if (ret == child_pid_) { - if (WIFSIGNALED(status)) { - retcode_ = WTERMSIG(status); - } else if (WIFEXITED(status)) { - retcode_ = WEXITSTATUS(status); - } else { - retcode_ = 255; - } - return retcode_; - } - - if (ret == -1) { - // From subprocess.py - // This happens if SIGCHLD is set to be ignored - // or waiting for child process has otherwise been disabled - // for our process. This child is dead, we cannot get the - // status. - if (errno == ECHILD) retcode_ = 0; - else throw OSError("waitpid failed", errno); - } else { - retcode_ = ret; - } - - return retcode_; -#endif -} - inline void Popen::execute_process() noexcept(false) { #ifdef __USING_WINDOWS__ @@ -1233,8 +1161,6 @@ inline void Popen::execute_process() noexcept(false) throw OSError("fork failed", errno); } - child_created_ = true; - if (child_pid_ == 0) { // Close descriptors belonging to parent diff --git a/src/util/threadnames.cpp b/src/util/threadnames.cpp index ea597dd05a..0249de37e3 100644 --- a/src/util/threadnames.cpp +++ b/src/util/threadnames.cpp @@ -4,6 +4,7 @@ #include <config/bitcoin-config.h> // IWYU pragma: keep +#include <cstring> #include <string> #include <thread> #include <utility> @@ -36,31 +37,30 @@ static void SetThreadName(const char* name) #endif } -// If we have thread_local, just keep thread ID and name in a thread_local -// global. -#if defined(HAVE_THREAD_LOCAL) - -static thread_local std::string g_thread_name; -const std::string& util::ThreadGetInternalName() { return g_thread_name; } +/** + * The name of the thread. We use char array instead of std::string to avoid + * complications with running a destructor when the thread exits. Avoid adding + * other thread_local variables. + * @see https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=278701 + */ +static thread_local char g_thread_name[128]{'\0'}; +std::string util::ThreadGetInternalName() { return g_thread_name; } //! Set the in-memory internal name for this thread. Does not affect the process //! name. -static void SetInternalName(std::string name) { g_thread_name = std::move(name); } - -// Without thread_local available, don't handle internal name at all. -#else - -static const std::string empty_string; -const std::string& util::ThreadGetInternalName() { return empty_string; } -static void SetInternalName(std::string name) { } -#endif +static void SetInternalName(const std::string& name) +{ + const size_t copy_bytes{std::min(sizeof(g_thread_name) - 1, name.length())}; + std::memcpy(g_thread_name, name.data(), copy_bytes); + g_thread_name[copy_bytes] = '\0'; +} -void util::ThreadRename(std::string&& name) +void util::ThreadRename(const std::string& name) { SetThreadName(("b-" + name).c_str()); - SetInternalName(std::move(name)); + SetInternalName(name); } -void util::ThreadSetInternalName(std::string&& name) +void util::ThreadSetInternalName(const std::string& name) { - SetInternalName(std::move(name)); + SetInternalName(name); } diff --git a/src/util/threadnames.h b/src/util/threadnames.h index 64b2689cf1..adca8c3000 100644 --- a/src/util/threadnames.h +++ b/src/util/threadnames.h @@ -12,14 +12,14 @@ namespace util { //! as its system thread name. //! @note Do not call this for the main thread, as this will interfere with //! UNIX utilities such as top and killall. Use ThreadSetInternalName instead. -void ThreadRename(std::string&&); +void ThreadRename(const std::string&); //! Set the internal (in-memory) name of the current thread only. -void ThreadSetInternalName(std::string&&); +void ThreadSetInternalName(const std::string&); //! Get the thread's internal (in-memory) name; used e.g. for identification in //! logging. -const std::string& ThreadGetInternalName(); +std::string ThreadGetInternalName(); } // namespace util diff --git a/src/util/vecdeque.h b/src/util/vecdeque.h new file mode 100644 index 0000000000..a9264a5ad6 --- /dev/null +++ b/src/util/vecdeque.h @@ -0,0 +1,317 @@ +// Copyright (c) The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_UTIL_VECDEQUE_H +#define BITCOIN_UTIL_VECDEQUE_H + +#include <util/check.h> + +#include <cstring> +#include <memory> +#include <type_traits> + +/** Data structure largely mimicking std::deque, but using single preallocated ring buffer. + * + * - More efficient and better memory locality than std::deque. + * - Most operations ({push_,pop_,emplace_,}{front,back}(), operator[], ...) are O(1), + * unless reallocation is needed (in which case they are O(n)). + * - Supports reserve(), capacity(), shrink_to_fit() like vectors. + * - No iterator support. + * - Data is not stored in a single contiguous block, so no data(). + */ +template<typename T> +class VecDeque +{ + /** Pointer to allocated memory. Can contain constructed and uninitialized T objects. */ + T* m_buffer{nullptr}; + /** m_buffer + m_offset points to first object in queue. m_offset = 0 if m_capacity is 0; + * otherwise 0 <= m_offset < m_capacity. */ + size_t m_offset{0}; + /** Number of objects in the container. 0 <= m_size <= m_capacity. */ + size_t m_size{0}; + /** The size of m_buffer, expressed as a multiple of the size of T. */ + size_t m_capacity{0}; + + /** Returns the number of populated objects between m_offset and the end of the buffer. */ + size_t FirstPart() const noexcept { return std::min(m_capacity - m_offset, m_size); } + + void Reallocate(size_t capacity) + { + Assume(capacity >= m_size); + Assume((m_offset == 0 && m_capacity == 0) || m_offset < m_capacity); + // Allocate new buffer. + T* new_buffer = capacity ? std::allocator<T>().allocate(capacity) : nullptr; + if (capacity) { + if constexpr (std::is_trivially_copyable_v<T>) { + // When T is trivially copyable, just copy the data over from old to new buffer. + size_t first_part = FirstPart(); + if (first_part != 0) { + std::memcpy(new_buffer, m_buffer + m_offset, first_part * sizeof(T)); + } + if (first_part != m_size) { + std::memcpy(new_buffer + first_part, m_buffer, (m_size - first_part) * sizeof(T)); + } + } else { + // Otherwise move-construct in place in the new buffer, and destroy old buffer objects. + size_t old_pos = m_offset; + for (size_t new_pos = 0; new_pos < m_size; ++new_pos) { + std::construct_at(new_buffer + new_pos, std::move(*(m_buffer + old_pos))); + std::destroy_at(m_buffer + old_pos); + ++old_pos; + if (old_pos == m_capacity) old_pos = 0; + } + } + } + // Deallocate old buffer and update housekeeping. + std::allocator<T>().deallocate(m_buffer, m_capacity); + m_buffer = new_buffer; + m_offset = 0; + m_capacity = capacity; + Assume((m_offset == 0 && m_capacity == 0) || m_offset < m_capacity); + } + + /** What index in the buffer does logical entry number pos have? */ + size_t BufferIndex(size_t pos) const noexcept + { + Assume(pos < m_capacity); + // The expression below is used instead of the more obvious (pos + m_offset >= m_capacity), + // because the addition there could in theory overflow with very large deques. + if (pos >= m_capacity - m_offset) { + return (m_offset + pos) - m_capacity; + } else { + return m_offset + pos; + } + } + + /** Specialization of resize() that can only shrink. Separate so that clear() can call it + * without requiring a default T constructor. */ + void ResizeDown(size_t size) noexcept + { + Assume(size <= m_size); + if constexpr (std::is_trivially_destructible_v<T>) { + // If T is trivially destructible, we do not need to do anything but update the + // housekeeping record. Default constructor or zero-filling will be used when + // the space is reused. + m_size = size; + } else { + // If not, we need to invoke the destructor for every element separately. + while (m_size > size) { + std::destroy_at(m_buffer + BufferIndex(m_size - 1)); + --m_size; + } + } + } + +public: + VecDeque() noexcept = default; + + /** Resize the deque to be exactly size size (adding default-constructed elements if needed). */ + void resize(size_t size) + { + if (size < m_size) { + // Delegate to ResizeDown when shrinking. + ResizeDown(size); + } else if (size > m_size) { + // When growing, first see if we need to allocate more space. + if (size > m_capacity) Reallocate(size); + while (m_size < size) { + std::construct_at(m_buffer + BufferIndex(m_size)); + ++m_size; + } + } + } + + /** Resize the deque to be size 0. The capacity will remain unchanged. */ + void clear() noexcept { ResizeDown(0); } + + /** Destroy a deque. */ + ~VecDeque() + { + clear(); + Reallocate(0); + } + + /** Copy-assign a deque. */ + VecDeque& operator=(const VecDeque& other) + { + if (&other == this) [[unlikely]] return *this; + clear(); + Reallocate(other.m_size); + if constexpr (std::is_trivially_copyable_v<T>) { + size_t first_part = other.FirstPart(); + Assume(first_part > 0 || m_size == 0); + if (first_part != 0) { + std::memcpy(m_buffer, other.m_buffer + other.m_offset, first_part * sizeof(T)); + } + if (first_part != other.m_size) { + std::memcpy(m_buffer + first_part, other.m_buffer, (other.m_size - first_part) * sizeof(T)); + } + m_size = other.m_size; + } else { + while (m_size < other.m_size) { + std::construct_at(m_buffer + BufferIndex(m_size), other[m_size]); + ++m_size; + } + } + return *this; + } + + /** Swap two deques. */ + void swap(VecDeque& other) noexcept + { + std::swap(m_buffer, other.m_buffer); + std::swap(m_offset, other.m_offset); + std::swap(m_size, other.m_size); + std::swap(m_capacity, other.m_capacity); + } + + /** Non-member version of swap. */ + friend void swap(VecDeque& a, VecDeque& b) noexcept { a.swap(b); } + + /** Move-assign a deque. */ + VecDeque& operator=(VecDeque&& other) noexcept + { + swap(other); + return *this; + } + + /** Copy-construct a deque. */ + VecDeque(const VecDeque& other) { *this = other; } + /** Move-construct a deque. */ + VecDeque(VecDeque&& other) noexcept { swap(other); } + + /** Equality comparison between two deques (only compares size+contents, not capacity). */ + bool friend operator==(const VecDeque& a, const VecDeque& b) + { + if (a.m_size != b.m_size) return false; + for (size_t i = 0; i < a.m_size; ++i) { + if (a[i] != b[i]) return false; + } + return true; + } + + /** Comparison between two deques, implementing lexicographic ordering on the contents. */ + std::strong_ordering friend operator<=>(const VecDeque& a, const VecDeque& b) + { + size_t pos_a{0}, pos_b{0}; + while (pos_a < a.m_size && pos_b < b.m_size) { + auto cmp = a[pos_a++] <=> b[pos_b++]; + if (cmp != 0) return cmp; + } + return a.m_size <=> b.m_size; + } + + /** Increase the capacity to capacity. Capacity will not shrink. */ + void reserve(size_t capacity) + { + if (capacity > m_capacity) Reallocate(capacity); + } + + /** Make the capacity equal to the size. The contents does not change. */ + void shrink_to_fit() + { + if (m_capacity > m_size) Reallocate(m_size); + } + + /** Construct a new element at the end of the deque. */ + template<typename... Args> + void emplace_back(Args&&... args) + { + if (m_size == m_capacity) Reallocate((m_size + 1) * 2); + std::construct_at(m_buffer + BufferIndex(m_size), std::forward<Args>(args)...); + ++m_size; + } + + /** Move-construct a new element at the end of the deque. */ + void push_back(T&& elem) { emplace_back(std::move(elem)); } + + /** Copy-construct a new element at the end of the deque. */ + void push_back(const T& elem) { emplace_back(elem); } + + /** Construct a new element at the beginning of the deque. */ + template<typename... Args> + void emplace_front(Args&&... args) + { + if (m_size == m_capacity) Reallocate((m_size + 1) * 2); + std::construct_at(m_buffer + BufferIndex(m_capacity - 1), std::forward<Args>(args)...); + if (m_offset == 0) m_offset = m_capacity; + --m_offset; + ++m_size; + } + + /** Copy-construct a new element at the beginning of the deque. */ + void push_front(const T& elem) { emplace_front(elem); } + + /** Move-construct a new element at the beginning of the deque. */ + void push_front(T&& elem) { emplace_front(std::move(elem)); } + + /** Remove the first element of the deque. Requires !empty(). */ + void pop_front() + { + Assume(m_size); + std::destroy_at(m_buffer + m_offset); + --m_size; + ++m_offset; + if (m_offset == m_capacity) m_offset = 0; + } + + /** Remove the last element of the deque. Requires !empty(). */ + void pop_back() + { + Assume(m_size); + std::destroy_at(m_buffer + BufferIndex(m_size - 1)); + --m_size; + } + + /** Get a mutable reference to the first element of the deque. Requires !empty(). */ + T& front() noexcept + { + Assume(m_size); + return m_buffer[m_offset]; + } + + /** Get a const reference to the first element of the deque. Requires !empty(). */ + const T& front() const noexcept + { + Assume(m_size); + return m_buffer[m_offset]; + } + + /** Get a mutable reference to the last element of the deque. Requires !empty(). */ + T& back() noexcept + { + Assume(m_size); + return m_buffer[BufferIndex(m_size - 1)]; + } + + /** Get a const reference to the last element of the deque. Requires !empty(). */ + const T& back() const noexcept + { + Assume(m_size); + return m_buffer[BufferIndex(m_size - 1)]; + } + + /** Get a mutable reference to the element in the deque at the given index. Requires idx < size(). */ + T& operator[](size_t idx) noexcept + { + Assume(idx < m_size); + return m_buffer[BufferIndex(idx)]; + } + + /** Get a const reference to the element in the deque at the given index. Requires idx < size(). */ + const T& operator[](size_t idx) const noexcept + { + Assume(idx < m_size); + return m_buffer[BufferIndex(idx)]; + } + + /** Test whether the contents of this deque is empty. */ + bool empty() const noexcept { return m_size == 0; } + /** Get the number of elements in this deque. */ + size_t size() const noexcept { return m_size; } + /** Get the capacity of this deque (maximum size it can have without reallocating). */ + size_t capacity() const noexcept { return m_capacity; } +}; + +#endif // BITCOIN_UTIL_VECDEQUE_H diff --git a/src/validation.cpp b/src/validation.cpp index c2b56555a2..3e9ba08bb1 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -27,14 +27,15 @@ #include <kernel/mempool_entry.h> #include <kernel/messagestartchars.h> #include <kernel/notifications_interface.h> +#include <kernel/warning.h> #include <logging.h> #include <logging/timer.h> #include <node/blockstorage.h> #include <node/utxo_snapshot.h> -#include <policy/v3_policy.h> #include <policy/policy.h> #include <policy/rbf.h> #include <policy/settings.h> +#include <policy/v3_policy.h> #include <pow.h> #include <primitives/block.h> #include <primitives/transaction.h> @@ -57,11 +58,11 @@ #include <util/result.h> #include <util/signalinterrupt.h> #include <util/strencodings.h> +#include <util/string.h> #include <util/time.h> #include <util/trace.h> #include <util/translation.h> #include <validationinterface.h> -#include <warnings.h> #include <algorithm> #include <cassert> @@ -83,7 +84,6 @@ using node::BlockManager; using node::BlockMap; using node::CBlockIndexHeightOnlyComparator; using node::CBlockIndexWorkComparator; -using node::fReindex; using node::SnapshotMetadata; /** Time to wait between writing blocks/block index to disk. */ @@ -266,13 +266,13 @@ static void LimitMempoolSize(CTxMemPool& pool, CCoinsViewCache& coins_cache) { AssertLockHeld(::cs_main); AssertLockHeld(pool.cs); - int expired = pool.Expire(GetTime<std::chrono::seconds>() - pool.m_expiry); + int expired = pool.Expire(GetTime<std::chrono::seconds>() - pool.m_opts.expiry); if (expired != 0) { LogPrint(BCLog::MEMPOOL, "Expired %i transactions from the memory pool\n", expired); } std::vector<COutPoint> vNoSpendsRemaining; - pool.TrimToSize(pool.m_max_size_bytes, &vNoSpendsRemaining); + pool.TrimToSize(pool.m_opts.max_size_bytes, &vNoSpendsRemaining); for (const COutPoint& removed : vNoSpendsRemaining) coins_cache.Uncache(removed); } @@ -456,11 +456,14 @@ public: * the mempool. */ std::vector<COutPoint>& m_coins_to_uncache; + /** When true, the transaction or package will not be submitted to the mempool. */ const bool m_test_accept; - /** Whether we allow transactions to replace mempool transactions by BIP125 rules. If false, + /** Whether we allow transactions to replace mempool transactions. If false, * any transaction spending the same inputs as a transaction in the mempool is considered * a conflict. */ const bool m_allow_replacement; + /** When true, allow sibling eviction. This only occurs in single transaction package settings. */ + const bool m_allow_sibling_eviction; /** When true, the mempool will not be trimmed when any transactions are submitted in * Finalize(). Instead, limits should be enforced at the end to ensure the package is not * partially submitted. @@ -476,6 +479,9 @@ public: */ const std::optional<CFeeRate> m_client_maxfeerate; + /** Whether CPFP carveout and RBF carveout are granted. */ + const bool m_allow_carveouts; + /** Parameters for single transaction mempool validation. */ static ATMPArgs SingleAccept(const CChainParams& chainparams, int64_t accept_time, bool bypass_limits, std::vector<COutPoint>& coins_to_uncache, @@ -486,9 +492,11 @@ public: /* m_coins_to_uncache */ coins_to_uncache, /* m_test_accept */ test_accept, /* m_allow_replacement */ true, + /* m_allow_sibling_eviction */ true, /* m_package_submission */ false, /* m_package_feerates */ false, /* m_client_maxfeerate */ {}, // checked by caller + /* m_allow_carveouts */ true, }; } @@ -501,9 +509,11 @@ public: /* m_coins_to_uncache */ coins_to_uncache, /* m_test_accept */ true, /* m_allow_replacement */ false, + /* m_allow_sibling_eviction */ false, /* m_package_submission */ false, // not submitting to mempool /* m_package_feerates */ false, /* m_client_maxfeerate */ {}, // checked by caller + /* m_allow_carveouts */ false, }; } @@ -515,10 +525,12 @@ public: /* m_bypass_limits */ false, /* m_coins_to_uncache */ coins_to_uncache, /* m_test_accept */ false, - /* m_allow_replacement */ false, + /* m_allow_replacement */ true, + /* m_allow_sibling_eviction */ false, /* m_package_submission */ true, /* m_package_feerates */ true, /* m_client_maxfeerate */ client_maxfeerate, + /* m_allow_carveouts */ false, }; } @@ -530,9 +542,11 @@ public: /* m_coins_to_uncache */ package_args.m_coins_to_uncache, /* m_test_accept */ package_args.m_test_accept, /* m_allow_replacement */ true, + /* m_allow_sibling_eviction */ true, /* m_package_submission */ true, // do not LimitMempoolSize in Finalize() /* m_package_feerates */ false, // only 1 transaction /* m_client_maxfeerate */ package_args.m_client_maxfeerate, + /* m_allow_carveouts */ false, }; } @@ -545,19 +559,31 @@ public: std::vector<COutPoint>& coins_to_uncache, bool test_accept, bool allow_replacement, + bool allow_sibling_eviction, bool package_submission, bool package_feerates, - std::optional<CFeeRate> client_maxfeerate) + std::optional<CFeeRate> client_maxfeerate, + bool allow_carveouts) : m_chainparams{chainparams}, m_accept_time{accept_time}, m_bypass_limits{bypass_limits}, m_coins_to_uncache{coins_to_uncache}, m_test_accept{test_accept}, m_allow_replacement{allow_replacement}, + m_allow_sibling_eviction{allow_sibling_eviction}, m_package_submission{package_submission}, m_package_feerates{package_feerates}, - m_client_maxfeerate{client_maxfeerate} + m_client_maxfeerate{client_maxfeerate}, + m_allow_carveouts{allow_carveouts} { + // If we are using package feerates, we must be doing package submission. + // It also means carveouts and sibling eviction are not permitted. + if (m_package_feerates) { + Assume(m_package_submission); + Assume(!m_allow_carveouts); + Assume(!m_allow_sibling_eviction); + } + if (m_allow_sibling_eviction) Assume(m_allow_replacement); } }; @@ -577,8 +603,8 @@ public: /** * Submission of a subpackage. * If subpackage size == 1, calls AcceptSingleTransaction() with adjusted ATMPArgs to avoid - * package policy restrictions like no CPFP carve out (PackageMempoolChecks) and disabled RBF - * (m_allow_replacement), and creates a PackageMempoolAcceptResult wrapping the result. + * package policy restrictions like no CPFP carve out (PackageMempoolChecks) + * and creates a PackageMempoolAcceptResult wrapping the result. * * If subpackage size > 1, calls AcceptMultipleTransactions() with the provided ATMPArgs. * @@ -604,18 +630,11 @@ private: /** Iterators to mempool entries that this transaction directly conflicts with or may * replace via sibling eviction. */ CTxMemPool::setEntries m_iters_conflicting; - /** Iterators to all mempool entries that would be replaced by this transaction, including - * m_conflicts and their descendants. */ - CTxMemPool::setEntries m_all_conflicting; /** All mempool ancestors of this transaction. */ CTxMemPool::setEntries m_ancestors; /** Mempool entry constructed for this transaction. Constructed in PreChecks() but not * inserted into the mempool until Finalize(). */ std::unique_ptr<CTxMemPoolEntry> m_entry; - /** Pointers to the transactions that have been removed from the mempool and replaced by - * this transaction (everything in m_all_conflicting), used to return to the MemPoolAccept caller. Only populated if - * validation is successful and the original transactions are removed. */ - std::list<CTransactionRef> m_replaced_transactions; /** Whether RBF-related data structures (m_conflicts, m_iters_conflicting, m_all_conflicting, * m_replaced_transactions) include a sibling in addition to txns with conflicting inputs. */ bool m_sibling_eviction{false}; @@ -627,10 +646,6 @@ private: CAmount m_base_fees; /** Base fees + any fee delta set by the user with prioritisetransaction. */ CAmount m_modified_fees; - /** Total modified fees of all transactions being replaced. */ - CAmount m_conflicting_fees{0}; - /** Total virtual size of all transactions being replaced. */ - size_t m_conflicting_size{0}; /** If we're doing package validation (i.e. m_package_feerates=true), the "effective" * package feerate of this transaction is the total fees divided by the total size of @@ -652,12 +667,13 @@ private: // only tests that are fast should be done here (to avoid CPU DoS). bool PreChecks(ATMPArgs& args, Workspace& ws) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs); - // Run checks for mempool replace-by-fee. + // Run checks for mempool replace-by-fee, only used in AcceptSingleTransaction. bool ReplacementChecks(Workspace& ws) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs); // Enforce package mempool ancestor/descendant limits (distinct from individual - // ancestor/descendant limits done in PreChecks). + // ancestor/descendant limits done in PreChecks) and run Package RBF checks. bool PackageMempoolChecks(const std::vector<CTransactionRef>& txns, + std::vector<Workspace>& workspaces, int64_t total_vsize, PackageValidationState& package_state) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs); @@ -693,9 +709,9 @@ private: return state.Invalid(TxValidationResult::TX_RECONSIDERABLE, "mempool min fee not met", strprintf("%d < %d", package_fee, mempoolRejectFee)); } - if (package_fee < m_pool.m_min_relay_feerate.GetFee(package_size)) { + if (package_fee < m_pool.m_opts.min_relay_feerate.GetFee(package_size)) { return state.Invalid(TxValidationResult::TX_RECONSIDERABLE, "min relay fee not met", - strprintf("%d < %d", package_fee, m_pool.m_min_relay_feerate.GetFee(package_size))); + strprintf("%d < %d", package_fee, m_pool.m_opts.min_relay_feerate.GetFee(package_size))); } return true; } @@ -708,9 +724,39 @@ private: Chainstate& m_active_chainstate; - /** Whether the transaction(s) would replace any mempool transactions and/or evict any siblings. - * If so, RBF rules apply. */ - bool m_rbf{false}; + // Fields below are per *sub*package state and must be reset prior to subsequent + // AcceptSingleTransaction and AcceptMultipleTransactions invocations + struct SubPackageState { + /** Aggregated modified fees of all transactions, used to calculate package feerate. */ + CAmount m_total_modified_fees{0}; + /** Aggregated virtual size of all transactions, used to calculate package feerate. */ + int64_t m_total_vsize{0}; + + // RBF-related members + /** Whether the transaction(s) would replace any mempool transactions and/or evict any siblings. + * If so, RBF rules apply. */ + bool m_rbf{false}; + /** All directly conflicting mempool transactions and their descendants. */ + CTxMemPool::setEntries m_all_conflicts; + /** Mempool transactions that were replaced. */ + std::list<CTransactionRef> m_replaced_transactions; + + /** Total modified fees of mempool transactions being replaced. */ + CAmount m_conflicting_fees{0}; + /** Total size (in virtual bytes) of mempool transactions being replaced. */ + size_t m_conflicting_size{0}; + }; + + struct SubPackageState m_subpackage; + + /** Re-set sub-package state to not leak between evaluations */ + void ClearSubPackageState() EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs) + { + m_subpackage = SubPackageState{}; + + // And clean coins while at it + CleanupTemporaryCoins(); + } }; bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws) @@ -740,7 +786,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws) // Rather not work on nonstandard transactions (unless -testnet/-regtest) std::string reason; - if (m_pool.m_require_standard && !IsStandardTx(tx, m_pool.m_max_datacarrier_bytes, m_pool.m_permit_bare_multisig, m_pool.m_dust_relay_feerate, reason)) { + if (m_pool.m_opts.require_standard && !IsStandardTx(tx, m_pool.m_opts.max_datacarrier_bytes, m_pool.m_opts.permit_bare_multisig, m_pool.m_opts.dust_relay_feerate, reason)) { return state.Invalid(TxValidationResult::TX_NOT_STANDARD, reason); } @@ -787,7 +833,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws) // // Replaceability signaling of the original transactions may be // ignored due to node setting. - const bool allow_rbf{m_pool.m_full_rbf || SignalsOptInRBF(*ptxConflicting) || ptxConflicting->nVersion == 3}; + const bool allow_rbf{m_pool.m_opts.full_rbf || SignalsOptInRBF(*ptxConflicting) || ptxConflicting->version == TRUC_VERSION}; if (!allow_rbf) { return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "txn-mempool-conflict"); } @@ -848,12 +894,12 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws) return false; // state filled in by CheckTxInputs } - if (m_pool.m_require_standard && !AreInputsStandard(tx, m_view)) { + if (m_pool.m_opts.require_standard && !AreInputsStandard(tx, m_view)) { return state.Invalid(TxValidationResult::TX_INPUTS_NOT_STANDARD, "bad-txns-nonstandard-inputs"); } // Check for non-standard witnesses. - if (tx.HasWitness() && m_pool.m_require_standard && !IsWitnessStandard(tx, m_view)) { + if (tx.HasWitness() && m_pool.m_opts.require_standard && !IsWitnessStandard(tx, m_view)) { return state.Invalid(TxValidationResult::TX_WITNESS_MUTATED, "bad-witness-nonstandard"); } @@ -891,11 +937,11 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws) // method of ensuring the tx remains bumped. For example, the fee-bumping child could disappear // due to a replacement. // The only exception is v3 transactions. - if (!bypass_limits && ws.m_ptx->nVersion != 3 && ws.m_modified_fees < m_pool.m_min_relay_feerate.GetFee(ws.m_vsize)) { + if (!bypass_limits && ws.m_ptx->version != TRUC_VERSION && ws.m_modified_fees < m_pool.m_opts.min_relay_feerate.GetFee(ws.m_vsize)) { // Even though this is a fee-related failure, this result is TX_MEMPOOL_POLICY, not // TX_RECONSIDERABLE, because it cannot be bypassed using package validation. return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "min relay fee not met", - strprintf("%d < %d", ws.m_modified_fees, m_pool.m_min_relay_feerate.GetFee(ws.m_vsize))); + strprintf("%d < %d", ws.m_modified_fees, m_pool.m_opts.min_relay_feerate.GetFee(ws.m_vsize))); } // No individual transactions are allowed below the mempool min feerate except from disconnected // blocks and transactions in a package. Package transactions will be checked using package @@ -905,11 +951,11 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws) ws.m_iters_conflicting = m_pool.GetIterSet(ws.m_conflicts); // Note that these modifications are only applicable to single transaction scenarios; - // carve-outs and package RBF are disabled for multi-transaction evaluations. - CTxMemPool::Limits maybe_rbf_limits = m_pool.m_limits; + // carve-outs are disabled for multi-transaction evaluations. + CTxMemPool::Limits maybe_rbf_limits = m_pool.m_opts.limits; // Calculate in-mempool ancestors, up to a limit. - if (ws.m_conflicts.size() == 1) { + if (ws.m_conflicts.size() == 1 && args.m_allow_carveouts) { // In general, when we receive an RBF transaction with mempool conflicts, we want to know whether we // would meet the chain limits after the conflicts have been removed. However, there isn't a practical // way to do this short of calculating the ancestor and descendant sets with an overlay cache of @@ -948,11 +994,19 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws) ws.m_ancestors = std::move(*ancestors); } else { // If CalculateMemPoolAncestors fails second time, we want the original error string. + const auto error_message{util::ErrorString(ancestors).original}; + + // Carve-out is not allowed in this context; fail + if (!args.m_allow_carveouts) { + return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "too-long-mempool-chain", error_message); + } + // Contracting/payment channels CPFP carve-out: // If the new transaction is relatively small (up to 40k weight) // and has at most one ancestor (ie ancestor limit of 2, including // the new transaction), allow it if its parent has exactly the - // descendant limit descendants. + // descendant limit descendants. The transaction also cannot be v3, + // as its topology restrictions do not allow a second child. // // This allows protocols which rely on distrusting counterparties // being able to broadcast descendants of an unconfirmed transaction @@ -965,8 +1019,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws) .descendant_count = maybe_rbf_limits.descendant_count + 1, .descendant_size_vbytes = maybe_rbf_limits.descendant_size_vbytes + EXTRA_DESCENDANT_TX_SIZE_LIMIT, }; - const auto error_message{util::ErrorString(ancestors).original}; - if (ws.m_vsize > EXTRA_DESCENDANT_TX_SIZE_LIMIT) { + if (ws.m_vsize > EXTRA_DESCENDANT_TX_SIZE_LIMIT || ws.m_ptx->version == TRUC_VERSION) { return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "too-long-mempool-chain", error_message); } if (auto ancestors_retry{m_pool.CalculateMemPoolAncestors(*entry, cpfp_carve_out_limits)}) { @@ -980,8 +1033,11 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws) // check using the full ancestor set here because it's more convenient to use what we have // already calculated. if (const auto err{SingleV3Checks(ws.m_ptx, ws.m_ancestors, ws.m_conflicts, ws.m_vsize)}) { - // Disabled within package validation. - if (err->second != nullptr && args.m_allow_replacement) { + // Single transaction contexts only. + if (args.m_allow_sibling_eviction && err->second != nullptr) { + // We should only be considering where replacement is considered valid as well. + Assume(args.m_allow_replacement); + // Potential sibling eviction. Add the sibling to our list of mempool conflicts to be // included in RBF checks. ws.m_conflicts.insert(err->second->GetHash()); @@ -1009,7 +1065,8 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws) return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-spends-conflicting-tx", *err_string); } - m_rbf = !ws.m_conflicts.empty(); + // We want to detect conflicts in any tx in a package to trigger package RBF logic + m_subpackage.m_rbf |= !ws.m_conflicts.empty(); return true; } @@ -1033,43 +1090,42 @@ bool MemPoolAccept::ReplacementChecks(Workspace& ws) // descendant transaction of a direct conflict to pay a higher feerate than the transaction that // might replace them, under these rules. if (const auto err_string{PaysMoreThanConflicts(ws.m_iters_conflicting, newFeeRate, hash)}) { - // Even though this is a fee-related failure, this result is TX_MEMPOOL_POLICY, not - // TX_RECONSIDERABLE, because it cannot be bypassed using package validation. - // This must be changed if package RBF is enabled. - return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, + // This fee-related failure is TX_RECONSIDERABLE because validating in a package may change + // the result. + return state.Invalid(TxValidationResult::TX_RECONSIDERABLE, strprintf("insufficient fee%s", ws.m_sibling_eviction ? " (including sibling eviction)" : ""), *err_string); } // Calculate all conflicting entries and enforce Rule #5. - if (const auto err_string{GetEntriesForConflicts(tx, m_pool, ws.m_iters_conflicting, ws.m_all_conflicting)}) { + if (const auto err_string{GetEntriesForConflicts(tx, m_pool, ws.m_iters_conflicting, m_subpackage.m_all_conflicts)}) { return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, strprintf("too many potential replacements%s", ws.m_sibling_eviction ? " (including sibling eviction)" : ""), *err_string); } // Enforce Rule #2. - if (const auto err_string{HasNoNewUnconfirmed(tx, m_pool, ws.m_iters_conflicting)}) { + if (const auto err_string{HasNoNewUnconfirmed(tx, m_pool, m_subpackage.m_all_conflicts)}) { // Sibling eviction is only done for v3 transactions, which cannot have multiple ancestors. Assume(!ws.m_sibling_eviction); return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, strprintf("replacement-adds-unconfirmed%s", ws.m_sibling_eviction ? " (including sibling eviction)" : ""), *err_string); } + // Check if it's economically rational to mine this transaction rather than the ones it // replaces and pays for its own relay fees. Enforce Rules #3 and #4. - for (CTxMemPool::txiter it : ws.m_all_conflicting) { - ws.m_conflicting_fees += it->GetModifiedFee(); - ws.m_conflicting_size += it->GetTxSize(); - } - if (const auto err_string{PaysForRBF(ws.m_conflicting_fees, ws.m_modified_fees, ws.m_vsize, - m_pool.m_incremental_relay_feerate, hash)}) { - // Even though this is a fee-related failure, this result is TX_MEMPOOL_POLICY, not - // TX_RECONSIDERABLE, because it cannot be bypassed using package validation. - // This must be changed if package RBF is enabled. - return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, + for (CTxMemPool::txiter it : m_subpackage.m_all_conflicts) { + m_subpackage.m_conflicting_fees += it->GetModifiedFee(); + m_subpackage.m_conflicting_size += it->GetTxSize(); + } + if (const auto err_string{PaysForRBF(m_subpackage.m_conflicting_fees, ws.m_modified_fees, ws.m_vsize, + m_pool.m_opts.incremental_relay_feerate, hash)}) { + // Result may change in a package context + return state.Invalid(TxValidationResult::TX_RECONSIDERABLE, strprintf("insufficient fee%s", ws.m_sibling_eviction ? " (including sibling eviction)" : ""), *err_string); } return true; } bool MemPoolAccept::PackageMempoolChecks(const std::vector<CTransactionRef>& txns, + std::vector<Workspace>& workspaces, const int64_t total_vsize, PackageValidationState& package_state) { @@ -1080,12 +1136,88 @@ bool MemPoolAccept::PackageMempoolChecks(const std::vector<CTransactionRef>& txn assert(std::all_of(txns.cbegin(), txns.cend(), [this](const auto& tx) { return !m_pool.exists(GenTxid::Txid(tx->GetHash()));})); + assert(txns.size() == workspaces.size()); + auto result = m_pool.CheckPackageLimits(txns, total_vsize); if (!result) { // This is a package-wide error, separate from an individual transaction error. return package_state.Invalid(PackageValidationResult::PCKG_POLICY, "package-mempool-limits", util::ErrorString(result).original); } - return true; + + // No conflicts means we're finished. Further checks are all RBF-only. + if (!m_subpackage.m_rbf) return true; + + // We're in package RBF context; replacement proposal must be size 2 + if (workspaces.size() != 2 || !Assume(IsChildWithParents(txns))) { + return package_state.Invalid(PackageValidationResult::PCKG_POLICY, "package RBF failed: package must be 1-parent-1-child"); + } + + // If the package has in-mempool ancestors, we won't consider a package RBF + // since it would result in a cluster larger than 2. + // N.B. To relax this constraint we will need to revisit how CCoinsViewMemPool::PackageAddTransaction + // is being used inside AcceptMultipleTransactions to track available inputs while processing a package. + for (const auto& ws : workspaces) { + if (!ws.m_ancestors.empty()) { + return package_state.Invalid(PackageValidationResult::PCKG_POLICY, "package RBF failed: new transaction cannot have mempool ancestors"); + } + } + + // Aggregate all conflicts into one set. + CTxMemPool::setEntries direct_conflict_iters; + for (Workspace& ws : workspaces) { + // Aggregate all conflicts into one set. + direct_conflict_iters.merge(ws.m_iters_conflicting); + } + + const auto& parent_ws = workspaces[0]; + const auto& child_ws = workspaces[1]; + + // Don't consider replacements that would cause us to remove a large number of mempool entries. + // This limit is not increased in a package RBF. Use the aggregate number of transactions. + if (const auto err_string{GetEntriesForConflicts(*child_ws.m_ptx, m_pool, direct_conflict_iters, + m_subpackage.m_all_conflicts)}) { + return package_state.Invalid(PackageValidationResult::PCKG_POLICY, + "package RBF failed: too many potential replacements", *err_string); + } + + for (CTxMemPool::txiter it : m_subpackage.m_all_conflicts) { + m_subpackage.m_conflicting_fees += it->GetModifiedFee(); + m_subpackage.m_conflicting_size += it->GetTxSize(); + } + + // Use the child as the transaction for attributing errors to. + const Txid& child_hash = child_ws.m_ptx->GetHash(); + if (const auto err_string{PaysForRBF(/*original_fees=*/m_subpackage.m_conflicting_fees, + /*replacement_fees=*/m_subpackage.m_total_modified_fees, + /*replacement_vsize=*/m_subpackage.m_total_vsize, + m_pool.m_opts.incremental_relay_feerate, child_hash)}) { + return package_state.Invalid(PackageValidationResult::PCKG_POLICY, + "package RBF failed: insufficient anti-DoS fees", *err_string); + } + + // Ensure this two transaction package is a "chunk" on its own; we don't want the child + // to be only paying anti-DoS fees + const CFeeRate parent_feerate(parent_ws.m_modified_fees, parent_ws.m_vsize); + const CFeeRate package_feerate(m_subpackage.m_total_modified_fees, m_subpackage.m_total_vsize); + if (package_feerate <= parent_feerate) { + return package_state.Invalid(PackageValidationResult::PCKG_POLICY, + "package RBF failed: package feerate is less than parent feerate", + strprintf("package feerate %s <= parent feerate is %s", package_feerate.ToString(), parent_feerate.ToString())); + } + + // Check if it's economically rational to mine this package rather than the ones it replaces. + // This takes the place of ReplacementChecks()'s PaysMoreThanConflicts() in the package RBF setting. + if (const auto err_tup{ImprovesFeerateDiagram(m_pool, direct_conflict_iters, m_subpackage.m_all_conflicts, m_subpackage.m_total_modified_fees, m_subpackage.m_total_vsize)}) { + return package_state.Invalid(PackageValidationResult::PCKG_POLICY, + "package RBF failed: " + err_tup.value().second, ""); + } + + LogPrint(BCLog::TXPACKAGES, "package RBF checks passed: parent %s (wtxid=%s), child %s (wtxid=%s)\n", + txns.front()->GetHash().ToString(), txns.front()->GetWitnessHash().ToString(), + txns.back()->GetHash().ToString(), txns.back()->GetWitnessHash().ToString()); + + + return true; } bool MemPoolAccept::PolicyScriptChecks(const ATMPArgs& args, Workspace& ws) @@ -1157,19 +1289,21 @@ bool MemPoolAccept::Finalize(const ATMPArgs& args, Workspace& ws) const uint256& hash = ws.m_hash; TxValidationState& state = ws.m_state; const bool bypass_limits = args.m_bypass_limits; - std::unique_ptr<CTxMemPoolEntry>& entry = ws.m_entry; + if (!m_subpackage.m_all_conflicts.empty()) Assume(args.m_allow_replacement); // Remove conflicting transactions from the mempool - for (CTxMemPool::txiter it : ws.m_all_conflicting) + for (CTxMemPool::txiter it : m_subpackage.m_all_conflicts) { - LogPrint(BCLog::MEMPOOL, "replacing tx %s (wtxid=%s) with %s (wtxid=%s) for %s additional fees, %d delta bytes\n", + LogPrint(BCLog::MEMPOOL, "replacing mempool tx %s (wtxid=%s, fees=%s, vsize=%s). New tx %s (wtxid=%s, fees=%s, vsize=%s)\n", it->GetTx().GetHash().ToString(), it->GetTx().GetWitnessHash().ToString(), + it->GetFee(), + it->GetTxSize(), hash.ToString(), tx.GetWitnessHash().ToString(), - FormatMoney(ws.m_modified_fees - ws.m_conflicting_fees), - (int)entry->GetTxSize() - (int)ws.m_conflicting_size); + entry->GetFee(), + entry->GetTxSize()); TRACE7(mempool, replaced, it->GetTx().GetHash().data(), it->GetTxSize(), @@ -1179,9 +1313,12 @@ bool MemPoolAccept::Finalize(const ATMPArgs& args, Workspace& ws) entry->GetTxSize(), entry->GetFee() ); - ws.m_replaced_transactions.push_back(it->GetSharedTx()); + m_subpackage.m_replaced_transactions.push_back(it->GetSharedTx()); } - m_pool.RemoveStaged(ws.m_all_conflicting, false, MemPoolRemovalReason::REPLACED); + m_pool.RemoveStaged(m_subpackage.m_all_conflicts, false, MemPoolRemovalReason::REPLACED); + // Don't attempt to process the same conflicts repeatedly during subpackage evaluation: + // they no longer exist on subsequent calls to Finalize() post-RemoveStaged + m_subpackage.m_all_conflicts.clear(); // Store transaction in memory m_pool.addUnchecked(*entry, ws.m_ancestors); @@ -1228,7 +1365,7 @@ bool MemPoolAccept::SubmitPackage(const ATMPArgs& args, std::vector<Workspace>& // Re-calculate mempool ancestors to call addUnchecked(). They may have changed since the // last calculation done in PreChecks, since package ancestors have already been submitted. { - auto ancestors{m_pool.CalculateMemPoolAncestors(*ws.m_entry, m_pool.m_limits)}; + auto ancestors{m_pool.CalculateMemPoolAncestors(*ws.m_entry, m_pool.m_opts.limits)}; if(!ancestors) { results.emplace(ws.m_ptx->GetWitnessHash(), MempoolAcceptResult::Failure(ws.m_state)); // Since PreChecks() and PackageMempoolChecks() both enforce limits, this should never fail. @@ -1260,6 +1397,13 @@ bool MemPoolAccept::SubmitPackage(const ATMPArgs& args, std::vector<Workspace>& std::transform(workspaces.cbegin(), workspaces.cend(), std::back_inserter(all_package_wtxids), [](const auto& ws) { return ws.m_ptx->GetWitnessHash(); }); + if (!m_subpackage.m_replaced_transactions.empty()) { + LogPrint(BCLog::MEMPOOL, "replaced %u mempool transactions with %u new one(s) for %s additional fees, %d delta bytes\n", + m_subpackage.m_replaced_transactions.size(), workspaces.size(), + m_subpackage.m_total_modified_fees - m_subpackage.m_conflicting_fees, + m_subpackage.m_total_vsize - static_cast<int>(m_subpackage.m_conflicting_size)); + } + // Add successful results. The returned results may change later if LimitMempoolSize() evicts them. for (Workspace& ws : workspaces) { const auto effective_feerate = args.m_package_feerates ? ws.m_package_feerate : @@ -1267,16 +1411,16 @@ bool MemPoolAccept::SubmitPackage(const ATMPArgs& args, std::vector<Workspace>& const auto effective_feerate_wtxids = args.m_package_feerates ? all_package_wtxids : std::vector<Wtxid>{ws.m_ptx->GetWitnessHash()}; results.emplace(ws.m_ptx->GetWitnessHash(), - MempoolAcceptResult::Success(std::move(ws.m_replaced_transactions), ws.m_vsize, + MempoolAcceptResult::Success(std::move(m_subpackage.m_replaced_transactions), ws.m_vsize, ws.m_base_fees, effective_feerate, effective_feerate_wtxids)); - if (!m_pool.m_signals) continue; + if (!m_pool.m_opts.signals) continue; const CTransaction& tx = *ws.m_ptx; const auto tx_info = NewMempoolTransactionInfo(ws.m_ptx, ws.m_base_fees, ws.m_vsize, ws.m_entry->GetHeight(), args.m_bypass_limits, args.m_package_submission, IsCurrentForFeeEstimation(m_active_chainstate), m_pool.HasNoInputsOf(tx)); - m_pool.m_signals->TransactionAddedToMempool(tx_info, m_pool.GetAndIncrementSequence()); + m_pool.m_opts.signals->TransactionAddedToMempool(tx_info, m_pool.GetAndIncrementSequence()); } return all_submitted; } @@ -1284,7 +1428,7 @@ bool MemPoolAccept::SubmitPackage(const ATMPArgs& args, std::vector<Workspace>& MempoolAcceptResult MemPoolAccept::AcceptSingleTransaction(const CTransactionRef& ptx, ATMPArgs& args) { AssertLockHeld(cs_main); - LOCK(m_pool.cs); // mempool "read lock" (held through m_pool.m_signals->TransactionAddedToMempool()) + LOCK(m_pool.cs); // mempool "read lock" (held through m_pool.m_opts.signals->TransactionAddedToMempool()) Workspace ws(ptx); const std::vector<Wtxid> single_wtxid{ws.m_ptx->GetWitnessHash()}; @@ -1303,7 +1447,13 @@ MempoolAcceptResult MemPoolAccept::AcceptSingleTransaction(const CTransactionRef return MempoolAcceptResult::Failure(ws.m_state); } - if (m_rbf && !ReplacementChecks(ws)) return MempoolAcceptResult::Failure(ws.m_state); + if (m_subpackage.m_rbf && !ReplacementChecks(ws)) { + if (ws.m_state.GetResult() == TxValidationResult::TX_RECONSIDERABLE) { + // Failed for incentives-based fee reasons. Provide the effective feerate and which tx was included. + return MempoolAcceptResult::FeeFailure(ws.m_state, CFeeRate(ws.m_modified_fees, ws.m_vsize), single_wtxid); + } + return MempoolAcceptResult::Failure(ws.m_state); + } // Perform the inexpensive checks first and avoid hashing and signature verification unless // those checks pass, to mitigate CPU exhaustion denial-of-service attacks. @@ -1314,7 +1464,7 @@ MempoolAcceptResult MemPoolAccept::AcceptSingleTransaction(const CTransactionRef const CFeeRate effective_feerate{ws.m_modified_fees, static_cast<uint32_t>(ws.m_vsize)}; // Tx was accepted, but not added if (args.m_test_accept) { - return MempoolAcceptResult::Success(std::move(ws.m_replaced_transactions), ws.m_vsize, + return MempoolAcceptResult::Success(std::move(m_subpackage.m_replaced_transactions), ws.m_vsize, ws.m_base_fees, effective_feerate, single_wtxid); } @@ -1325,17 +1475,24 @@ MempoolAcceptResult MemPoolAccept::AcceptSingleTransaction(const CTransactionRef return MempoolAcceptResult::FeeFailure(ws.m_state, CFeeRate(ws.m_modified_fees, ws.m_vsize), {ws.m_ptx->GetWitnessHash()}); } - if (m_pool.m_signals) { + if (m_pool.m_opts.signals) { const CTransaction& tx = *ws.m_ptx; const auto tx_info = NewMempoolTransactionInfo(ws.m_ptx, ws.m_base_fees, ws.m_vsize, ws.m_entry->GetHeight(), args.m_bypass_limits, args.m_package_submission, IsCurrentForFeeEstimation(m_active_chainstate), m_pool.HasNoInputsOf(tx)); - m_pool.m_signals->TransactionAddedToMempool(tx_info, m_pool.GetAndIncrementSequence()); + m_pool.m_opts.signals->TransactionAddedToMempool(tx_info, m_pool.GetAndIncrementSequence()); + } + + if (!m_subpackage.m_replaced_transactions.empty()) { + LogPrint(BCLog::MEMPOOL, "replaced %u mempool transactions with 1 new transaction for %s additional fees, %d delta bytes\n", + m_subpackage.m_replaced_transactions.size(), + ws.m_modified_fees - m_subpackage.m_conflicting_fees, + ws.m_vsize - static_cast<int>(m_subpackage.m_conflicting_size)); } - return MempoolAcceptResult::Success(std::move(ws.m_replaced_transactions), ws.m_vsize, ws.m_base_fees, + return MempoolAcceptResult::Success(std::move(m_subpackage.m_replaced_transactions), ws.m_vsize, ws.m_base_fees, effective_feerate, single_wtxid); } @@ -1376,10 +1533,14 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptMultipleTransactions(const std:: } // Make the coins created by this transaction available for subsequent transactions in the - // package to spend. Since we already checked conflicts in the package and we don't allow - // replacements, we don't need to track the coins spent. Note that this logic will need to be - // updated if package replace-by-fee is allowed in the future. - assert(!args.m_allow_replacement); + // package to spend. If there are no conflicts within the package, no transaction can spend a coin + // needed by another transaction in the package. We also need to make sure that no package + // tx replaces (or replaces the ancestor of) the parent of another package tx. As long as we + // check these two things, we don't need to track the coins spent. + // If a package tx conflicts with a mempool tx, PackageMempoolChecks() ensures later that any package RBF attempt + // has *no* in-mempool ancestors, so we don't have to worry about subsequent transactions in + // same package spending the same in-mempool outpoints. This needs to be revisited for general + // package RBF. m_viewmempool.PackageAddTransaction(ws.m_ptx); } @@ -1401,28 +1562,26 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptMultipleTransactions(const std:: // a child that is below mempool minimum feerate. To avoid these behaviors, callers of // AcceptMultipleTransactions need to restrict txns topology (e.g. to ancestor sets) and check // the feerates of individuals and subsets. - const auto m_total_vsize = std::accumulate(workspaces.cbegin(), workspaces.cend(), int64_t{0}, + m_subpackage.m_total_vsize = std::accumulate(workspaces.cbegin(), workspaces.cend(), int64_t{0}, [](int64_t sum, auto& ws) { return sum + ws.m_vsize; }); - const auto m_total_modified_fees = std::accumulate(workspaces.cbegin(), workspaces.cend(), CAmount{0}, + m_subpackage.m_total_modified_fees = std::accumulate(workspaces.cbegin(), workspaces.cend(), CAmount{0}, [](CAmount sum, auto& ws) { return sum + ws.m_modified_fees; }); - const CFeeRate package_feerate(m_total_modified_fees, m_total_vsize); + const CFeeRate package_feerate(m_subpackage.m_total_modified_fees, m_subpackage.m_total_vsize); std::vector<Wtxid> all_package_wtxids; all_package_wtxids.reserve(workspaces.size()); std::transform(workspaces.cbegin(), workspaces.cend(), std::back_inserter(all_package_wtxids), [](const auto& ws) { return ws.m_ptx->GetWitnessHash(); }); TxValidationState placeholder_state; if (args.m_package_feerates && - !CheckFeeRate(m_total_vsize, m_total_modified_fees, placeholder_state)) { + !CheckFeeRate(m_subpackage.m_total_vsize, m_subpackage.m_total_modified_fees, placeholder_state)) { package_state.Invalid(PackageValidationResult::PCKG_TX, "transaction failed"); return PackageMempoolAcceptResult(package_state, {{workspaces.back().m_ptx->GetWitnessHash(), - MempoolAcceptResult::FeeFailure(placeholder_state, CFeeRate(m_total_modified_fees, m_total_vsize), all_package_wtxids)}}); + MempoolAcceptResult::FeeFailure(placeholder_state, CFeeRate(m_subpackage.m_total_modified_fees, m_subpackage.m_total_vsize), all_package_wtxids)}}); } // Apply package mempool ancestor/descendant limits. Skip if there is only one transaction, - // because it's unnecessary. Also, CPFP carve out can increase the limit for individual - // transactions, but this exemption is not extended to packages in CheckPackageLimits(). - std::string err_string; - if (txns.size() > 1 && !PackageMempoolChecks(txns, m_total_vsize, package_state)) { + // because it's unnecessary. + if (txns.size() > 1 && !PackageMempoolChecks(txns, workspaces, m_subpackage.m_total_vsize, package_state)) { return PackageMempoolAcceptResult(package_state, std::move(results)); } @@ -1440,7 +1599,7 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptMultipleTransactions(const std:: const auto effective_feerate_wtxids = args.m_package_feerates ? all_package_wtxids : std::vector<Wtxid>{ws.m_ptx->GetWitnessHash()}; results.emplace(ws.m_ptx->GetWitnessHash(), - MempoolAcceptResult::Success(std::move(ws.m_replaced_transactions), + MempoolAcceptResult::Success(std::move(m_subpackage.m_replaced_transactions), ws.m_vsize, ws.m_base_fees, effective_feerate, effective_feerate_wtxids)); } @@ -1505,7 +1664,8 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptSubPackage(const std::vector<CTr // Clean up m_view and m_viewmempool so that other subpackage evaluations don't have access to // coins they shouldn't. Keep some coins in order to minimize re-fetching coins from the UTXO set. - CleanupTemporaryCoins(); + // Clean up package feerate and rbf calculations + ClearSubPackageState(); return result; } @@ -1689,7 +1849,6 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptPackage(const Package& package, MempoolAcceptResult AcceptToMemoryPool(Chainstate& active_chainstate, const CTransactionRef& tx, int64_t accept_time, bool bypass_limits, bool test_accept) - EXCLUSIVE_LOCKS_REQUIRED(::cs_main) { AssertLockHeld(::cs_main); const CChainParams& chainparams{active_chainstate.m_chainman.GetParams()}; @@ -1863,9 +2022,11 @@ void Chainstate::CheckForkWarningConditions() if (m_chainman.m_best_invalid && m_chainman.m_best_invalid->nChainWork > m_chain.Tip()->nChainWork + (GetBlockProof(*m_chain.Tip()) * 6)) { LogPrintf("%s: Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.\n", __func__); - SetfLargeWorkInvalidChainFound(true); + m_chainman.GetNotifications().warningSet( + kernel::Warning::LARGE_WORK_INVALID_CHAIN, + _("Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.")); } else { - SetfLargeWorkInvalidChainFound(false); + m_chainman.GetNotifications().warningUnset(kernel::Warning::LARGE_WORK_INVALID_CHAIN); } } @@ -2595,7 +2756,7 @@ CoinsCacheSizeState Chainstate::GetCoinsCacheSizeState() AssertLockHeld(::cs_main); return this->GetCoinsCacheSizeState( m_coinstip_cache_size_bytes, - m_mempool ? m_mempool->m_max_size_bytes : 0); + m_mempool ? m_mempool->m_opts.max_size_bytes : 0); } CoinsCacheSizeState Chainstate::GetCoinsCacheSizeState( @@ -2642,7 +2803,7 @@ bool Chainstate::FlushStateToDisk( CoinsCacheSizeState cache_state = GetCoinsCacheSizeState(); LOCK(m_blockman.cs_LastBlockFile); - if (m_blockman.IsPruneMode() && (m_blockman.m_check_for_pruning || nManualPruneHeight > 0) && !fReindex) { + if (m_blockman.IsPruneMode() && (m_blockman.m_check_for_pruning || nManualPruneHeight > 0) && m_chainman.m_blockman.m_blockfiles_indexed) { // make sure we don't prune above any of the prune locks bestblocks // pruning is height-based int last_prune{m_chain.Height()}; // last height we can prune @@ -2748,8 +2909,10 @@ bool Chainstate::FlushStateToDisk( return FatalError(m_chainman.GetNotifications(), state, _("Disk space is too low!")); } // Flush the chainstate (which may refer to block index entries). - if (!CoinsTip().Flush()) + const auto empty_cache{(mode == FlushStateMode::ALWAYS) || fCacheLarge || fCacheCritical || fFlushForPrune}; + if (empty_cache ? !CoinsTip().Flush() : !CoinsTip().Sync()) { return FatalError(m_chainman.GetNotifications(), state, _("Failed to write to coin database.")); + } m_last_flush = nNow; full_flush_completed = true; TRACE5(utxocache, flush, @@ -2787,13 +2950,6 @@ void Chainstate::PruneAndFlush() } } -/** Private helper function that concatenates warning messages. */ -static void AppendWarning(bilingual_str& res, const bilingual_str& warn) -{ - if (!res.empty()) res += Untranslated(", "); - res += warn; -} - static void UpdateTipLog( const CCoinsViewCache& coins_tip, const CBlockIndex* tip, @@ -2844,7 +3000,7 @@ void Chainstate::UpdateTip(const CBlockIndex* pindexNew) g_best_block_cv.notify_all(); } - bilingual_str warning_messages; + std::vector<bilingual_str> warning_messages; if (!m_chainman.IsInitialBlockDownload()) { const CBlockIndex* pindex = pindexNew; for (int bit = 0; bit < VERSIONBITS_NUM_BITS; bit++) { @@ -2853,14 +3009,15 @@ void Chainstate::UpdateTip(const CBlockIndex* pindexNew) if (state == ThresholdState::ACTIVE || state == ThresholdState::LOCKED_IN) { const bilingual_str warning = strprintf(_("Unknown new rules activated (versionbit %i)"), bit); if (state == ThresholdState::ACTIVE) { - m_chainman.GetNotifications().warning(warning); + m_chainman.GetNotifications().warningSet(kernel::Warning::UNKNOWN_NEW_RULES_ACTIVATED, warning); } else { - AppendWarning(warning_messages, warning); + warning_messages.push_back(warning); } } } } - UpdateTipLog(coins_tip, pindexNew, params, __func__, "", warning_messages.original); + UpdateTipLog(coins_tip, pindexNew, params, __func__, "", + util::Join(warning_messages, Untranslated(", ")).original); } /** Disconnect m_chain's tip. @@ -3253,10 +3410,10 @@ bool Chainstate::ActivateBestChainStep(BlockValidationState& state, CBlockIndex* return true; } -static SynchronizationState GetSynchronizationState(bool init) +static SynchronizationState GetSynchronizationState(bool init, bool blockfiles_indexed) { if (!init) return SynchronizationState::POST_INIT; - if (::fReindex) return SynchronizationState::INIT_REINDEX; + if (!blockfiles_indexed) return SynchronizationState::INIT_REINDEX; return SynchronizationState::INIT_DOWNLOAD; } @@ -3278,7 +3435,7 @@ static bool NotifyHeaderTip(ChainstateManager& chainman) LOCKS_EXCLUDED(cs_main) } // Send block tip changed notifications without cs_main if (fNotify) { - chainman.GetNotifications().headerTip(GetSynchronizationState(fInitialBlockDownload), pindexHeader->nHeight, pindexHeader->nTime, false); + chainman.GetNotifications().headerTip(GetSynchronizationState(fInitialBlockDownload, chainman.m_blockman.m_blockfiles_indexed), pindexHeader->nHeight, pindexHeader->nTime, false); } return fNotify; } @@ -3397,7 +3554,7 @@ bool Chainstate::ActivateBestChain(BlockValidationState& state, std::shared_ptr< } // Always notify the UI if a new block tip was connected - if (kernel::IsInterrupted(m_chainman.GetNotifications().blockTip(GetSynchronizationState(still_in_ibd), *pindexNewTip))) { + if (kernel::IsInterrupted(m_chainman.GetNotifications().blockTip(GetSynchronizationState(still_in_ibd, m_chainman.m_blockman.m_blockfiles_indexed), *pindexNewTip))) { // Just breaking and returning success for now. This could // be changed to bubble up the kernel::Interrupted value to // the caller so the caller could distinguish between @@ -3623,7 +3780,7 @@ bool Chainstate::InvalidateBlock(BlockValidationState& state, CBlockIndex* pinde // parameter indicating the source of the tip change so hooks can // distinguish user-initiated invalidateblock changes from other // changes. - (void)m_chainman.GetNotifications().blockTip(GetSynchronizationState(m_chainman.IsInitialBlockDownload()), *to_mark_failed->pprev); + (void)m_chainman.GetNotifications().blockTip(GetSynchronizationState(m_chainman.IsInitialBlockDownload(), m_chainman.m_blockman.m_blockfiles_indexed), *to_mark_failed->pprev); } return true; } @@ -4262,7 +4419,7 @@ void ChainstateManager::ReportHeadersPresync(const arith_uint256& work, int64_t m_last_presync_update = now; } bool initial_download = IsInitialBlockDownload(); - GetNotifications().headerTip(GetSynchronizationState(initial_download), height, timestamp, /*presync=*/true); + GetNotifications().headerTip(GetSynchronizationState(initial_download, m_blockman.m_blockfiles_indexed), height, timestamp, /*presync=*/true); if (initial_download) { int64_t blocks_left{(NodeClock::now() - NodeSeconds{std::chrono::seconds{timestamp}}) / GetConsensus().PowTargetSpacing()}; blocks_left = std::max<int64_t>(0, blocks_left); @@ -4343,10 +4500,16 @@ bool ChainstateManager::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, // Write block to history file if (fNewBlock) *fNewBlock = true; try { - FlatFilePos blockPos{m_blockman.SaveBlockToDisk(block, pindex->nHeight, dbp)}; - if (blockPos.IsNull()) { - state.Error(strprintf("%s: Failed to find position to write new block to disk", __func__)); - return false; + FlatFilePos blockPos{}; + if (dbp) { + blockPos = *dbp; + m_blockman.UpdateBlockInfo(block, pindex->nHeight, blockPos); + } else { + blockPos = m_blockman.SaveBlockToDisk(block, pindex->nHeight); + if (blockPos.IsNull()) { + state.Error(strprintf("%s: Failed to find position to write new block to disk", __func__)); + return false; + } } ReceivedBlockTransactions(block, pindex, blockPos); } catch (const std::runtime_error& e) { @@ -4783,8 +4946,7 @@ bool ChainstateManager::LoadBlockIndex() { AssertLockHeld(cs_main); // Load block index from databases - bool needs_init = fReindex; - if (!fReindex) { + if (m_blockman.m_blockfiles_indexed) { bool ret{m_blockman.LoadBlockIndexDB(SnapshotBlockhash())}; if (!ret) return false; @@ -4815,18 +4977,6 @@ bool ChainstateManager::LoadBlockIndex() if (pindex->IsValid(BLOCK_VALID_TREE) && (m_best_header == nullptr || CBlockIndexWorkComparator()(m_best_header, pindex))) m_best_header = pindex; } - - needs_init = m_blockman.m_block_index.empty(); - } - - if (needs_init) { - // Everything here is for *new* reindex/DBs. Thus, though - // LoadBlockIndexDB may have set fReindex if we shut down - // mid-reindex previously, we don't check fReindex and - // instead only check it prior to LoadBlockIndexDB to set - // needs_init. - - LogPrintf("Initializing databases...\n"); } return true; } @@ -4846,7 +4996,7 @@ bool Chainstate::LoadGenesisBlock() try { const CBlock& block = params.GenesisBlock(); - FlatFilePos blockPos{m_blockman.SaveBlockToDisk(block, 0, nullptr)}; + FlatFilePos blockPos{m_blockman.SaveBlockToDisk(block, 0)}; if (blockPos.IsNull()) { LogError("%s: writing genesis block to disk failed\n", __func__); return false; @@ -4967,7 +5117,7 @@ void ChainstateManager::LoadExternalBlockFile( } } - if (m_blockman.IsPruneMode() && !fReindex && pblock) { + if (m_blockman.IsPruneMode() && m_blockman.m_blockfiles_indexed && pblock) { // must update the tip for pruning to work while importing with -loadblock. // this is a tradeoff to conserve disk space at the expense of time // spent updating the tip to be able to prune. @@ -5039,6 +5189,14 @@ void ChainstateManager::LoadExternalBlockFile( LogPrintf("Loaded %i blocks from external file in %dms\n", nLoaded, Ticks<std::chrono::milliseconds>(SteadyClock::now() - start)); } +bool ChainstateManager::ShouldCheckBlockIndex() const +{ + // Assert to verify Flatten() has been called. + if (!*Assert(m_options.check_block_index)) return false; + if (GetRand(*m_options.check_block_index) >= 1) return false; + return true; +} + void ChainstateManager::CheckBlockIndex() { if (!ShouldCheckBlockIndex()) { @@ -5055,19 +5213,28 @@ void ChainstateManager::CheckBlockIndex() return; } - // Build forward-pointing map of the entire block tree. + // Build forward-pointing data structure for the entire block tree. + // For performance reasons, indexes of the best header chain are stored in a vector (within CChain). + // All remaining blocks are stored in a multimap. + // The best header chain can differ from the active chain: E.g. its entries may belong to blocks that + // are not yet validated. + CChain best_hdr_chain; + assert(m_best_header); + best_hdr_chain.SetTip(*m_best_header); + std::multimap<CBlockIndex*,CBlockIndex*> forward; for (auto& [_, block_index] : m_blockman.m_block_index) { - forward.emplace(block_index.pprev, &block_index); + // Only save indexes in forward that are not part of the best header chain. + if (!best_hdr_chain.Contains(&block_index)) { + // Only genesis, which must be part of the best header chain, can have a nullptr parent. + assert(block_index.pprev); + forward.emplace(block_index.pprev, &block_index); + } } + assert(forward.size() + best_hdr_chain.Height() + 1 == m_blockman.m_block_index.size()); - assert(forward.size() == m_blockman.m_block_index.size()); - - std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeGenesis = forward.equal_range(nullptr); - CBlockIndex *pindex = rangeGenesis.first->second; - rangeGenesis.first++; - assert(rangeGenesis.first == rangeGenesis.second); // There is only one index entry with parent nullptr. - + CBlockIndex* pindex = best_hdr_chain[0]; + assert(pindex); // Iterate over the entire block tree, using depth-first search. // Along the way, remember whether there are blocks on the path from genesis // block being explored which are the first to have certain properties. @@ -5279,14 +5446,21 @@ void ChainstateManager::CheckBlockIndex() // assert(pindex->GetBlockHash() == pindex->GetBlockHeader().GetHash()); // Perhaps too slow // End: actual consistency checks. - // Try descending into the first subnode. + + // Try descending into the first subnode. Always process forks first and the best header chain after. snap_update_firsts(); std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> range = forward.equal_range(pindex); if (range.first != range.second) { - // A subnode was found. + // A subnode not part of the best header chain was found. pindex = range.first->second; nHeight++; continue; + } else if (best_hdr_chain.Contains(pindex)) { + // Descend further into best header chain. + nHeight++; + pindex = best_hdr_chain[nHeight]; + if (!pindex) break; // we are finished, since the best header chain is always processed last + continue; } // This is a leaf node. // Move upwards until we reach a node of which we have not yet visited the last child. @@ -5312,9 +5486,15 @@ void ChainstateManager::CheckBlockIndex() // Proceed to the next one. rangePar.first++; if (rangePar.first != rangePar.second) { - // Move to the sibling. + // Move to a sibling not part of the best header chain. pindex = rangePar.first->second; break; + } else if (pindexPar == best_hdr_chain[nHeight - 1]) { + // Move to pindex's sibling on the best-chain, if it has one. + pindex = best_hdr_chain[nHeight]; + // There will not be a next block if (and only if) parent block is the best header. + assert((pindex == nullptr) == (pindexPar == best_hdr_chain.Tip())); + break; } else { // Move up further. pindex = pindexPar; @@ -5324,8 +5504,8 @@ void ChainstateManager::CheckBlockIndex() } } - // Check that we actually traversed the entire map. - assert(nNodes == forward.size()); + // Check that we actually traversed the entire block index. + assert(nNodes == forward.size() + best_hdr_chain.Height() + 1); } std::string Chainstate::ToString() @@ -5658,69 +5838,81 @@ bool ChainstateManager::PopulateAndValidateSnapshot( return false; } - COutPoint outpoint; - Coin coin; const uint64_t coins_count = metadata.m_coins_count; uint64_t coins_left = metadata.m_coins_count; - LogPrintf("[snapshot] loading coins from snapshot %s\n", base_blockhash.ToString()); + LogPrintf("[snapshot] loading %d coins from snapshot %s\n", coins_left, base_blockhash.ToString()); int64_t coins_processed{0}; while (coins_left > 0) { try { - coins_file >> outpoint; - coins_file >> coin; - } catch (const std::ios_base::failure&) { - LogPrintf("[snapshot] bad snapshot format or truncated snapshot after deserializing %d coins\n", - coins_count - coins_left); - return false; - } - if (coin.nHeight > base_height || - outpoint.n >= std::numeric_limits<decltype(outpoint.n)>::max() // Avoid integer wrap-around in coinstats.cpp:ApplyHash - ) { - LogPrintf("[snapshot] bad snapshot data after deserializing %d coins\n", - coins_count - coins_left); - return false; - } - if (!MoneyRange(coin.out.nValue)) { - LogPrintf("[snapshot] bad snapshot data after deserializing %d coins - bad tx out value\n", - coins_count - coins_left); - return false; - } + Txid txid; + coins_file >> txid; + size_t coins_per_txid{0}; + coins_per_txid = ReadCompactSize(coins_file); - coins_cache.EmplaceCoinInternalDANGER(std::move(outpoint), std::move(coin)); + if (coins_per_txid > coins_left) { + LogPrintf("[snapshot] mismatch in coins count in snapshot metadata and actual snapshot data\n"); + return false; + } - --coins_left; - ++coins_processed; + for (size_t i = 0; i < coins_per_txid; i++) { + COutPoint outpoint; + Coin coin; + outpoint.n = static_cast<uint32_t>(ReadCompactSize(coins_file)); + outpoint.hash = txid; + coins_file >> coin; + if (coin.nHeight > base_height || + outpoint.n >= std::numeric_limits<decltype(outpoint.n)>::max() // Avoid integer wrap-around in coinstats.cpp:ApplyHash + ) { + LogPrintf("[snapshot] bad snapshot data after deserializing %d coins\n", + coins_count - coins_left); + return false; + } + if (!MoneyRange(coin.out.nValue)) { + LogPrintf("[snapshot] bad snapshot data after deserializing %d coins - bad tx out value\n", + coins_count - coins_left); + return false; + } + coins_cache.EmplaceCoinInternalDANGER(std::move(outpoint), std::move(coin)); - if (coins_processed % 1000000 == 0) { - LogPrintf("[snapshot] %d coins loaded (%.2f%%, %.2f MB)\n", - coins_processed, - static_cast<float>(coins_processed) * 100 / static_cast<float>(coins_count), - coins_cache.DynamicMemoryUsage() / (1000 * 1000)); - } + --coins_left; + ++coins_processed; - // Batch write and flush (if we need to) every so often. - // - // If our average Coin size is roughly 41 bytes, checking every 120,000 coins - // means <5MB of memory imprecision. - if (coins_processed % 120000 == 0) { - if (m_interrupt) { - return false; - } + if (coins_processed % 1000000 == 0) { + LogPrintf("[snapshot] %d coins loaded (%.2f%%, %.2f MB)\n", + coins_processed, + static_cast<float>(coins_processed) * 100 / static_cast<float>(coins_count), + coins_cache.DynamicMemoryUsage() / (1000 * 1000)); + } - const auto snapshot_cache_state = WITH_LOCK(::cs_main, - return snapshot_chainstate.GetCoinsCacheSizeState()); + // Batch write and flush (if we need to) every so often. + // + // If our average Coin size is roughly 41 bytes, checking every 120,000 coins + // means <5MB of memory imprecision. + if (coins_processed % 120000 == 0) { + if (m_interrupt) { + return false; + } + + const auto snapshot_cache_state = WITH_LOCK(::cs_main, + return snapshot_chainstate.GetCoinsCacheSizeState()); - if (snapshot_cache_state >= CoinsCacheSizeState::CRITICAL) { - // This is a hack - we don't know what the actual best block is, but that - // doesn't matter for the purposes of flushing the cache here. We'll set this - // to its correct value (`base_blockhash`) below after the coins are loaded. - coins_cache.SetBestBlock(GetRandHash()); + if (snapshot_cache_state >= CoinsCacheSizeState::CRITICAL) { + // This is a hack - we don't know what the actual best block is, but that + // doesn't matter for the purposes of flushing the cache here. We'll set this + // to its correct value (`base_blockhash`) below after the coins are loaded. + coins_cache.SetBestBlock(GetRandHash()); - // No need to acquire cs_main since this chainstate isn't being used yet. - FlushSnapshotToDisk(coins_cache, /*snapshot_loaded=*/false); + // No need to acquire cs_main since this chainstate isn't being used yet. + FlushSnapshotToDisk(coins_cache, /*snapshot_loaded=*/false); + } + } } + } catch (const std::ios_base::failure&) { + LogPrintf("[snapshot] bad snapshot format or truncated snapshot after deserializing %d coins\n", + coins_processed); + return false; } } @@ -5733,7 +5925,8 @@ bool ChainstateManager::PopulateAndValidateSnapshot( bool out_of_coins{false}; try { - coins_file >> outpoint; + std::byte left_over_byte; + coins_file >> left_over_byte; } catch (const std::ios_base::failure&) { // We expect an exception since we should be out of coins. out_of_coins = true; @@ -5871,8 +6064,8 @@ SnapshotCompletionResult ChainstateManager::MaybeCompleteSnapshotValidation() PACKAGE_NAME, snapshot_tip_height, snapshot_base_height, snapshot_base_height, PACKAGE_BUGREPORT ); - LogPrintf("[snapshot] !!! %s\n", user_error.original); - LogPrintf("[snapshot] deleting snapshot, reverting to validated chain, and stopping node\n"); + LogError("[snapshot] !!! %s\n", user_error.original); + LogError("[snapshot] deleting snapshot, reverting to validated chain, and stopping node\n"); m_active_chainstate = m_ibd_chainstate.get(); m_snapshot_chainstate->m_disabled = true; @@ -6224,7 +6417,7 @@ bool ChainstateManager::ValidatedSnapshotCleanup() fs::path p_old, fs::path p_new, const fs::filesystem_error& err) { - LogPrintf("Error renaming path (%s) -> (%s): %s\n", + LogError("[snapshot] Error renaming path (%s) -> (%s): %s\n", fs::PathToString(p_old), fs::PathToString(p_new), err.what()); GetNotifications().fatalError(strprintf(_( "Rename of '%s' -> '%s' failed. " diff --git a/src/validation.h b/src/validation.h index 28b045fe80..ab7891539a 100644 --- a/src/validation.h +++ b/src/validation.h @@ -885,6 +885,12 @@ private: CBlockIndex* m_best_invalid GUARDED_BY(::cs_main){nullptr}; //! Internal helper for ActivateSnapshot(). + //! + //! De-serialization of a snapshot that is created with + //! CreateUTXOSnapshot() in rpc/blockchain.cpp. + //! To reduce space the serialization format of the snapshot avoids + //! duplication of tx hashes. The code takes advantage of the guarantee by + //! leveldb that keys are lexicographically sorted. [[nodiscard]] bool PopulateAndValidateSnapshot( Chainstate& snapshot_chainstate, AutoFile& coins_file, @@ -932,7 +938,7 @@ public: const CChainParams& GetParams() const { return m_options.chainparams; } const Consensus::Params& GetConsensus() const { return m_options.chainparams.GetConsensus(); } - bool ShouldCheckBlockIndex() const { return *Assert(m_options.check_block_index); } + bool ShouldCheckBlockIndex() const; const arith_uint256& MinimumChainWork() const { return *Assert(m_options.minimum_chain_work); } const uint256& AssumedValidBlock() const { return *Assert(m_options.assumed_valid_block); } kernel::Notifications& GetNotifications() const { return m_options.notifications; }; diff --git a/src/wallet/bdb.cpp b/src/wallet/bdb.cpp index 38cca32f80..d82d8d4513 100644 --- a/src/wallet/bdb.cpp +++ b/src/wallet/bdb.cpp @@ -65,6 +65,8 @@ RecursiveMutex cs_db; std::map<std::string, std::weak_ptr<BerkeleyEnvironment>> g_dbenvs GUARDED_BY(cs_db); //!< Map from directory name to db environment. } // namespace +static constexpr auto REVERSE_BYTE_ORDER{std::endian::native == std::endian::little ? 4321 : 1234}; + bool WalletDatabaseFileId::operator==(const WalletDatabaseFileId& rhs) const { return memcmp(value, &rhs.value, sizeof(value)) == 0; @@ -300,7 +302,11 @@ static Span<const std::byte> SpanFromDbt(const SafeDbt& dbt) } BerkeleyDatabase::BerkeleyDatabase(std::shared_ptr<BerkeleyEnvironment> env, fs::path filename, const DatabaseOptions& options) : - WalletDatabase(), env(std::move(env)), m_filename(std::move(filename)), m_max_log_mb(options.max_log_mb) + WalletDatabase(), + env(std::move(env)), + m_byteswap(options.require_format == DatabaseFormat::BERKELEY_SWAP), + m_filename(std::move(filename)), + m_max_log_mb(options.max_log_mb) { auto inserted = this->env->m_databases.emplace(m_filename, std::ref(*this)); assert(inserted.second); @@ -389,6 +395,10 @@ void BerkeleyDatabase::Open() } } + if (m_byteswap) { + pdb_temp->set_lorder(REVERSE_BYTE_ORDER); + } + ret = pdb_temp->open(nullptr, // Txn pointer fMockDb ? nullptr : strFile.c_str(), // Filename fMockDb ? strFile.c_str() : "main", // Logical db name @@ -521,6 +531,10 @@ bool BerkeleyDatabase::Rewrite(const char* pszSkip) BerkeleyBatch db(*this, true); std::unique_ptr<Db> pdbCopy = std::make_unique<Db>(env->dbenv.get(), 0); + if (m_byteswap) { + pdbCopy->set_lorder(REVERSE_BYTE_ORDER); + } + int ret = pdbCopy->open(nullptr, // Txn pointer strFileRes.c_str(), // Filename "main", // Logical db name diff --git a/src/wallet/bdb.h b/src/wallet/bdb.h index 630630ebe0..af0c78f0d9 100644 --- a/src/wallet/bdb.h +++ b/src/wallet/bdb.h @@ -147,6 +147,9 @@ public: /** Database pointer. This is initialized lazily and reset during flushes, so it can be null. */ std::unique_ptr<Db> m_db; + // Whether to byteswap + bool m_byteswap; + fs::path m_filename; int64_t m_max_log_mb; diff --git a/src/wallet/coinselection.cpp b/src/wallet/coinselection.cpp index 42615b5d42..f1706b6800 100644 --- a/src/wallet/coinselection.cpp +++ b/src/wallet/coinselection.cpp @@ -194,7 +194,7 @@ util::Result<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool for (const size_t& i : best_selection) { result.AddInput(utxo_pool.at(i)); } - result.ComputeAndSetWaste(cost_of_change, cost_of_change, CAmount{0}); + result.RecalculateWaste(cost_of_change, cost_of_change, CAmount{0}); assert(best_waste == result.GetWaste()); return result; @@ -792,35 +792,6 @@ void OutputGroupTypeMap::Push(const OutputGroup& group, OutputType type, bool in } } -CAmount SelectionResult::GetSelectionWaste(CAmount change_cost, CAmount target, bool use_effective_value) -{ - // This function should not be called with empty inputs as that would mean the selection failed - assert(!m_selected_inputs.empty()); - - // Always consider the cost of spending an input now vs in the future. - CAmount waste = 0; - for (const auto& coin_ptr : m_selected_inputs) { - const COutput& coin = *coin_ptr; - waste += coin.GetFee() - coin.long_term_fee; - } - // Bump fee of whole selection may diverge from sum of individual bump fees - waste -= bump_fee_group_discount; - - if (change_cost) { - // Consider the cost of making change and spending it in the future - // If we aren't making change, the caller should've set change_cost to 0 - assert(change_cost > 0); - waste += change_cost; - } else { - // When we are not making change (change_cost == 0), consider the excess we are throwing away to fees - CAmount selected_effective_value = use_effective_value ? GetSelectedEffectiveValue() : GetSelectedValue(); - assert(selected_effective_value >= target); - waste += selected_effective_value - target; - } - - return waste; -} - CAmount GenerateChangeTarget(const CAmount payment_value, const CAmount change_fee, FastRandomContext& rng) { if (payment_value <= CHANGE_LOWER / 2) { @@ -839,16 +810,32 @@ void SelectionResult::SetBumpFeeDiscount(const CAmount discount) bump_fee_group_discount = discount; } - -void SelectionResult::ComputeAndSetWaste(const CAmount min_viable_change, const CAmount change_cost, const CAmount change_fee) +void SelectionResult::RecalculateWaste(const CAmount min_viable_change, const CAmount change_cost, const CAmount change_fee) { - const CAmount change = GetChange(min_viable_change, change_fee); + // This function should not be called with empty inputs as that would mean the selection failed + assert(!m_selected_inputs.empty()); + + // Always consider the cost of spending an input now vs in the future. + CAmount waste = 0; + for (const auto& coin_ptr : m_selected_inputs) { + const COutput& coin = *coin_ptr; + waste += coin.GetFee() - coin.long_term_fee; + } + // Bump fee of whole selection may diverge from sum of individual bump fees + waste -= bump_fee_group_discount; - if (change > 0) { - m_waste = GetSelectionWaste(change_cost, m_target, m_use_effective); + if (GetChange(min_viable_change, change_fee)) { + // if we have a minimum viable amount after deducting fees, account for + // cost of creating and spending change + waste += change_cost; } else { - m_waste = GetSelectionWaste(0, m_target, m_use_effective); + // When we are not making change (GetChange(…) == 0), consider the excess we are throwing away to fees + CAmount selected_effective_value = m_use_effective ? GetSelectedEffectiveValue() : GetSelectedValue(); + assert(selected_effective_value >= m_target); + waste += selected_effective_value - m_target; } + + m_waste = waste; } void SelectionResult::SetAlgoCompleted(bool algo_completed) diff --git a/src/wallet/coinselection.h b/src/wallet/coinselection.h index 80c92e1b0e..9fb000422c 100644 --- a/src/wallet/coinselection.h +++ b/src/wallet/coinselection.h @@ -350,22 +350,6 @@ private: } } - /** Compute the waste for this result given the cost of change - * and the opportunity cost of spending these inputs now vs in the future. - * If change exists, waste = change_cost + inputs * (effective_feerate - long_term_feerate) - * If no change, waste = excess + inputs * (effective_feerate - long_term_feerate) - * where excess = selected_effective_value - target - * change_cost = effective_feerate * change_output_size + long_term_feerate * change_spend_size - * - * @param[in] change_cost The cost of creating change and spending it in the future. - * Only used if there is change, in which case it must be positive. - * Must be 0 if there is no change. - * @param[in] target The amount targeted by the coin selection algorithm. - * @param[in] use_effective_value Whether to use the input's effective value (when true) or the real value (when false). - * @return The waste - */ - [[nodiscard]] CAmount GetSelectionWaste(CAmount change_cost, CAmount target, bool use_effective_value = true); - public: explicit SelectionResult(const CAmount target, SelectionAlgorithm algo) : m_target(target), m_algo(algo) {} @@ -387,8 +371,19 @@ public: /** How much individual inputs overestimated the bump fees for shared ancestries */ void SetBumpFeeDiscount(const CAmount discount); - /** Calculates and stores the waste for this selection via GetSelectionWaste */ - void ComputeAndSetWaste(const CAmount min_viable_change, const CAmount change_cost, const CAmount change_fee); + /** Calculates and stores the waste for this result given the cost of change + * and the opportunity cost of spending these inputs now vs in the future. + * If change exists, waste = change_cost + inputs * (effective_feerate - long_term_feerate) - bump_fee_group_discount + * If no change, waste = excess + inputs * (effective_feerate - long_term_feerate) - bump_fee_group_discount + * where excess = selected_effective_value - target + * change_cost = effective_feerate * change_output_size + long_term_feerate * change_spend_size + * + * @param[in] min_viable_change The minimum amount necessary to make a change output economic + * @param[in] change_cost The cost of creating a change output and spending it in the future. Only + * used if there is change, in which case it must be non-negative. + * @param[in] change_fee The fee for creating a change output + */ + void RecalculateWaste(const CAmount min_viable_change, const CAmount change_cost, const CAmount change_fee); [[nodiscard]] CAmount GetWaste() const; /** Tracks that algorithm was able to exhaustively search the entire combination space before hitting limit of tries */ diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index ea06767e9b..a5a5f8ec6f 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -16,6 +16,9 @@ #include <vector> namespace wallet { +bool operator<(BytePrefix a, Span<const std::byte> b) { return a.prefix < b.subspan(0, std::min(a.prefix.size(), b.size())); } +bool operator<(Span<const std::byte> a, BytePrefix b) { return a.subspan(0, std::min(a.size(), b.prefix.size())) < b.prefix; } + std::vector<fs::path> ListDatabases(const fs::path& wallet_dir) { std::vector<fs::path> paths; diff --git a/src/wallet/db.h b/src/wallet/db.h index 084fcadc24..b45076d10c 100644 --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -20,6 +20,12 @@ class ArgsManager; struct bilingual_str; namespace wallet { +// BytePrefix compares equality with other byte spans that begin with the same prefix. +struct BytePrefix { + Span<const std::byte> prefix; +}; +bool operator<(BytePrefix a, Span<const std::byte> b); +bool operator<(Span<const std::byte> a, BytePrefix b); class DatabaseCursor { @@ -177,6 +183,8 @@ public: enum class DatabaseFormat { BERKELEY, SQLITE, + BERKELEY_RO, + BERKELEY_SWAP, }; struct DatabaseOptions { diff --git a/src/wallet/dump.cpp b/src/wallet/dump.cpp index 7a36910dc1..db2756e0ca 100644 --- a/src/wallet/dump.cpp +++ b/src/wallet/dump.cpp @@ -60,7 +60,13 @@ bool DumpWallet(const ArgsManager& args, WalletDatabase& db, bilingual_str& erro hasher << Span{line}; // Write out the file format - line = strprintf("%s,%s\n", "format", db.Format()); + std::string format = db.Format(); + // BDB files that are opened using BerkeleyRODatabase have it's format as "bdb_ro" + // We want to override that format back to "bdb" + if (format == "bdb_ro") { + format = "bdb"; + } + line = strprintf("%s,%s\n", "format", format); dump_file.write(line.data(), line.size()); hasher << Span{line}; @@ -180,6 +186,8 @@ bool CreateFromDump(const ArgsManager& args, const std::string& name, const fs:: data_format = DatabaseFormat::BERKELEY; } else if (file_format == "sqlite") { data_format = DatabaseFormat::SQLITE; + } else if (file_format == "bdb_swap") { + data_format = DatabaseFormat::BERKELEY_SWAP; } else { error = strprintf(_("Unknown wallet file format \"%s\" provided. Please provide one of \"bdb\" or \"sqlite\"."), file_format); return false; diff --git a/src/wallet/external_signer_scriptpubkeyman.cpp b/src/wallet/external_signer_scriptpubkeyman.cpp index b5703fa54a..32e9941453 100644 --- a/src/wallet/external_signer_scriptpubkeyman.cpp +++ b/src/wallet/external_signer_scriptpubkeyman.cpp @@ -6,6 +6,7 @@ #include <common/args.h> #include <common/system.h> #include <external_signer.h> +#include <node/types.h> #include <wallet/external_signer_scriptpubkeyman.h> #include <iostream> @@ -17,6 +18,8 @@ #include <utility> #include <vector> +using common::PSBTError; + namespace wallet { bool ExternalSignerScriptPubKeyMan::SetupDescriptor(WalletBatch& batch, std::unique_ptr<Descriptor> desc) { @@ -76,7 +79,7 @@ util::Result<void> ExternalSignerScriptPubKeyMan::DisplayAddress(const CTxDestin } // If sign is true, transaction must previously have been filled -TransactionError ExternalSignerScriptPubKeyMan::FillPSBT(PartiallySignedTransaction& psbt, const PrecomputedTransactionData& txdata, int sighash_type, bool sign, bool bip32derivs, int* n_signed, bool finalize) const +std::optional<PSBTError> ExternalSignerScriptPubKeyMan::FillPSBT(PartiallySignedTransaction& psbt, const PrecomputedTransactionData& txdata, int sighash_type, bool sign, bool bip32derivs, int* n_signed, bool finalize) const { if (!sign) { return DescriptorScriptPubKeyMan::FillPSBT(psbt, txdata, sighash_type, false, bip32derivs, n_signed, finalize); @@ -88,14 +91,14 @@ TransactionError ExternalSignerScriptPubKeyMan::FillPSBT(PartiallySignedTransact // TODO: for multisig wallets, we should only care if all _our_ inputs are signed complete &= PSBTInputSigned(input); } - if (complete) return TransactionError::OK; + if (complete) return {}; std::string strFailReason; if(!GetExternalSigner().SignTransaction(psbt, strFailReason)) { tfm::format(std::cerr, "Failed to sign: %s\n", strFailReason); - return TransactionError::EXTERNAL_SIGNER_FAILED; + return PSBTError::EXTERNAL_SIGNER_FAILED; } if (finalize) FinalizePSBT(psbt); // This won't work in a multisig setup - return TransactionError::OK; + return {}; } } // namespace wallet diff --git a/src/wallet/external_signer_scriptpubkeyman.h b/src/wallet/external_signer_scriptpubkeyman.h index 44286456b6..10d67d2ab4 100644 --- a/src/wallet/external_signer_scriptpubkeyman.h +++ b/src/wallet/external_signer_scriptpubkeyman.h @@ -35,7 +35,7 @@ class ExternalSignerScriptPubKeyMan : public DescriptorScriptPubKeyMan */ util::Result<void> DisplayAddress(const CTxDestination& dest, const ExternalSigner& signer) const; - TransactionError FillPSBT(PartiallySignedTransaction& psbt, const PrecomputedTransactionData& txdata, int sighash_type = 1 /* SIGHASH_ALL */, bool sign = true, bool bip32derivs = false, int* n_signed = nullptr, bool finalize = true) const override; + std::optional<common::PSBTError> FillPSBT(PartiallySignedTransaction& psbt, const PrecomputedTransactionData& txdata, int sighash_type = 1 /* SIGHASH_ALL */, bool sign = true, bool bip32derivs = false, int* n_signed = nullptr, bool finalize = true) const override; }; } // namespace wallet #endif // BITCOIN_WALLET_EXTERNAL_SIGNER_SCRIPTPUBKEYMAN_H diff --git a/src/wallet/feebumper.cpp b/src/wallet/feebumper.cpp index 6a8453965b..3184d0f3b0 100644 --- a/src/wallet/feebumper.cpp +++ b/src/wallet/feebumper.cpp @@ -5,6 +5,7 @@ #include <common/system.h> #include <consensus/validation.h> #include <interfaces/chain.h> +#include <node/types.h> #include <policy/fees.h> #include <policy/policy.h> #include <util/moneystr.h> @@ -92,7 +93,7 @@ static feebumper::Result CheckFeeRate(const CWallet& wallet, const CMutableTrans } CAmount new_total_fee = newFeerate.GetFee(maxTxSize) + combined_bump_fee.value(); - CFeeRate incrementalRelayFee = std::max(wallet.chain().relayIncrementalFee(), CFeeRate(WALLET_INCREMENTAL_RELAY_FEE)); + CFeeRate incrementalRelayFee = wallet.chain().relayIncrementalFee(); // Min total fee is old fee + relay fee CAmount minTotalFee = old_fee + incrementalRelayFee.GetFee(maxTxSize); @@ -343,8 +344,8 @@ bool SignTransaction(CWallet& wallet, CMutableTransaction& mtx) { // so external signers are not asked to sign more than once. bool complete; wallet.FillPSBT(psbtx, complete, SIGHASH_ALL, false /* sign */, true /* bip32derivs */); - const TransactionError err = wallet.FillPSBT(psbtx, complete, SIGHASH_ALL, true /* sign */, false /* bip32derivs */); - if (err != TransactionError::OK) return false; + auto err{wallet.FillPSBT(psbtx, complete, SIGHASH_ALL, true /* sign */, false /* bip32derivs */)}; + if (err) return false; complete = FinalizeAndExtractPSBT(psbtx, mtx); return complete; } else { diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp index 14e988ec1a..14d22bb54e 100644 --- a/src/wallet/init.cpp +++ b/src/wallet/init.cpp @@ -85,8 +85,9 @@ void WalletInit::AddWalletOptions(ArgsManager& argsman) const argsman.AddArg("-dblogsize=<n>", strprintf("Flush wallet database activity from memory to disk log every <n> megabytes (default: %u)", DatabaseOptions().max_log_mb), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::WALLET_DEBUG_TEST); argsman.AddArg("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", DEFAULT_FLUSHWALLET), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::WALLET_DEBUG_TEST); argsman.AddArg("-privdb", strprintf("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)", !DatabaseOptions().use_shared_memory), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::WALLET_DEBUG_TEST); + argsman.AddArg("-swapbdbendian", "Swaps the internal endianness of BDB wallet databases (default: false)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::WALLET_DEBUG_TEST); #else - argsman.AddHiddenArgs({"-dblogsize", "-flushwallet", "-privdb"}); + argsman.AddHiddenArgs({"-dblogsize", "-flushwallet", "-privdb", "-swapbdbendian"}); #endif #ifdef USE_SQLITE diff --git a/src/wallet/interfaces.cpp b/src/wallet/interfaces.cpp index 0c1cae7253..9fab1b2ee4 100644 --- a/src/wallet/interfaces.cpp +++ b/src/wallet/interfaces.cpp @@ -8,6 +8,7 @@ #include <consensus/amount.h> #include <interfaces/chain.h> #include <interfaces/handler.h> +#include <node/types.h> #include <policy/fees.h> #include <primitives/transaction.h> #include <rpc/server.h> @@ -34,6 +35,7 @@ #include <utility> #include <vector> +using common::PSBTError; using interfaces::Chain; using interfaces::FoundBlock; using interfaces::Handler; @@ -389,7 +391,7 @@ public: } return {}; } - TransactionError fillPSBT(int sighash_type, + std::optional<PSBTError> fillPSBT(int sighash_type, bool sign, bool bip32derivs, size_t* n_signed, diff --git a/src/wallet/load.cpp b/src/wallet/load.cpp index 8b78a670e4..fe35f6b223 100644 --- a/src/wallet/load.cpp +++ b/src/wallet/load.cpp @@ -21,6 +21,8 @@ #include <system_error> +using util::Join; + namespace wallet { bool VerifyWallets(WalletContext& context) { diff --git a/src/wallet/migrate.cpp b/src/wallet/migrate.cpp new file mode 100644 index 0000000000..d7d8577374 --- /dev/null +++ b/src/wallet/migrate.cpp @@ -0,0 +1,784 @@ +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <compat/byteswap.h> +#include <crypto/common.h> // For ReadBE32 +#include <logging.h> +#include <streams.h> +#include <util/translation.h> +#include <wallet/migrate.h> + +#include <optional> +#include <variant> + +namespace wallet { +// Magic bytes in both endianness's +constexpr uint32_t BTREE_MAGIC = 0x00053162; // If the file endianness matches our system, we see this magic +constexpr uint32_t BTREE_MAGIC_OE = 0x62310500; // If the file endianness is the other one, we will see this magic + +// Subdatabase name +static const std::vector<std::byte> SUBDATABASE_NAME = {std::byte{'m'}, std::byte{'a'}, std::byte{'i'}, std::byte{'n'}}; + +enum class PageType : uint8_t { + /* + * BDB has several page types, most of which we do not use + * They are listed here for completeness, but commented out + * to avoid opening something unintended. + INVALID = 0, // Invalid page type + DUPLICATE = 1, // Duplicate. Deprecated and no longer used + HASH_UNSORTED = 2, // Hash pages. Deprecated. + RECNO_INTERNAL = 4, // Recno internal + RECNO_LEAF = 6, // Recno leaf + HASH_META = 8, // Hash metadata + QUEUE_META = 10, // Queue Metadata + QUEUE_DATA = 11, // Queue Data + DUPLICATE_LEAF = 12, // Off-page duplicate leaf + HASH_SORTED = 13, // Sorted hash page + */ + BTREE_INTERNAL = 3, // BTree internal + BTREE_LEAF = 5, // BTree leaf + OVERFLOW_DATA = 7, // Overflow + BTREE_META = 9, // BTree metadata +}; + +enum class RecordType : uint8_t { + KEYDATA = 1, + // DUPLICATE = 2, Unused as our databases do not support duplicate records + OVERFLOW_DATA = 3, + DELETE = 0x80, // Indicate this record is deleted. This is OR'd with the real type. +}; + +enum class BTreeFlags : uint32_t { + /* + * BTree databases have feature flags, but we do not use them except for + * subdatabases. The unused flags are included for completeness, but commented out + * to avoid accidental use. + DUP = 1, // Duplicates + RECNO = 2, // Recno tree + RECNUM = 4, // BTree: Maintain record counts + FIXEDLEN = 8, // Recno: fixed length records + RENUMBER = 0x10, // Recno: renumber on insert/delete + DUPSORT = 0x40, // Duplicates are sorted + COMPRESS = 0x80, // Compressed + */ + SUBDB = 0x20, // Subdatabases +}; + +/** Berkeley DB BTree metadata page layout */ +class MetaPage +{ +public: + uint32_t lsn_file; // Log Sequence Number file + uint32_t lsn_offset; // Log Sequence Number offset + uint32_t page_num; // Current page number + uint32_t magic; // Magic number + uint32_t version; // Version + uint32_t pagesize; // Page size + uint8_t encrypt_algo; // Encryption algorithm + PageType type; // Page type + uint8_t metaflags; // Meta-only flags + uint8_t unused1; // Unused + uint32_t free_list; // Free list page number + uint32_t last_page; // Page number of last page in db + uint32_t partitions; // Number of partitions + uint32_t key_count; // Cached key count + uint32_t record_count; // Cached record count + BTreeFlags flags; // Flags + std::array<std::byte, 20> uid; // 20 byte unique file ID + uint32_t unused2; // Unused + uint32_t minkey; // Minimum key + uint32_t re_len; // Recno: fixed length record length + uint32_t re_pad; // Recno: fixed length record pad + uint32_t root; // Root page number + char unused3[368]; // 92 * 4 bytes of unused space + uint32_t crypto_magic; // Crypto magic number + char trash[12]; // 3 * 4 bytes of trash space + unsigned char iv[20]; // Crypto IV + unsigned char chksum[16]; // Checksum + + bool other_endian; + uint32_t expected_page_num; + + MetaPage(uint32_t expected_page_num) : expected_page_num(expected_page_num) {} + MetaPage() = delete; + + template <typename Stream> + void Unserialize(Stream& s) + { + s >> lsn_file; + s >> lsn_offset; + s >> page_num; + s >> magic; + s >> version; + s >> pagesize; + s >> encrypt_algo; + + other_endian = magic == BTREE_MAGIC_OE; + + uint8_t uint8_type; + s >> uint8_type; + type = static_cast<PageType>(uint8_type); + + s >> metaflags; + s >> unused1; + s >> free_list; + s >> last_page; + s >> partitions; + s >> key_count; + s >> record_count; + + uint32_t uint32_flags; + s >> uint32_flags; + if (other_endian) { + uint32_flags = internal_bswap_32(uint32_flags); + } + flags = static_cast<BTreeFlags>(uint32_flags); + + s >> uid; + s >> unused2; + s >> minkey; + s >> re_len; + s >> re_pad; + s >> root; + s >> unused3; + s >> crypto_magic; + s >> trash; + s >> iv; + s >> chksum; + + if (other_endian) { + lsn_file = internal_bswap_32(lsn_file); + lsn_offset = internal_bswap_32(lsn_offset); + page_num = internal_bswap_32(page_num); + magic = internal_bswap_32(magic); + version = internal_bswap_32(version); + pagesize = internal_bswap_32(pagesize); + free_list = internal_bswap_32(free_list); + last_page = internal_bswap_32(last_page); + partitions = internal_bswap_32(partitions); + key_count = internal_bswap_32(key_count); + record_count = internal_bswap_32(record_count); + unused2 = internal_bswap_32(unused2); + minkey = internal_bswap_32(minkey); + re_len = internal_bswap_32(re_len); + re_pad = internal_bswap_32(re_pad); + root = internal_bswap_32(root); + crypto_magic = internal_bswap_32(crypto_magic); + } + + // Page number must match + if (page_num != expected_page_num) { + throw std::runtime_error("Meta page number mismatch"); + } + + // Check magic + if (magic != BTREE_MAGIC) { + throw std::runtime_error("Not a BDB file"); + } + + // Only version 9 is supported + if (version != 9) { + throw std::runtime_error("Unsupported BDB data file version number"); + } + + // Page size must be 512 <= pagesize <= 64k, and be a power of 2 + if (pagesize < 512 || pagesize > 65536 || (pagesize & (pagesize - 1)) != 0) { + throw std::runtime_error("Bad page size"); + } + + // Page type must be the btree type + if (type != PageType::BTREE_META) { + throw std::runtime_error("Unexpected page type, should be 9 (BTree Metadata)"); + } + + // Only supported meta-flag is subdatabase + if (flags != BTreeFlags::SUBDB) { + throw std::runtime_error("Unexpected database flags, should only be 0x20 (subdatabases)"); + } + } +}; + +/** General class for records in a BDB BTree database. Contains common fields. */ +class RecordHeader +{ +public: + uint16_t len; // Key/data item length + RecordType type; // Page type (BDB has this include a DELETE FLAG that we track separately) + bool deleted; // Whether the DELETE flag was set on type + + static constexpr size_t SIZE = 3; // The record header is 3 bytes + + bool other_endian; + + RecordHeader(bool other_endian) : other_endian(other_endian) {} + RecordHeader() = delete; + + template <typename Stream> + void Unserialize(Stream& s) + { + s >> len; + + uint8_t uint8_type; + s >> uint8_type; + type = static_cast<RecordType>(uint8_type & ~static_cast<uint8_t>(RecordType::DELETE)); + deleted = uint8_type & static_cast<uint8_t>(RecordType::DELETE); + + if (other_endian) { + len = internal_bswap_16(len); + } + } +}; + +/** Class for data in the record directly */ +class DataRecord +{ +public: + DataRecord(const RecordHeader& header) : m_header(header) {} + DataRecord() = delete; + + RecordHeader m_header; + + std::vector<std::byte> data; // Variable length key/data item + + template <typename Stream> + void Unserialize(Stream& s) + { + data.resize(m_header.len); + s.read(AsWritableBytes(Span(data.data(), data.size()))); + } +}; + +/** Class for records representing internal nodes of the BTree. */ +class InternalRecord +{ +public: + InternalRecord(const RecordHeader& header) : m_header(header) {} + InternalRecord() = delete; + + RecordHeader m_header; + + uint8_t unused; // Padding, unused + uint32_t page_num; // Page number of referenced page + uint32_t records; // Subtree record count + std::vector<std::byte> data; // Variable length key item + + static constexpr size_t FIXED_SIZE = 9; // Size of fixed data is 9 bytes + + template <typename Stream> + void Unserialize(Stream& s) + { + s >> unused; + s >> page_num; + s >> records; + + data.resize(m_header.len); + s.read(AsWritableBytes(Span(data.data(), data.size()))); + + if (m_header.other_endian) { + page_num = internal_bswap_32(page_num); + records = internal_bswap_32(records); + } + } +}; + +/** Class for records representing overflow records of the BTree. + * Overflow records point to a page which contains the data in the record. + * Those pages may point to further pages with the rest of the data if it does not fit + * in one page */ +class OverflowRecord +{ +public: + OverflowRecord(const RecordHeader& header) : m_header(header) {} + OverflowRecord() = delete; + + RecordHeader m_header; + + uint8_t unused2; // Padding, unused + uint32_t page_number; // Page number where data begins + uint32_t item_len; // Total length of item + + static constexpr size_t SIZE = 9; // Overflow record is always 9 bytes + + template <typename Stream> + void Unserialize(Stream& s) + { + s >> unused2; + s >> page_number; + s >> item_len; + + if (m_header.other_endian) { + page_number = internal_bswap_32(page_number); + item_len = internal_bswap_32(item_len); + } + } +}; + +/** A generic data page in the database. Contains fields common to all data pages. */ +class PageHeader +{ +public: + uint32_t lsn_file; // Log Sequence Number file + uint32_t lsn_offset; // Log Sequence Number offset + uint32_t page_num; // Current page number + uint32_t prev_page; // Previous page number + uint32_t next_page; // Next page number + uint16_t entries; // Number of items on the page + uint16_t hf_offset; // High free byte page offset + uint8_t level; // Btree page level + PageType type; // Page type + + static constexpr int64_t SIZE = 26; // The header is 26 bytes + + uint32_t expected_page_num; + bool other_endian; + + PageHeader(uint32_t page_num, bool other_endian) : expected_page_num(page_num), other_endian(other_endian) {} + PageHeader() = delete; + + template <typename Stream> + void Unserialize(Stream& s) + { + s >> lsn_file; + s >> lsn_offset; + s >> page_num; + s >> prev_page; + s >> next_page; + s >> entries; + s >> hf_offset; + s >> level; + + uint8_t uint8_type; + s >> uint8_type; + type = static_cast<PageType>(uint8_type); + + if (other_endian) { + lsn_file = internal_bswap_32(lsn_file); + lsn_offset = internal_bswap_32(lsn_offset); + page_num = internal_bswap_32(page_num); + prev_page = internal_bswap_32(prev_page); + next_page = internal_bswap_32(next_page); + entries = internal_bswap_16(entries); + hf_offset = internal_bswap_16(hf_offset); + } + + if (expected_page_num != page_num) { + throw std::runtime_error("Page number mismatch"); + } + if ((type != PageType::OVERFLOW_DATA && level < 1) || (type == PageType::OVERFLOW_DATA && level != 0)) { + throw std::runtime_error("Bad btree level"); + } + } +}; + +/** A page of records in the database */ +class RecordsPage +{ +public: + RecordsPage(const PageHeader& header) : m_header(header) {} + RecordsPage() = delete; + + PageHeader m_header; + + std::vector<uint16_t> indexes; + std::vector<std::variant<DataRecord, OverflowRecord>> records; + + template <typename Stream> + void Unserialize(Stream& s) + { + // Current position within the page + int64_t pos = PageHeader::SIZE; + + // Get the items + for (uint32_t i = 0; i < m_header.entries; ++i) { + // Get the index + uint16_t index; + s >> index; + if (m_header.other_endian) { + index = internal_bswap_16(index); + } + indexes.push_back(index); + pos += sizeof(uint16_t); + + // Go to the offset from the index + int64_t to_jump = index - pos; + if (to_jump < 0) { + throw std::runtime_error("Data record position not in page"); + } + s.ignore(to_jump); + + // Read the record + RecordHeader rec_hdr(m_header.other_endian); + s >> rec_hdr; + to_jump += RecordHeader::SIZE; + + switch (rec_hdr.type) { + case RecordType::KEYDATA: { + DataRecord record(rec_hdr); + s >> record; + records.emplace_back(record); + to_jump += rec_hdr.len; + break; + } + case RecordType::OVERFLOW_DATA: { + OverflowRecord record(rec_hdr); + s >> record; + records.emplace_back(record); + to_jump += OverflowRecord::SIZE; + break; + } + default: + throw std::runtime_error("Unknown record type in records page"); + } + + // Go back to the indexes + s.seek(-to_jump, SEEK_CUR); + } + } +}; + +/** A page containing overflow data */ +class OverflowPage +{ +public: + OverflowPage(const PageHeader& header) : m_header(header) {} + OverflowPage() = delete; + + PageHeader m_header; + + // BDB overloads some page fields to store overflow page data + // hf_offset contains the length of the overflow data stored on this page + // entries contains a reference count for references to this item + + // The overflow data itself. Begins immediately following header + std::vector<std::byte> data; + + template <typename Stream> + void Unserialize(Stream& s) + { + data.resize(m_header.hf_offset); + s.read(AsWritableBytes(Span(data.data(), data.size()))); + } +}; + +/** A page of records in the database */ +class InternalPage +{ +public: + InternalPage(const PageHeader& header) : m_header(header) {} + InternalPage() = delete; + + PageHeader m_header; + + std::vector<uint16_t> indexes; + std::vector<InternalRecord> records; + + template <typename Stream> + void Unserialize(Stream& s) + { + // Current position within the page + int64_t pos = PageHeader::SIZE; + + // Get the items + for (uint32_t i = 0; i < m_header.entries; ++i) { + // Get the index + uint16_t index; + s >> index; + if (m_header.other_endian) { + index = internal_bswap_16(index); + } + indexes.push_back(index); + pos += sizeof(uint16_t); + + // Go to the offset from the index + int64_t to_jump = index - pos; + if (to_jump < 0) { + throw std::runtime_error("Internal record position not in page"); + } + s.ignore(to_jump); + + // Read the record + RecordHeader rec_hdr(m_header.other_endian); + s >> rec_hdr; + to_jump += RecordHeader::SIZE; + + if (rec_hdr.type != RecordType::KEYDATA) { + throw std::runtime_error("Unknown record type in internal page"); + } + InternalRecord record(rec_hdr); + s >> record; + records.emplace_back(record); + to_jump += InternalRecord::FIXED_SIZE + rec_hdr.len; + + // Go back to the indexes + s.seek(-to_jump, SEEK_CUR); + } + } +}; + +static void SeekToPage(AutoFile& s, uint32_t page_num, uint32_t page_size) +{ + int64_t pos = int64_t{page_num} * page_size; + s.seek(pos, SEEK_SET); +} + +void BerkeleyRODatabase::Open() +{ + // Open the file + FILE* file = fsbridge::fopen(m_filepath, "rb"); + AutoFile db_file(file); + if (db_file.IsNull()) { + throw std::runtime_error("BerkeleyRODatabase: Failed to open database file"); + } + + uint32_t page_size = 4096; // Default page size + + // Read the outer metapage + // Expected page number is 0 + MetaPage outer_meta(0); + db_file >> outer_meta; + page_size = outer_meta.pagesize; + + // Verify the size of the file is a multiple of the page size + db_file.seek(0, SEEK_END); + int64_t size = db_file.tell(); + + // Since BDB stores everything in a page, the file size should be a multiple of the page size; + // However, BDB doesn't actually check that this is the case, and enforcing this check results + // in us rejecting a database that BDB would not, so this check needs to be excluded. + // This is left commented out as a reminder to not accidentally implement this in the future. + // if (size % page_size != 0) { + // throw std::runtime_error("File size is not a multiple of page size"); + // } + + // Check the last page number + uint32_t expected_last_page{uint32_t((size / page_size) - 1)}; + if (outer_meta.last_page != expected_last_page) { + throw std::runtime_error("Last page number could not fit in file"); + } + + // Make sure encryption is disabled + if (outer_meta.encrypt_algo != 0) { + throw std::runtime_error("BDB builtin encryption is not supported"); + } + + // Check all Log Sequence Numbers (LSN) point to file 0 and offset 1 which indicates that the LSNs were + // reset and that the log files are not necessary to get all of the data in the database. + for (uint32_t i = 0; i < outer_meta.last_page; ++i) { + // The LSN is composed of 2 32-bit ints, the first is a file id, the second an offset + // It will always be the first 8 bytes of a page, so we deserialize it directly for every page + uint32_t file; + uint32_t offset; + SeekToPage(db_file, i, page_size); + db_file >> file >> offset; + if (outer_meta.other_endian) { + file = internal_bswap_32(file); + offset = internal_bswap_32(offset); + } + if (file != 0 || offset != 1) { + throw std::runtime_error("LSNs are not reset, this database is not completely flushed. Please reopen then close the database with a version that has BDB support"); + } + } + + // Read the root page + SeekToPage(db_file, outer_meta.root, page_size); + PageHeader header(outer_meta.root, outer_meta.other_endian); + db_file >> header; + if (header.type != PageType::BTREE_LEAF) { + throw std::runtime_error("Unexpected outer database root page type"); + } + if (header.entries != 2) { + throw std::runtime_error("Unexpected number of entries in outer database root page"); + } + RecordsPage page(header); + db_file >> page; + + // First record should be the string "main" + if (!std::holds_alternative<DataRecord>(page.records.at(0)) || std::get<DataRecord>(page.records.at(0)).data != SUBDATABASE_NAME) { + throw std::runtime_error("Subdatabase has an unexpected name"); + } + // Check length of page number for subdatabase location + if (!std::holds_alternative<DataRecord>(page.records.at(1)) || std::get<DataRecord>(page.records.at(1)).m_header.len != 4) { + throw std::runtime_error("Subdatabase page number has unexpected length"); + } + + // Read subdatabase page number + // It is written as a big endian 32 bit number + uint32_t main_db_page = ReadBE32(UCharCast(std::get<DataRecord>(page.records.at(1)).data.data())); + + // The main database is in a page that doesn't exist + if (main_db_page > outer_meta.last_page) { + throw std::runtime_error("Page number is greater than database last page"); + } + + // Read the inner metapage + SeekToPage(db_file, main_db_page, page_size); + MetaPage inner_meta(main_db_page); + db_file >> inner_meta; + + if (inner_meta.pagesize != page_size) { + throw std::runtime_error("Unexpected page size"); + } + + if (inner_meta.last_page > outer_meta.last_page) { + throw std::runtime_error("Subdatabase last page is greater than database last page"); + } + + // Make sure encryption is disabled + if (inner_meta.encrypt_algo != 0) { + throw std::runtime_error("BDB builtin encryption is not supported"); + } + + // Do a DFS through the BTree, starting at root + std::vector<uint32_t> pages{inner_meta.root}; + while (pages.size() > 0) { + uint32_t curr_page = pages.back(); + // It turns out BDB completely ignores this last_page field and doesn't actually update it to the correct + // last page. While we should be checking this, we can't. + // This is left commented out as a reminder to not accidentally implement this in the future. + // if (curr_page > inner_meta.last_page) { + // throw std::runtime_error("Page number is greater than subdatabase last page"); + // } + pages.pop_back(); + SeekToPage(db_file, curr_page, page_size); + PageHeader header(curr_page, inner_meta.other_endian); + db_file >> header; + switch (header.type) { + case PageType::BTREE_INTERNAL: { + InternalPage int_page(header); + db_file >> int_page; + for (const InternalRecord& rec : int_page.records) { + if (rec.m_header.deleted) continue; + pages.push_back(rec.page_num); + } + break; + } + case PageType::BTREE_LEAF: { + RecordsPage rec_page(header); + db_file >> rec_page; + if (rec_page.records.size() % 2 != 0) { + // BDB stores key value pairs in consecutive records, thus an odd number of records is unexpected + throw std::runtime_error("Records page has odd number of records"); + } + bool is_key = true; + std::vector<std::byte> key; + for (const std::variant<DataRecord, OverflowRecord>& rec : rec_page.records) { + std::vector<std::byte> data; + if (const DataRecord* drec = std::get_if<DataRecord>(&rec)) { + if (drec->m_header.deleted) continue; + data = drec->data; + } else if (const OverflowRecord* orec = std::get_if<OverflowRecord>(&rec)) { + if (orec->m_header.deleted) continue; + uint32_t next_page = orec->page_number; + while (next_page != 0) { + SeekToPage(db_file, next_page, page_size); + PageHeader opage_header(next_page, inner_meta.other_endian); + db_file >> opage_header; + if (opage_header.type != PageType::OVERFLOW_DATA) { + throw std::runtime_error("Bad overflow record page type"); + } + OverflowPage opage(opage_header); + db_file >> opage; + data.insert(data.end(), opage.data.begin(), opage.data.end()); + next_page = opage_header.next_page; + } + } + + if (is_key) { + key = data; + } else { + m_records.emplace(SerializeData{key.begin(), key.end()}, SerializeData{data.begin(), data.end()}); + key.clear(); + } + is_key = !is_key; + } + break; + } + default: + throw std::runtime_error("Unexpected page type"); + } + } +} + +std::unique_ptr<DatabaseBatch> BerkeleyRODatabase::MakeBatch(bool flush_on_close) +{ + return std::make_unique<BerkeleyROBatch>(*this); +} + +bool BerkeleyRODatabase::Backup(const std::string& dest) const +{ + fs::path src(m_filepath); + fs::path dst(fs::PathFromString(dest)); + + if (fs::is_directory(dst)) { + dst = BDBDataFile(dst); + } + try { + if (fs::exists(dst) && fs::equivalent(src, dst)) { + LogPrintf("cannot backup to wallet source file %s\n", fs::PathToString(dst)); + return false; + } + + fs::copy_file(src, dst, fs::copy_options::overwrite_existing); + LogPrintf("copied %s to %s\n", fs::PathToString(m_filepath), fs::PathToString(dst)); + return true; + } catch (const fs::filesystem_error& e) { + LogPrintf("error copying %s to %s - %s\n", fs::PathToString(m_filepath), fs::PathToString(dst), fsbridge::get_filesystem_error_message(e)); + return false; + } +} + +bool BerkeleyROBatch::ReadKey(DataStream&& key, DataStream& value) +{ + SerializeData key_data{key.begin(), key.end()}; + const auto it{m_database.m_records.find(key_data)}; + if (it == m_database.m_records.end()) { + return false; + } + auto val = it->second; + value.clear(); + value.write(Span(val)); + return true; +} + +bool BerkeleyROBatch::HasKey(DataStream&& key) +{ + SerializeData key_data{key.begin(), key.end()}; + return m_database.m_records.count(key_data) > 0; +} + +BerkeleyROCursor::BerkeleyROCursor(const BerkeleyRODatabase& database, Span<const std::byte> prefix) + : m_database(database) +{ + std::tie(m_cursor, m_cursor_end) = m_database.m_records.equal_range(BytePrefix{prefix}); +} + +DatabaseCursor::Status BerkeleyROCursor::Next(DataStream& ssKey, DataStream& ssValue) +{ + if (m_cursor == m_cursor_end) { + return DatabaseCursor::Status::DONE; + } + ssKey.write(Span(m_cursor->first)); + ssValue.write(Span(m_cursor->second)); + m_cursor++; + return DatabaseCursor::Status::MORE; +} + +std::unique_ptr<DatabaseCursor> BerkeleyROBatch::GetNewPrefixCursor(Span<const std::byte> prefix) +{ + return std::make_unique<BerkeleyROCursor>(m_database, prefix); +} + +std::unique_ptr<BerkeleyRODatabase> MakeBerkeleyRODatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error) +{ + fs::path data_file = BDBDataFile(path); + try { + std::unique_ptr<BerkeleyRODatabase> db = std::make_unique<BerkeleyRODatabase>(data_file); + status = DatabaseStatus::SUCCESS; + return db; + } catch (const std::runtime_error& e) { + error.original = e.what(); + status = DatabaseStatus::FAILED_LOAD; + return nullptr; + } +} +} // namespace wallet diff --git a/src/wallet/migrate.h b/src/wallet/migrate.h new file mode 100644 index 0000000000..e4826450af --- /dev/null +++ b/src/wallet/migrate.h @@ -0,0 +1,124 @@ +// Copyright (c) 2021 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_WALLET_MIGRATE_H +#define BITCOIN_WALLET_MIGRATE_H + +#include <wallet/db.h> + +#include <optional> + +namespace wallet { + +using BerkeleyROData = std::map<SerializeData, SerializeData, std::less<>>; + +/** + * A class representing a BerkeleyDB file from which we can only read records. + * This is used only for migration of legacy to descriptor wallets + */ +class BerkeleyRODatabase : public WalletDatabase +{ +private: + const fs::path m_filepath; + +public: + /** Create DB handle */ + BerkeleyRODatabase(const fs::path& filepath, bool open = true) : WalletDatabase(), m_filepath(filepath) + { + if (open) Open(); + } + ~BerkeleyRODatabase(){}; + + BerkeleyROData m_records; + + /** Open the database if it is not already opened. */ + void Open() override; + + /** Indicate the a new database user has began using the database. Increments m_refcount */ + void AddRef() override {} + /** Indicate that database user has stopped using the database and that it could be flushed or closed. Decrement m_refcount */ + void RemoveRef() override {} + + /** Rewrite the entire database on disk, with the exception of key pszSkip if non-zero + */ + bool Rewrite(const char* pszSkip = nullptr) override { return false; } + + /** Back up the entire database to a file. + */ + bool Backup(const std::string& strDest) const override; + + /** Make sure all changes are flushed to database file. + */ + void Flush() override {} + /** Flush to the database file and close the database. + * Also close the environment if no other databases are open in it. + */ + void Close() override {} + /* flush the wallet passively (TRY_LOCK) + ideal to be called periodically */ + bool PeriodicFlush() override { return false; } + + void IncrementUpdateCounter() override {} + + void ReloadDbEnv() override {} + + /** Return path to main database file for logs and error messages. */ + std::string Filename() override { return fs::PathToString(m_filepath); } + + std::string Format() override { return "bdb_ro"; } + + /** Make a DatabaseBatch connected to this database */ + std::unique_ptr<DatabaseBatch> MakeBatch(bool flush_on_close = true) override; +}; + +class BerkeleyROCursor : public DatabaseCursor +{ +private: + const BerkeleyRODatabase& m_database; + BerkeleyROData::const_iterator m_cursor; + BerkeleyROData::const_iterator m_cursor_end; + +public: + explicit BerkeleyROCursor(const BerkeleyRODatabase& database, Span<const std::byte> prefix = {}); + ~BerkeleyROCursor() {} + + Status Next(DataStream& key, DataStream& value) override; +}; + +/** RAII class that provides access to a BerkeleyRODatabase */ +class BerkeleyROBatch : public DatabaseBatch +{ +private: + const BerkeleyRODatabase& m_database; + + bool ReadKey(DataStream&& key, DataStream& value) override; + // WriteKey returns true since various automatic upgrades for older wallets will expect writing to not fail. + // It is okay for this batch type to not actually write anything as those automatic upgrades will occur again after migration. + bool WriteKey(DataStream&& key, DataStream&& value, bool overwrite = true) override { return true; } + bool EraseKey(DataStream&& key) override { return false; } + bool HasKey(DataStream&& key) override; + bool ErasePrefix(Span<const std::byte> prefix) override { return false; } + +public: + explicit BerkeleyROBatch(const BerkeleyRODatabase& database) : m_database(database) {} + ~BerkeleyROBatch() {} + + BerkeleyROBatch(const BerkeleyROBatch&) = delete; + BerkeleyROBatch& operator=(const BerkeleyROBatch&) = delete; + + void Flush() override {} + void Close() override {} + + std::unique_ptr<DatabaseCursor> GetNewCursor() override { return std::make_unique<BerkeleyROCursor>(m_database); } + std::unique_ptr<DatabaseCursor> GetNewPrefixCursor(Span<const std::byte> prefix) override; + bool TxnBegin() override { return false; } + bool TxnCommit() override { return false; } + bool TxnAbort() override { return false; } +}; + +//! Return object giving access to Berkeley Read Only database at specified path. +std::unique_ptr<BerkeleyRODatabase> MakeBerkeleyRODatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error); +} // namespace wallet + +#endif // BITCOIN_WALLET_MIGRATE_H diff --git a/src/wallet/rpc/addresses.cpp b/src/wallet/rpc/addresses.cpp index 65587f0b18..0c2ad06eea 100644 --- a/src/wallet/rpc/addresses.cpp +++ b/src/wallet/rpc/addresses.cpp @@ -206,9 +206,9 @@ RPCHelpMan listaddressgroupings() addressInfo.push_back(address_book_entry->GetLabel()); } } - jsonGrouping.push_back(addressInfo); + jsonGrouping.push_back(std::move(addressInfo)); } - jsonGroupings.push_back(jsonGrouping); + jsonGroupings.push_back(std::move(jsonGrouping)); } return jsonGroupings; }, @@ -287,9 +287,30 @@ RPCHelpMan addmultisigaddress() output_type = parsed.value(); } - // Construct using pay-to-script-hash: + // Construct multisig scripts + FlatSigningProvider provider; CScript inner; - CTxDestination dest = AddAndGetMultisigDestination(required, pubkeys, output_type, spk_man, inner); + CTxDestination dest = AddAndGetMultisigDestination(required, pubkeys, output_type, provider, inner); + + // Import scripts into the wallet + for (const auto& [id, script] : provider.scripts) { + // Due to a bug in the legacy wallet, the p2sh maximum script size limit is also imposed on 'p2sh-segwit' and 'bech32' redeem scripts. + // Even when redeem scripts over MAX_SCRIPT_ELEMENT_SIZE bytes are valid for segwit output types, we don't want to + // enable it because: + // 1) It introduces a compatibility-breaking change requiring downgrade protection; older wallets would be unable to interact with these "new" legacy wallets. + // 2) Considering the ongoing deprecation of the legacy spkm, this issue adds another good reason to transition towards descriptors. + if (script.size() > MAX_SCRIPT_ELEMENT_SIZE) throw JSONRPCError(RPC_WALLET_ERROR, "Unsupported multisig script size for legacy wallet. Upgrade to descriptors to overcome this limitation for p2sh-segwit or bech32 scripts"); + + if (!spk_man.AddCScript(script)) { + if (CScript inner_script; spk_man.GetCScript(CScriptID(script), inner_script)) { + CHECK_NONFATAL(inner_script == script); // Nothing to add, script already contained by the wallet + continue; + } + throw JSONRPCError(RPC_WALLET_ERROR, strprintf("Error importing script into the wallet")); + } + } + + // Store destination in the addressbook pwallet->SetAddressBook(dest, label, AddressPurpose::SEND); // Make the descriptor @@ -407,9 +428,9 @@ public: // Only when the script corresponds to an address. UniValue subobj(UniValue::VOBJ); UniValue detail = DescribeAddress(embedded); - subobj.pushKVs(detail); + subobj.pushKVs(std::move(detail)); UniValue wallet_detail = std::visit(*this, embedded); - subobj.pushKVs(wallet_detail); + subobj.pushKVs(std::move(wallet_detail)); subobj.pushKV("address", EncodeDestination(embedded)); subobj.pushKV("scriptPubKey", HexStr(subscript)); // Always report the pubkey at the top level, so that `getnewaddress()['pubkey']` always works. @@ -490,7 +511,7 @@ static UniValue DescribeWalletAddress(const CWallet& wallet, const CTxDestinatio CScript script = GetScriptForDestination(dest); std::unique_ptr<SigningProvider> provider = nullptr; provider = wallet.GetSolvingProvider(script); - ret.pushKVs(detail); + ret.pushKVs(std::move(detail)); ret.pushKVs(std::visit(DescribeWalletAddressVisitor(provider.get()), dest)); return ret; } @@ -607,7 +628,7 @@ RPCHelpMan getaddressinfo() ret.pushKV("iswatchonly", bool(mine & ISMINE_WATCH_ONLY)); UniValue detail = DescribeWalletAddress(*pwallet, dest); - ret.pushKVs(detail); + ret.pushKVs(std::move(detail)); ret.pushKV("ischange", ScriptIsChange(*pwallet, scriptPubKey)); @@ -688,7 +709,7 @@ RPCHelpMan getaddressesbylabel() // which currently is O(1). UniValue value(UniValue::VOBJ); value.pushKV("purpose", _purpose ? PurposeToString(*_purpose) : "unknown"); - ret.pushKVEnd(address, value); + ret.pushKVEnd(address, std::move(value)); } }); diff --git a/src/wallet/rpc/backup.cpp b/src/wallet/rpc/backup.cpp index c05600484e..8cddb8b099 100644 --- a/src/wallet/rpc/backup.cpp +++ b/src/wallet/rpc/backup.cpp @@ -34,6 +34,7 @@ using interfaces::FoundBlock; +using util::SplitString; namespace wallet { std::string static EncodeDumpString(const std::string &str) { @@ -456,12 +457,7 @@ RPCHelpMan importpubkey() throw JSONRPCError(RPC_WALLET_ERROR, "Wallet is currently rescanning. Abort existing rescan or wait."); } - if (!IsHex(request.params[0].get_str())) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey must be a hex string"); - std::vector<unsigned char> data(ParseHex(request.params[0].get_str())); - CPubKey pubKey(data); - if (!pubKey.IsFullyValid()) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey is not a valid public key"); + CPubKey pubKey = HexToPubKey(request.params[0].get_str()); { LOCK(pwallet->cs_wallet); @@ -983,15 +979,7 @@ static UniValue ProcessImportLegacy(ImportData& import_data, std::map<CKeyID, CP import_data.witnessscript = std::make_unique<CScript>(parsed_witnessscript.begin(), parsed_witnessscript.end()); } for (size_t i = 0; i < pubKeys.size(); ++i) { - const auto& str = pubKeys[i].get_str(); - if (!IsHex(str)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey \"" + str + "\" must be a hex string"); - } - auto parsed_pubkey = ParseHex(str); - CPubKey pubkey(parsed_pubkey); - if (!pubkey.IsFullyValid()) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey \"" + str + "\" is not a valid public key"); - } + CPubKey pubkey = HexToPubKey(pubKeys[i].get_str()); pubkey_map.emplace(pubkey.GetID(), pubkey); ordered_pubkeys.push_back(pubkey.GetID()); } @@ -1840,16 +1828,16 @@ RPCHelpMan listdescriptors() UniValue range(UniValue::VARR); range.push_back(info.range->first); range.push_back(info.range->second - 1); - spk.pushKV("range", range); + spk.pushKV("range", std::move(range)); spk.pushKV("next", info.next_index); spk.pushKV("next_index", info.next_index); } - descriptors.push_back(spk); + descriptors.push_back(std::move(spk)); } UniValue response(UniValue::VOBJ); response.pushKV("wallet_name", wallet->GetName()); - response.pushKV("descriptors", descriptors); + response.pushKV("descriptors", std::move(descriptors)); return response; }, diff --git a/src/wallet/rpc/coins.cpp b/src/wallet/rpc/coins.cpp index b6c7396f4b..2cf94a5722 100644 --- a/src/wallet/rpc/coins.cpp +++ b/src/wallet/rpc/coins.cpp @@ -416,7 +416,7 @@ RPCHelpMan listlockunspent() o.pushKV("txid", outpt.hash.GetHex()); o.pushKV("vout", (int)outpt.n); - ret.push_back(o); + ret.push_back(std::move(o)); } return ret; @@ -477,7 +477,7 @@ RPCHelpMan getbalances() const auto full_bal = GetBalance(wallet, 0, false); balances_mine.pushKV("used", ValueFromAmount(full_bal.m_mine_trusted + full_bal.m_mine_untrusted_pending - bal.m_mine_trusted - bal.m_mine_untrusted_pending)); } - balances.pushKV("mine", balances_mine); + balances.pushKV("mine", std::move(balances_mine)); } auto spk_man = wallet.GetLegacyScriptPubKeyMan(); if (spk_man && spk_man->HaveWatchOnly()) { @@ -485,7 +485,7 @@ RPCHelpMan getbalances() balances_watchonly.pushKV("trusted", ValueFromAmount(bal.m_watchonly_trusted)); balances_watchonly.pushKV("untrusted_pending", ValueFromAmount(bal.m_watchonly_untrusted_pending)); balances_watchonly.pushKV("immature", ValueFromAmount(bal.m_watchonly_immature)); - balances.pushKV("watchonly", balances_watchonly); + balances.pushKV("watchonly", std::move(balances_watchonly)); } AppendLastProcessedBlock(balances, wallet); @@ -724,7 +724,7 @@ RPCHelpMan listunspent() PushParentDescriptors(*pwallet, scriptPubKey, entry); if (avoid_reuse) entry.pushKV("reused", reused); entry.pushKV("safe", out.safe); - results.push_back(entry); + results.push_back(std::move(entry)); } return results; diff --git a/src/wallet/rpc/signmessage.cpp b/src/wallet/rpc/signmessage.cpp index c9fb693482..edf93ecab7 100644 --- a/src/wallet/rpc/signmessage.cpp +++ b/src/wallet/rpc/signmessage.cpp @@ -2,9 +2,9 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <common/signmessage.h> #include <key_io.h> #include <rpc/util.h> -#include <util/message.h> #include <wallet/rpc/util.h> #include <wallet/wallet.h> diff --git a/src/wallet/rpc/spend.cpp b/src/wallet/rpc/spend.cpp index 6060f017ce..ac2a4826f0 100644 --- a/src/wallet/rpc/spend.cpp +++ b/src/wallet/rpc/spend.cpp @@ -2,14 +2,15 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <common/messages.h> #include <consensus/validation.h> #include <core_io.h> #include <key_io.h> +#include <node/types.h> #include <policy/policy.h> #include <rpc/rawtransaction_util.h> #include <rpc/util.h> #include <script/script.h> -#include <util/fees.h> #include <util/rbf.h> #include <util/translation.h> #include <util/vector.h> @@ -22,6 +23,12 @@ #include <univalue.h> +using common::FeeModeFromString; +using common::FeeModes; +using common::InvalidEstimateModeErrorMessage; +using common::StringForFeeReason; +using common::TransactionErrorString; +using node::TransactionError; namespace wallet { std::vector<CRecipient> CreateRecipients(const std::vector<std::pair<CTxDestination, CAmount>>& outputs, const std::set<int>& subtract_fee_outputs) @@ -97,9 +104,9 @@ static UniValue FinishTransaction(const std::shared_ptr<CWallet> pwallet, const // so external signers are not asked to sign more than once. bool complete; pwallet->FillPSBT(psbtx, complete, SIGHASH_DEFAULT, /*sign=*/false, /*bip32derivs=*/true); - const TransactionError err{pwallet->FillPSBT(psbtx, complete, SIGHASH_DEFAULT, /*sign=*/true, /*bip32derivs=*/false)}; - if (err != TransactionError::OK) { - throw JSONRPCTransactionError(err); + const auto err{pwallet->FillPSBT(psbtx, complete, SIGHASH_DEFAULT, /*sign=*/true, /*bip32derivs=*/false)}; + if (err) { + throw JSONRPCPSBTError(*err); } CMutableTransaction mtx; @@ -627,15 +634,7 @@ CreatedTransactionResult FundTransaction(CWallet& wallet, const CMutableTransact const UniValue solving_data = options["solving_data"].get_obj(); if (solving_data.exists("pubkeys")) { for (const UniValue& pk_univ : solving_data["pubkeys"].get_array().getValues()) { - const std::string& pk_str = pk_univ.get_str(); - if (!IsHex(pk_str)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("'%s' is not hex", pk_str)); - } - const std::vector<unsigned char> data(ParseHex(pk_str)); - const CPubKey pubkey(data.begin(), data.end()); - if (!pubkey.IsFullyValid()) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("'%s' is not a valid public key", pk_str)); - } + const CPubKey pubkey = HexToPubKey(pk_univ.get_str()); coinControl.m_external_provider.pubkeys.emplace(pubkey.GetID(), pubkey); // Add witness script for pubkeys const CScript wit_script = GetScriptForDestination(WitnessV0KeyHash(pubkey)); @@ -726,7 +725,7 @@ static void SetOptionsInputWeights(const UniValue& inputs, UniValue& options) weights.push_back(input); } } - options.pushKV("input_weights", weights); + options.pushKV("input_weights", std::move(weights)); } RPCHelpMan fundrawtransaction() @@ -1161,8 +1160,8 @@ static RPCHelpMan bumpfee_helper(std::string method_name) } else { PartiallySignedTransaction psbtx(mtx); bool complete = false; - const TransactionError err = pwallet->FillPSBT(psbtx, complete, SIGHASH_DEFAULT, /*sign=*/false, /*bip32derivs=*/true); - CHECK_NONFATAL(err == TransactionError::OK); + const auto err{pwallet->FillPSBT(psbtx, complete, SIGHASH_DEFAULT, /*sign=*/false, /*bip32derivs=*/true)}; + CHECK_NONFATAL(!err); CHECK_NONFATAL(!complete); DataStream ssTx{}; ssTx << psbtx; @@ -1175,7 +1174,7 @@ static RPCHelpMan bumpfee_helper(std::string method_name) for (const bilingual_str& error : errors) { result_errors.push_back(error.original); } - result.pushKV("errors", result_errors); + result.pushKV("errors", std::move(result_errors)); return result; }, @@ -1303,7 +1302,7 @@ RPCHelpMan sendall() { return RPCHelpMan{"sendall", "EXPERIMENTAL warning: this call may be changed in future releases.\n" - "\nSpend the value of all (or specific) confirmed UTXOs in the wallet to one or more recipients.\n" + "\nSpend the value of all (or specific) confirmed UTXOs and unconfirmed change in the wallet to one or more recipients.\n" "Unconfirmed inbound UTXOs and locked UTXOs will not be spent. Sendall will respect the avoid_reuse wallet flag.\n" "If your wallet contains many small inputs, either because it received tiny payments or as a result of accumulating change, consider using `send_max` to exclude inputs that are worth less than the fees needed to spend them.\n", { @@ -1396,7 +1395,7 @@ RPCHelpMan sendall() if (recipient.isStr()) { UniValue rkvp(UniValue::VOBJ); rkvp.pushKV(recipient.get_str(), 0); - recipient_key_value_pairs.push_back(rkvp); + recipient_key_value_pairs.push_back(std::move(rkvp)); addresses_without_amount.insert(recipient.get_str()); } else { recipient_key_value_pairs.push_back(recipient); @@ -1478,10 +1477,18 @@ RPCHelpMan sendall() } } + std::vector<COutPoint> outpoints_spent; + outpoints_spent.reserve(rawTx.vin.size()); + + for (const CTxIn& tx_in : rawTx.vin) { + outpoints_spent.push_back(tx_in.prevout); + } + // estimate final size of tx const TxSize tx_size{CalculateMaximumSignedTxSize(CTransaction(rawTx), pwallet.get())}; const CAmount fee_from_size{fee_rate.GetFee(tx_size.vsize)}; - const CAmount effective_value{total_input_value - fee_from_size}; + const std::optional<CAmount> total_bump_fees{pwallet->chain().calculateCombinedBumpFee(outpoints_spent, fee_rate)}; + CAmount effective_value = total_input_value - fee_from_size - total_bump_fees.value_or(0); if (fee_from_size > pwallet->m_default_max_tx_fee) { throw JSONRPCError(RPC_WALLET_ERROR, TransactionErrorString(TransactionError::MAX_FEE_EXCEEDED).original); @@ -1610,9 +1617,9 @@ RPCHelpMan walletprocesspsbt() if (sign) EnsureWalletIsUnlocked(*pwallet); - const TransactionError err{wallet.FillPSBT(psbtx, complete, nHashType, sign, bip32derivs, nullptr, finalize)}; - if (err != TransactionError::OK) { - throw JSONRPCTransactionError(err); + const auto err{wallet.FillPSBT(psbtx, complete, nHashType, sign, bip32derivs, nullptr, finalize)}; + if (err) { + throw JSONRPCPSBTError(*err); } UniValue result(UniValue::VOBJ); @@ -1744,9 +1751,9 @@ RPCHelpMan walletcreatefundedpsbt() // Fill transaction with out data but don't sign bool bip32derivs = request.params[4].isNull() ? true : request.params[4].get_bool(); bool complete = true; - const TransactionError err{wallet.FillPSBT(psbtx, complete, 1, /*sign=*/false, /*bip32derivs=*/bip32derivs)}; - if (err != TransactionError::OK) { - throw JSONRPCTransactionError(err); + const auto err{wallet.FillPSBT(psbtx, complete, 1, /*sign=*/false, /*bip32derivs=*/bip32derivs)}; + if (err) { + throw JSONRPCPSBTError(*err); } // Serialize the PSBT diff --git a/src/wallet/rpc/transactions.cpp b/src/wallet/rpc/transactions.cpp index 05b340995d..5abc983701 100644 --- a/src/wallet/rpc/transactions.cpp +++ b/src/wallet/rpc/transactions.cpp @@ -39,11 +39,11 @@ static void WalletTxToJSON(const CWallet& wallet, const CWalletTx& wtx, UniValue UniValue conflicts(UniValue::VARR); for (const uint256& conflict : wallet.GetTxConflicts(wtx)) conflicts.push_back(conflict.GetHex()); - entry.pushKV("walletconflicts", conflicts); + entry.pushKV("walletconflicts", std::move(conflicts)); UniValue mempool_conflicts(UniValue::VARR); for (const Txid& mempool_conflict : wtx.mempool_conflicts) mempool_conflicts.push_back(mempool_conflict.GetHex()); - entry.pushKV("mempoolconflicts", mempool_conflicts); + entry.pushKV("mempoolconflicts", std::move(mempool_conflicts)); entry.pushKV("time", wtx.GetTxTime()); entry.pushKV("timereceived", int64_t{wtx.nTimeReceived}); @@ -172,8 +172,8 @@ static UniValue ListReceived(const CWallet& wallet, const UniValue& params, cons transactions.push_back(_item.GetHex()); } } - obj.pushKV("txids", transactions); - ret.push_back(obj); + obj.pushKV("txids", std::move(transactions)); + ret.push_back(std::move(obj)); } }; @@ -195,7 +195,7 @@ static UniValue ListReceived(const CWallet& wallet, const UniValue& params, cons obj.pushKV("amount", ValueFromAmount(nAmount)); obj.pushKV("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf)); obj.pushKV("label", entry.first); - ret.push_back(obj); + ret.push_back(std::move(obj)); } } @@ -353,7 +353,7 @@ static void ListTransactions(const CWallet& wallet, const CWalletTx& wtx, int nM if (fLong) WalletTxToJSON(wallet, wtx, entry); entry.pushKV("abandoned", wtx.isAbandoned()); - ret.push_back(entry); + ret.push_back(std::move(entry)); } } @@ -396,7 +396,7 @@ static void ListTransactions(const CWallet& wallet, const CWalletTx& wtx, int nM entry.pushKV("abandoned", wtx.isAbandoned()); if (fLong) WalletTxToJSON(wallet, wtx, entry); - ret.push_back(entry); + ret.push_back(std::move(entry)); } } } @@ -682,8 +682,8 @@ RPCHelpMan listsinceblock() CHECK_NONFATAL(wallet.chain().findAncestorByHeight(wallet.GetLastBlockHash(), wallet.GetLastBlockHeight() + 1 - target_confirms, FoundBlock().hash(lastblock))); UniValue ret(UniValue::VOBJ); - ret.pushKV("transactions", transactions); - if (include_removed) ret.pushKV("removed", removed); + ret.pushKV("transactions", std::move(transactions)); + if (include_removed) ret.pushKV("removed", std::move(removed)); ret.pushKV("lastblock", lastblock.GetHex()); return ret; @@ -789,14 +789,14 @@ RPCHelpMan gettransaction() UniValue details(UniValue::VARR); ListTransactions(*pwallet, wtx, 0, false, details, filter, /*filter_label=*/std::nullopt); - entry.pushKV("details", details); + entry.pushKV("details", std::move(details)); entry.pushKV("hex", EncodeHexTx(*wtx.tx)); if (verbose) { UniValue decoded(UniValue::VOBJ); TxToUniv(*wtx.tx, /*block_hash=*/uint256(), /*entry=*/decoded, /*include_hex=*/false); - entry.pushKV("decoded", decoded); + entry.pushKV("decoded", std::move(decoded)); } AppendLastProcessedBlock(entry, *pwallet); diff --git a/src/wallet/rpc/util.cpp b/src/wallet/rpc/util.cpp index 1252843e9d..67b5ae0fe2 100644 --- a/src/wallet/rpc/util.cpp +++ b/src/wallet/rpc/util.cpp @@ -149,7 +149,7 @@ void PushParentDescriptors(const CWallet& wallet, const CScript& script_pubkey, for (const auto& desc: wallet.GetWalletDescriptors(script_pubkey)) { parent_descs.push_back(desc.descriptor->ToString()); } - entry.pushKV("parent_descs", parent_descs); + entry.pushKV("parent_descs", std::move(parent_descs)); } void HandleWalletError(const std::shared_ptr<CWallet> wallet, DatabaseStatus& status, bilingual_str& error) @@ -179,13 +179,13 @@ void HandleWalletError(const std::shared_ptr<CWallet> wallet, DatabaseStatus& st } } -void AppendLastProcessedBlock(UniValue& entry, const CWallet& wallet) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet) +void AppendLastProcessedBlock(UniValue& entry, const CWallet& wallet) { AssertLockHeld(wallet.cs_wallet); UniValue lastprocessedblock{UniValue::VOBJ}; lastprocessedblock.pushKV("hash", wallet.GetLastBlockHash().GetHex()); lastprocessedblock.pushKV("height", wallet.GetLastBlockHeight()); - entry.pushKV("lastprocessedblock", lastprocessedblock); + entry.pushKV("lastprocessedblock", std::move(lastprocessedblock)); } } // namespace wallet diff --git a/src/wallet/rpc/wallet.cpp b/src/wallet/rpc/wallet.cpp index f1cb595271..8c218ad766 100644 --- a/src/wallet/rpc/wallet.cpp +++ b/src/wallet/rpc/wallet.cpp @@ -128,7 +128,7 @@ static RPCHelpMan getwalletinfo() UniValue scanning(UniValue::VOBJ); scanning.pushKV("duration", Ticks<std::chrono::seconds>(pwallet->ScanningDuration())); scanning.pushKV("progress", pwallet->ScanningProgress()); - obj.pushKV("scanning", scanning); + obj.pushKV("scanning", std::move(scanning)); } else { obj.pushKV("scanning", false); } @@ -172,11 +172,11 @@ static RPCHelpMan listwalletdir() for (const auto& path : ListDatabases(GetWalletDir())) { UniValue wallet(UniValue::VOBJ); wallet.pushKV("name", path.utf8string()); - wallets.push_back(wallet); + wallets.push_back(std::move(wallet)); } UniValue result(UniValue::VOBJ); - result.pushKV("wallets", wallets); + result.pushKV("wallets", std::move(wallets)); return result; }, }; @@ -395,7 +395,7 @@ static RPCHelpMan createwallet() if (!request.params[4].isNull() && request.params[4].get_bool()) { flags |= WALLET_FLAG_AVOID_REUSE; } - if (self.Arg<bool>(5)) { + if (self.Arg<bool>("descriptors")) { #ifndef USE_SQLITE throw JSONRPCError(RPC_WALLET_ERROR, "Compiled without sqlite support (required for descriptor wallets)"); #endif @@ -489,7 +489,7 @@ static RPCHelpMan unloadwallet() // Release the "main" shared pointer and prevent further notifications. // Note that any attempt to load the same wallet would fail until the wallet // is destroyed (see CheckUniqueFileid). - std::optional<bool> load_on_start{self.MaybeArg<bool>(1)}; + std::optional<bool> load_on_start{self.MaybeArg<bool>("load_on_startup")}; if (!RemoveWallet(context, wallet, load_on_start, warnings)) { throw JSONRPCError(RPC_MISC_ERROR, "Requested wallet already unloaded"); } diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp index b42275fe4b..c64aff5fe2 100644 --- a/src/wallet/scriptpubkeyman.cpp +++ b/src/wallet/scriptpubkeyman.cpp @@ -5,6 +5,7 @@ #include <hash.h> #include <key_io.h> #include <logging.h> +#include <node/types.h> #include <outputtype.h> #include <script/descriptor.h> #include <script/script.h> @@ -20,6 +21,9 @@ #include <optional> +using common::PSBTError; +using util::ToString; + namespace wallet { //! Value for the first BIP 32 hardened derivation. Can be used as a bit mask and as a value. See BIP 32 for more details. const uint32_t BIP32_HARDENED_KEY_LIMIT = 0x80000000; @@ -627,7 +631,7 @@ SigningResult LegacyScriptPubKeyMan::SignMessage(const std::string& message, con return SigningResult::SIGNING_FAILED; } -TransactionError LegacyScriptPubKeyMan::FillPSBT(PartiallySignedTransaction& psbtx, const PrecomputedTransactionData& txdata, int sighash_type, bool sign, bool bip32derivs, int* n_signed, bool finalize) const +std::optional<PSBTError> LegacyScriptPubKeyMan::FillPSBT(PartiallySignedTransaction& psbtx, const PrecomputedTransactionData& txdata, int sighash_type, bool sign, bool bip32derivs, int* n_signed, bool finalize) const { if (n_signed) { *n_signed = 0; @@ -642,13 +646,13 @@ TransactionError LegacyScriptPubKeyMan::FillPSBT(PartiallySignedTransaction& psb // Get the Sighash type if (sign && input.sighash_type != std::nullopt && *input.sighash_type != sighash_type) { - return TransactionError::SIGHASH_MISMATCH; + return PSBTError::SIGHASH_MISMATCH; } // Check non_witness_utxo has specified prevout if (input.non_witness_utxo) { if (txin.prevout.n >= input.non_witness_utxo->vout.size()) { - return TransactionError::MISSING_INPUTS; + return PSBTError::MISSING_INPUTS; } } else if (input.witness_utxo.IsNull()) { // There's no UTXO so we can just skip this now @@ -670,7 +674,7 @@ TransactionError LegacyScriptPubKeyMan::FillPSBT(PartiallySignedTransaction& psb UpdatePSBTOutput(HidingSigningProvider(this, true, !bip32derivs), psbtx, i); } - return TransactionError::OK; + return {}; } std::unique_ptr<CKeyMetadata> LegacyScriptPubKeyMan::GetMetadata(const CTxDestination& dest) const @@ -2485,7 +2489,7 @@ SigningResult DescriptorScriptPubKeyMan::SignMessage(const std::string& message, return SigningResult::OK; } -TransactionError DescriptorScriptPubKeyMan::FillPSBT(PartiallySignedTransaction& psbtx, const PrecomputedTransactionData& txdata, int sighash_type, bool sign, bool bip32derivs, int* n_signed, bool finalize) const +std::optional<PSBTError> DescriptorScriptPubKeyMan::FillPSBT(PartiallySignedTransaction& psbtx, const PrecomputedTransactionData& txdata, int sighash_type, bool sign, bool bip32derivs, int* n_signed, bool finalize) const { if (n_signed) { *n_signed = 0; @@ -2500,7 +2504,7 @@ TransactionError DescriptorScriptPubKeyMan::FillPSBT(PartiallySignedTransaction& // Get the Sighash type if (sign && input.sighash_type != std::nullopt && *input.sighash_type != sighash_type) { - return TransactionError::SIGHASH_MISMATCH; + return PSBTError::SIGHASH_MISMATCH; } // Get the scriptPubKey to know which SigningProvider to use @@ -2509,7 +2513,7 @@ TransactionError DescriptorScriptPubKeyMan::FillPSBT(PartiallySignedTransaction& script = input.witness_utxo.scriptPubKey; } else if (input.non_witness_utxo) { if (txin.prevout.n >= input.non_witness_utxo->vout.size()) { - return TransactionError::MISSING_INPUTS; + return PSBTError::MISSING_INPUTS; } script = input.non_witness_utxo->vout[txin.prevout.n].scriptPubKey; } else { @@ -2580,7 +2584,7 @@ TransactionError DescriptorScriptPubKeyMan::FillPSBT(PartiallySignedTransaction& UpdatePSBTOutput(HidingSigningProvider(keys.get(), /*hide_secret=*/true, /*hide_origin=*/!bip32derivs), psbtx, i); } - return TransactionError::OK; + return {}; } std::unique_ptr<CKeyMetadata> DescriptorScriptPubKeyMan::GetMetadata(const CTxDestination& dest) const diff --git a/src/wallet/scriptpubkeyman.h b/src/wallet/scriptpubkeyman.h index 2c1ab8d44a..4d9f7bb1fa 100644 --- a/src/wallet/scriptpubkeyman.h +++ b/src/wallet/scriptpubkeyman.h @@ -6,13 +6,15 @@ #define BITCOIN_WALLET_SCRIPTPUBKEYMAN_H #include <addresstype.h> +#include <common/messages.h> +#include <common/signmessage.h> +#include <common/types.h> #include <logging.h> +#include <node/types.h> #include <psbt.h> #include <script/descriptor.h> #include <script/script.h> #include <script/signingprovider.h> -#include <util/error.h> -#include <util/message.h> #include <util/result.h> #include <util/time.h> #include <wallet/crypter.h> @@ -243,7 +245,7 @@ public: /** Sign a message with the given script */ virtual SigningResult SignMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) const { return SigningResult::SIGNING_FAILED; }; /** Adds script and derivation path information to a PSBT, and optionally signs it. */ - virtual TransactionError FillPSBT(PartiallySignedTransaction& psbt, const PrecomputedTransactionData& txdata, int sighash_type = SIGHASH_DEFAULT, bool sign = true, bool bip32derivs = false, int* n_signed = nullptr, bool finalize = true) const { return TransactionError::INVALID_PSBT; } + virtual std::optional<common::PSBTError> FillPSBT(PartiallySignedTransaction& psbt, const PrecomputedTransactionData& txdata, int sighash_type = SIGHASH_DEFAULT, bool sign = true, bool bip32derivs = false, int* n_signed = nullptr, bool finalize = true) const { return common::PSBTError::UNSUPPORTED; } virtual uint256 GetID() const { return uint256(); } @@ -421,7 +423,7 @@ public: bool SignTransaction(CMutableTransaction& tx, const std::map<COutPoint, Coin>& coins, int sighash, std::map<int, bilingual_str>& input_errors) const override; SigningResult SignMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) const override; - TransactionError FillPSBT(PartiallySignedTransaction& psbt, const PrecomputedTransactionData& txdata, int sighash_type = SIGHASH_DEFAULT, bool sign = true, bool bip32derivs = false, int* n_signed = nullptr, bool finalize = true) const override; + std::optional<common::PSBTError> FillPSBT(PartiallySignedTransaction& psbt, const PrecomputedTransactionData& txdata, int sighash_type = SIGHASH_DEFAULT, bool sign = true, bool bip32derivs = false, int* n_signed = nullptr, bool finalize = true) const override; uint256 GetID() const override; @@ -651,7 +653,7 @@ public: bool SignTransaction(CMutableTransaction& tx, const std::map<COutPoint, Coin>& coins, int sighash, std::map<int, bilingual_str>& input_errors) const override; SigningResult SignMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) const override; - TransactionError FillPSBT(PartiallySignedTransaction& psbt, const PrecomputedTransactionData& txdata, int sighash_type = SIGHASH_DEFAULT, bool sign = true, bool bip32derivs = false, int* n_signed = nullptr, bool finalize = true) const override; + std::optional<common::PSBTError> FillPSBT(PartiallySignedTransaction& psbt, const PrecomputedTransactionData& txdata, int sighash_type = SIGHASH_DEFAULT, bool sign = true, bool bip32derivs = false, int* n_signed = nullptr, bool finalize = true) const override; uint256 GetID() const override; diff --git a/src/wallet/spend.cpp b/src/wallet/spend.cpp index 9a7e166e68..0a59353052 100644 --- a/src/wallet/spend.cpp +++ b/src/wallet/spend.cpp @@ -4,10 +4,12 @@ #include <algorithm> #include <common/args.h> +#include <common/messages.h> #include <common/system.h> #include <consensus/amount.h> #include <consensus/validation.h> #include <interfaces/chain.h> +#include <node/types.h> #include <numeric> #include <policy/policy.h> #include <primitives/transaction.h> @@ -15,7 +17,6 @@ #include <script/signingprovider.h> #include <script/solver.h> #include <util/check.h> -#include <util/fees.h> #include <util/moneystr.h> #include <util/rbf.h> #include <util/trace.h> @@ -29,7 +30,10 @@ #include <cmath> +using common::StringForFeeReason; +using common::TransactionErrorString; using interfaces::FoundBlock; +using node::TransactionError; namespace wallet { static constexpr size_t OUTPUT_GROUP_MAX_ENTRIES{100}; @@ -132,7 +136,7 @@ static std::optional<int64_t> GetSignedTxinWeight(const CWallet* wallet, const C // txouts needs to be in the order of tx.vin TxSize CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, const std::vector<CTxOut>& txouts, const CCoinControl* coin_control) { - // nVersion + nLockTime + input count + output count + // version + nLockTime + input count + output count int64_t weight = (4 + 4 + GetSizeOfCompactSize(tx.vin.size()) + GetSizeOfCompactSize(tx.vout.size())) * WITNESS_SCALE_FACTOR; // Whether any input spends a witness program. Necessary to run before the next loop over the // inputs in order to accurately compute the compactSize length for the witness data per input. @@ -256,7 +260,7 @@ static OutputType GetOutputType(TxoutType type, bool is_from_p2sh) // Fetch and validate the coin control selected inputs. // Coins could be internal (from the wallet) or external. util::Result<PreSelectedInputs> FetchSelectedInputs(const CWallet& wallet, const CCoinControl& coin_control, - const CoinSelectionParams& coin_selection_params) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet) + const CoinSelectionParams& coin_selection_params) { PreSelectedInputs result; const bool can_grind_r = wallet.CanGrindR(); @@ -711,7 +715,7 @@ util::Result<SelectionResult> ChooseSelectionResult(interfaces::Chain& chain, co if (coin_selection_params.m_effective_feerate > CFeeRate{3 * coin_selection_params.m_long_term_feerate}) { // Minimize input set for feerates of at least 3×LTFRE (default: 30 ṩ/vB+) if (auto cg_result{CoinGrinder(groups.positive_group, nTargetValue, coin_selection_params.m_min_change_target, max_inputs_weight)}) { - cg_result->ComputeAndSetWaste(coin_selection_params.min_viable_change, coin_selection_params.m_cost_of_change, coin_selection_params.m_change_fee); + cg_result->RecalculateWaste(coin_selection_params.min_viable_change, coin_selection_params.m_cost_of_change, coin_selection_params.m_change_fee); results.push_back(*cg_result); } else { append_error(std::move(cg_result)); @@ -746,7 +750,7 @@ util::Result<SelectionResult> ChooseSelectionResult(interfaces::Chain& chain, co if (bump_fee_overestimate) { result.SetBumpFeeDiscount(bump_fee_overestimate); } - result.ComputeAndSetWaste(coin_selection_params.min_viable_change, coin_selection_params.m_cost_of_change, coin_selection_params.m_change_fee); + result.RecalculateWaste(coin_selection_params.min_viable_change, coin_selection_params.m_cost_of_change, coin_selection_params.m_change_fee); } // Choose the result with the least waste @@ -771,7 +775,7 @@ util::Result<SelectionResult> SelectCoins(const CWallet& wallet, CoinsResult& av if (selection_target <= 0) { SelectionResult result(nTargetValue, SelectionAlgorithm::MANUAL); result.AddInputs(pre_set_inputs.coins, coin_selection_params.m_subtract_fee_outputs); - result.ComputeAndSetWaste(coin_selection_params.min_viable_change, coin_selection_params.m_cost_of_change, coin_selection_params.m_change_fee); + result.RecalculateWaste(coin_selection_params.min_viable_change, coin_selection_params.m_cost_of_change, coin_selection_params.m_change_fee); return result; } @@ -792,9 +796,16 @@ util::Result<SelectionResult> SelectCoins(const CWallet& wallet, CoinsResult& av SelectionResult preselected(pre_set_inputs.total_amount, SelectionAlgorithm::MANUAL); preselected.AddInputs(pre_set_inputs.coins, coin_selection_params.m_subtract_fee_outputs); op_selection_result->Merge(preselected); - op_selection_result->ComputeAndSetWaste(coin_selection_params.min_viable_change, + op_selection_result->RecalculateWaste(coin_selection_params.min_viable_change, coin_selection_params.m_cost_of_change, coin_selection_params.m_change_fee); + + // Verify we haven't exceeded the maximum allowed weight + int max_inputs_weight = MAX_STANDARD_TX_WEIGHT - (coin_selection_params.tx_noinputs_size * WITNESS_SCALE_FACTOR); + if (op_selection_result->GetWeight() > max_inputs_weight) { + return util::Error{_("The combination of the pre-selected inputs and the wallet automatic inputs selection exceeds the transaction maximum weight. " + "Please try sending a smaller amount or manually consolidating your wallet's UTXOs")}; + } } return op_selection_result; } @@ -972,6 +983,16 @@ static void DiscourageFeeSniping(CMutableTransaction& tx, FastRandomContext& rng } } +size_t GetSerializeSizeForRecipient(const CRecipient& recipient) +{ + return ::GetSerializeSize(CTxOut(recipient.nAmount, GetScriptForDestination(recipient.dest))); +} + +bool IsDust(const CRecipient& recipient, const CFeeRate& dustRelayFee) +{ + return ::IsDust(CTxOut(recipient.nAmount, GetScriptForDestination(recipient.dest)), dustRelayFee); +} + static util::Result<CreatedTransactionResult> CreateTransactionInternal( CWallet& wallet, const std::vector<CRecipient>& vecSend, @@ -985,7 +1006,7 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal( CMutableTransaction txNew; // The resulting transaction that we make if (coin_control.m_version) { - txNew.nVersion = coin_control.m_version.value(); + txNew.version = coin_control.m_version.value(); } CoinSelectionParams coin_selection_params{rng_fast}; // Parameters for coin selection, init with dummy @@ -994,12 +1015,20 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal( // Set the long term feerate estimate to the wallet's consolidate feerate coin_selection_params.m_long_term_feerate = wallet.m_consolidate_feerate; + // Static vsize overhead + outputs vsize. 4 nVersion, 4 nLocktime, 1 input count, 1 witness overhead (dummy, flag, stack size) + coin_selection_params.tx_noinputs_size = 10 + GetSizeOfCompactSize(vecSend.size()); // bytes for output count CAmount recipients_sum = 0; const OutputType change_type = wallet.TransactionChangeType(coin_control.m_change_type ? *coin_control.m_change_type : wallet.m_default_change_type, vecSend); ReserveDestination reservedest(&wallet, change_type); unsigned int outputs_to_subtract_fee_from = 0; // The number of outputs which we are subtracting the fee from for (const auto& recipient : vecSend) { + if (IsDust(recipient, wallet.chain().relayDustFee())) { + return util::Error{_("Transaction amount too small")}; + } + + // Include the fee cost for outputs. + coin_selection_params.tx_noinputs_size += GetSerializeSizeForRecipient(recipient); recipients_sum += recipient.nAmount; if (recipient.fSubtractFeeFromAmount) { @@ -1084,23 +1113,6 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal( const auto change_spend_fee = coin_selection_params.m_discard_feerate.GetFee(coin_selection_params.change_spend_size); coin_selection_params.min_viable_change = std::max(change_spend_fee + 1, dust); - // Static vsize overhead + outputs vsize. 4 nVersion, 4 nLocktime, 1 input count, 1 witness overhead (dummy, flag, stack size) - coin_selection_params.tx_noinputs_size = 10 + GetSizeOfCompactSize(vecSend.size()); // bytes for output count - - // vouts to the payees - for (const auto& recipient : vecSend) - { - CTxOut txout(recipient.nAmount, GetScriptForDestination(recipient.dest)); - - // Include the fee cost for outputs. - coin_selection_params.tx_noinputs_size += ::GetSerializeSize(txout); - - if (IsDust(txout, wallet.chain().relayDustFee())) { - return util::Error{_("Transaction amount too small")}; - } - txNew.vout.push_back(txout); - } - // Include the fees for things that aren't inputs, excluding the change output const CAmount not_input_fees = coin_selection_params.m_effective_feerate.GetFee(coin_selection_params.m_subtract_fee_outputs ? 0 : coin_selection_params.tx_noinputs_size); CAmount selection_target = recipients_sum + not_input_fees; @@ -1141,6 +1153,11 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal( result.GetWaste(), result.GetSelectedValue()); + // vouts to the payees + for (const auto& recipient : vecSend) + { + txNew.vout.emplace_back(recipient.nAmount, GetScriptForDestination(recipient.dest)); + } const CAmount change_amount = result.GetChange(coin_selection_params.min_viable_change, coin_selection_params.m_change_fee); if (change_amount > 0) { CTxOut newTxOut(change_amount, scriptChange); @@ -1394,7 +1411,7 @@ util::Result<CreatedTransactionResult> FundTransaction(CWallet& wallet, const CM coinControl.m_locktime = tx.nLockTime; // Set the user desired version - coinControl.m_version = tx.nVersion; + coinControl.m_version = tx.version; // Acquire the locks to prevent races to the new locked unspents between the // CreateTransaction call and LockCoin calls (when lockUnspents is true). diff --git a/src/wallet/test/coinselector_tests.cpp b/src/wallet/test/coinselector_tests.cpp index 9a349f0992..7bd92b471c 100644 --- a/src/wallet/test/coinselector_tests.cpp +++ b/src/wallet/test/coinselector_tests.cpp @@ -874,29 +874,32 @@ BOOST_AUTO_TEST_CASE(SelectCoins_test) BOOST_AUTO_TEST_CASE(waste_test) { const CAmount fee{100}; + const CAmount min_viable_change{300}; const CAmount change_cost{125}; + const CAmount change_fee{30}; const CAmount fee_diff{40}; const CAmount in_amt{3 * COIN}; const CAmount target{2 * COIN}; - const CAmount excess{in_amt - fee * 2 - target}; + const CAmount excess{80}; + const CAmount exact_target{in_amt - fee * 2}; // Maximum spendable amount after fees: no change, no excess - // The following tests that the waste is calculated correctly in various scenarios. - // ComputeAndSetWaste will first determine the size of the change output. We don't really - // care about the change and just want to use the variant that always includes the change_cost, - // so min_viable_change and change_fee are set to 0 to ensure that. + // In the following, we test that the waste is calculated correctly in various scenarios. + // Usually, RecalculateWaste would compute change_fee and change_cost on basis of the + // change output type, current feerate, and discard_feerate, but we use fixed values + // across this test to make the test easier to understand. { // Waste with change is the change cost and difference between fee and long term fee SelectionResult selection1{target, SelectionAlgorithm::MANUAL}; - add_coin(1 * COIN, 1, selection1, fee, fee - fee_diff); + add_coin(1 * COIN, 1, selection1, /*fee=*/fee, /*long_term_fee=*/fee - fee_diff); add_coin(2 * COIN, 2, selection1, fee, fee - fee_diff); - selection1.ComputeAndSetWaste(/*min_viable_change=*/0, change_cost, /*change_fee=*/0); + selection1.RecalculateWaste(min_viable_change, change_cost, change_fee); BOOST_CHECK_EQUAL(fee_diff * 2 + change_cost, selection1.GetWaste()); // Waste will be greater when fee is greater, but long term fee is the same SelectionResult selection2{target, SelectionAlgorithm::MANUAL}; add_coin(1 * COIN, 1, selection2, fee * 2, fee - fee_diff); add_coin(2 * COIN, 2, selection2, fee * 2, fee - fee_diff); - selection2.ComputeAndSetWaste(/*min_viable_change=*/0, change_cost, /*change_fee=*/0); + selection2.RecalculateWaste(min_viable_change, change_cost, change_fee); BOOST_CHECK_GT(selection2.GetWaste(), selection1.GetWaste()); // Waste with change is the change cost and difference between fee and long term fee @@ -904,25 +907,25 @@ BOOST_AUTO_TEST_CASE(waste_test) SelectionResult selection3{target, SelectionAlgorithm::MANUAL}; add_coin(1 * COIN, 1, selection3, fee, fee + fee_diff); add_coin(2 * COIN, 2, selection3, fee, fee + fee_diff); - selection3.ComputeAndSetWaste(/*min_viable_change=*/0, change_cost, /*change_fee=*/0); + selection3.RecalculateWaste(min_viable_change, change_cost, change_fee); BOOST_CHECK_EQUAL(fee_diff * -2 + change_cost, selection3.GetWaste()); BOOST_CHECK_LT(selection3.GetWaste(), selection1.GetWaste()); } { // Waste without change is the excess and difference between fee and long term fee - SelectionResult selection_nochange1{target, SelectionAlgorithm::MANUAL}; + SelectionResult selection_nochange1{exact_target - excess, SelectionAlgorithm::MANUAL}; add_coin(1 * COIN, 1, selection_nochange1, fee, fee - fee_diff); add_coin(2 * COIN, 2, selection_nochange1, fee, fee - fee_diff); - selection_nochange1.ComputeAndSetWaste(/*min_viable_change=*/0, /*change_cost=*/0, /*change_fee=*/0); + selection_nochange1.RecalculateWaste(min_viable_change, change_cost, change_fee); BOOST_CHECK_EQUAL(fee_diff * 2 + excess, selection_nochange1.GetWaste()); // Waste without change is the excess and difference between fee and long term fee // With long term fee greater than fee, waste should be less than when long term fee is less than fee - SelectionResult selection_nochange2{target, SelectionAlgorithm::MANUAL}; + SelectionResult selection_nochange2{exact_target - excess, SelectionAlgorithm::MANUAL}; add_coin(1 * COIN, 1, selection_nochange2, fee, fee + fee_diff); add_coin(2 * COIN, 2, selection_nochange2, fee, fee + fee_diff); - selection_nochange2.ComputeAndSetWaste(/*min_viable_change=*/0, /*change_cost=*/0, /*change_fee=*/0); + selection_nochange2.RecalculateWaste(min_viable_change, change_cost, change_fee); BOOST_CHECK_EQUAL(fee_diff * -2 + excess, selection_nochange2.GetWaste()); BOOST_CHECK_LT(selection_nochange2.GetWaste(), selection_nochange1.GetWaste()); } @@ -932,57 +935,54 @@ BOOST_AUTO_TEST_CASE(waste_test) SelectionResult selection{target, SelectionAlgorithm::MANUAL}; add_coin(1 * COIN, 1, selection, fee, fee); add_coin(2 * COIN, 2, selection, fee, fee); - selection.ComputeAndSetWaste(/*min_viable_change=*/0, change_cost, /*change_fee=*/0); + selection.RecalculateWaste(min_viable_change, change_cost, change_fee); BOOST_CHECK_EQUAL(change_cost, selection.GetWaste()); } { // Waste without change and fee == long term fee is just the excess - SelectionResult selection{target, SelectionAlgorithm::MANUAL}; + SelectionResult selection{exact_target - excess, SelectionAlgorithm::MANUAL}; add_coin(1 * COIN, 1, selection, fee, fee); add_coin(2 * COIN, 2, selection, fee, fee); - selection.ComputeAndSetWaste(/*min_viable_change=*/0, /*change_cost=*/0, /*change_fee=*/0); + selection.RecalculateWaste(min_viable_change, change_cost, change_fee); BOOST_CHECK_EQUAL(excess, selection.GetWaste()); } { - // No Waste when fee == long_term_fee, no change, and no excess - const CAmount exact_target{in_amt - fee * 2}; + // Waste is 0 when fee == long_term_fee, no change, and no excess SelectionResult selection{exact_target, SelectionAlgorithm::MANUAL}; add_coin(1 * COIN, 1, selection, fee, fee); add_coin(2 * COIN, 2, selection, fee, fee); - selection.ComputeAndSetWaste(/*min_viable_change=*/0, /*change_cost=*/0, /*change_fee=*/0); + selection.RecalculateWaste(min_viable_change, change_cost , change_fee); BOOST_CHECK_EQUAL(0, selection.GetWaste()); } { - // No Waste when (fee - long_term_fee) == (-cost_of_change), and no excess + // Waste is 0 when (fee - long_term_fee) == (-cost_of_change), and no excess SelectionResult selection{target, SelectionAlgorithm::MANUAL}; - const CAmount new_change_cost{fee_diff * 2}; add_coin(1 * COIN, 1, selection, fee, fee + fee_diff); add_coin(2 * COIN, 2, selection, fee, fee + fee_diff); - selection.ComputeAndSetWaste(/*min_viable_change=*/0, new_change_cost, /*change_fee=*/0); + selection.RecalculateWaste(min_viable_change, /*change_cost=*/fee_diff * 2, change_fee); BOOST_CHECK_EQUAL(0, selection.GetWaste()); } { - // No Waste when (fee - long_term_fee) == (-excess), no change cost - const CAmount new_target{in_amt - fee * 2 - fee_diff * 2}; + // Waste is 0 when (fee - long_term_fee) == (-excess), no change cost + const CAmount new_target{exact_target - /*excess=*/fee_diff * 2}; SelectionResult selection{new_target, SelectionAlgorithm::MANUAL}; add_coin(1 * COIN, 1, selection, fee, fee + fee_diff); add_coin(2 * COIN, 2, selection, fee, fee + fee_diff); - selection.ComputeAndSetWaste(/*min_viable_change=*/0, /*change_cost=*/0, /*change_fee=*/0); + selection.RecalculateWaste(min_viable_change, change_cost, change_fee); BOOST_CHECK_EQUAL(0, selection.GetWaste()); } { // Negative waste when the long term fee is greater than the current fee and the selected value == target - const CAmount exact_target{3 * COIN - 2 * fee}; SelectionResult selection{exact_target, SelectionAlgorithm::MANUAL}; const CAmount target_waste1{-2 * fee_diff}; // = (2 * fee) - (2 * (fee + fee_diff)) add_coin(1 * COIN, 1, selection, fee, fee + fee_diff); add_coin(2 * COIN, 2, selection, fee, fee + fee_diff); - selection.ComputeAndSetWaste(/*min_viable_change=*/0, /*change_cost=*/0, /*change_fee=*/0); + selection.RecalculateWaste(min_viable_change, change_cost, change_fee); BOOST_CHECK_EQUAL(target_waste1, selection.GetWaste()); } @@ -990,10 +990,14 @@ BOOST_AUTO_TEST_CASE(waste_test) // Negative waste when the long term fee is greater than the current fee and change_cost < - (inputs * (fee - long_term_fee)) SelectionResult selection{target, SelectionAlgorithm::MANUAL}; const CAmount large_fee_diff{90}; - const CAmount target_waste2{-2 * large_fee_diff + change_cost}; // = (2 * fee) - (2 * (fee + large_fee_diff)) + change_cost + const CAmount target_waste2{-2 * large_fee_diff + change_cost}; + // = (2 * fee) - (2 * (fee + large_fee_diff)) + change_cost + // = (2 * 100) - (2 * (100 + 90)) + 125 + // = 200 - 380 + 125 = -55 + assert(target_waste2 == -55); add_coin(1 * COIN, 1, selection, fee, fee + large_fee_diff); add_coin(2 * COIN, 2, selection, fee, fee + large_fee_diff); - selection.ComputeAndSetWaste(/*min_viable_change=*/0, change_cost, /*change_fee=*/0); + selection.RecalculateWaste(min_viable_change, change_cost, change_fee); BOOST_CHECK_EQUAL(target_waste2, selection.GetWaste()); } } @@ -1018,12 +1022,12 @@ BOOST_AUTO_TEST_CASE(bump_fee_test) inputs[i]->ApplyBumpFee(20*(i+1)); } - selection.ComputeAndSetWaste(min_viable_change, change_cost, change_fee); + selection.RecalculateWaste(min_viable_change, change_cost, change_fee); CAmount expected_waste = fee_diff * -2 + change_cost + /*bump_fees=*/60; BOOST_CHECK_EQUAL(expected_waste, selection.GetWaste()); selection.SetBumpFeeDiscount(30); - selection.ComputeAndSetWaste(min_viable_change, change_cost, change_fee); + selection.RecalculateWaste(min_viable_change, change_cost, change_fee); expected_waste = fee_diff * -2 + change_cost + /*bump_fees=*/60 - /*group_discount=*/30; BOOST_CHECK_EQUAL(expected_waste, selection.GetWaste()); } @@ -1044,12 +1048,12 @@ BOOST_AUTO_TEST_CASE(bump_fee_test) inputs[i]->ApplyBumpFee(20*(i+1)); } - selection.ComputeAndSetWaste(min_viable_change, change_cost, change_fee); + selection.RecalculateWaste(min_viable_change, change_cost, change_fee); CAmount expected_waste = fee_diff * -2 + /*bump_fees=*/60 + /*excess = 100 - bump_fees*/40; BOOST_CHECK_EQUAL(expected_waste, selection.GetWaste()); selection.SetBumpFeeDiscount(30); - selection.ComputeAndSetWaste(min_viable_change, change_cost, change_fee); + selection.RecalculateWaste(min_viable_change, change_cost, change_fee); expected_waste = fee_diff * -2 + /*bump_fees=*/60 - /*group_discount=*/30 + /*excess = 100 - bump_fees + group_discount*/70; BOOST_CHECK_EQUAL(expected_waste, selection.GetWaste()); } @@ -1429,6 +1433,7 @@ BOOST_AUTO_TEST_CASE(check_max_weight) /*avoid_partial=*/false, }; + int max_weight = MAX_STANDARD_TX_WEIGHT - WITNESS_SCALE_FACTOR * (cs_params.tx_noinputs_size + cs_params.change_output_size); { // Scenario 1: // The actor starts with 1x 50.0 BTC and 1515x 0.033 BTC (~100.0 BTC total) unspent outputs @@ -1450,10 +1455,9 @@ BOOST_AUTO_TEST_CASE(check_max_weight) m_node); BOOST_CHECK(result); - // Verify that only the 50 BTC UTXO was selected - const auto& selection_res = result->GetInputSet(); - BOOST_CHECK(selection_res.size() == 1); - BOOST_CHECK((*selection_res.begin())->GetEffectiveValue() == 50 * COIN); + // Verify that the 50 BTC UTXO was selected, and result is below max_weight + BOOST_CHECK(has_coin(result->GetInputSet(), CAmount(50 * COIN))); + BOOST_CHECK_LE(result->GetWeight(), max_weight); } { @@ -1479,6 +1483,7 @@ BOOST_AUTO_TEST_CASE(check_max_weight) BOOST_CHECK(has_coin(result->GetInputSet(), CAmount(0.0625 * COIN))); BOOST_CHECK(has_coin(result->GetInputSet(), CAmount(0.025 * COIN))); + BOOST_CHECK_LE(result->GetWeight(), max_weight); } { diff --git a/src/wallet/test/db_tests.cpp b/src/wallet/test/db_tests.cpp index 438dfceb7f..2fac356263 100644 --- a/src/wallet/test/db_tests.cpp +++ b/src/wallet/test/db_tests.cpp @@ -16,6 +16,7 @@ #ifdef USE_SQLITE #include <wallet/sqlite.h> #endif +#include <wallet/migrate.h> #include <wallet/test/util.h> #include <wallet/walletutil.h> // for WALLET_FLAG_DESCRIPTORS @@ -132,6 +133,8 @@ static std::vector<std::unique_ptr<WalletDatabase>> TestDatabases(const fs::path bilingual_str error; #ifdef USE_BDB dbs.emplace_back(MakeBerkeleyDatabase(path_root / "bdb", options, status, error)); + // Needs BDB to make the DB to read + dbs.emplace_back(std::make_unique<BerkeleyRODatabase>(BDBDataFile(path_root / "bdb"), /*open=*/false)); #endif #ifdef USE_SQLITE dbs.emplace_back(MakeSQLiteDatabase(path_root / "sqlite", options, status, error)); @@ -146,11 +149,16 @@ BOOST_AUTO_TEST_CASE(db_cursor_prefix_range_test) for (const auto& database : TestDatabases(m_path_root)) { std::vector<std::string> prefixes = {"", "FIRST", "SECOND", "P\xfe\xff", "P\xff\x01", "\xff\xff"}; - // Write elements to it std::unique_ptr<DatabaseBatch> handler = Assert(database)->MakeBatch(); - for (unsigned int i = 0; i < 10; i++) { - for (const auto& prefix : prefixes) { - BOOST_CHECK(handler->Write(std::make_pair(prefix, i), i)); + if (dynamic_cast<BerkeleyRODatabase*>(database.get())) { + // For BerkeleyRO, open the file now. This must happen after BDB has written to the file + database->Open(); + } else { + // Write elements to it if not berkeleyro + for (unsigned int i = 0; i < 10; i++) { + for (const auto& prefix : prefixes) { + BOOST_CHECK(handler->Write(std::make_pair(prefix, i), i)); + } } } @@ -178,6 +186,8 @@ BOOST_AUTO_TEST_CASE(db_cursor_prefix_range_test) // Let's now read it once more, it should return DONE BOOST_CHECK(cursor->Next(key, value) == DatabaseCursor::Status::DONE); } + handler.reset(); + database->Close(); } } @@ -197,13 +207,23 @@ BOOST_AUTO_TEST_CASE(db_cursor_prefix_byte_test) ffs{StringData("\xff\xffsuffix"), StringData("ffs")}; for (const auto& database : TestDatabases(m_path_root)) { std::unique_ptr<DatabaseBatch> batch = database->MakeBatch(); - for (const auto& [k, v] : {e, p, ps, f, fs, ff, ffs}) { - batch->Write(Span{k}, Span{v}); + + if (dynamic_cast<BerkeleyRODatabase*>(database.get())) { + // For BerkeleyRO, open the file now. This must happen after BDB has written to the file + database->Open(); + } else { + // Write elements to it if not berkeleyro + for (const auto& [k, v] : {e, p, ps, f, fs, ff, ffs}) { + batch->Write(Span{k}, Span{v}); + } } + CheckPrefix(*batch, StringBytes(""), {e, p, ps, f, fs, ff, ffs}); CheckPrefix(*batch, StringBytes("prefix"), {p, ps}); CheckPrefix(*batch, StringBytes("\xff"), {f, fs, ff, ffs}); CheckPrefix(*batch, StringBytes("\xff\xff"), {ff, ffs}); + batch.reset(); + database->Close(); } } @@ -213,6 +233,10 @@ BOOST_AUTO_TEST_CASE(db_availability_after_write_error) // To simulate the behavior, record overwrites are disallowed, and the test verifies // that the database remains active after failing to store an existing record. for (const auto& database : TestDatabases(m_path_root)) { + if (dynamic_cast<BerkeleyRODatabase*>(database.get())) { + // Skip this test if BerkeleyRO + continue; + } // Write original record std::unique_ptr<DatabaseBatch> batch = database->MakeBatch(); std::string key = "key"; @@ -241,6 +265,10 @@ BOOST_AUTO_TEST_CASE(erase_prefix) auto make_key = [](std::string type, std::string id) { return std::make_pair(type, id); }; for (const auto& database : TestDatabases(m_path_root)) { + if (dynamic_cast<BerkeleyRODatabase*>(database.get())) { + // Skip this test if BerkeleyRO + continue; + } std::unique_ptr<DatabaseBatch> batch = database->MakeBatch(); // Write two entries with the same key type prefix, a third one with a different prefix diff --git a/src/wallet/test/fuzz/coinselection.cpp b/src/wallet/test/fuzz/coinselection.cpp index 331590df7f..644a8dd7ad 100644 --- a/src/wallet/test/fuzz/coinselection.cpp +++ b/src/wallet/test/fuzz/coinselection.cpp @@ -270,7 +270,7 @@ FUZZ_TARGET(coinselection) if (result_srd) { assert(result_srd->GetSelectedValue() >= target); assert(result_srd->GetChange(CHANGE_LOWER, coin_params.m_change_fee) > 0); // Demonstrate that SRD creates change of at least CHANGE_LOWER - result_srd->ComputeAndSetWaste(coin_params.min_viable_change, coin_params.m_cost_of_change, coin_params.m_change_fee); + result_srd->RecalculateWaste(coin_params.min_viable_change, coin_params.m_cost_of_change, coin_params.m_change_fee); (void)result_srd->GetShuffledInputVector(); (void)result_srd->GetInputSet(); } @@ -279,7 +279,7 @@ FUZZ_TARGET(coinselection) auto result_knapsack = KnapsackSolver(group_all, target, change_target, fast_random_context, MAX_STANDARD_TX_WEIGHT); if (result_knapsack) { assert(result_knapsack->GetSelectedValue() >= target); - result_knapsack->ComputeAndSetWaste(coin_params.min_viable_change, coin_params.m_cost_of_change, coin_params.m_change_fee); + result_knapsack->RecalculateWaste(coin_params.min_viable_change, coin_params.m_cost_of_change, coin_params.m_change_fee); (void)result_knapsack->GetShuffledInputVector(); (void)result_knapsack->GetInputSet(); } diff --git a/src/wallet/test/fuzz/crypter.cpp b/src/wallet/test/fuzz/crypter.cpp new file mode 100644 index 0000000000..62dd1bfde0 --- /dev/null +++ b/src/wallet/test/fuzz/crypter.cpp @@ -0,0 +1,92 @@ +// Copyright (c) 2022 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <test/fuzz/FuzzedDataProvider.h> +#include <test/fuzz/fuzz.h> +#include <test/fuzz/util.h> +#include <test/util/setup_common.h> +#include <wallet/crypter.h> + +namespace wallet { +namespace { + +const TestingSetup* g_setup; +void initialize_crypter() +{ + static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>(); + g_setup = testing_setup.get(); +} + +FUZZ_TARGET(crypter, .init = initialize_crypter) +{ + FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); + bool good_data{true}; + + CCrypter crypt; + // These values are regularly updated within `CallOneOf` + std::vector<unsigned char> cipher_text_ed; + CKeyingMaterial plain_text_ed; + const std::vector<unsigned char> random_key = ConsumeRandomLengthByteVector(fuzzed_data_provider); + + LIMITED_WHILE(good_data && fuzzed_data_provider.ConsumeBool(), 10000) + { + CallOneOf( + fuzzed_data_provider, + [&] { + const std::string random_string = fuzzed_data_provider.ConsumeRandomLengthString(); + SecureString secure_string(random_string.begin(), random_string.end()); + + const unsigned int derivation_method = fuzzed_data_provider.ConsumeBool() ? 0 : fuzzed_data_provider.ConsumeIntegral<unsigned int>(); + + // Limiting the value of nRounds since it is otherwise uselessly expensive and causes a timeout when fuzzing. + crypt.SetKeyFromPassphrase(/*strKeyData=*/secure_string, + /*chSalt=*/ConsumeRandomLengthByteVector(fuzzed_data_provider), + /*nRounds=*/fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(0, 25000), + /*nDerivationMethod=*/derivation_method); + }, + [&] { + const std::vector<unsigned char> random_vector = ConsumeFixedLengthByteVector(fuzzed_data_provider, 32); + const CKeyingMaterial new_key(random_vector.begin(), random_vector.end()); + const std::vector<unsigned char>& new_IV = ConsumeFixedLengthByteVector(fuzzed_data_provider, 16); + crypt.SetKey(new_key, new_IV); + }, + [&] { + const std::vector<unsigned char> random_vector = ConsumeRandomLengthByteVector(fuzzed_data_provider); + plain_text_ed = CKeyingMaterial(random_vector.begin(), random_vector.end()); + }, + [&] { + cipher_text_ed = ConsumeRandomLengthByteVector(fuzzed_data_provider); + }, + [&] { + (void)crypt.Encrypt(plain_text_ed, cipher_text_ed); + }, + [&] { + (void)crypt.Decrypt(cipher_text_ed, plain_text_ed); + }, + [&] { + const CKeyingMaterial master_key(random_key.begin(), random_key.end()); + const uint256 iv = ConsumeUInt256(fuzzed_data_provider); + EncryptSecret(master_key, plain_text_ed, iv, cipher_text_ed); + }, + [&] { + const CKeyingMaterial master_key(random_key.begin(), random_key.end()); + const uint256 iv = ConsumeUInt256(fuzzed_data_provider); + DecryptSecret(master_key, cipher_text_ed, iv, plain_text_ed); + }, + [&] { + std::optional<CPubKey> random_pub_key = ConsumeDeserializable<CPubKey>(fuzzed_data_provider); + if (!random_pub_key) { + good_data = false; + return; + } + const CPubKey pub_key = *random_pub_key; + const CKeyingMaterial master_key(random_key.begin(), random_key.end()); + const std::vector<unsigned char> crypted_secret = ConsumeRandomLengthByteVector(fuzzed_data_provider); + CKey key; + DecryptKey(master_key, crypted_secret, pub_key, key); + }); + } +} +} // namespace +} // namespace wallet diff --git a/src/wallet/test/fuzz/scriptpubkeyman.cpp b/src/wallet/test/fuzz/scriptpubkeyman.cpp index 228e9629ed..835470aeae 100644 --- a/src/wallet/test/fuzz/scriptpubkeyman.cpp +++ b/src/wallet/test/fuzz/scriptpubkeyman.cpp @@ -137,6 +137,15 @@ FUZZ_TARGET(scriptpubkeyman, .init = initialize_spkm) PKHash{ConsumeUInt160(fuzzed_data_provider)}}; std::string str_sig; (void)spk_manager->SignMessage(msg, pk_hash, str_sig); + (void)spk_manager->GetMetadata(dest); + } + } + }, + [&] { + auto spks{spk_manager->GetScriptPubKeys()}; + for (const CScript& spk : spks) { + if (fuzzed_data_provider.ConsumeBool()) { + spk_manager->MarkUnusedAddresses(spk); } } }, @@ -148,6 +157,10 @@ FUZZ_TARGET(scriptpubkeyman, .init = initialize_spkm) } spk_manager->AddDescriptorKey(key, key.GetPubKey()); spk_manager->TopUp(); + LOCK(spk_manager->cs_desc_man); + auto particular_key{spk_manager->GetKey(key.GetPubKey().GetID())}; + assert(*particular_key == key); + assert(spk_manager->HasPrivKey(key.GetPubKey().GetID())); }, [&] { std::string descriptor; @@ -194,6 +207,9 @@ FUZZ_TARGET(scriptpubkeyman, .init = initialize_spkm) } ); } + + (void)spk_manager->GetEndRange(); + (void)spk_manager->GetKeyPoolSize(); } } // namespace diff --git a/src/wallet/test/fuzz/wallet_bdb_parser.cpp b/src/wallet/test/fuzz/wallet_bdb_parser.cpp new file mode 100644 index 0000000000..6fbd695fc5 --- /dev/null +++ b/src/wallet/test/fuzz/wallet_bdb_parser.cpp @@ -0,0 +1,136 @@ +// Copyright (c) 2023-present The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <config/bitcoin-config.h> // IWYU pragma: keep +#include <test/fuzz/FuzzedDataProvider.h> +#include <test/fuzz/fuzz.h> +#include <test/fuzz/util.h> +#include <test/util/setup_common.h> +#include <util/fs.h> +#include <util/time.h> +#include <util/translation.h> +#include <wallet/bdb.h> +#include <wallet/db.h> +#include <wallet/dump.h> +#include <wallet/migrate.h> + +#include <fstream> +#include <iostream> + +using wallet::DatabaseOptions; +using wallet::DatabaseStatus; + +namespace { +TestingSetup* g_setup; +} // namespace + +void initialize_wallet_bdb_parser() +{ + static auto testing_setup = MakeNoLogFileContext<TestingSetup>(); + g_setup = testing_setup.get(); +} + +FUZZ_TARGET(wallet_bdb_parser, .init = initialize_wallet_bdb_parser) +{ + const auto wallet_path = g_setup->m_args.GetDataDirNet() / "fuzzed_wallet.dat"; + + { + AutoFile outfile{fsbridge::fopen(wallet_path, "wb")}; + outfile << Span{buffer}; + } + + const DatabaseOptions options{}; + DatabaseStatus status; + bilingual_str error; + + fs::path bdb_ro_dumpfile{g_setup->m_args.GetDataDirNet() / "fuzzed_dumpfile_bdb_ro.dump"}; + if (fs::exists(bdb_ro_dumpfile)) { // Writing into an existing dump file will throw an exception + remove(bdb_ro_dumpfile); + } + g_setup->m_args.ForceSetArg("-dumpfile", fs::PathToString(bdb_ro_dumpfile)); + +#ifdef USE_BDB + bool bdb_ro_err = false; + bool bdb_ro_strict_err = false; +#endif + auto db{MakeBerkeleyRODatabase(wallet_path, options, status, error)}; + if (db) { + assert(DumpWallet(g_setup->m_args, *db, error)); + } else { +#ifdef USE_BDB + bdb_ro_err = true; +#endif + if (error.original.starts_with("AutoFile::ignore: end of file") || + error.original.starts_with("AutoFile::read: end of file") || + error.original.starts_with("AutoFile::seek: ") || + error.original == "Not a BDB file" || + error.original == "Unexpected page type, should be 9 (BTree Metadata)" || + error.original == "Unexpected database flags, should only be 0x20 (subdatabases)" || + error.original == "Unexpected outer database root page type" || + error.original == "Unexpected number of entries in outer database root page" || + error.original == "Subdatabase page number has unexpected length" || + error.original == "Unknown record type in records page" || + error.original == "Unknown record type in internal page" || + error.original == "Unexpected page size" || + error.original == "Unexpected page type" || + error.original == "Page number mismatch" || + error.original == "Bad btree level" || + error.original == "Bad page size" || + error.original == "Meta page number mismatch" || + error.original == "Data record position not in page" || + error.original == "Internal record position not in page" || + error.original == "LSNs are not reset, this database is not completely flushed. Please reopen then close the database with a version that has BDB support" || + error.original == "Records page has odd number of records" || + error.original == "Bad overflow record page type") { + // Do nothing + } else if (error.original == "Subdatabase last page is greater than database last page" || + error.original == "Page number is greater than database last page" || + error.original == "Last page number could not fit in file" || + error.original == "Subdatabase has an unexpected name" || + error.original == "Unsupported BDB data file version number" || + error.original == "BDB builtin encryption is not supported") { +#ifdef USE_BDB + bdb_ro_strict_err = true; +#endif + } else { + throw std::runtime_error(error.original); + } + } + +#ifdef USE_BDB + // Try opening with BDB + fs::path bdb_dumpfile{g_setup->m_args.GetDataDirNet() / "fuzzed_dumpfile_bdb.dump"}; + if (fs::exists(bdb_dumpfile)) { // Writing into an existing dump file will throw an exception + remove(bdb_dumpfile); + } + g_setup->m_args.ForceSetArg("-dumpfile", fs::PathToString(bdb_dumpfile)); + + try { + auto db{MakeBerkeleyDatabase(wallet_path, options, status, error)}; + if (bdb_ro_err && !db) { + return; + } + assert(db); + if (bdb_ro_strict_err) { + // BerkeleyRO will be stricter than BDB. Ignore when those specific errors are hit. + return; + } + assert(!bdb_ro_err); + assert(DumpWallet(g_setup->m_args, *db, error)); + } catch (const std::runtime_error& e) { + if (bdb_ro_err) return; + throw e; + } + + // Make sure the dumpfiles match + if (fs::exists(bdb_ro_dumpfile) && fs::exists(bdb_dumpfile)) { + std::ifstream bdb_ro_dump(bdb_ro_dumpfile, std::ios_base::binary | std::ios_base::in); + std::ifstream bdb_dump(bdb_dumpfile, std::ios_base::binary | std::ios_base::in); + assert(std::equal( + std::istreambuf_iterator<char>(bdb_ro_dump.rdbuf()), + std::istreambuf_iterator<char>(), + std::istreambuf_iterator<char>(bdb_dump.rdbuf()))); + } +#endif +} diff --git a/src/wallet/test/psbt_wallet_tests.cpp b/src/wallet/test/psbt_wallet_tests.cpp index 9f533bf6ed..b5a3b22c54 100644 --- a/src/wallet/test/psbt_wallet_tests.cpp +++ b/src/wallet/test/psbt_wallet_tests.cpp @@ -3,6 +3,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <key_io.h> +#include <node/types.h> #include <util/bip32.h> #include <util/strencodings.h> #include <wallet/wallet.h> @@ -60,7 +61,7 @@ BOOST_AUTO_TEST_CASE(psbt_updater_test) // Fill transaction with our data bool complete = true; - BOOST_REQUIRE_EQUAL(TransactionError::OK, m_wallet.FillPSBT(psbtx, complete, SIGHASH_ALL, false, true)); + BOOST_REQUIRE(!m_wallet.FillPSBT(psbtx, complete, SIGHASH_ALL, false, true)); // Get the final tx DataStream ssTx{}; @@ -73,7 +74,7 @@ BOOST_AUTO_TEST_CASE(psbt_updater_test) // Try to sign the mutated input SignatureData sigdata; - BOOST_CHECK(m_wallet.FillPSBT(psbtx, complete, SIGHASH_ALL, true, true) != TransactionError::OK); + BOOST_CHECK(m_wallet.FillPSBT(psbtx, complete, SIGHASH_ALL, true, true)); } BOOST_AUTO_TEST_CASE(parse_hd_keypath) diff --git a/src/wallet/test/util.cpp b/src/wallet/test/util.cpp index 49d206f409..b21a9a601d 100644 --- a/src/wallet/test/util.cpp +++ b/src/wallet/test/util.cpp @@ -93,11 +93,6 @@ CTxDestination getNewDestination(CWallet& w, OutputType output_type) return *Assert(w.GetNewDestination(output_type, "")); } -// BytePrefix compares equality with other byte spans that begin with the same prefix. -struct BytePrefix { Span<const std::byte> prefix; }; -bool operator<(BytePrefix a, Span<const std::byte> b) { return a.prefix < b.subspan(0, std::min(a.prefix.size(), b.size())); } -bool operator<(Span<const std::byte> a, BytePrefix b) { return a.subspan(0, std::min(a.size(), b.prefix.size())) < b.prefix; } - MockableCursor::MockableCursor(const MockableData& records, bool pass, Span<const std::byte> prefix) { m_pass = pass; diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index 3a67b9a433..53f3bcc421 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -235,11 +235,11 @@ BOOST_FIXTURE_TEST_CASE(importmulti_rescan, TestChain100Setup) key.pushKV("scriptPubKey", HexStr(GetScriptForRawPubKey(futureKey.GetPubKey()))); key.pushKV("timestamp", newTip->GetBlockTimeMax() + TIMESTAMP_WINDOW + 1); key.pushKV("internal", UniValue(true)); - keys.push_back(key); + keys.push_back(std::move(key)); JSONRPCRequest request; request.context = &context; request.params.setArray(); - request.params.push_back(keys); + request.params.push_back(std::move(keys)); UniValue response = importmulti().HandleRequest(request); BOOST_CHECK_EQUAL(response.write(), @@ -499,8 +499,10 @@ static void TestWatchOnlyPubKey(LegacyScriptPubKeyMan* spk_man, const CPubKey& a // Cryptographically invalidate a PubKey whilst keeping length and first byte static void PollutePubKey(CPubKey& pubkey) { - std::vector<unsigned char> pubkey_raw(pubkey.begin(), pubkey.end()); - std::fill(pubkey_raw.begin()+1, pubkey_raw.end(), 0); + assert(pubkey.size() >= 1); + std::vector<unsigned char> pubkey_raw; + pubkey_raw.push_back(pubkey[0]); + pubkey_raw.insert(pubkey_raw.end(), pubkey.size() - 1, 0); pubkey = CPubKey(pubkey_raw); assert(!pubkey.IsFullyValid()); assert(pubkey.IsValid()); diff --git a/src/wallet/transaction.h b/src/wallet/transaction.h index 9c27574103..9079f6dd82 100644 --- a/src/wallet/transaction.h +++ b/src/wallet/transaction.h @@ -273,7 +273,7 @@ public: mapValueCopy["fromaccount"] = ""; if (nOrderPos != -1) { - mapValueCopy["n"] = ToString(nOrderPos); + mapValueCopy["n"] = util::ToString(nOrderPos); } if (nTimeSmart) { mapValueCopy["timesmart"] = strprintf("%u", nTimeSmart); diff --git a/src/wallet/types.h b/src/wallet/types.h index 6198f1ae33..7e3b2caeb1 100644 --- a/src/wallet/types.h +++ b/src/wallet/types.h @@ -3,12 +3,13 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -//! @file Public type definitions that are used inside and outside of the wallet -//! (e.g. by src/wallet and src/interfaces and src/qt code). +//! @file wallet/types.h is a home for public enum and struct type definitions +//! that are used by internally by wallet code, but also used externally by node +//! or GUI code. //! -//! File is home for simple enum and struct definitions that don't deserve -//! separate header files. More complicated wallet public types like -//! CCoinControl that are used externally can have separate headers. +//! This file is intended to define only simple types that do not have external +//! dependencies. More complicated public wallet types like CCoinControl should +//! be defined in dedicated header files. #ifndef BITCOIN_WALLET_TYPES_H #define BITCOIN_WALLET_TYPES_H diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 45f69f52d1..d569c64b43 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -11,7 +11,9 @@ #include <chain.h> #include <coins.h> #include <common/args.h> +#include <common/messages.h> #include <common/settings.h> +#include <common/signmessage.h> #include <common/system.h> #include <consensus/amount.h> #include <consensus/consensus.h> @@ -25,6 +27,7 @@ #include <key.h> #include <key_io.h> #include <logging.h> +#include <node/types.h> #include <outputtype.h> #include <policy/feerate.h> #include <primitives/block.h> @@ -49,10 +52,8 @@ #include <uint256.h> #include <univalue.h> #include <util/check.h> -#include <util/error.h> #include <util/fs.h> #include <util/fs_helpers.h> -#include <util/message.h> #include <util/moneystr.h> #include <util/result.h> #include <util/string.h> @@ -81,7 +82,12 @@ struct KeyOriginInfo; +using common::AmountErrMsg; +using common::AmountHighWarn; +using common::PSBTError; using interfaces::FoundBlock; +using util::ReplaceAll; +using util::ToString; namespace wallet { @@ -373,7 +379,12 @@ std::shared_ptr<CWallet> CreateWallet(WalletContext& context, const std::string& uint64_t wallet_creation_flags = options.create_flags; const SecureString& passphrase = options.create_passphrase; + ArgsManager& args = *Assert(context.args); + if (wallet_creation_flags & WALLET_FLAG_DESCRIPTORS) options.require_format = DatabaseFormat::SQLITE; + else if (args.GetBoolArg("-swapbdbendian", false)) { + options.require_format = DatabaseFormat::BERKELEY_SWAP; + } // Indicate that the wallet is actually supposed to be blank and not just blank to make it encrypted bool create_blank = (wallet_creation_flags & WALLET_FLAG_BLANK_WALLET); @@ -1355,13 +1366,13 @@ void CWallet::MarkConflicted(const uint256& hashBlock, int conflicting_height, c } -void CWallet::RecursiveUpdateTxState(const uint256& tx_hash, const TryUpdatingStateFn& try_updating_state) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) { +void CWallet::RecursiveUpdateTxState(const uint256& tx_hash, const TryUpdatingStateFn& try_updating_state) { // Do not flush the wallet here for performance reasons WalletBatch batch(GetDatabase(), false); RecursiveUpdateTxState(&batch, tx_hash, try_updating_state); } -void CWallet::RecursiveUpdateTxState(WalletBatch* batch, const uint256& tx_hash, const TryUpdatingStateFn& try_updating_state) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) { +void CWallet::RecursiveUpdateTxState(WalletBatch* batch, const uint256& tx_hash, const TryUpdatingStateFn& try_updating_state) { std::set<uint256> todo; std::set<uint256> done; @@ -2167,7 +2178,7 @@ bool CWallet::SignTransaction(CMutableTransaction& tx, const std::map<COutPoint, return false; } -TransactionError CWallet::FillPSBT(PartiallySignedTransaction& psbtx, bool& complete, int sighash_type, bool sign, bool bip32derivs, size_t * n_signed, bool finalize) const +std::optional<PSBTError> CWallet::FillPSBT(PartiallySignedTransaction& psbtx, bool& complete, int sighash_type, bool sign, bool bip32derivs, size_t * n_signed, bool finalize) const { if (n_signed) { *n_signed = 0; @@ -2200,9 +2211,9 @@ TransactionError CWallet::FillPSBT(PartiallySignedTransaction& psbtx, bool& comp // Fill in information from ScriptPubKeyMans for (ScriptPubKeyMan* spk_man : GetAllScriptPubKeyMans()) { int n_signed_this_spkm = 0; - TransactionError res = spk_man->FillPSBT(psbtx, txdata, sighash_type, sign, bip32derivs, &n_signed_this_spkm, finalize); - if (res != TransactionError::OK) { - return res; + const auto error{spk_man->FillPSBT(psbtx, txdata, sighash_type, sign, bip32derivs, &n_signed_this_spkm, finalize)}; + if (error) { + return error; } if (n_signed) { @@ -2218,7 +2229,7 @@ TransactionError CWallet::FillPSBT(PartiallySignedTransaction& psbtx, bool& comp complete &= PSBTInputSigned(input); } - return TransactionError::OK; + return {}; } SigningResult CWallet::SignMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) const diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 6a998fa398..5bc888462f 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -58,7 +58,9 @@ class Coin; class SigningProvider; enum class MemPoolRemovalReason; enum class SigningResult; -enum class TransactionError; +namespace common { +enum class PSBTError; +} // namespace common namespace interfaces { class Wallet; } @@ -659,7 +661,7 @@ public: * @param[in] finalize whether to create the final scriptSig or scriptWitness if possible * return error */ - TransactionError FillPSBT(PartiallySignedTransaction& psbtx, + std::optional<common::PSBTError> FillPSBT(PartiallySignedTransaction& psbtx, bool& complete, int sighash_type = SIGHASH_DEFAULT, bool sign = true, diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 3ba43cdb73..f34fcfc3fd 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -21,6 +21,7 @@ #ifdef USE_BDB #include <wallet/bdb.h> #endif +#include <wallet/migrate.h> #ifdef USE_SQLITE #include <wallet/sqlite.h> #endif @@ -1387,6 +1388,11 @@ std::unique_ptr<WalletDatabase> MakeDatabase(const fs::path& path, const Databas return nullptr; } + // If BERKELEY was the format, then change the format from BERKELEY to BERKELEY_RO + if (format && options.require_format && format == DatabaseFormat::BERKELEY && options.require_format == DatabaseFormat::BERKELEY_RO) { + format = DatabaseFormat::BERKELEY_RO; + } + // A db already exists so format is set, but options also specifies the format, so make sure they agree if (format && options.require_format && format != options.require_format) { error = Untranslated(strprintf("Failed to load database path '%s'. Data is not in required format.", fs::PathToString(path))); @@ -1420,6 +1426,10 @@ std::unique_ptr<WalletDatabase> MakeDatabase(const fs::path& path, const Databas } } + if (format == DatabaseFormat::BERKELEY_RO) { + return MakeBerkeleyRODatabase(path, options, status, error); + } + #ifdef USE_BDB if constexpr (true) { return MakeBerkeleyDatabase(path, options, status, error); diff --git a/src/wallet/wallettool.cpp b/src/wallet/wallettool.cpp index 7a1930fd31..10785ad354 100644 --- a/src/wallet/wallettool.cpp +++ b/src/wallet/wallettool.cpp @@ -192,6 +192,11 @@ bool ExecuteWalletToolFunc(const ArgsManager& args, const std::string& command) ReadDatabaseArgs(args, options); options.require_existing = true; DatabaseStatus status; + + if (args.GetBoolArg("-withinternalbdb", false) && IsBDBFile(BDBDataFile(path))) { + options.require_format = DatabaseFormat::BERKELEY_RO; + } + bilingual_str error; std::unique_ptr<WalletDatabase> database = MakeDatabase(path, options, status, error); if (!database) { diff --git a/src/warnings.cpp b/src/warnings.cpp deleted file mode 100644 index 38c0554cf2..0000000000 --- a/src/warnings.cpp +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2022 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include <config/bitcoin-config.h> // IWYU pragma: keep - -#include <warnings.h> - -#include <common/system.h> -#include <sync.h> -#include <util/translation.h> - -#include <optional> -#include <vector> - -static GlobalMutex g_warnings_mutex; -static bilingual_str g_misc_warnings GUARDED_BY(g_warnings_mutex); -static bool fLargeWorkInvalidChainFound GUARDED_BY(g_warnings_mutex) = false; -static std::optional<bilingual_str> g_timeoffset_warning GUARDED_BY(g_warnings_mutex){}; - -void SetMiscWarning(const bilingual_str& warning) -{ - LOCK(g_warnings_mutex); - g_misc_warnings = warning; -} - -void SetfLargeWorkInvalidChainFound(bool flag) -{ - LOCK(g_warnings_mutex); - fLargeWorkInvalidChainFound = flag; -} - -void SetMedianTimeOffsetWarning(std::optional<bilingual_str> warning) -{ - LOCK(g_warnings_mutex); - g_timeoffset_warning = warning; -} - -std::vector<bilingual_str> GetWarnings() -{ - std::vector<bilingual_str> warnings; - - LOCK(g_warnings_mutex); - - // Pre-release build warning - if (!CLIENT_VERSION_IS_RELEASE) { - warnings.emplace_back(_("This is a pre-release test build - use at your own risk - do not use for mining or merchant applications")); - } - - // Misc warnings like out of disk space and clock is wrong - if (!g_misc_warnings.empty()) { - warnings.emplace_back(g_misc_warnings); - } - - if (fLargeWorkInvalidChainFound) { - warnings.emplace_back(_("Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.")); - } - - if (g_timeoffset_warning) { - warnings.emplace_back(g_timeoffset_warning.value()); - } - - return warnings; -} diff --git a/src/warnings.h b/src/warnings.h deleted file mode 100644 index 79dc2ffabf..0000000000 --- a/src/warnings.h +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2021 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef BITCOIN_WARNINGS_H -#define BITCOIN_WARNINGS_H - -#include <optional> -#include <string> -#include <vector> - -struct bilingual_str; - -void SetMiscWarning(const bilingual_str& warning); -void SetfLargeWorkInvalidChainFound(bool flag); -/** Pass std::nullopt to disable the warning */ -void SetMedianTimeOffsetWarning(std::optional<bilingual_str> warning); -/** Return potential problems detected by the node. */ -std::vector<bilingual_str> GetWarnings(); - -#endif // BITCOIN_WARNINGS_H diff --git a/src/zmq/zmqrpc.cpp b/src/zmq/zmqrpc.cpp index fcc2608262..84995d12d3 100644 --- a/src/zmq/zmqrpc.cpp +++ b/src/zmq/zmqrpc.cpp @@ -47,7 +47,7 @@ static RPCHelpMan getzmqnotifications() obj.pushKV("type", n->GetType()); obj.pushKV("address", n->GetAddress()); obj.pushKV("hwm", n->GetOutboundMessageHighWaterMark()); - result.push_back(obj); + result.push_back(std::move(obj)); } } diff --git a/test/functional/feature_addrman.py b/test/functional/feature_addrman.py index 95d33d62ea..2efad70900 100755 --- a/test/functional/feature_addrman.py +++ b/test/functional/feature_addrman.py @@ -6,7 +6,6 @@ import os import re -import struct from test_framework.messages import ser_uint256, hash256, MAGIC_BYTES from test_framework.netutil import ADDRMAN_NEW_BUCKET_COUNT, ADDRMAN_TRIED_BUCKET_COUNT, ADDRMAN_BUCKET_SIZE @@ -28,15 +27,15 @@ def serialize_addrman( tried = [] INCOMPATIBILITY_BASE = 32 r = MAGIC_BYTES[net_magic] - r += struct.pack("B", format) - r += struct.pack("B", INCOMPATIBILITY_BASE + lowest_compatible) + r += format.to_bytes(1, "little") + r += (INCOMPATIBILITY_BASE + lowest_compatible).to_bytes(1, "little") r += ser_uint256(bucket_key) - r += struct.pack("<i", len_new or len(new)) - r += struct.pack("<i", len_tried or len(tried)) + r += (len_new or len(new)).to_bytes(4, "little", signed=True) + r += (len_tried or len(tried)).to_bytes(4, "little", signed=True) ADDRMAN_NEW_BUCKET_COUNT = 1 << 10 - r += struct.pack("<i", ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30)) + r += (ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30)).to_bytes(4, "little", signed=True) for _ in range(ADDRMAN_NEW_BUCKET_COUNT): - r += struct.pack("<i", 0) + r += (0).to_bytes(4, "little", signed=True) checksum = hash256(r) r += mock_checksum or checksum return r diff --git a/test/functional/feature_asmap.py b/test/functional/feature_asmap.py index 024a8fa18c..e469deef49 100755 --- a/test/functional/feature_asmap.py +++ b/test/functional/feature_asmap.py @@ -27,6 +27,7 @@ import os import shutil from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal DEFAULT_ASMAP_FILENAME = 'ip_asn.map' # defined in src/init.cpp ASMAP = '../../src/test/data/asmap.raw' # path to unit test skeleton asmap @@ -118,6 +119,14 @@ class AsmapTest(BitcoinTestFramework): msg = "ASMap Health Check: 4 clearnet peers are mapped to 3 ASNs with 0 peers being unmapped" with self.node.assert_debug_log(expected_msgs=[msg]): self.start_node(0, extra_args=['-asmap']) + raw_addrman = self.node.getrawaddrman() + asns = [] + for _, entries in raw_addrman.items(): + for _, entry in entries.items(): + asn = entry['mapped_as'] + if asn not in asns: + asns.append(asn) + assert_equal(len(asns), 3) os.remove(self.default_asmap) def run_test(self): diff --git a/test/functional/feature_assumeutxo.py b/test/functional/feature_assumeutxo.py index 2842d82d80..658eea0a0e 100755 --- a/test/functional/feature_assumeutxo.py +++ b/test/functional/feature_assumeutxo.py @@ -75,41 +75,76 @@ class AssumeutxoTest(BitcoinTestFramework): with self.nodes[1].assert_debug_log([log_msg]): assert_raises_rpc_error(-32603, f"Unable to load UTXO snapshot{rpc_details}", self.nodes[1].loadtxoutset, bad_snapshot_path) + self.log.info(" - snapshot file with invalid file magic") + parsing_error_code = -22 + bad_magic = 0xf00f00f000 + with open(bad_snapshot_path, 'wb') as f: + f.write(bad_magic.to_bytes(5, "big") + valid_snapshot_contents[5:]) + assert_raises_rpc_error(parsing_error_code, "Unable to parse metadata: Invalid UTXO set snapshot magic bytes. Please check if this is indeed a snapshot file or if you are using an outdated snapshot format.", self.nodes[1].loadtxoutset, bad_snapshot_path) + + self.log.info(" - snapshot file with unsupported version") + for version in [0, 2]: + with open(bad_snapshot_path, 'wb') as f: + f.write(valid_snapshot_contents[:5] + version.to_bytes(2, "little") + valid_snapshot_contents[7:]) + assert_raises_rpc_error(parsing_error_code, f"Unable to parse metadata: Version of snapshot {version} does not match any of the supported versions.", self.nodes[1].loadtxoutset, bad_snapshot_path) + + self.log.info(" - snapshot file with mismatching network magic") + invalid_magics = [ + # magic, name, real + [0xf9beb4d9, "main", True], + [0x0b110907, "test", True], + [0x0a03cf40, "signet", True], + [0x00000000, "", False], + [0xffffffff, "", False], + ] + for [magic, name, real] in invalid_magics: + with open(bad_snapshot_path, 'wb') as f: + f.write(valid_snapshot_contents[:7] + magic.to_bytes(4, 'big') + valid_snapshot_contents[11:]) + if real: + assert_raises_rpc_error(parsing_error_code, f"Unable to parse metadata: The network of the snapshot ({name}) does not match the network of this node (regtest).", self.nodes[1].loadtxoutset, bad_snapshot_path) + else: + assert_raises_rpc_error(parsing_error_code, "Unable to parse metadata: This snapshot has been created for an unrecognized network. This could be a custom signet, a new testnet or possibly caused by data corruption.", self.nodes[1].loadtxoutset, bad_snapshot_path) + self.log.info(" - snapshot file referring to a block that is not in the assumeutxo parameters") prev_block_hash = self.nodes[0].getblockhash(SNAPSHOT_BASE_HEIGHT - 1) bogus_block_hash = "0" * 64 # Represents any unknown block hash + # The height is not used for anything critical currently, so we just + # confirm the manipulation in the error message + bogus_height = 1337 for bad_block_hash in [bogus_block_hash, prev_block_hash]: with open(bad_snapshot_path, 'wb') as f: - # block hash of the snapshot base is stored right at the start (first 32 bytes) - f.write(bytes.fromhex(bad_block_hash)[::-1] + valid_snapshot_contents[32:]) - error_details = f", assumeutxo block hash in snapshot metadata not recognized ({bad_block_hash})" + f.write(valid_snapshot_contents[:11] + bogus_height.to_bytes(4, "little") + bytes.fromhex(bad_block_hash)[::-1] + valid_snapshot_contents[47:]) + error_details = f", assumeutxo block hash in snapshot metadata not recognized (hash: {bad_block_hash}, height: {bogus_height}). The following snapshot heights are available: 110, 299." expected_error(rpc_details=error_details) self.log.info(" - snapshot file with wrong number of coins") - valid_num_coins = int.from_bytes(valid_snapshot_contents[32:32 + 8], "little") + valid_num_coins = int.from_bytes(valid_snapshot_contents[47:47 + 8], "little") for off in [-1, +1]: with open(bad_snapshot_path, 'wb') as f: - f.write(valid_snapshot_contents[:32]) + f.write(valid_snapshot_contents[:47]) f.write((valid_num_coins + off).to_bytes(8, "little")) - f.write(valid_snapshot_contents[32 + 8:]) + f.write(valid_snapshot_contents[47 + 8:]) expected_error(log_msg=f"bad snapshot - coins left over after deserializing 298 coins" if off == -1 else f"bad snapshot format or truncated snapshot after deserializing 299 coins") - self.log.info(" - snapshot file with alternated UTXO data") + self.log.info(" - snapshot file with alternated but parsable UTXO data results in different hash") cases = [ # (content, offset, wrong_hash, custom_message) [b"\xff" * 32, 0, "7d52155c9a9fdc4525b637ef6170568e5dad6fabd0b1fdbb9432010b8453095b", None], # wrong outpoint hash - [(1).to_bytes(4, "little"), 32, "9f4d897031ab8547665b4153317ae2fdbf0130c7840b66427ebc48b881cb80ad", None], # wrong outpoint index - [b"\x81", 36, "3da966ba9826fb6d2604260e01607b55ba44e1a5de298606b08704bc62570ea8", None], # wrong coin code VARINT - [b"\x80", 36, "091e893b3ccb4334378709578025356c8bcb0a623f37c7c4e493133c988648e5", None], # another wrong coin code - [b"\x84\x58", 36, None, "[snapshot] bad snapshot data after deserializing 0 coins"], # wrong coin case with height 364 and coinbase 0 - [b"\xCA\xD2\x8F\x5A", 41, None, "[snapshot] bad snapshot data after deserializing 0 coins - bad tx out value"], # Amount exceeds MAX_MONEY + [(2).to_bytes(1, "little"), 32, None, "[snapshot] bad snapshot data after deserializing 1 coins"], # wrong txid coins count + [b"\xfd\xff\xff", 32, None, "[snapshot] mismatch in coins count in snapshot metadata and actual snapshot data"], # txid coins count exceeds coins left + [b"\x01", 33, "9f4d897031ab8547665b4153317ae2fdbf0130c7840b66427ebc48b881cb80ad", None], # wrong outpoint index + [b"\x81", 34, "3da966ba9826fb6d2604260e01607b55ba44e1a5de298606b08704bc62570ea8", None], # wrong coin code VARINT + [b"\x80", 34, "091e893b3ccb4334378709578025356c8bcb0a623f37c7c4e493133c988648e5", None], # another wrong coin code + [b"\x84\x58", 34, None, "[snapshot] bad snapshot data after deserializing 0 coins"], # wrong coin case with height 364 and coinbase 0 + [b"\xCA\xD2\x8F\x5A", 39, None, "[snapshot] bad snapshot data after deserializing 0 coins - bad tx out value"], # Amount exceeds MAX_MONEY ] for content, offset, wrong_hash, custom_message in cases: with open(bad_snapshot_path, "wb") as f: - f.write(valid_snapshot_contents[:(32 + 8 + offset)]) + # Prior to offset: Snapshot magic, snapshot version, network magic, height, hash, coins count + f.write(valid_snapshot_contents[:(5 + 2 + 4 + 4 + 32 + 8 + offset)]) f.write(content) - f.write(valid_snapshot_contents[(32 + 8 + offset + len(content)):]) + f.write(valid_snapshot_contents[(5 + 2 + 4 + 4 + 32 + 8 + offset + len(content)):]) log_msg = custom_message if custom_message is not None else f"[snapshot] bad snapshot content hash: expected a4bf3407ccb2cc0145c49ebba8fa91199f8a3903daf0883875941497d2493c27, got {wrong_hash}" expected_error(log_msg=log_msg) @@ -155,6 +190,20 @@ class AssumeutxoTest(BitcoinTestFramework): self.restart_node(2, extra_args=self.extra_args[2]) + def test_invalid_file_path(self): + self.log.info("Test bitcoind should fail when file path is invalid.") + node = self.nodes[0] + path = node.datadir_path / node.chain / "invalid" / "path" + assert_raises_rpc_error(-8, "Couldn't open file {} for reading.".format(path), node.loadtxoutset, path) + + def test_snapshot_with_less_work(self, dump_output_path): + self.log.info("Test bitcoind should fail when snapshot has less accumulated work than this node.") + node = self.nodes[0] + assert_equal(node.getblockcount(), FINAL_HEIGHT) + with node.assert_debug_log(expected_msgs=["[snapshot] activation failed - work does not exceed active chainstate"]): + assert_raises_rpc_error(-32603, "Unable to load UTXO snapshot", node.loadtxoutset, dump_output_path) + self.restart_node(0, extra_args=self.extra_args[0]) + def run_test(self): """ Bring up two (disconnected) nodes, mine some new blocks on the first, @@ -236,9 +285,11 @@ class AssumeutxoTest(BitcoinTestFramework): assert_equal(n0.getblockchaininfo()["blocks"], FINAL_HEIGHT) + self.test_snapshot_with_less_work(dump_output['path']) self.test_invalid_mempool_state(dump_output['path']) self.test_invalid_snapshot_scenarios(dump_output['path']) self.test_invalid_chainstate_scenarios() + self.test_invalid_file_path() self.log.info(f"Loading snapshot into second node from {dump_output['path']}") loaded = n1.loadtxoutset(dump_output['path']) @@ -398,6 +449,10 @@ class AssumeutxoTest(BitcoinTestFramework): assert_equal(snapshot['snapshot_blockhash'], dump_output['base_hash']) assert_equal(snapshot['validated'], False) + self.log.info("Check that loading the snapshot again will fail because there is already an active snapshot.") + with n2.assert_debug_log(expected_msgs=["[snapshot] can't activate a snapshot-based chainstate more than once"]): + assert_raises_rpc_error(-32603, "Unable to load UTXO snapshot", n2.loadtxoutset, dump_output['path']) + self.connect_nodes(0, 2) self.wait_until(lambda: n2.getchainstates()['chainstates'][-1]['blocks'] == FINAL_HEIGHT) self.sync_blocks() diff --git a/test/functional/feature_bip68_sequence.py b/test/functional/feature_bip68_sequence.py index 8768d4040d..14b92d6733 100755 --- a/test/functional/feature_bip68_sequence.py +++ b/test/functional/feature_bip68_sequence.py @@ -78,8 +78,8 @@ class BIP68Test(BitcoinTestFramework): self.log.info("Activating BIP68 (and 112/113)") self.activateCSV() - self.log.info("Verifying nVersion=2 transactions are standard.") - self.log.info("Note that nVersion=2 transactions are always standard (independent of BIP68 activation status).") + self.log.info("Verifying version=2 transactions are standard.") + self.log.info("Note that version=2 transactions are always standard (independent of BIP68 activation status).") self.test_version2_relay() self.log.info("Passed") @@ -107,7 +107,7 @@ class BIP68Test(BitcoinTestFramework): # This transaction will enable sequence-locks, so this transaction should # fail tx2 = CTransaction() - tx2.nVersion = 2 + tx2.version = 2 sequence_value = sequence_value & 0x7fffffff tx2.vin = [CTxIn(COutPoint(tx1_id, 0), nSequence=sequence_value)] tx2.wit.vtxinwit = [CTxInWitness()] @@ -119,7 +119,7 @@ class BIP68Test(BitcoinTestFramework): # Setting the version back down to 1 should disable the sequence lock, # so this should be accepted. - tx2.nVersion = 1 + tx2.version = 1 self.wallet.sendrawtransaction(from_node=self.nodes[0], tx_hex=tx2.serialize().hex()) @@ -159,7 +159,7 @@ class BIP68Test(BitcoinTestFramework): using_sequence_locks = False tx = CTransaction() - tx.nVersion = 2 + tx.version = 2 value = 0 for j in range(num_inputs): sequence_value = 0xfffffffe # this disables sequence locks @@ -228,7 +228,7 @@ class BIP68Test(BitcoinTestFramework): # Anyone-can-spend mempool tx. # Sequence lock of 0 should pass. tx2 = CTransaction() - tx2.nVersion = 2 + tx2.version = 2 tx2.vin = [CTxIn(COutPoint(tx1.sha256, 0), nSequence=0)] tx2.vout = [CTxOut(int(tx1.vout[0].nValue - self.relayfee * COIN), SCRIPT_W0_SH_OP_TRUE)] self.wallet.sign_tx(tx=tx2) @@ -246,7 +246,7 @@ class BIP68Test(BitcoinTestFramework): sequence_value |= SEQUENCE_LOCKTIME_TYPE_FLAG tx = CTransaction() - tx.nVersion = 2 + tx.version = 2 tx.vin = [CTxIn(COutPoint(orig_tx.sha256, 0), nSequence=sequence_value)] tx.wit.vtxinwit = [CTxInWitness()] tx.wit.vtxinwit[0].scriptWitness.stack = [CScript([OP_TRUE])] @@ -360,7 +360,7 @@ class BIP68Test(BitcoinTestFramework): # Make an anyone-can-spend transaction tx2 = CTransaction() - tx2.nVersion = 1 + tx2.version = 1 tx2.vin = [CTxIn(COutPoint(tx1.sha256, 0), nSequence=0)] tx2.vout = [CTxOut(int(tx1.vout[0].nValue - self.relayfee * COIN), SCRIPT_W0_SH_OP_TRUE)] @@ -376,7 +376,7 @@ class BIP68Test(BitcoinTestFramework): sequence_value = 100 # 100 block relative locktime tx3 = CTransaction() - tx3.nVersion = 2 + tx3.version = 2 tx3.vin = [CTxIn(COutPoint(tx2.sha256, 0), nSequence=sequence_value)] tx3.wit.vtxinwit = [CTxInWitness()] tx3.wit.vtxinwit[0].scriptWitness.stack = [CScript([OP_TRUE])] diff --git a/test/functional/feature_block.py b/test/functional/feature_block.py index 8a95975184..932f37a083 100755 --- a/test/functional/feature_block.py +++ b/test/functional/feature_block.py @@ -4,7 +4,6 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test block processing.""" import copy -import struct import time from test_framework.blocktools import ( @@ -67,7 +66,7 @@ class CBrokenBlock(CBlock): def serialize(self, with_witness=False): r = b"" r += super(CBlock, self).serialize() - r += struct.pack("<BQ", 255, len(self.vtx)) + r += (255).to_bytes(1, "little") + len(self.vtx).to_bytes(8, "little") for tx in self.vtx: if with_witness: r += tx.serialize_with_witness() diff --git a/test/functional/feature_csv_activation.py b/test/functional/feature_csv_activation.py index bc1f9e8f2f..2db9682931 100755 --- a/test/functional/feature_csv_activation.py +++ b/test/functional/feature_csv_activation.py @@ -110,7 +110,7 @@ class BIP68_112_113Test(BitcoinTestFramework): def create_bip112special(self, input, txversion): tx = self.create_self_transfer_from_utxo(input) - tx.nVersion = txversion + tx.version = txversion self.miniwallet.sign_tx(tx) tx.vin[0].scriptSig = CScript([-1, OP_CHECKSEQUENCEVERIFY, OP_DROP] + list(CScript(tx.vin[0].scriptSig))) tx.rehash() @@ -118,7 +118,7 @@ class BIP68_112_113Test(BitcoinTestFramework): def create_bip112emptystack(self, input, txversion): tx = self.create_self_transfer_from_utxo(input) - tx.nVersion = txversion + tx.version = txversion self.miniwallet.sign_tx(tx) tx.vin[0].scriptSig = CScript([OP_CHECKSEQUENCEVERIFY] + list(CScript(tx.vin[0].scriptSig))) tx.rehash() @@ -136,7 +136,7 @@ class BIP68_112_113Test(BitcoinTestFramework): for i, (sdf, srhb, stf, srlb) in enumerate(product(*[[True, False]] * 4)): locktime = relative_locktime(sdf, srhb, stf, srlb) tx = self.create_self_transfer_from_utxo(bip68inputs[i]) - tx.nVersion = txversion + tx.version = txversion tx.vin[0].nSequence = locktime + locktime_delta self.miniwallet.sign_tx(tx) txs.append({'tx': tx, 'sdf': sdf, 'stf': stf}) @@ -154,7 +154,7 @@ class BIP68_112_113Test(BitcoinTestFramework): tx.vin[0].nSequence = BASE_RELATIVE_LOCKTIME + locktime_delta else: # vary nSequence instead, OP_CSV is fixed tx.vin[0].nSequence = locktime + locktime_delta - tx.nVersion = txversion + tx.version = txversion self.miniwallet.sign_tx(tx) if varyOP_CSV: tx.vin[0].scriptSig = CScript([locktime, OP_CHECKSEQUENCEVERIFY, OP_DROP] + list(CScript(tx.vin[0].scriptSig))) @@ -257,10 +257,10 @@ class BIP68_112_113Test(BitcoinTestFramework): # BIP113 test transaction will be modified before each use to put in appropriate block time bip113tx_v1 = self.create_self_transfer_from_utxo(bip113input) bip113tx_v1.vin[0].nSequence = 0xFFFFFFFE - bip113tx_v1.nVersion = 1 + bip113tx_v1.version = 1 bip113tx_v2 = self.create_self_transfer_from_utxo(bip113input) bip113tx_v2.vin[0].nSequence = 0xFFFFFFFE - bip113tx_v2.nVersion = 2 + bip113tx_v2.version = 2 # For BIP68 test all 16 relative sequence locktimes bip68txs_v1 = self.create_bip68txs(bip68inputs, 1) diff --git a/test/functional/feature_framework_miniwallet.py b/test/functional/feature_framework_miniwallet.py new file mode 100755 index 0000000000..f108289018 --- /dev/null +++ b/test/functional/feature_framework_miniwallet.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 +# Copyright (c) 2024 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +"""Test MiniWallet.""" +from test_framework.blocktools import COINBASE_MATURITY +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + assert_greater_than_or_equal, +) +from test_framework.wallet import ( + MiniWallet, + MiniWalletMode, +) + + +class FeatureFrameworkMiniWalletTest(BitcoinTestFramework): + def set_test_params(self): + self.num_nodes = 1 + + def test_tx_padding(self): + """Verify that MiniWallet's transaction padding (`target_weight` parameter) + works accurately enough (i.e. at most 3 WUs higher) with all modes.""" + for mode_name, wallet in self.wallets: + self.log.info(f"Test tx padding with MiniWallet mode {mode_name}...") + utxo = wallet.get_utxo(mark_as_spent=False) + for target_weight in [1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000, 4000000, + 989, 2001, 4337, 13371, 23219, 49153, 102035, 223419, 3999989]: + tx = wallet.create_self_transfer(utxo_to_spend=utxo, target_weight=target_weight)["tx"] + self.log.debug(f"-> target weight: {target_weight}, actual weight: {tx.get_weight()}") + assert_greater_than_or_equal(tx.get_weight(), target_weight) + assert_greater_than_or_equal(target_weight + 3, tx.get_weight()) + + def run_test(self): + node = self.nodes[0] + self.wallets = [ + ("ADDRESS_OP_TRUE", MiniWallet(node, mode=MiniWalletMode.ADDRESS_OP_TRUE)), + ("RAW_OP_TRUE", MiniWallet(node, mode=MiniWalletMode.RAW_OP_TRUE)), + ("RAW_P2PK", MiniWallet(node, mode=MiniWalletMode.RAW_P2PK)), + ] + for _, wallet in self.wallets: + self.generate(wallet, 10) + self.generate(wallet, COINBASE_MATURITY) + + self.test_tx_padding() + + +if __name__ == '__main__': + FeatureFrameworkMiniWalletTest().main() diff --git a/test/functional/feature_framework_unit_tests.py b/test/functional/feature_framework_unit_tests.py index c9754e083c..14d83f8a70 100755 --- a/test/functional/feature_framework_unit_tests.py +++ b/test/functional/feature_framework_unit_tests.py @@ -25,7 +25,9 @@ TEST_FRAMEWORK_MODULES = [ "crypto.muhash", "crypto.poly1305", "crypto.ripemd160", + "crypto.secp256k1", "script", + "script_util", "segwit_addr", "wallet_util", ] diff --git a/test/functional/feature_init.py b/test/functional/feature_init.py index 268009b0f4..22ae0c307b 100755 --- a/test/functional/feature_init.py +++ b/test/functional/feature_init.py @@ -85,7 +85,7 @@ class InitStressTest(BitcoinTestFramework): for terminate_line in lines_to_terminate_after: self.log.info(f"Starting node and will exit after line {terminate_line}") - with node.wait_for_debug_log([terminate_line]): + with node.busy_wait_for_debug_log([terminate_line]): node.start(extra_args=['-txindex=1', '-blockfilterindex=1', '-coinstatsindex=1']) self.log.debug("Terminating node after terminate line was found") sigterm_node() diff --git a/test/functional/feature_rbf.py b/test/functional/feature_rbf.py index c5eeaf66e0..739b9b9bb9 100755 --- a/test/functional/feature_rbf.py +++ b/test/functional/feature_rbf.py @@ -28,7 +28,6 @@ class ReplaceByFeeTest(BitcoinTestFramework): self.num_nodes = 2 self.extra_args = [ [ - "-maxorphantx=1000", "-limitancestorcount=50", "-limitancestorsize=101", "-limitdescendantcount=200", diff --git a/test/functional/feature_reindex.py b/test/functional/feature_reindex.py index f0f32a61ab..835cd0c5cf 100755 --- a/test/functional/feature_reindex.py +++ b/test/functional/feature_reindex.py @@ -73,6 +73,25 @@ class ReindexTest(BitcoinTestFramework): # All blocks should be accepted and processed. assert_equal(self.nodes[0].getblockcount(), 12) + def continue_reindex_after_shutdown(self): + node = self.nodes[0] + self.generate(node, 1500) + + # Restart node with reindex and stop reindex as soon as it starts reindexing + self.log.info("Restarting node while reindexing..") + node.stop_node() + with node.busy_wait_for_debug_log([b'initload thread start']): + node.start(['-blockfilterindex', '-reindex']) + node.wait_for_rpc_connection(wait_for_import=False) + node.stop_node() + + # Start node without the reindex flag and verify it does not wipe the indexes data again + db_path = node.chain_path / 'indexes' / 'blockfilter' / 'basic' / 'db' + with node.assert_debug_log(expected_msgs=[f'Opening LevelDB in {db_path}'], unexpected_msgs=[f'Wiping LevelDB in {db_path}']): + node.start(['-blockfilterindex']) + node.wait_for_rpc_connection(wait_for_import=False) + node.stop_node() + def run_test(self): self.reindex(False) self.reindex(True) @@ -80,6 +99,7 @@ class ReindexTest(BitcoinTestFramework): self.reindex(True) self.out_of_order() + self.continue_reindex_after_shutdown() if __name__ == '__main__': diff --git a/test/functional/feature_reindex_readonly.py b/test/functional/feature_reindex_readonly.py index 25cff87a3b..52c0bb26a6 100755 --- a/test/functional/feature_reindex_readonly.py +++ b/test/functional/feature_reindex_readonly.py @@ -75,7 +75,7 @@ class BlockstoreReindexTest(BitcoinTestFramework): if undo_immutable: self.log.debug("Attempt to restart and reindex the node with the unwritable block file") - with self.nodes[0].wait_for_debug_log([b"Reindexing finished"]): + with self.nodes[0].assert_debug_log(["Reindexing finished"], timeout=60): self.start_node(0, extra_args=['-reindex', '-fastprune']) assert block_count == self.nodes[0].getblockcount() undo_immutable() diff --git a/test/functional/feature_settings.py b/test/functional/feature_settings.py index 0214e781de..1cd0aeabd3 100755 --- a/test/functional/feature_settings.py +++ b/test/functional/feature_settings.py @@ -25,7 +25,7 @@ class SettingsTest(BitcoinTestFramework): # Assert default settings file was created self.stop_node(0) - default_settings = {"_warning_": "This file is automatically generated and updated by Bitcoin Core. Please do not edit this file while the node is running, as any changes might be ignored or overwritten."} + default_settings = {"_warning_": f"This file is automatically generated and updated by {self.config['environment']['PACKAGE_NAME']}. Please do not edit this file while the node is running, as any changes might be ignored or overwritten."} with settings.open() as fp: assert_equal(json.load(fp), default_settings) diff --git a/test/functional/feature_taproot.py b/test/functional/feature_taproot.py index e7d65b4539..1a0844d240 100755 --- a/test/functional/feature_taproot.py +++ b/test/functional/feature_taproot.py @@ -1408,10 +1408,10 @@ class TaprootTest(BitcoinTestFramework): left = done while left: - # Construct CTransaction with random nVersion, nLocktime + # Construct CTransaction with random version, nLocktime tx = CTransaction() - tx.nVersion = random.choice([1, 2, random.randint(-0x80000000, 0x7fffffff)]) - min_sequence = (tx.nVersion != 1 and tx.nVersion != 0) * 0x80000000 # The minimum sequence number to disable relative locktime + tx.version = random.choice([1, 2, random.getrandbits(32)]) + min_sequence = (tx.version != 1 and tx.version != 0) * 0x80000000 # The minimum sequence number to disable relative locktime if random.choice([True, False]): tx.nLockTime = random.randrange(LOCKTIME_THRESHOLD, self.lastblocktime - 7200) # all absolute locktimes in the past else: @@ -1502,8 +1502,8 @@ class TaprootTest(BitcoinTestFramework): is_standard_tx = ( fail_input is None # Must be valid to be standard and (all(utxo.spender.is_standard for utxo in input_utxos)) # All inputs must be standard - and tx.nVersion >= 1 # The tx version must be standard - and tx.nVersion <= 2) + and tx.version >= 1 # The tx version must be standard + and tx.version <= 2) tx.rehash() msg = ','.join(utxo.spender.comment + ("*" if n == fail_input else "") for n, utxo in enumerate(input_utxos)) if is_standard_tx: @@ -1530,7 +1530,7 @@ class TaprootTest(BitcoinTestFramework): # Deterministically mine coins to OP_TRUE in block 1 assert_equal(self.nodes[0].getblockcount(), 0) coinbase = CTransaction() - coinbase.nVersion = 1 + coinbase.version = 1 coinbase.vin = [CTxIn(COutPoint(0, 0xffffffff), CScript([OP_1, OP_1]), SEQUENCE_FINAL)] coinbase.vout = [CTxOut(5000000000, CScript([OP_1]))] coinbase.nLockTime = 0 @@ -1622,7 +1622,7 @@ class TaprootTest(BitcoinTestFramework): for i, spk in enumerate(old_spks + tap_spks): val = 42000000 * (i + 7) tx = CTransaction() - tx.nVersion = 1 + tx.version = 1 tx.vin = [CTxIn(COutPoint(lasttxid, i & 1), CScript([]), SEQUENCE_FINAL)] tx.vout = [CTxOut(val, spk), CTxOut(amount - val, CScript([OP_1]))] if i & 1: @@ -1679,7 +1679,7 @@ class TaprootTest(BitcoinTestFramework): # Construct a deterministic transaction spending all outputs created above. tx = CTransaction() - tx.nVersion = 2 + tx.version = 2 tx.vin = [] inputs = [] input_spks = [tap_spks[0], tap_spks[1], old_spks[0], tap_spks[2], tap_spks[5], old_spks[2], tap_spks[6], tap_spks[3], tap_spks[4]] diff --git a/test/functional/interface_bitcoin_cli.py b/test/functional/interface_bitcoin_cli.py index 83bb5121e5..a6628dcbf3 100755 --- a/test/functional/interface_bitcoin_cli.py +++ b/test/functional/interface_bitcoin_cli.py @@ -8,6 +8,7 @@ from decimal import Decimal import re from test_framework.blocktools import COINBASE_MATURITY +from test_framework.netutil import test_ipv6_local from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, @@ -15,6 +16,7 @@ from test_framework.util import ( assert_raises_process_error, assert_raises_rpc_error, get_auth_cookie, + rpc_port, ) import time @@ -107,6 +109,53 @@ class TestBitcoinCli(BitcoinTestFramework): self.log.info("Test connecting to a non-existing server") assert_raises_process_error(1, "Could not connect to the server", self.nodes[0].cli('-rpcport=1').echo) + self.log.info("Test handling of invalid ports in rpcconnect") + assert_raises_process_error(1, "Invalid port provided in -rpcconnect: 127.0.0.1:notaport", self.nodes[0].cli("-rpcconnect=127.0.0.1:notaport").echo) + assert_raises_process_error(1, "Invalid port provided in -rpcconnect: 127.0.0.1:-1", self.nodes[0].cli("-rpcconnect=127.0.0.1:-1").echo) + assert_raises_process_error(1, "Invalid port provided in -rpcconnect: 127.0.0.1:0", self.nodes[0].cli("-rpcconnect=127.0.0.1:0").echo) + assert_raises_process_error(1, "Invalid port provided in -rpcconnect: 127.0.0.1:65536", self.nodes[0].cli("-rpcconnect=127.0.0.1:65536").echo) + + self.log.info("Checking for IPv6") + have_ipv6 = test_ipv6_local() + if not have_ipv6: + self.log.info("Skipping IPv6 tests") + + if have_ipv6: + assert_raises_process_error(1, "Invalid port provided in -rpcconnect: [::1]:notaport", self.nodes[0].cli("-rpcconnect=[::1]:notaport").echo) + assert_raises_process_error(1, "Invalid port provided in -rpcconnect: [::1]:-1", self.nodes[0].cli("-rpcconnect=[::1]:-1").echo) + assert_raises_process_error(1, "Invalid port provided in -rpcconnect: [::1]:0", self.nodes[0].cli("-rpcconnect=[::1]:0").echo) + assert_raises_process_error(1, "Invalid port provided in -rpcconnect: [::1]:65536", self.nodes[0].cli("-rpcconnect=[::1]:65536").echo) + + self.log.info("Test handling of invalid ports in rpcport") + assert_raises_process_error(1, "Invalid port provided in -rpcport: notaport", self.nodes[0].cli("-rpcport=notaport").echo) + assert_raises_process_error(1, "Invalid port provided in -rpcport: -1", self.nodes[0].cli("-rpcport=-1").echo) + assert_raises_process_error(1, "Invalid port provided in -rpcport: 0", self.nodes[0].cli("-rpcport=0").echo) + assert_raises_process_error(1, "Invalid port provided in -rpcport: 65536", self.nodes[0].cli("-rpcport=65536").echo) + + self.log.info("Test port usage preferences") + node_rpc_port = rpc_port(self.nodes[0].index) + # Prevent bitcoin-cli from using existing rpcport in conf + conf_rpcport = "rpcport=" + str(node_rpc_port) + self.nodes[0].replace_in_config([(conf_rpcport, "#" + conf_rpcport)]) + # prefer rpcport over rpcconnect + assert_raises_process_error(1, "Could not connect to the server 127.0.0.1:1", self.nodes[0].cli(f"-rpcconnect=127.0.0.1:{node_rpc_port}", "-rpcport=1").echo) + if have_ipv6: + assert_raises_process_error(1, "Could not connect to the server ::1:1", self.nodes[0].cli(f"-rpcconnect=[::1]:{node_rpc_port}", "-rpcport=1").echo) + + assert_equal(BLOCKS, self.nodes[0].cli("-rpcconnect=127.0.0.1:18999", f'-rpcport={node_rpc_port}').getblockcount()) + if have_ipv6: + assert_equal(BLOCKS, self.nodes[0].cli("-rpcconnect=[::1]:18999", f'-rpcport={node_rpc_port}').getblockcount()) + + # prefer rpcconnect port over default + assert_equal(BLOCKS, self.nodes[0].cli(f"-rpcconnect=127.0.0.1:{node_rpc_port}").getblockcount()) + if have_ipv6: + assert_equal(BLOCKS, self.nodes[0].cli(f"-rpcconnect=[::1]:{node_rpc_port}").getblockcount()) + + # prefer rpcport over default + assert_equal(BLOCKS, self.nodes[0].cli(f'-rpcport={node_rpc_port}').getblockcount()) + # Re-enable rpcport in conf if present + self.nodes[0].replace_in_config([("#" + conf_rpcport, conf_rpcport)]) + self.log.info("Test connecting with non-existing RPC cookie file") assert_raises_process_error(1, "Could not locate RPC credentials", self.nodes[0].cli('-rpccookiefile=does-not-exist', '-rpcpassword=').echo) diff --git a/test/functional/interface_rpc.py b/test/functional/interface_rpc.py index e873e2da0b..6c1855c400 100755 --- a/test/functional/interface_rpc.py +++ b/test/functional/interface_rpc.py @@ -4,22 +4,79 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Tests some generic aspects of the RPC interface.""" +import json import os -from test_framework.authproxy import JSONRPCException +from dataclasses import dataclass from test_framework.test_framework import BitcoinTestFramework from test_framework.util import assert_equal, assert_greater_than_or_equal from threading import Thread +from typing import Optional import subprocess -def expect_http_status(expected_http_status, expected_rpc_code, - fcn, *args): - try: - fcn(*args) - raise AssertionError(f"Expected RPC error {expected_rpc_code}, got none") - except JSONRPCException as exc: - assert_equal(exc.error["code"], expected_rpc_code) - assert_equal(exc.http_status, expected_http_status) +RPC_INVALID_PARAMETER = -8 +RPC_METHOD_NOT_FOUND = -32601 +RPC_INVALID_REQUEST = -32600 +RPC_PARSE_ERROR = -32700 + + +@dataclass +class BatchOptions: + version: Optional[int] = None + notification: bool = False + request_fields: Optional[dict] = None + response_fields: Optional[dict] = None + + +def format_request(options, idx, fields): + request = {} + if options.version == 1: + request.update(version="1.1") + elif options.version == 2: + request.update(jsonrpc="2.0") + elif options.version is not None: + raise NotImplementedError(f"Unknown JSONRPC version {options.version}") + if not options.notification: + request.update(id=idx) + request.update(fields) + if options.request_fields: + request.update(options.request_fields) + return request + + +def format_response(options, idx, fields): + if options.version == 2 and options.notification: + return None + response = {} + if not options.notification: + response.update(id=idx) + if options.version == 2: + response.update(jsonrpc="2.0") + else: + response.update(result=None, error=None) + response.update(fields) + if options.response_fields: + response.update(options.response_fields) + return response + + +def send_raw_rpc(node, raw_body: bytes) -> tuple[object, int]: + return node._request("POST", "/", raw_body) + + +def send_json_rpc(node, body: object) -> tuple[object, int]: + raw = json.dumps(body).encode("utf-8") + return send_raw_rpc(node, raw) + + +def expect_http_rpc_status(expected_http_status, expected_rpc_error_code, node, method, params, version=1, notification=False): + req = format_request(BatchOptions(version, notification), 0, {"method": method, "params": params}) + response, status = send_json_rpc(node, req) + + if expected_rpc_error_code is not None: + assert_equal(response["error"]["code"], expected_rpc_error_code) + + assert_equal(status, expected_http_status) def test_work_queue_getblock(node, got_exceeded_error): @@ -48,37 +105,126 @@ class RPCInterfaceTest(BitcoinTestFramework): assert_greater_than_or_equal(command['duration'], 0) assert_equal(info['logpath'], os.path.join(self.nodes[0].chain_path, 'debug.log')) - def test_batch_request(self): - self.log.info("Testing basic JSON-RPC batch request...") - - results = self.nodes[0].batch([ + def test_batch_request(self, call_options): + calls = [ # A basic request that will work fine. - {"method": "getblockcount", "id": 1}, + {"method": "getblockcount"}, # Request that will fail. The whole batch request should still # work fine. - {"method": "invalidmethod", "id": 2}, + {"method": "invalidmethod"}, # Another call that should succeed. - {"method": "getblockhash", "id": 3, "params": [0]}, - ]) - - result_by_id = {} - for res in results: - result_by_id[res["id"]] = res - - assert_equal(result_by_id[1]['error'], None) - assert_equal(result_by_id[1]['result'], 0) - - assert_equal(result_by_id[2]['error']['code'], -32601) - assert_equal(result_by_id[2]['result'], None) - - assert_equal(result_by_id[3]['error'], None) - assert result_by_id[3]['result'] is not None + {"method": "getblockhash", "params": [0]}, + # Invalid request format + {"pizza": "sausage"} + ] + results = [ + {"result": 0}, + {"error": {"code": RPC_METHOD_NOT_FOUND, "message": "Method not found"}}, + {"result": "0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"}, + {"error": {"code": RPC_INVALID_REQUEST, "message": "Missing method"}}, + ] + + request = [] + response = [] + for idx, (call, result) in enumerate(zip(calls, results), 1): + options = call_options(idx) + if options is None: + continue + request.append(format_request(options, idx, call)) + r = format_response(options, idx, result) + if r is not None: + response.append(r) + + rpc_response, http_status = send_json_rpc(self.nodes[0], request) + if len(response) == 0 and len(request) > 0: + assert_equal(http_status, 204) + assert_equal(rpc_response, None) + else: + assert_equal(http_status, 200) + assert_equal(rpc_response, response) + + def test_batch_requests(self): + self.log.info("Testing empty batch request...") + self.test_batch_request(lambda idx: None) + + self.log.info("Testing basic JSON-RPC 2.0 batch request...") + self.test_batch_request(lambda idx: BatchOptions(version=2)) + + self.log.info("Testing JSON-RPC 2.0 batch with notifications...") + self.test_batch_request(lambda idx: BatchOptions(version=2, notification=idx < 2)) + + self.log.info("Testing JSON-RPC 2.0 batch of ALL notifications...") + self.test_batch_request(lambda idx: BatchOptions(version=2, notification=True)) + + # JSONRPC 1.1 does not support batch requests, but test them for backwards compatibility. + self.log.info("Testing nonstandard JSON-RPC 1.1 batch request...") + self.test_batch_request(lambda idx: BatchOptions(version=1)) + + self.log.info("Testing nonstandard mixed JSON-RPC 1.1/2.0 batch request...") + self.test_batch_request(lambda idx: BatchOptions(version=2 if idx % 2 else 1)) + + self.log.info("Testing nonstandard batch request without version numbers...") + self.test_batch_request(lambda idx: BatchOptions()) + + self.log.info("Testing nonstandard batch request without version numbers or ids...") + self.test_batch_request(lambda idx: BatchOptions(notification=True)) + + self.log.info("Testing nonstandard jsonrpc 1.0 version number is accepted...") + self.test_batch_request(lambda idx: BatchOptions(request_fields={"jsonrpc": "1.0"})) + + self.log.info("Testing unrecognized jsonrpc version number is rejected...") + self.test_batch_request(lambda idx: BatchOptions( + request_fields={"jsonrpc": "2.1"}, + response_fields={"result": None, "error": {"code": RPC_INVALID_REQUEST, "message": "JSON-RPC version not supported"}})) def test_http_status_codes(self): - self.log.info("Testing HTTP status codes for JSON-RPC requests...") - - expect_http_status(404, -32601, self.nodes[0].invalidmethod) - expect_http_status(500, -8, self.nodes[0].getblockhash, 42) + self.log.info("Testing HTTP status codes for JSON-RPC 1.1 requests...") + # OK + expect_http_rpc_status(200, None, self.nodes[0], "getblockhash", [0]) + # Errors + expect_http_rpc_status(404, RPC_METHOD_NOT_FOUND, self.nodes[0], "invalidmethod", []) + expect_http_rpc_status(500, RPC_INVALID_PARAMETER, self.nodes[0], "getblockhash", [42]) + # force-send empty request + response, status = send_raw_rpc(self.nodes[0], b"") + assert_equal(response, {"id": None, "result": None, "error": {"code": RPC_PARSE_ERROR, "message": "Parse error"}}) + assert_equal(status, 500) + # force-send invalidly formatted request + response, status = send_raw_rpc(self.nodes[0], b"this is bad") + assert_equal(response, {"id": None, "result": None, "error": {"code": RPC_PARSE_ERROR, "message": "Parse error"}}) + assert_equal(status, 500) + + self.log.info("Testing HTTP status codes for JSON-RPC 2.0 requests...") + # OK + expect_http_rpc_status(200, None, self.nodes[0], "getblockhash", [0], 2, False) + # RPC errors but not HTTP errors + expect_http_rpc_status(200, RPC_METHOD_NOT_FOUND, self.nodes[0], "invalidmethod", [], 2, False) + expect_http_rpc_status(200, RPC_INVALID_PARAMETER, self.nodes[0], "getblockhash", [42], 2, False) + # force-send invalidly formatted requests + response, status = send_json_rpc(self.nodes[0], {"jsonrpc": 2, "method": "getblockcount"}) + assert_equal(response, {"result": None, "error": {"code": RPC_INVALID_REQUEST, "message": "jsonrpc field must be a string"}}) + assert_equal(status, 400) + response, status = send_json_rpc(self.nodes[0], {"jsonrpc": "3.0", "method": "getblockcount"}) + assert_equal(response, {"result": None, "error": {"code": RPC_INVALID_REQUEST, "message": "JSON-RPC version not supported"}}) + assert_equal(status, 400) + + self.log.info("Testing HTTP status codes for JSON-RPC 2.0 notifications...") + # Not notification: id exists + response, status = send_json_rpc(self.nodes[0], {"jsonrpc": "2.0", "id": None, "method": "getblockcount"}) + assert_equal(response["result"], 0) + assert_equal(status, 200) + # Not notification: JSON 1.1 + expect_http_rpc_status(200, None, self.nodes[0], "getblockcount", [], 1) + # Not notification: has "id" field + expect_http_rpc_status(200, None, self.nodes[0], "getblockcount", [], 2, False) + block_count = self.nodes[0].getblockcount() + # Notification response status code: HTTP_NO_CONTENT + expect_http_rpc_status(204, None, self.nodes[0], "generatetoaddress", [1, "bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqdku202"], 2, True) + # The command worked even though there was no response + assert_equal(block_count + 1, self.nodes[0].getblockcount()) + # No error response for notifications even if they are invalid + expect_http_rpc_status(204, None, self.nodes[0], "generatetoaddress", [1, "invalid_address"], 2, True) + # Sanity check: command was not executed + assert_equal(block_count + 1, self.nodes[0].getblockcount()) def test_work_queue_exceeded(self): self.log.info("Testing work queue exceeded...") @@ -94,7 +240,7 @@ class RPCInterfaceTest(BitcoinTestFramework): def run_test(self): self.test_getrpcinfo() - self.test_batch_request() + self.test_batch_requests() self.test_http_status_codes() self.test_work_queue_exceeded() diff --git a/test/functional/mempool_accept.py b/test/functional/mempool_accept.py index b00be5f4f0..e1cee46839 100755 --- a/test/functional/mempool_accept.py +++ b/test/functional/mempool_accept.py @@ -18,6 +18,7 @@ from test_framework.messages import ( CTxInWitness, CTxOut, MAX_BLOCK_WEIGHT, + WITNESS_SCALE_FACTOR, MAX_MONEY, SEQUENCE_FINAL, tx_from_hex, @@ -228,7 +229,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework): self.log.info('A really large transaction') tx = tx_from_hex(raw_tx_reference) - tx.vin = [tx.vin[0]] * math.ceil(MAX_BLOCK_WEIGHT // 4 / len(tx.vin[0].serialize())) + tx.vin = [tx.vin[0]] * math.ceil((MAX_BLOCK_WEIGHT // WITNESS_SCALE_FACTOR) / len(tx.vin[0].serialize())) self.check_mempool_result( result_expected=[{'txid': tx.rehash(), 'allowed': False, 'reject-reason': 'bad-txns-oversize'}], rawtxs=[tx.serialize().hex()], @@ -287,7 +288,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework): self.log.info('Some nonstandard transactions') tx = tx_from_hex(raw_tx_reference) - tx.nVersion = 3 # A version currently non-standard + tx.version = 4 # A version currently non-standard self.check_mempool_result( result_expected=[{'txid': tx.rehash(), 'allowed': False, 'reject-reason': 'version'}], rawtxs=[tx.serialize().hex()], diff --git a/test/functional/mempool_accept_v3.py b/test/functional/mempool_accept_v3.py index 8285b82c19..d4a33c232e 100755 --- a/test/functional/mempool_accept_v3.py +++ b/test/functional/mempool_accept_v3.py @@ -6,6 +6,7 @@ from decimal import Decimal from test_framework.messages import ( MAX_BIP125_RBF_SEQUENCE, + WITNESS_SCALE_FACTOR, ) from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( @@ -21,6 +22,7 @@ from test_framework.wallet import ( ) MAX_REPLACEMENT_CANDIDATES = 100 +V3_MAX_VSIZE = 10000 def cleanup(extra_args=None): def decorator(func): @@ -40,7 +42,7 @@ def cleanup(extra_args=None): class MempoolAcceptV3(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 - self.extra_args = [["-acceptnonstdtxn=1"]] + self.extra_args = [[]] self.setup_clean_chain = True def check_mempool(self, txids): @@ -49,7 +51,21 @@ class MempoolAcceptV3(BitcoinTestFramework): assert_equal(len(txids), len(mempool_contents)) assert all([txid in txids for txid in mempool_contents]) - @cleanup(extra_args=["-datacarriersize=1000", "-acceptnonstdtxn=1"]) + @cleanup(extra_args=["-datacarriersize=20000"]) + def test_v3_max_vsize(self): + node = self.nodes[0] + self.log.info("Test v3-specific maximum transaction vsize") + tx_v3_heavy = self.wallet.create_self_transfer(target_weight=(V3_MAX_VSIZE + 1) * WITNESS_SCALE_FACTOR, version=3) + assert_greater_than_or_equal(tx_v3_heavy["tx"].get_vsize(), V3_MAX_VSIZE) + expected_error_heavy = f"v3-rule-violation, v3 tx {tx_v3_heavy['txid']} (wtxid={tx_v3_heavy['wtxid']}) is too big" + assert_raises_rpc_error(-26, expected_error_heavy, node.sendrawtransaction, tx_v3_heavy["hex"]) + self.check_mempool([]) + + # Ensure we are hitting the v3-specific limit and not something else + tx_v2_heavy = self.wallet.send_self_transfer(from_node=node, target_weight=(V3_MAX_VSIZE + 1) * WITNESS_SCALE_FACTOR, version=2) + self.check_mempool([tx_v2_heavy["txid"]]) + + @cleanup(extra_args=["-datacarriersize=1000"]) def test_v3_acceptance(self): node = self.nodes[0] self.log.info("Test a child of a v3 transaction cannot be more than 1000vB") @@ -89,7 +105,7 @@ class MempoolAcceptV3(BitcoinTestFramework): self.check_mempool([tx_v3_parent_normal["txid"], tx_v3_child_almost_heavy_rbf["txid"]]) assert_equal(node.getmempoolentry(tx_v3_parent_normal["txid"])["descendantcount"], 2) - @cleanup(extra_args=["-acceptnonstdtxn=1"]) + @cleanup(extra_args=None) def test_v3_replacement(self): node = self.nodes[0] self.log.info("Test v3 transactions may be replaced by v3 transactions") @@ -146,7 +162,7 @@ class MempoolAcceptV3(BitcoinTestFramework): self.check_mempool([tx_v3_bip125_rbf_v2["txid"], tx_v3_parent["txid"], tx_v3_child["txid"]]) - @cleanup(extra_args=["-acceptnonstdtxn=1"]) + @cleanup(extra_args=None) def test_v3_bip125(self): node = self.nodes[0] self.log.info("Test v3 transactions that don't signal BIP125 are replaceable") @@ -170,7 +186,7 @@ class MempoolAcceptV3(BitcoinTestFramework): ) self.check_mempool([tx_v3_no_bip125_rbf["txid"]]) - @cleanup(extra_args=["-datacarriersize=40000", "-acceptnonstdtxn=1"]) + @cleanup(extra_args=["-datacarriersize=40000"]) def test_v3_reorg(self): node = self.nodes[0] self.log.info("Test that, during a reorg, v3 rules are not enforced") @@ -192,7 +208,7 @@ class MempoolAcceptV3(BitcoinTestFramework): node.reconsiderblock(block[0]) - @cleanup(extra_args=["-limitdescendantsize=10", "-datacarriersize=40000", "-acceptnonstdtxn=1"]) + @cleanup(extra_args=["-limitdescendantsize=10", "-datacarriersize=40000"]) def test_nondefault_package_limits(self): """ Max standard tx size + v3 rules imply the ancestor/descendant rules (at their default @@ -201,25 +217,51 @@ class MempoolAcceptV3(BitcoinTestFramework): """ node = self.nodes[0] self.log.info("Test that a decreased limitdescendantsize also applies to v3 child") - tx_v3_parent_large1 = self.wallet.send_self_transfer(from_node=node, target_weight=99900, version=3) - tx_v3_child_large1 = self.wallet.create_self_transfer(utxo_to_spend=tx_v3_parent_large1["new_utxo"], version=3) - # Child is within v3 limits, but parent's descendant limit is exceeded - assert_greater_than(1000, tx_v3_child_large1["tx"].get_vsize()) + parent_target_weight = 9990 * WITNESS_SCALE_FACTOR + child_target_weight = 500 * WITNESS_SCALE_FACTOR + tx_v3_parent_large1 = self.wallet.send_self_transfer( + from_node=node, + target_weight=parent_target_weight, + version=3 + ) + tx_v3_child_large1 = self.wallet.create_self_transfer( + utxo_to_spend=tx_v3_parent_large1["new_utxo"], + target_weight=child_target_weight, + version=3 + ) + + # Parent and child are within v3 limits, but parent's 10kvB descendant limit is exceeded + assert_greater_than_or_equal(V3_MAX_VSIZE, tx_v3_parent_large1["tx"].get_vsize()) + assert_greater_than_or_equal(1000, tx_v3_child_large1["tx"].get_vsize()) + assert_greater_than(tx_v3_parent_large1["tx"].get_vsize() + tx_v3_child_large1["tx"].get_vsize(), 10000) + assert_raises_rpc_error(-26, f"too-long-mempool-chain, exceeds descendant size limit for tx {tx_v3_parent_large1['txid']}", node.sendrawtransaction, tx_v3_child_large1["hex"]) self.check_mempool([tx_v3_parent_large1["txid"]]) assert_equal(node.getmempoolentry(tx_v3_parent_large1["txid"])["descendantcount"], 1) self.generate(node, 1) self.log.info("Test that a decreased limitancestorsize also applies to v3 parent") - self.restart_node(0, extra_args=["-limitancestorsize=10", "-datacarriersize=40000", "-acceptnonstdtxn=1"]) - tx_v3_parent_large2 = self.wallet.send_self_transfer(from_node=node, target_weight=99900, version=3) - tx_v3_child_large2 = self.wallet.create_self_transfer(utxo_to_spend=tx_v3_parent_large2["new_utxo"], version=3) - # Child is within v3 limits + self.restart_node(0, extra_args=["-limitancestorsize=10", "-datacarriersize=40000"]) + tx_v3_parent_large2 = self.wallet.send_self_transfer( + from_node=node, + target_weight=parent_target_weight, + version=3 + ) + tx_v3_child_large2 = self.wallet.create_self_transfer( + utxo_to_spend=tx_v3_parent_large2["new_utxo"], + target_weight=child_target_weight, + version=3 + ) + + # Parent and child are within v3 limits + assert_greater_than_or_equal(V3_MAX_VSIZE, tx_v3_parent_large2["tx"].get_vsize()) assert_greater_than_or_equal(1000, tx_v3_child_large2["tx"].get_vsize()) + assert_greater_than(tx_v3_parent_large2["tx"].get_vsize() + tx_v3_child_large2["tx"].get_vsize(), 10000) + assert_raises_rpc_error(-26, f"too-long-mempool-chain, exceeds ancestor size limit", node.sendrawtransaction, tx_v3_child_large2["hex"]) self.check_mempool([tx_v3_parent_large2["txid"]]) - @cleanup(extra_args=["-datacarriersize=1000", "-acceptnonstdtxn=1"]) + @cleanup(extra_args=["-datacarriersize=1000"]) def test_v3_ancestors_package(self): self.log.info("Test that v3 ancestor limits are checked within the package") node = self.nodes[0] @@ -262,7 +304,7 @@ class MempoolAcceptV3(BitcoinTestFramework): result = node.testmempoolaccept([tx_v3_parent["hex"], tx_v3_child["hex"], tx_v3_grandchild["hex"]]) assert all([txresult["package-error"] == f"v3-violation, tx {tx_v3_grandchild['txid']} (wtxid={tx_v3_grandchild['wtxid']}) would have too many ancestors" for txresult in result]) - @cleanup(extra_args=["-acceptnonstdtxn=1"]) + @cleanup(extra_args=None) def test_v3_ancestors_package_and_mempool(self): """ A v3 transaction in a package cannot have 2 v3 parents. @@ -292,7 +334,7 @@ class MempoolAcceptV3(BitcoinTestFramework): assert_equal(result['package_msg'], f"v3-violation, tx {tx_child_violator['txid']} (wtxid={tx_child_violator['wtxid']}) would have too many ancestors") self.check_mempool([tx_in_mempool["txid"]]) - @cleanup(extra_args=["-acceptnonstdtxn=1"]) + @cleanup(extra_args=None) def test_sibling_eviction_package(self): """ When a transaction has a mempool sibling, it may be eligible for sibling eviction. @@ -368,7 +410,7 @@ class MempoolAcceptV3(BitcoinTestFramework): assert_equal(result_package_cpfp["tx-results"][tx_sibling_3['wtxid']]['error'], expected_error_cpfp) - @cleanup(extra_args=["-datacarriersize=1000", "-acceptnonstdtxn=1"]) + @cleanup(extra_args=["-datacarriersize=1000"]) def test_v3_package_inheritance(self): self.log.info("Test that v3 inheritance is checked within package") node = self.nodes[0] @@ -387,7 +429,7 @@ class MempoolAcceptV3(BitcoinTestFramework): assert_equal(result['package_msg'], f"v3-violation, non-v3 tx {tx_v2_child['txid']} (wtxid={tx_v2_child['wtxid']}) cannot spend from v3 tx {tx_v3_parent['txid']} (wtxid={tx_v3_parent['wtxid']})") self.check_mempool([]) - @cleanup(extra_args=["-acceptnonstdtxn=1"]) + @cleanup(extra_args=None) def test_v3_in_testmempoolaccept(self): node = self.nodes[0] @@ -437,7 +479,7 @@ class MempoolAcceptV3(BitcoinTestFramework): test_accept_2children_with_in_mempool_parent = node.testmempoolaccept([tx_v3_child_1["hex"], tx_v3_child_2["hex"]]) assert all([result["package-error"] == expected_error_extra for result in test_accept_2children_with_in_mempool_parent]) - @cleanup(extra_args=["-acceptnonstdtxn=1"]) + @cleanup(extra_args=None) def test_reorg_2child_rbf(self): node = self.nodes[0] self.log.info("Test that children of a v3 transaction can be replaced individually, even if there are multiple due to reorg") @@ -468,7 +510,7 @@ class MempoolAcceptV3(BitcoinTestFramework): self.check_mempool([ancestor_tx["txid"], child_1_conflict["txid"], child_2["txid"]]) assert_equal(node.getmempoolentry(ancestor_tx["txid"])["descendantcount"], 3) - @cleanup(extra_args=["-acceptnonstdtxn=1"]) + @cleanup(extra_args=None) def test_v3_sibling_eviction(self): self.log.info("Test sibling eviction for v3") node = self.nodes[0] @@ -541,7 +583,7 @@ class MempoolAcceptV3(BitcoinTestFramework): node.sendrawtransaction(tx_v3_child_3["hex"]) self.check_mempool(txids_v2_100 + [tx_v3_parent["txid"], tx_v3_child_3["txid"]]) - @cleanup(extra_args=["-acceptnonstdtxn=1"]) + @cleanup(extra_args=None) def test_reorg_sibling_eviction_1p2c(self): node = self.nodes[0] self.log.info("Test that sibling eviction is not allowed when multiple siblings exist") @@ -585,6 +627,7 @@ class MempoolAcceptV3(BitcoinTestFramework): node = self.nodes[0] self.wallet = MiniWallet(node) self.generate(self.wallet, 120) + self.test_v3_max_vsize() self.test_v3_acceptance() self.test_v3_replacement() self.test_v3_bip125() diff --git a/test/functional/mempool_limit.py b/test/functional/mempool_limit.py index e8a568f7ab..49a0a32c45 100755 --- a/test/functional/mempool_limit.py +++ b/test/functional/mempool_limit.py @@ -6,6 +6,9 @@ from decimal import Decimal +from test_framework.mempool_util import ( + fill_mempool, +) from test_framework.p2p import P2PTxInvStore from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( @@ -13,7 +16,6 @@ from test_framework.util import ( assert_fee_amount, assert_greater_than, assert_raises_rpc_error, - fill_mempool, ) from test_framework.wallet import ( COIN, @@ -57,7 +59,7 @@ class MempoolLimitTest(BitcoinTestFramework): mempoolmin_feerate = node.getmempoolinfo()["mempoolminfee"] tx_A = self.wallet.send_self_transfer( from_node=node, - fee=(mempoolmin_feerate / 1000) * (A_weight // 4) + Decimal('0.000001'), + fee_rate=mempoolmin_feerate, target_weight=A_weight, utxo_to_spend=rbf_utxo, confirmed_only=True @@ -75,7 +77,7 @@ class MempoolLimitTest(BitcoinTestFramework): non_cpfp_carveout_weight = 40001 # EXTRA_DESCENDANT_TX_SIZE_LIMIT + 1 tx_C = self.wallet.create_self_transfer( target_weight=non_cpfp_carveout_weight, - fee = (mempoolmin_feerate / 1000) * (non_cpfp_carveout_weight // 4) + Decimal('0.000001'), + fee_rate=mempoolmin_feerate, utxo_to_spend=tx_B["new_utxo"], confirmed_only=True ) @@ -93,7 +95,7 @@ class MempoolLimitTest(BitcoinTestFramework): assert_equal(node.getmempoolinfo()['minrelaytxfee'], Decimal('0.00001000')) assert_equal(node.getmempoolinfo()['mempoolminfee'], Decimal('0.00001000')) - fill_mempool(self, node, self.wallet) + fill_mempool(self, node) current_info = node.getmempoolinfo() mempoolmin_feerate = current_info["mempoolminfee"] @@ -107,7 +109,7 @@ class MempoolLimitTest(BitcoinTestFramework): # happen in the middle of package evaluation, as it can invalidate the coins cache. mempool_evicted_tx = self.wallet.send_self_transfer( from_node=node, - fee=(mempoolmin_feerate / 1000) * (evicted_weight // 4) + Decimal('0.000001'), + fee_rate=mempoolmin_feerate, target_weight=evicted_weight, confirmed_only=True ) @@ -133,11 +135,11 @@ class MempoolLimitTest(BitcoinTestFramework): parent_weight = 100000 num_big_parents = 3 assert_greater_than(parent_weight * num_big_parents, current_info["maxmempool"] - current_info["bytes"]) - parent_fee = (100 * mempoolmin_feerate / 1000) * (parent_weight // 4) + parent_feerate = 100 * mempoolmin_feerate big_parent_txids = [] for i in range(num_big_parents): - parent = self.wallet.create_self_transfer(fee=parent_fee, target_weight=parent_weight, confirmed_only=True) + parent = self.wallet.create_self_transfer(fee_rate=parent_feerate, target_weight=parent_weight, confirmed_only=True) parent_utxos.append(parent["new_utxo"]) package_hex.append(parent["hex"]) big_parent_txids.append(parent["txid"]) @@ -183,7 +185,7 @@ class MempoolLimitTest(BitcoinTestFramework): assert_equal(node.getmempoolinfo()['minrelaytxfee'], Decimal('0.00001000')) assert_equal(node.getmempoolinfo()['mempoolminfee'], Decimal('0.00001000')) - fill_mempool(self, node, self.wallet) + fill_mempool(self, node) current_info = node.getmempoolinfo() mempoolmin_feerate = current_info["mempoolminfee"] @@ -257,7 +259,7 @@ class MempoolLimitTest(BitcoinTestFramework): assert_equal(node.getmempoolinfo()['minrelaytxfee'], Decimal('0.00001000')) assert_equal(node.getmempoolinfo()['mempoolminfee'], Decimal('0.00001000')) - fill_mempool(self, node, self.wallet) + fill_mempool(self, node) # Deliberately try to create a tx with a fee less than the minimum mempool fee to assert that it does not get added to the mempool self.log.info('Create a mempool tx that will not pass mempoolminfee') @@ -312,18 +314,20 @@ class MempoolLimitTest(BitcoinTestFramework): target_weight_each = 200000 assert_greater_than(target_weight_each * 2, node.getmempoolinfo()["maxmempool"] - node.getmempoolinfo()["bytes"]) # Should be a true CPFP: parent's feerate is just below mempool min feerate - parent_fee = (mempoolmin_feerate / 1000) * (target_weight_each // 4) - Decimal("0.00001") + parent_feerate = mempoolmin_feerate - Decimal("0.000001") # 0.1 sats/vbyte below min feerate # Parent + child is above mempool minimum feerate - child_fee = (worst_feerate_btcvb) * (target_weight_each // 4) - Decimal("0.00001") + child_feerate = (worst_feerate_btcvb * 1000) - Decimal("0.000001") # 0.1 sats/vbyte below worst feerate # However, when eviction is triggered, these transactions should be at the bottom. # This assertion assumes parent and child are the same size. miniwallet.rescan_utxos() - tx_parent_just_below = miniwallet.create_self_transfer(fee=parent_fee, target_weight=target_weight_each) - tx_child_just_above = miniwallet.create_self_transfer(utxo_to_spend=tx_parent_just_below["new_utxo"], fee=child_fee, target_weight=target_weight_each) + tx_parent_just_below = miniwallet.create_self_transfer(fee_rate=parent_feerate, target_weight=target_weight_each) + tx_child_just_above = miniwallet.create_self_transfer(utxo_to_spend=tx_parent_just_below["new_utxo"], fee_rate=child_feerate, target_weight=target_weight_each) # This package ranks below the lowest descendant package in the mempool - assert_greater_than(worst_feerate_btcvb, (parent_fee + child_fee) / (tx_parent_just_below["tx"].get_vsize() + tx_child_just_above["tx"].get_vsize())) - assert_greater_than(mempoolmin_feerate, (parent_fee) / (tx_parent_just_below["tx"].get_vsize())) - assert_greater_than((parent_fee + child_fee) / (tx_parent_just_below["tx"].get_vsize() + tx_child_just_above["tx"].get_vsize()), mempoolmin_feerate / 1000) + package_fee = tx_parent_just_below["fee"] + tx_child_just_above["fee"] + package_vsize = tx_parent_just_below["tx"].get_vsize() + tx_child_just_above["tx"].get_vsize() + assert_greater_than(worst_feerate_btcvb, package_fee / package_vsize) + assert_greater_than(mempoolmin_feerate, tx_parent_just_below["fee"] / (tx_parent_just_below["tx"].get_vsize())) + assert_greater_than(package_fee / package_vsize, mempoolmin_feerate / 1000) res = node.submitpackage([tx_parent_just_below["hex"], tx_child_just_above["hex"]]) for wtxid in [tx_parent_just_below["wtxid"], tx_child_just_above["wtxid"]]: assert_equal(res["tx-results"][wtxid]["error"], "mempool full") diff --git a/test/functional/mempool_package_onemore.py b/test/functional/mempool_package_onemore.py index 921c190668..632425814a 100755 --- a/test/functional/mempool_package_onemore.py +++ b/test/functional/mempool_package_onemore.py @@ -21,7 +21,6 @@ from test_framework.wallet import MiniWallet class MempoolPackagesTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 - self.extra_args = [["-maxorphantx=1000"]] def chain_tx(self, utxos_to_spend, *, num_outputs=1): return self.wallet.send_self_transfer_multi( @@ -41,28 +40,37 @@ class MempoolPackagesTest(BitcoinTestFramework): for _ in range(DEFAULT_ANCESTOR_LIMIT - 4): utxo, = self.chain_tx([utxo]) chain.append(utxo) - second_chain, = self.chain_tx([self.wallet.get_utxo()]) + second_chain, = self.chain_tx([self.wallet.get_utxo(confirmed_only=True)]) # Check mempool has DEFAULT_ANCESTOR_LIMIT + 1 transactions in it assert_equal(len(self.nodes[0].getrawmempool()), DEFAULT_ANCESTOR_LIMIT + 1) # Adding one more transaction on to the chain should fail. assert_raises_rpc_error(-26, "too-long-mempool-chain, too many unconfirmed ancestors [limit: 25]", self.chain_tx, [utxo]) - # ...even if it chains on from some point in the middle of the chain. + # ... or if it chains on from some point in the middle of the chain. assert_raises_rpc_error(-26, "too-long-mempool-chain, too many descendants", self.chain_tx, [chain[2]]) assert_raises_rpc_error(-26, "too-long-mempool-chain, too many descendants", self.chain_tx, [chain[1]]) # ...even if it chains on to two parent transactions with one in the chain. assert_raises_rpc_error(-26, "too-long-mempool-chain, too many descendants", self.chain_tx, [chain[0], second_chain]) # ...especially if its > 40k weight assert_raises_rpc_error(-26, "too-long-mempool-chain, too many descendants", self.chain_tx, [chain[0]], num_outputs=350) + # ...even if it's submitted with other transactions + replaceable_tx = self.wallet.create_self_transfer_multi(utxos_to_spend=[chain[0]]) + txns = [replaceable_tx["tx"], self.wallet.create_self_transfer_multi(utxos_to_spend=replaceable_tx["new_utxos"])["tx"]] + txns_hex = [tx.serialize().hex() for tx in txns] + assert_equal(self.nodes[0].testmempoolaccept(txns_hex)[0]["reject-reason"], "too-long-mempool-chain") + pkg_result = self.nodes[0].submitpackage(txns_hex) + assert "too-long-mempool-chain" in pkg_result["tx-results"][txns[0].getwtxid()]["error"] + assert_equal(pkg_result["tx-results"][txns[1].getwtxid()]["error"], "bad-txns-inputs-missingorspent") # But not if it chains directly off the first transaction - replacable_tx = self.wallet.send_self_transfer_multi(from_node=self.nodes[0], utxos_to_spend=[chain[0]])['tx'] + self.nodes[0].sendrawtransaction(replaceable_tx["hex"]) # and the second chain should work just fine self.chain_tx([second_chain]) - # Make sure we can RBF the chain which used our carve-out rule - replacable_tx.vout[0].nValue -= 1000000 - self.nodes[0].sendrawtransaction(replacable_tx.serialize().hex()) + # Ensure an individual transaction with single direct conflict can RBF the chain which used our carve-out rule + replacement_tx = replaceable_tx["tx"] + replacement_tx.vout[0].nValue -= 1000000 + self.nodes[0].sendrawtransaction(replacement_tx.serialize().hex()) # Finally, check that we added two transactions assert_equal(len(self.nodes[0].getrawmempool()), DEFAULT_ANCESTOR_LIMIT + 3) diff --git a/test/functional/mempool_package_rbf.py b/test/functional/mempool_package_rbf.py new file mode 100755 index 0000000000..ceb9530394 --- /dev/null +++ b/test/functional/mempool_package_rbf.py @@ -0,0 +1,587 @@ +#!/usr/bin/env python3 +# Copyright (c) 2021 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from decimal import Decimal + +from test_framework.messages import ( + COIN, + MAX_BIP125_RBF_SEQUENCE, +) +from test_framework.test_framework import BitcoinTestFramework +from test_framework.mempool_util import fill_mempool +from test_framework.util import ( + assert_greater_than_or_equal, + assert_equal, +) +from test_framework.wallet import ( + DEFAULT_FEE, + MiniWallet, +) + +MAX_REPLACEMENT_CANDIDATES = 100 + +# Value high enough to cause evictions in each subtest +# for typical cases +DEFAULT_CHILD_FEE = DEFAULT_FEE * 4 + +class PackageRBFTest(BitcoinTestFramework): + def set_test_params(self): + self.num_nodes = 2 + self.setup_clean_chain = True + # Required for fill_mempool() + self.extra_args = [[ + "-datacarriersize=100000", + "-maxmempool=5", + ]] * self.num_nodes + + def assert_mempool_contents(self, expected=None): + """Assert that all transactions in expected are in the mempool, + and no additional ones exist. + """ + if not expected: + expected = [] + mempool = self.nodes[0].getrawmempool(verbose=False) + assert_equal(len(mempool), len(expected)) + for tx in expected: + assert tx.rehash() in mempool + + def create_simple_package(self, parent_coin, parent_fee=DEFAULT_FEE, child_fee=DEFAULT_CHILD_FEE, heavy_child=False): + """Create a 1 parent 1 child package using the coin passed in as the parent's input. The + parent has 1 output, used to fund 1 child transaction. + All transactions signal BIP125 replaceability, but nSequence changes based on self.ctr. This + prevents identical txids between packages when the parents spend the same coin and have the + same fee (i.e. 0sat). + + returns tuple (hex serialized txns, CTransaction objects) + """ + self.ctr += 1 + # Use fee_rate=0 because create_self_transfer will use the default fee_rate value otherwise. + # Passing in fee>0 overrides fee_rate, so this still works for non-zero parent_fee. + parent_result = self.wallet.create_self_transfer( + fee=parent_fee, + utxo_to_spend=parent_coin, + sequence=MAX_BIP125_RBF_SEQUENCE - self.ctr, + ) + + num_child_outputs = 10 if heavy_child else 1 + child_result = self.wallet.create_self_transfer_multi( + utxos_to_spend=[parent_result["new_utxo"]], + num_outputs=num_child_outputs, + fee_per_output=int(child_fee * COIN // num_child_outputs), + sequence=MAX_BIP125_RBF_SEQUENCE - self.ctr, + ) + package_hex = [parent_result["hex"], child_result["hex"]] + package_txns = [parent_result["tx"], child_result["tx"]] + return package_hex, package_txns + + def run_test(self): + # Counter used to count the number of times we constructed packages. Since we're constructing parent transactions with the same + # coins (to create conflicts), and perhaps giving them the same fee, we might accidentally just create the same transaction again. + # To prevent this, set nSequences to MAX_BIP125_RBF_SEQUENCE - self.ctr. + self.ctr = 0 + + self.log.info("Generate blocks to create UTXOs") + self.wallet = MiniWallet(self.nodes[0]) + + # Make more than enough coins for the sum of all tests, + # otherwise a wallet rescan is needed later + self.generate(self.wallet, 300) + self.coins = self.wallet.get_utxos(mark_as_spent=False) + + self.test_package_rbf_basic() + self.test_package_rbf_singleton() + self.test_package_rbf_additional_fees() + self.test_package_rbf_max_conflicts() + self.test_too_numerous_ancestors() + self.test_package_rbf_with_wrong_pkg_size() + self.test_insufficient_feerate() + self.test_wrong_conflict_cluster_size_linear() + self.test_wrong_conflict_cluster_size_parents_child() + self.test_wrong_conflict_cluster_size_parent_children() + self.test_0fee_package_rbf() + self.test_child_conflicts_parent_mempool_ancestor() + + def test_package_rbf_basic(self): + self.log.info("Test that a child can pay to replace its parents' conflicts of cluster size 2") + node = self.nodes[0] + # Reuse the same coins so that the transactions conflict with one another. + parent_coin = self.coins.pop() + package_hex1, package_txns1 = self.create_simple_package(parent_coin, DEFAULT_FEE, DEFAULT_FEE) + package_hex2, package_txns2 = self.create_simple_package(parent_coin, DEFAULT_FEE, DEFAULT_CHILD_FEE) + node.submitpackage(package_hex1) + self.assert_mempool_contents(expected=package_txns1) + + # Make sure 2nd node gets set up for basic package RBF + self.sync_all() + + # Test run rejected because conflicts are not allowed in subpackage evaluation + testres = node.testmempoolaccept(package_hex2) + assert_equal(testres[0]["reject-reason"], "bip125-replacement-disallowed") + + # But accepted during normal submission + submitres = node.submitpackage(package_hex2) + assert_equal(set(submitres["replaced-transactions"]), set([tx.rehash() for tx in package_txns1])) + self.assert_mempool_contents(expected=package_txns2) + + # Make sure 2nd node gets a basic package RBF over p2p + self.sync_all() + + self.generate(node, 1) + + def test_package_rbf_singleton(self): + self.log.info("Test child can pay to replace a parent's single conflicted tx") + node = self.nodes[0] + + # Make singleton tx to conflict with in next batch + singleton_coin = self.coins.pop() + singleton_tx = self.wallet.create_self_transfer(utxo_to_spend=singleton_coin) + node.sendrawtransaction(singleton_tx["hex"]) + self.assert_mempool_contents(expected=[singleton_tx["tx"]]) + + package_hex, package_txns = self.create_simple_package(singleton_coin, DEFAULT_FEE, singleton_tx["fee"] * 2) + + submitres = node.submitpackage(package_hex) + assert_equal(submitres["replaced-transactions"], [singleton_tx["tx"].rehash()]) + self.assert_mempool_contents(expected=package_txns) + + self.generate(node, 1) + + def test_package_rbf_additional_fees(self): + self.log.info("Check Package RBF must increase the absolute fee") + node = self.nodes[0] + coin = self.coins.pop() + + package_hex1, package_txns1 = self.create_simple_package(coin, parent_fee=DEFAULT_FEE, child_fee=DEFAULT_CHILD_FEE, heavy_child=True) + assert_greater_than_or_equal(1000, package_txns1[-1].get_vsize()) + node.submitpackage(package_hex1) + self.assert_mempool_contents(expected=package_txns1) + + PACKAGE_FEE = DEFAULT_FEE + DEFAULT_CHILD_FEE + PACKAGE_FEE_MINUS_ONE = PACKAGE_FEE - Decimal("0.00000001") + + # Package 2 has a higher feerate but lower absolute fee + package_hex2, package_txns2 = self.create_simple_package(coin, parent_fee=DEFAULT_FEE, child_fee=DEFAULT_CHILD_FEE - Decimal("0.00000001")) + pkg_results2 = node.submitpackage(package_hex2) + assert_equal(f"package RBF failed: insufficient anti-DoS fees, rejecting replacement {package_txns2[1].rehash()}, less fees than conflicting txs; {PACKAGE_FEE_MINUS_ONE} < {PACKAGE_FEE}", pkg_results2["package_msg"]) + self.assert_mempool_contents(expected=package_txns1) + + self.log.info("Check replacement pays for incremental bandwidth") + package_hex3, package_txns3 = self.create_simple_package(coin, parent_fee=DEFAULT_FEE, child_fee=DEFAULT_CHILD_FEE) + pkg_results3 = node.submitpackage(package_hex3) + assert_equal(f"package RBF failed: insufficient anti-DoS fees, rejecting replacement {package_txns3[1].rehash()}, not enough additional fees to relay; 0.00 < 0.00000{sum([tx.get_vsize() for tx in package_txns3])}", pkg_results3["package_msg"]) + + self.assert_mempool_contents(expected=package_txns1) + self.generate(node, 1) + + self.log.info("Check Package RBF must have strict cpfp structure") + coin = self.coins.pop() + package_hex4, package_txns4 = self.create_simple_package(coin, parent_fee=DEFAULT_FEE, child_fee=DEFAULT_CHILD_FEE) + node.submitpackage(package_hex4) + self.assert_mempool_contents(expected=package_txns4) + package_hex5, package_txns5 = self.create_simple_package(coin, parent_fee=DEFAULT_CHILD_FEE, child_fee=DEFAULT_CHILD_FEE - Decimal("0.00000001")) + pkg_results5 = node.submitpackage(package_hex5) + assert 'package RBF failed: package feerate is less than parent feerate' in pkg_results5["package_msg"] + + self.assert_mempool_contents(expected=package_txns4) + self.generate(node, 1) + + def test_package_rbf_max_conflicts(self): + node = self.nodes[0] + self.log.info("Check Package RBF cannot replace more than MAX_REPLACEMENT_CANDIDATES transactions") + num_coins = 51 + parent_coins = self.coins[:num_coins] + del self.coins[:num_coins] + + # Original transactions: 51 transactions with 1 descendants each -> 102 total transactions + size_two_clusters = [] + for coin in parent_coins: + size_two_clusters.append(self.wallet.send_self_transfer_chain(from_node=node, chain_length=2, utxo_to_spend=coin)) + expected_txns = [txn["tx"] for parent_child_txns in size_two_clusters for txn in parent_child_txns] + assert_equal(len(expected_txns), num_coins * 2) + self.assert_mempool_contents(expected=expected_txns) + + # parent feeerate needs to be high enough for minrelay + # child feerate needs to be large enough to trigger package rbf with a very large parent and + # pay for all evicted fees. maxfeerate turned off for all submissions since child feerate + # is extremely high + parent_fee_per_conflict = 10000 + child_feerate = 10000 * DEFAULT_FEE + + # Conflict against all transactions by double-spending each parent, causing 102 evictions + package_parent = self.wallet.create_self_transfer_multi(utxos_to_spend=parent_coins, fee_per_output=parent_fee_per_conflict) + package_child = self.wallet.create_self_transfer(fee_rate=child_feerate, utxo_to_spend=package_parent["new_utxos"][0]) + + pkg_results = node.submitpackage([package_parent["hex"], package_child["hex"]], maxfeerate=0) + assert_equal(f"package RBF failed: too many potential replacements, rejecting replacement {package_child['tx'].rehash()}; too many potential replacements (102 > 100)\n", pkg_results["package_msg"]) + self.assert_mempool_contents(expected=expected_txns) + + # Make singleton tx to conflict with in next batch + singleton_coin = self.coins.pop() + singleton_tx = self.wallet.create_self_transfer(utxo_to_spend=singleton_coin) + node.sendrawtransaction(singleton_tx["hex"]) + expected_txns.append(singleton_tx["tx"]) + + # Double-spend same set minus last, and double-spend singleton. This hits 101 evictions; should still fail. + # N.B. we can't RBF just a child tx in the clusters, as that would make resulting cluster of size 3. + double_spending_coins = parent_coins[:-1] + [singleton_coin] + package_parent = self.wallet.create_self_transfer_multi(utxos_to_spend=double_spending_coins, fee_per_output=parent_fee_per_conflict) + package_child = self.wallet.create_self_transfer(fee_rate=child_feerate, utxo_to_spend=package_parent["new_utxos"][0]) + pkg_results = node.submitpackage([package_parent["hex"], package_child["hex"]], maxfeerate=0) + assert_equal(f"package RBF failed: too many potential replacements, rejecting replacement {package_child['tx'].rehash()}; too many potential replacements (101 > 100)\n", pkg_results["package_msg"]) + self.assert_mempool_contents(expected=expected_txns) + + # Finally, evict MAX_REPLACEMENT_CANDIDATES + package_parent = self.wallet.create_self_transfer_multi(utxos_to_spend=parent_coins[:-1], fee_per_output=parent_fee_per_conflict) + package_child = self.wallet.create_self_transfer(fee_rate=child_feerate, utxo_to_spend=package_parent["new_utxos"][0]) + pkg_results = node.submitpackage([package_parent["hex"], package_child["hex"]], maxfeerate=0) + assert_equal(pkg_results["package_msg"], "success") + self.assert_mempool_contents(expected=[singleton_tx["tx"], size_two_clusters[-1][0]["tx"], size_two_clusters[-1][1]["tx"], package_parent["tx"], package_child["tx"]] ) + + self.generate(node, 1) + + def test_too_numerous_ancestors(self): + self.log.info("Test that package RBF doesn't work with packages larger than 2 due to ancestors") + node = self.nodes[0] + coin = self.coins.pop() + + package_hex1, package_txns1 = self.create_simple_package(coin, DEFAULT_FEE, DEFAULT_CHILD_FEE) + node.submitpackage(package_hex1) + self.assert_mempool_contents(expected=package_txns1) + + # Double-spends the original package + self.ctr += 1 + parent_result1 = self.wallet.create_self_transfer( + fee=DEFAULT_FEE, + utxo_to_spend=coin, + sequence=MAX_BIP125_RBF_SEQUENCE - self.ctr, + ) + + coin2 = self.coins.pop() + + # Added to make package too large for package RBF; + # it will enter mempool individually + self.ctr += 1 + parent_result2 = self.wallet.create_self_transfer( + fee=DEFAULT_FEE, + utxo_to_spend=coin2, + sequence=MAX_BIP125_RBF_SEQUENCE - self.ctr, + ) + + # Child that spends both, violating cluster size rule due + # to in-mempool ancestry + self.ctr += 1 + child_result = self.wallet.create_self_transfer_multi( + fee_per_output=int(DEFAULT_CHILD_FEE * COIN), + utxos_to_spend=[parent_result1["new_utxo"], parent_result2["new_utxo"]], + sequence=MAX_BIP125_RBF_SEQUENCE - self.ctr, + ) + + package_hex2 = [parent_result1["hex"], parent_result2["hex"], child_result["hex"]] + package_txns2_succeed = [parent_result2["tx"]] + + pkg_result = node.submitpackage(package_hex2) + assert_equal(pkg_result["package_msg"], 'package RBF failed: new transaction cannot have mempool ancestors') + self.assert_mempool_contents(expected=package_txns1 + package_txns2_succeed) + self.generate(node, 1) + + def test_wrong_conflict_cluster_size_linear(self): + self.log.info("Test that conflicting with a cluster not sized two is rejected: linear chain") + node = self.nodes[0] + + # Coins we will conflict with + coin1 = self.coins.pop() + coin2 = self.coins.pop() + coin3 = self.coins.pop() + + # Three transactions chained; package RBF against any of these + # should be rejected + self.ctr += 1 + parent_result = self.wallet.create_self_transfer( + fee=DEFAULT_FEE, + utxo_to_spend=coin1, + sequence=MAX_BIP125_RBF_SEQUENCE - self.ctr, + ) + + self.ctr += 1 + child_result = self.wallet.create_self_transfer_multi( + fee_per_output=int(DEFAULT_FEE * COIN), + utxos_to_spend=[parent_result["new_utxo"], coin2], + sequence=MAX_BIP125_RBF_SEQUENCE - self.ctr, + ) + + self.ctr += 1 + grandchild_result = self.wallet.create_self_transfer_multi( + fee_per_output=int(DEFAULT_FEE * COIN), + utxos_to_spend=[child_result["new_utxos"][0], coin3], + sequence=MAX_BIP125_RBF_SEQUENCE - self.ctr, + ) + + expected_txns = [parent_result["tx"], child_result["tx"], grandchild_result["tx"]] + for tx in expected_txns: + node.sendrawtransaction(tx.serialize().hex()) + self.assert_mempool_contents(expected=expected_txns) + + # Now make conflicting packages for each coin + package_hex1, package_txns1 = self.create_simple_package(coin1, DEFAULT_FEE, DEFAULT_CHILD_FEE) + + package_result = node.submitpackage(package_hex1) + assert_equal(f"package RBF failed: {parent_result['tx'].rehash()} has 2 descendants, max 1 allowed", package_result["package_msg"]) + + package_hex2, package_txns2 = self.create_simple_package(coin2, DEFAULT_FEE, DEFAULT_CHILD_FEE) + package_result = node.submitpackage(package_hex2) + assert_equal(f"package RBF failed: {child_result['tx'].rehash()} has both ancestor and descendant, exceeding cluster limit of 2", package_result["package_msg"]) + + package_hex3, package_txns3 = self.create_simple_package(coin3, DEFAULT_FEE, DEFAULT_CHILD_FEE) + package_result = node.submitpackage(package_hex3) + assert_equal(f"package RBF failed: {grandchild_result['tx'].rehash()} has 2 ancestors, max 1 allowed", package_result["package_msg"]) + + # Check that replacements were actually rejected + self.assert_mempool_contents(expected=expected_txns) + self.generate(node, 1) + + def test_wrong_conflict_cluster_size_parents_child(self): + self.log.info("Test that conflicting with a cluster not sized two is rejected: two parents one child") + node = self.nodes[0] + + # Coins we will conflict with + coin1 = self.coins.pop() + coin2 = self.coins.pop() + coin3 = self.coins.pop() + + self.ctr += 1 + parent1_result = self.wallet.create_self_transfer( + fee=DEFAULT_FEE, + utxo_to_spend=coin1, + sequence=MAX_BIP125_RBF_SEQUENCE - self.ctr, + ) + + self.ctr += 1 + parent2_result = self.wallet.create_self_transfer_multi( + fee_per_output=int(DEFAULT_FEE * COIN), + utxos_to_spend=[coin2], + sequence=MAX_BIP125_RBF_SEQUENCE - self.ctr, + ) + + self.ctr += 1 + child_result = self.wallet.create_self_transfer_multi( + fee_per_output=int(DEFAULT_FEE * COIN), + utxos_to_spend=[parent1_result["new_utxo"], parent2_result["new_utxos"][0], coin3], + sequence=MAX_BIP125_RBF_SEQUENCE - self.ctr, + ) + + expected_txns = [parent1_result["tx"], parent2_result["tx"], child_result["tx"]] + for tx in expected_txns: + node.sendrawtransaction(tx.serialize().hex()) + self.assert_mempool_contents(expected=expected_txns) + + # Now make conflicting packages for each coin + package_hex1, package_txns1 = self.create_simple_package(coin1, DEFAULT_FEE, DEFAULT_CHILD_FEE) + package_result = node.submitpackage(package_hex1) + assert_equal(f"package RBF failed: {parent1_result['tx'].rehash()} is not the only parent of child {child_result['tx'].rehash()}", package_result["package_msg"]) + + package_hex2, package_txns2 = self.create_simple_package(coin2, DEFAULT_FEE, DEFAULT_CHILD_FEE) + package_result = node.submitpackage(package_hex2) + assert_equal(f"package RBF failed: {parent2_result['tx'].rehash()} is not the only parent of child {child_result['tx'].rehash()}", package_result["package_msg"]) + + package_hex3, package_txns3 = self.create_simple_package(coin3, DEFAULT_FEE, DEFAULT_CHILD_FEE) + package_result = node.submitpackage(package_hex3) + assert_equal(f"package RBF failed: {child_result['tx'].rehash()} has 2 ancestors, max 1 allowed", package_result["package_msg"]) + + # Check that replacements were actually rejected + self.assert_mempool_contents(expected=expected_txns) + self.generate(node, 1) + + def test_wrong_conflict_cluster_size_parent_children(self): + self.log.info("Test that conflicting with a cluster not sized two is rejected: one parent two children") + node = self.nodes[0] + + # Coins we will conflict with + coin1 = self.coins.pop() + coin2 = self.coins.pop() + coin3 = self.coins.pop() + + self.ctr += 1 + parent_result = self.wallet.create_self_transfer_multi( + fee_per_output=int(DEFAULT_FEE * COIN), + num_outputs=2, + utxos_to_spend=[coin1], + sequence=MAX_BIP125_RBF_SEQUENCE - self.ctr, + ) + + self.ctr += 1 + child1_result = self.wallet.create_self_transfer_multi( + fee_per_output=int(DEFAULT_FEE * COIN), + utxos_to_spend=[parent_result["new_utxos"][0], coin2], + sequence=MAX_BIP125_RBF_SEQUENCE - self.ctr, + ) + + self.ctr += 1 + child2_result = self.wallet.create_self_transfer_multi( + fee_per_output=int(DEFAULT_FEE * COIN), + utxos_to_spend=[parent_result["new_utxos"][1], coin3], + sequence=MAX_BIP125_RBF_SEQUENCE - self.ctr, + ) + + # Submit them to mempool + expected_txns = [parent_result["tx"], child1_result["tx"], child2_result["tx"]] + for tx in expected_txns: + node.sendrawtransaction(tx.serialize().hex()) + self.assert_mempool_contents(expected=expected_txns) + + # Now make conflicting packages for each coin + package_hex1, package_txns1 = self.create_simple_package(coin1, DEFAULT_FEE, DEFAULT_CHILD_FEE) + package_result = node.submitpackage(package_hex1) + assert_equal(f"package RBF failed: {parent_result['tx'].rehash()} has 2 descendants, max 1 allowed", package_result["package_msg"]) + + package_hex2, package_txns2 = self.create_simple_package(coin2, DEFAULT_FEE, DEFAULT_CHILD_FEE) + package_result = node.submitpackage(package_hex2) + assert_equal(f"package RBF failed: {child1_result['tx'].rehash()} is not the only child of parent {parent_result['tx'].rehash()}", package_result["package_msg"]) + + package_hex3, package_txns3 = self.create_simple_package(coin3, DEFAULT_FEE, DEFAULT_CHILD_FEE) + package_result = node.submitpackage(package_hex3) + assert_equal(f"package RBF failed: {child2_result['tx'].rehash()} is not the only child of parent {parent_result['tx'].rehash()}", package_result["package_msg"]) + + # Check that replacements were actually rejected + self.assert_mempool_contents(expected=expected_txns) + self.generate(node, 1) + + def test_package_rbf_with_wrong_pkg_size(self): + self.log.info("Test that package RBF doesn't work with packages larger than 2 due to pkg size") + node = self.nodes[0] + coin1 = self.coins.pop() + coin2 = self.coins.pop() + + # Two packages to require multiple direct conflicts, easier to set up illicit pkg size + package_hex1, package_txns1 = self.create_simple_package(coin1, DEFAULT_FEE, DEFAULT_CHILD_FEE) + package_hex2, package_txns2 = self.create_simple_package(coin2, DEFAULT_FEE, DEFAULT_CHILD_FEE) + + node.submitpackage(package_hex1) + node.submitpackage(package_hex2) + + self.assert_mempool_contents(expected=package_txns1 + package_txns2) + assert_equal(len(node.getrawmempool()), 4) + + # Double-spends the first package + self.ctr += 1 + parent_result1 = self.wallet.create_self_transfer( + fee=DEFAULT_FEE, + utxo_to_spend=coin1, + sequence=MAX_BIP125_RBF_SEQUENCE - self.ctr, + ) + + # Double-spends the second package + self.ctr += 1 + parent_result2 = self.wallet.create_self_transfer( + fee=DEFAULT_FEE, + utxo_to_spend=coin2, + sequence=MAX_BIP125_RBF_SEQUENCE - self.ctr, + ) + + # Child that spends both, violating cluster size rule due + # to pkg size + self.ctr += 1 + child_result = self.wallet.create_self_transfer_multi( + fee_per_output=int(DEFAULT_CHILD_FEE * COIN), + utxos_to_spend=[parent_result1["new_utxo"], parent_result2["new_utxo"]], + sequence=MAX_BIP125_RBF_SEQUENCE - self.ctr, + ) + + package_hex3 = [parent_result1["hex"], parent_result2["hex"], child_result["hex"]] + + pkg_result = node.submitpackage(package_hex3) + assert_equal(pkg_result["package_msg"], 'package RBF failed: package must be 1-parent-1-child') + self.assert_mempool_contents(expected=package_txns1 + package_txns2) + self.generate(node, 1) + + def test_insufficient_feerate(self): + self.log.info("Check Package RBF must beat feerate of direct conflict") + node = self.nodes[0] + coin = self.coins.pop() + + # Non-cpfp structure + package_hex1, package_txns1 = self.create_simple_package(coin, parent_fee=DEFAULT_CHILD_FEE, child_fee=DEFAULT_FEE) + node.submitpackage(package_hex1) + self.assert_mempool_contents(expected=package_txns1) + + # Package 2 feerate is below the feerate of directly conflicted parent, so it fails even though + # total fees are higher than the original package + package_hex2, package_txns2 = self.create_simple_package(coin, parent_fee=DEFAULT_CHILD_FEE - Decimal("0.00000001"), child_fee=DEFAULT_CHILD_FEE) + pkg_results2 = node.submitpackage(package_hex2) + assert_equal(pkg_results2["package_msg"], 'package RBF failed: insufficient feerate: does not improve feerate diagram') + self.assert_mempool_contents(expected=package_txns1) + self.generate(node, 1) + + def test_0fee_package_rbf(self): + self.log.info("Test package RBF: TRUC 0-fee parent + high-fee child replaces parent's conflicts") + node = self.nodes[0] + # Reuse the same coins so that the transactions conflict with one another. + self.wallet.rescan_utxos() + parent_coin = self.wallet.get_utxo(confirmed_only=True) + + # package1 pays default fee on both transactions + parent1 = self.wallet.create_self_transfer(utxo_to_spend=parent_coin, version=3) + child1 = self.wallet.create_self_transfer(utxo_to_spend=parent1["new_utxo"], version=3) + package_hex1 = [parent1["hex"], child1["hex"]] + fees_package1 = parent1["fee"] + child1["fee"] + submitres1 = node.submitpackage(package_hex1) + assert_equal(submitres1["package_msg"], "success") + self.assert_mempool_contents([parent1["tx"], child1["tx"]]) + + # package2 has a 0-fee parent (conflicting with package1) and very high fee child + parent2 = self.wallet.create_self_transfer(utxo_to_spend=parent_coin, fee=0, fee_rate=0, version=3) + child2 = self.wallet.create_self_transfer(utxo_to_spend=parent2["new_utxo"], fee=fees_package1*10, version=3) + package_hex2 = [parent2["hex"], child2["hex"]] + + submitres2 = node.submitpackage(package_hex2) + assert_equal(submitres2["package_msg"], "success") + assert_equal(set(submitres2["replaced-transactions"]), set([parent1["txid"], child1["txid"]])) + self.assert_mempool_contents([parent2["tx"], child2["tx"]]) + + self.generate(node, 1) + + def test_child_conflicts_parent_mempool_ancestor(self): + fill_mempool(self, self.nodes[0]) + # Reset coins since we filled the mempool with current coins + self.coins = self.wallet.get_utxos(mark_as_spent=False, confirmed_only=True) + + self.log.info("Test that package RBF doesn't have issues with mempool<->package conflicts via inconsistency") + node = self.nodes[0] + coin = self.coins.pop() + + self.ctr += 1 + grandparent_result = self.wallet.create_self_transfer( + fee=DEFAULT_FEE, + utxo_to_spend=coin, + sequence=MAX_BIP125_RBF_SEQUENCE - self.ctr, + ) + + node.sendrawtransaction(grandparent_result["hex"]) + + # Now make package of two descendants that looks + # like a cpfp where the parent can't get in on its own + self.ctr += 1 + parent_result = self.wallet.create_self_transfer( + fee_rate=Decimal('0.00001000'), + utxo_to_spend=grandparent_result["new_utxo"], + sequence=MAX_BIP125_RBF_SEQUENCE - self.ctr, + ) + # Last tx double-spends grandparent's coin, + # which is not inside the current package + self.ctr += 1 + child_result = self.wallet.create_self_transfer_multi( + fee_per_output=int(DEFAULT_CHILD_FEE * COIN), + utxos_to_spend=[parent_result["new_utxo"], coin], + sequence=MAX_BIP125_RBF_SEQUENCE - self.ctr, + ) + + pkg_result = node.submitpackage([parent_result["hex"], child_result["hex"]]) + assert_equal(pkg_result["package_msg"], 'package RBF failed: new transaction cannot have mempool ancestors') + mempool_info = node.getrawmempool() + assert grandparent_result["txid"] in mempool_info + assert parent_result["txid"] not in mempool_info + assert child_result["txid"] not in mempool_info + +if __name__ == "__main__": + PackageRBFTest().main() diff --git a/test/functional/mempool_packages.py b/test/functional/mempool_packages.py index dcb66b2ca1..4be6594de6 100755 --- a/test/functional/mempool_packages.py +++ b/test/functional/mempool_packages.py @@ -31,10 +31,8 @@ class MempoolPackagesTest(BitcoinTestFramework): self.noban_tx_relay = True self.extra_args = [ [ - "-maxorphantx=1000", ], [ - "-maxorphantx=1000", "-limitancestorcount={}".format(CUSTOM_ANCESTOR_LIMIT), "-limitdescendantcount={}".format(CUSTOM_DESCENDANT_LIMIT), ], @@ -199,13 +197,13 @@ class MempoolPackagesTest(BitcoinTestFramework): assert set(mempool1).issubset(set(mempool0)) for tx in chain[:CUSTOM_ANCESTOR_LIMIT]: assert tx in mempool1 - # TODO: more detailed check of node1's mempool (fees etc.) - # check transaction unbroadcast info (should be false if in both mempools) - mempool = self.nodes[0].getrawmempool(True) - for tx in mempool: - assert_equal(mempool[tx]['unbroadcast'], False) - - # TODO: test ancestor size limits + entry0 = self.nodes[0].getmempoolentry(tx) + entry1 = self.nodes[1].getmempoolentry(tx) + assert not entry0['unbroadcast'] + assert not entry1['unbroadcast'] + assert_equal(entry1['fees']['base'], entry0['fees']['base']) + assert_equal(entry1['vsize'], entry0['vsize']) + assert_equal(entry1['depends'], entry0['depends']) # Now test descendant chain limits @@ -251,10 +249,14 @@ class MempoolPackagesTest(BitcoinTestFramework): assert tx in mempool1 for tx in chain[CUSTOM_DESCENDANT_LIMIT:]: assert tx not in mempool1 - # TODO: more detailed check of node1's mempool (fees etc.) - - # TODO: test descendant size limits - + for tx in mempool1: + entry0 = self.nodes[0].getmempoolentry(tx) + entry1 = self.nodes[1].getmempoolentry(tx) + assert not entry0['unbroadcast'] + assert not entry1['unbroadcast'] + assert_equal(entry1['fees']['base'], entry0['fees']['base']) + assert_equal(entry1['vsize'], entry0['vsize']) + assert_equal(entry1['depends'], entry0['depends']) # Test reorg handling # First, the basics: self.generate(self.nodes[0], 1) diff --git a/test/functional/p2p_1p1c_network.py b/test/functional/p2p_1p1c_network.py index e88c826962..ea59248506 100755 --- a/test/functional/p2p_1p1c_network.py +++ b/test/functional/p2p_1p1c_network.py @@ -12,6 +12,9 @@ too-low-feerate transactions). The packages should be received and accepted by a from decimal import Decimal from math import ceil +from test_framework.mempool_util import ( + fill_mempool, +) from test_framework.messages import ( msg_tx, ) @@ -22,7 +25,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, assert_greater_than, - fill_mempool, ) from test_framework.wallet import ( MiniWallet, @@ -45,8 +47,7 @@ class PackageRelayTest(BitcoinTestFramework): self.supports_cli = False def raise_network_minfee(self): - filler_wallet = MiniWallet(self.nodes[0]) - fill_mempool(self, self.nodes[0], filler_wallet) + fill_mempool(self, self.nodes[0]) self.log.debug("Wait for the network to sync mempools") self.sync_mempools() diff --git a/test/functional/p2p_addr_relay.py b/test/functional/p2p_addr_relay.py index b23ec1028b..d10e47e036 100755 --- a/test/functional/p2p_addr_relay.py +++ b/test/functional/p2p_addr_relay.py @@ -142,7 +142,8 @@ class AddrTest(BitcoinTestFramework): msg = self.setup_addr_msg(1010) with self.nodes[0].assert_debug_log(['addr message size = 1010']): - addr_source.send_and_ping(msg) + addr_source.send_message(msg) + addr_source.wait_for_disconnect() self.nodes[0].disconnect_p2ps() diff --git a/test/functional/p2p_addrv2_relay.py b/test/functional/p2p_addrv2_relay.py index ea114e7d70..4ec8e0bc04 100755 --- a/test/functional/p2p_addrv2_relay.py +++ b/test/functional/p2p_addrv2_relay.py @@ -86,11 +86,6 @@ class AddrTest(BitcoinTestFramework): addr_source = self.nodes[0].add_p2p_connection(P2PInterface()) msg = msg_addrv2() - self.log.info('Send too-large addrv2 message') - msg.addrs = ADDRS * 101 - with self.nodes[0].assert_debug_log(['addrv2 message size = 1010']): - addr_source.send_and_ping(msg) - self.log.info('Check that addrv2 message content is relayed and added to addrman') addr_receiver = self.nodes[0].add_p2p_connection(AddrReceiver()) msg.addrs = ADDRS @@ -106,6 +101,13 @@ class AddrTest(BitcoinTestFramework): assert addr_receiver.addrv2_received_and_checked assert_equal(len(self.nodes[0].getnodeaddresses(count=0, network="i2p")), 0) + self.log.info('Send too-large addrv2 message') + msg.addrs = ADDRS * 101 + with self.nodes[0].assert_debug_log(['addrv2 message size = 1010']): + addr_source.send_message(msg) + addr_source.wait_for_disconnect() + + if __name__ == '__main__': AddrTest().main() diff --git a/test/functional/p2p_disconnect_ban.py b/test/functional/p2p_disconnect_ban.py index 678b006886..e47f9c732b 100755 --- a/test/functional/p2p_disconnect_ban.py +++ b/test/functional/p2p_disconnect_ban.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2022 The Bitcoin Core developers +# Copyright (c) 2014-present The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test node disconnect and ban behavior""" @@ -18,7 +18,7 @@ class DisconnectBanTest(BitcoinTestFramework): self.supports_cli = False def run_test(self): - self.log.info("Connect nodes both way") + self.log.info("Connect nodes both ways") # By default, the test framework sets up an addnode connection from # node 1 --> node0. By connecting node0 --> node 1, we're left with # the two nodes being connected both ways. @@ -84,7 +84,7 @@ class DisconnectBanTest(BitcoinTestFramework): assert_equal("192.168.0.1/32", listBeforeShutdown[2]['address']) self.log.info("setban: test banning with absolute timestamp") - self.nodes[1].setban("192.168.0.2", "add", old_time + 120, True) + self.nodes[1].setban("192.168.0.2", "add", old_time + 120, absolute=True) # Move time forward by 3 seconds so the fourth ban has expired self.nodes[1].setmocktime(old_time + 3) @@ -102,7 +102,9 @@ class DisconnectBanTest(BitcoinTestFramework): assert_equal(ban["ban_duration"], 120) assert_equal(ban["time_remaining"], 117) - self.restart_node(1) + # Keep mocktime, to avoid ban expiry when restart takes longer than + # time_remaining + self.restart_node(1, extra_args=[f"-mocktime={old_time+4}"]) listAfterShutdown = self.nodes[1].listbanned() assert_equal("127.0.0.0/24", listAfterShutdown[0]['address']) @@ -113,7 +115,7 @@ class DisconnectBanTest(BitcoinTestFramework): # Clear ban lists self.nodes[1].clearbanned() - self.log.info("Connect nodes both way") + self.log.info("Connect nodes both ways") self.connect_nodes(0, 1) self.connect_nodes(1, 0) diff --git a/test/functional/p2p_invalid_messages.py b/test/functional/p2p_invalid_messages.py index 40a69936bc..8e459ba676 100755 --- a/test/functional/p2p_invalid_messages.py +++ b/test/functional/p2p_invalid_messages.py @@ -5,7 +5,6 @@ """Test node responses to invalid network messages.""" import random -import struct import time from test_framework.messages import ( @@ -233,7 +232,7 @@ class InvalidMessagesTest(BitcoinTestFramework): '208d')) # port def test_addrv2_unrecognized_network(self): - now_hex = struct.pack('<I', int(time.time())).hex() + now_hex = int(time.time()).to_bytes(4, "little").hex() self.test_addrv2('unrecognized network', [ 'received: addrv2 (25 bytes)', @@ -261,7 +260,9 @@ class InvalidMessagesTest(BitcoinTestFramework): msg_type = msg.msgtype.decode('ascii') self.log.info("Test {} message of size {} is logged as misbehaving".format(msg_type, size)) with self.nodes[0].assert_debug_log(['Misbehaving', '{} message size = {}'.format(msg_type, size)]): - self.nodes[0].add_p2p_connection(P2PInterface()).send_and_ping(msg) + conn = self.nodes[0].add_p2p_connection(P2PInterface()) + conn.send_message(msg) + conn.wait_for_disconnect() self.nodes[0].disconnect_p2ps() def test_oversized_inv_msg(self): @@ -322,7 +323,8 @@ class InvalidMessagesTest(BitcoinTestFramework): # delete arbitrary block header somewhere in the middle to break link del block_headers[random.randrange(1, len(block_headers)-1)] with self.nodes[0].assert_debug_log(expected_msgs=MISBEHAVING_NONCONTINUOUS_HEADERS_MSGS): - peer.send_and_ping(msg_headers(block_headers)) + peer.send_message(msg_headers(block_headers)) + peer.wait_for_disconnect() self.nodes[0].disconnect_p2ps() def test_resource_exhaustion(self): diff --git a/test/functional/p2p_invalid_tx.py b/test/functional/p2p_invalid_tx.py index ae9dc816ab..0ae05d4b0b 100755 --- a/test/functional/p2p_invalid_tx.py +++ b/test/functional/p2p_invalid_tx.py @@ -165,7 +165,7 @@ class InvalidTxRequestTest(BitcoinTestFramework): node.p2ps[0].send_txs_and_test([rejected_parent], node, success=False) self.log.info('Test that a peer disconnection causes erase its transactions from the orphan pool') - with node.assert_debug_log(['Erased 100 orphan tx from peer=25']): + with node.assert_debug_log(['Erased 100 orphan transaction(s) from peer=25']): self.reconnect_p2p(num_connections=1) self.log.info('Test that a transaction in the orphan pool is included in a new tip block causes erase this transaction from the orphan pool') @@ -190,7 +190,7 @@ class InvalidTxRequestTest(BitcoinTestFramework): block_A.solve() self.log.info('Send the block that includes the previous orphan ... ') - with node.assert_debug_log(["Erased 1 orphan tx included or conflicted by block"]): + with node.assert_debug_log(["Erased 1 orphan transaction(s) included or conflicted by block"]): node.p2ps[0].send_blocks_and_test([block_A], node, success=True) self.log.info('Test that a transaction in the orphan pool conflicts with a new tip block causes erase this transaction from the orphan pool') @@ -219,7 +219,7 @@ class InvalidTxRequestTest(BitcoinTestFramework): block_B.solve() self.log.info('Send the block that includes a transaction which conflicts with the previous orphan ... ') - with node.assert_debug_log(["Erased 1 orphan tx included or conflicted by block"]): + with node.assert_debug_log(["Erased 1 orphan transaction(s) included or conflicted by block"]): node.p2ps[0].send_blocks_and_test([block_B], node, success=True) diff --git a/test/functional/p2p_mutated_blocks.py b/test/functional/p2p_mutated_blocks.py index 737edaf5bf..708b19b1e5 100755 --- a/test/functional/p2p_mutated_blocks.py +++ b/test/functional/p2p_mutated_blocks.py @@ -55,7 +55,7 @@ class MutatedBlocksTest(BitcoinTestFramework): # Create mutated version of the block by changing the transaction # version on the self-transfer. mutated_block = copy.deepcopy(block) - mutated_block.vtx[1].nVersion = 4 + mutated_block.vtx[1].version = 4 # Announce the new block via a compact block through the honest relayer cmpctblock = HeaderAndShortIDs() @@ -104,11 +104,10 @@ class MutatedBlocksTest(BitcoinTestFramework): block_missing_prev.hashPrevBlock = 123 block_missing_prev.solve() - # Attacker gets a DoS score of 10, not immediately disconnected, so we do it 10 times to get to 100 - for _ in range(10): - assert_equal(len(self.nodes[0].getpeerinfo()), 2) - with self.nodes[0].assert_debug_log(expected_msgs=["AcceptBlock FAILED (prev-blk-not-found)"]): - attacker.send_message(msg_block(block_missing_prev)) + # Check that non-connecting block causes disconnect + assert_equal(len(self.nodes[0].getpeerinfo()), 2) + with self.nodes[0].assert_debug_log(expected_msgs=["AcceptBlock FAILED (prev-blk-not-found)"]): + attacker.send_message(msg_block(block_missing_prev)) attacker.wait_for_disconnect(timeout=5) diff --git a/test/functional/p2p_opportunistic_1p1c.py b/test/functional/p2p_opportunistic_1p1c.py index e07acd5481..aec6e95fbc 100755 --- a/test/functional/p2p_opportunistic_1p1c.py +++ b/test/functional/p2p_opportunistic_1p1c.py @@ -8,6 +8,9 @@ Test opportunistic 1p1c package submission logic. from decimal import Decimal import time +from test_framework.mempool_util import ( + fill_mempool, +) from test_framework.messages import ( CInv, CTxInWitness, @@ -24,7 +27,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, assert_greater_than, - fill_mempool, ) from test_framework.wallet import ( MiniWallet, @@ -386,8 +388,7 @@ class PackageRelayTest(BitcoinTestFramework): self.generate(self.wallet_nonsegwit, 10) self.generate(self.wallet, 20) - filler_wallet = MiniWallet(node) - fill_mempool(self, node, filler_wallet) + fill_mempool(self, node) self.log.info("Check opportunistic 1p1c logic when parent (txid != wtxid) is received before child") self.test_basic_parent_then_child(self.wallet) diff --git a/test/functional/p2p_orphan_handling.py b/test/functional/p2p_orphan_handling.py index 6166c62aa2..f525d87cca 100755 --- a/test/functional/p2p_orphan_handling.py +++ b/test/functional/p2p_orphan_handling.py @@ -7,6 +7,7 @@ import time from test_framework.messages import ( CInv, + CTxInWitness, MSG_TX, MSG_WITNESS_TX, MSG_WTX, @@ -21,6 +22,7 @@ from test_framework.p2p import ( NONPREF_PEER_TX_DELAY, OVERLOADED_PEER_TX_DELAY, p2p_lock, + P2PInterface, P2PTxInvStore, TXID_RELAY_DELAY, ) @@ -127,6 +129,22 @@ class OrphanHandlingTest(BitcoinTestFramework): peer.wait_for_getdata([wtxid]) peer.send_and_ping(msg_tx(tx)) + def create_malleated_version(self, tx): + """ + Create a malleated version of the tx where the witness is replaced with garbage data. + Returns a CTransaction object. + """ + tx_bad_wit = tx_from_hex(tx["hex"]) + tx_bad_wit.wit.vtxinwit = [CTxInWitness()] + # Add garbage data to witness 0. We cannot simply strip the witness, as the node would + # classify it as a transaction in which the witness was missing rather than wrong. + tx_bad_wit.wit.vtxinwit[0].scriptWitness.stack = [b'garbage'] + + assert_equal(tx["txid"], tx_bad_wit.rehash()) + assert tx["wtxid"] != tx_bad_wit.getwtxid() + + return tx_bad_wit + @cleanup def test_arrival_timing_orphan(self): self.log.info("Test missing parents that arrive during delay are not requested") @@ -284,8 +302,8 @@ class OrphanHandlingTest(BitcoinTestFramework): # doesn't give up on the orphan. Once all of the missing parents are received, it should be # submitted to mempool. peer.send_message(msg_notfound(vec=[CInv(MSG_WITNESS_TX, int(txid_conf_old, 16))])) + # Sync with ping to ensure orphans are reconsidered peer.send_and_ping(msg_tx(missing_tx["tx"])) - peer.sync_with_ping() assert_equal(node.getmempoolentry(orphan["txid"])["ancestorcount"], 3) @cleanup @@ -394,10 +412,161 @@ class OrphanHandlingTest(BitcoinTestFramework): peer2.assert_never_requested(child["tx"].getwtxid()) # The child should never be requested, even if announced again with potentially different witness. + # Sync with ping to ensure orphans are reconsidered peer3.send_and_ping(msg_inv([CInv(t=MSG_TX, h=int(child["txid"], 16))])) self.nodes[0].bumpmocktime(TXREQUEST_TIME_SKIP) peer3.assert_never_requested(child["txid"]) + @cleanup + def test_same_txid_orphan(self): + self.log.info("Check what happens when orphan with same txid is already in orphanage") + node = self.nodes[0] + + tx_parent = self.wallet.create_self_transfer() + + # Create the real child + tx_child = self.wallet.create_self_transfer(utxo_to_spend=tx_parent["new_utxo"]) + + # Create a fake version of the child + tx_orphan_bad_wit = self.create_malleated_version(tx_child) + + bad_peer = node.add_p2p_connection(P2PInterface()) + honest_peer = node.add_p2p_connection(P2PInterface()) + + # 1. Fake orphan is received first. It is missing an input. + bad_peer.send_and_ping(msg_tx(tx_orphan_bad_wit)) + + # 2. Node requests the missing parent by txid. + parent_txid_int = int(tx_parent["txid"], 16) + node.bumpmocktime(NONPREF_PEER_TX_DELAY + TXID_RELAY_DELAY) + bad_peer.wait_for_getdata([parent_txid_int]) + + # 3. Honest peer relays the real child, which is also missing parents and should be placed + # in the orphanage. + with node.assert_debug_log(["missingorspent", "stored orphan tx"]): + honest_peer.send_and_ping(msg_tx(tx_child["tx"])) + + # Time out the previous request for the parent (node will not request the same transaction + # from multiple nodes at the same time) + node.bumpmocktime(GETDATA_TX_INTERVAL) + + # 4. The parent is requested. Honest peer sends it. + honest_peer.wait_for_getdata([parent_txid_int]) + # Sync with ping to ensure orphans are reconsidered + honest_peer.send_and_ping(msg_tx(tx_parent["tx"])) + + # 5. After parent is accepted, orphans should be reconsidered. + # The real child should be accepted and the fake one rejected. + node_mempool = node.getrawmempool() + assert tx_parent["txid"] in node_mempool + assert tx_child["txid"] in node_mempool + assert_equal(node.getmempoolentry(tx_child["txid"])["wtxid"], tx_child["wtxid"]) + + @cleanup + def test_same_txid_orphan_of_orphan(self): + self.log.info("Check what happens when orphan's parent with same txid is already in orphanage") + node = self.nodes[0] + + tx_grandparent = self.wallet.create_self_transfer() + + # Create middle tx (both parent and child) which will be in orphanage. + tx_middle = self.wallet.create_self_transfer(utxo_to_spend=tx_grandparent["new_utxo"]) + + # Create a fake version of the middle tx + tx_orphan_bad_wit = self.create_malleated_version(tx_middle) + + # Create grandchild spending from tx_middle (and spending from tx_orphan_bad_wit since they + # have the same txid). + tx_grandchild = self.wallet.create_self_transfer(utxo_to_spend=tx_middle["new_utxo"]) + + bad_peer = node.add_p2p_connection(P2PInterface()) + honest_peer = node.add_p2p_connection(P2PInterface()) + + # 1. Fake orphan is received first. It is missing an input. + bad_peer.send_and_ping(msg_tx(tx_orphan_bad_wit)) + + # 2. Node requests missing tx_grandparent by txid. + grandparent_txid_int = int(tx_grandparent["txid"], 16) + node.bumpmocktime(NONPREF_PEER_TX_DELAY + TXID_RELAY_DELAY) + bad_peer.wait_for_getdata([grandparent_txid_int]) + + # 3. Honest peer relays the grandchild, which is missing a parent. The parent by txid already + # exists in orphanage, but should be re-requested because the node shouldn't assume that the + # witness data is the same. In this case, a same-txid-different-witness transaction exists! + with node.assert_debug_log(["stored orphan tx"]): + honest_peer.send_and_ping(msg_tx(tx_grandchild["tx"])) + middle_txid_int = int(tx_middle["txid"], 16) + node.bumpmocktime(NONPREF_PEER_TX_DELAY + TXID_RELAY_DELAY) + honest_peer.wait_for_getdata([middle_txid_int]) + + # 4. Honest peer relays the real child, which is also missing parents and should be placed + # in the orphanage. + with node.assert_debug_log(["stored orphan tx"]): + honest_peer.send_and_ping(msg_tx(tx_middle["tx"])) + assert_equal(len(node.getrawmempool()), 0) + + # 5. Honest peer sends tx_grandparent + honest_peer.send_and_ping(msg_tx(tx_grandparent["tx"])) + + # 6. After parent is accepted, orphans should be reconsidered. + # The real child should be accepted and the fake one rejected. + node_mempool = node.getrawmempool() + assert tx_grandparent["txid"] in node_mempool + assert tx_middle["txid"] in node_mempool + assert tx_grandchild["txid"] in node_mempool + assert_equal(node.getmempoolentry(tx_middle["txid"])["wtxid"], tx_middle["wtxid"]) + + @cleanup + def test_orphan_txid_inv(self): + self.log.info("Check node does not ignore announcement with same txid as tx in orphanage") + node = self.nodes[0] + + tx_parent = self.wallet.create_self_transfer() + + # Create the real child and fake version + tx_child = self.wallet.create_self_transfer(utxo_to_spend=tx_parent["new_utxo"]) + tx_orphan_bad_wit = self.create_malleated_version(tx_child) + + bad_peer = node.add_p2p_connection(PeerTxRelayer()) + # Must not send wtxidrelay because otherwise the inv(TX) will be ignored later + honest_peer = node.add_p2p_connection(P2PInterface(wtxidrelay=False)) + + # 1. Fake orphan is received first. It is missing an input. + bad_peer.send_and_ping(msg_tx(tx_orphan_bad_wit)) + + # 2. Node requests the missing parent by txid. + parent_txid_int = int(tx_parent["txid"], 16) + node.bumpmocktime(NONPREF_PEER_TX_DELAY + TXID_RELAY_DELAY) + bad_peer.wait_for_getdata([parent_txid_int]) + + # 3. Honest peer announces the real child, by txid (this isn't common but the node should + # still keep track of it). + child_txid_int = int(tx_child["txid"], 16) + honest_peer.send_and_ping(msg_inv([CInv(t=MSG_TX, h=child_txid_int)])) + + # 4. The child is requested. Honest peer sends it. + node.bumpmocktime(TXREQUEST_TIME_SKIP) + honest_peer.wait_for_getdata([child_txid_int]) + with node.assert_debug_log(["stored orphan tx"]): + honest_peer.send_and_ping(msg_tx(tx_child["tx"])) + + # 5. After first parent request times out, the node sends another one for the missing parent + # of the real orphan child. + node.bumpmocktime(GETDATA_TX_INTERVAL) + honest_peer.wait_for_getdata([parent_txid_int]) + honest_peer.send_and_ping(msg_tx(tx_parent["tx"])) + + # 6. After parent is accepted, orphans should be reconsidered. + # The real child should be accepted and the fake one rejected. This may happen in either + # order since the message-processing is randomized. If tx_orphan_bad_wit is validated first, + # its consensus error leads to disconnection of bad_peer. If tx_child is validated first, + # tx_orphan_bad_wit is rejected for txn-same-nonwitness-data-in-mempool (no punishment). + node_mempool = node.getrawmempool() + assert tx_parent["txid"] in node_mempool + assert tx_child["txid"] in node_mempool + assert_equal(node.getmempoolentry(tx_child["txid"])["wtxid"], tx_child["wtxid"]) + + def run_test(self): self.nodes[0].setmocktime(int(time.time())) self.wallet_nonsegwit = MiniWallet(self.nodes[0], mode=MiniWalletMode.RAW_P2PK) @@ -410,6 +579,9 @@ class OrphanHandlingTest(BitcoinTestFramework): self.test_orphans_overlapping_parents() self.test_orphan_of_orphan() self.test_orphan_inherit_rejection() + self.test_same_txid_orphan() + self.test_same_txid_orphan_of_orphan() + self.test_orphan_txid_inv() if __name__ == '__main__': diff --git a/test/functional/p2p_outbound_eviction.py b/test/functional/p2p_outbound_eviction.py new file mode 100755 index 0000000000..8d89688999 --- /dev/null +++ b/test/functional/p2p_outbound_eviction.py @@ -0,0 +1,253 @@ +#!/usr/bin/env python3 +# Copyright (c) 2019-2021 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +""" Test node outbound peer eviction logic + +A subset of our outbound peers are subject to eviction logic if they cannot keep up +with our vision of the best chain. This criteria applies only to non-protected peers, +and can be triggered by either not learning about any blocks from an outbound peer after +a certain deadline, or by them not being able to catch up fast enough (under the same deadline). + +This tests the different eviction paths based on the peer's behavior and on whether they are protected +or not. +""" +import time + +from test_framework.messages import ( + from_hex, + msg_headers, + CBlockHeader, +) +from test_framework.p2p import P2PInterface +from test_framework.test_framework import BitcoinTestFramework + +# Timeouts (in seconds) +CHAIN_SYNC_TIMEOUT = 20 * 60 +HEADERS_RESPONSE_TIME = 2 * 60 + + +class P2POutEvict(BitcoinTestFramework): + def set_test_params(self): + self.num_nodes = 1 + + def test_outbound_eviction_unprotected(self): + # This tests the eviction logic for **unprotected** outbound peers (that is, PeerManagerImpl::ConsiderEviction) + node = self.nodes[0] + cur_mock_time = node.mocktime + + # Get our tip header and its parent + tip_header = from_hex(CBlockHeader(), node.getblockheader(node.getbestblockhash(), False)) + prev_header = from_hex(CBlockHeader(), node.getblockheader(f"{tip_header.hashPrevBlock:064x}", False)) + + self.log.info("Create an outbound connection and don't send any headers") + # Test disconnect due to no block being announced in 22+ minutes (headers are not even exchanged) + peer = node.add_outbound_p2p_connection(P2PInterface(), p2p_idx=0, connection_type="outbound-full-relay") + # Wait for over 20 min to trigger the first eviction timeout. This sets the last call past 2 min in the future. + cur_mock_time += (CHAIN_SYNC_TIMEOUT + 1) + node.setmocktime(cur_mock_time) + peer.sync_with_ping() + # Wait for over 2 more min to trigger the disconnection + peer.wait_for_getheaders(block_hash=tip_header.hashPrevBlock) + cur_mock_time += (HEADERS_RESPONSE_TIME + 1) + node.setmocktime(cur_mock_time) + self.log.info("Test that the peer gets evicted") + peer.wait_for_disconnect() + + self.log.info("Create an outbound connection and send header but never catch up") + # Mimic a node that just falls behind for long enough + # This should also apply for a node doing IBD that does not catch up in time + # Connect a peer and make it send us headers ending in our tip's parent + peer = node.add_outbound_p2p_connection(P2PInterface(), p2p_idx=0, connection_type="outbound-full-relay") + peer.send_and_ping(msg_headers([prev_header])) + + # Trigger the timeouts + cur_mock_time += (CHAIN_SYNC_TIMEOUT + 1) + node.setmocktime(cur_mock_time) + peer.sync_with_ping() + peer.wait_for_getheaders(block_hash=tip_header.hashPrevBlock) + cur_mock_time += (HEADERS_RESPONSE_TIME + 1) + node.setmocktime(cur_mock_time) + self.log.info("Test that the peer gets evicted") + peer.wait_for_disconnect() + + self.log.info("Create an outbound connection and keep lagging behind, but not too much") + # Test that if the peer never catches up with our current tip, but it does with the + # expected work that we set when setting the timer (that is, our tip at the time) + # we do not disconnect the peer + peer = node.add_outbound_p2p_connection(P2PInterface(), p2p_idx=0, connection_type="outbound-full-relay") + + self.log.info("Mine a block so our peer starts lagging") + prev_prev_hash = tip_header.hashPrevBlock + best_block_hash = self.generateblock(node, output="raw(42)", transactions=[])["hash"] + peer.sync_with_ping() + + self.log.info("Keep catching up with the old tip and check that we are not evicted") + for i in range(10): + # Generate an additional block so the peers is 2 blocks behind + prev_header = from_hex(CBlockHeader(), node.getblockheader(best_block_hash, False)) + best_block_hash = self.generateblock(node, output="raw(42)", transactions=[])["hash"] + peer.sync_with_ping() + + # Advance time but not enough to evict the peer + cur_mock_time += (CHAIN_SYNC_TIMEOUT + 1) + node.setmocktime(cur_mock_time) + peer.sync_with_ping() + + # Wait until we get out last call (by receiving a getheaders) + peer.wait_for_getheaders(block_hash=prev_prev_hash) + + # Send a header with the previous tip (so we go back to 1 block behind) + peer.send_and_ping(msg_headers([prev_header])) + prev_prev_hash = tip_header.hash + + self.log.info("Create an outbound connection and take some time to catch up, but do it in time") + # Check that if the peer manages to catch up within time, the timeouts are removed (and the peer is not disconnected) + # We are reusing the peer from the previous case which already sent us a valid (but old) block and whose timer is ticking + + # Send an updated headers message matching our tip + peer.send_and_ping(msg_headers([from_hex(CBlockHeader(), node.getblockheader(best_block_hash, False))])) + + # Wait for long enough for the timeouts to have triggered and check that we are still connected + cur_mock_time += (CHAIN_SYNC_TIMEOUT + 1) + node.setmocktime(cur_mock_time) + peer.sync_with_ping() + cur_mock_time += (HEADERS_RESPONSE_TIME + 1) + node.setmocktime(cur_mock_time) + self.log.info("Test that the peer does not get evicted") + peer.sync_with_ping() + + node.disconnect_p2ps() + + def test_outbound_eviction_protected(self): + # This tests the eviction logic for **protected** outbound peers (that is, PeerManagerImpl::ConsiderEviction) + # Outbound connections are flagged as protected as long as they have sent us a connecting block with at least as + # much work as our current tip and we have enough empty protected_peers slots. + node = self.nodes[0] + cur_mock_time = node.mocktime + tip_header = from_hex(CBlockHeader(), node.getblockheader(node.getbestblockhash(), False)) + + self.log.info("Create an outbound connection to a peer that shares our tip so it gets granted protection") + peer = node.add_outbound_p2p_connection(P2PInterface(), p2p_idx=0, connection_type="outbound-full-relay") + peer.send_and_ping(msg_headers([tip_header])) + + self.log.info("Mine a new block and sync with our peer") + self.generateblock(node, output="raw(42)", transactions=[]) + peer.sync_with_ping() + + self.log.info("Let enough time pass for the timeouts to go off") + # Trigger the timeouts and check how we are still connected + cur_mock_time += (CHAIN_SYNC_TIMEOUT + 1) + node.setmocktime(cur_mock_time) + peer.sync_with_ping() + peer.wait_for_getheaders(block_hash=tip_header.hashPrevBlock) + cur_mock_time += (HEADERS_RESPONSE_TIME + 1) + node.setmocktime(cur_mock_time) + self.log.info("Test that the node does not get evicted") + peer.sync_with_ping() + + node.disconnect_p2ps() + + def test_outbound_eviction_mixed(self): + # This tests the outbound eviction logic for a mix of protected and unprotected peers. + node = self.nodes[0] + cur_mock_time = node.mocktime + + self.log.info("Create a mix of protected and unprotected outbound connections to check against eviction") + + # Let's try this logic having multiple peers, some protected and some unprotected + # We protect up to 4 peers as long as they have provided a block with the same amount of work as our tip + self.log.info("The first 4 peers are protected by sending us a valid block with enough work") + tip_header = from_hex(CBlockHeader(), node.getblockheader(node.getbestblockhash(), False)) + headers_message = msg_headers([tip_header]) + protected_peers = [] + for i in range(4): + peer = node.add_outbound_p2p_connection(P2PInterface(), p2p_idx=i, connection_type="outbound-full-relay") + peer.send_and_ping(headers_message) + protected_peers.append(peer) + + # We can create 4 additional outbound connections to peers that are unprotected. 2 of them will be well behaved, + # whereas the other 2 will misbehave (1 sending no headers, 1 sending old ones) + self.log.info("The remaining 4 peers will be mixed between honest (2) and misbehaving peers (2)") + prev_header = from_hex(CBlockHeader(), node.getblockheader(f"{tip_header.hashPrevBlock:064x}", False)) + headers_message = msg_headers([prev_header]) + honest_unprotected_peers = [] + for i in range(2): + peer = node.add_outbound_p2p_connection(P2PInterface(), p2p_idx=4+i, connection_type="outbound-full-relay") + peer.send_and_ping(headers_message) + honest_unprotected_peers.append(peer) + + misbehaving_unprotected_peers = [] + for i in range(2): + peer = node.add_outbound_p2p_connection(P2PInterface(), p2p_idx=6+i, connection_type="outbound-full-relay") + if i%2==0: + peer.send_and_ping(headers_message) + misbehaving_unprotected_peers.append(peer) + + self.log.info("Mine a new block and keep the unprotected honest peer on sync, all the rest off-sync") + # Mine a block so all peers become outdated + target_hash = prev_header.rehash() + tip_hash = self.generateblock(node, output="raw(42)", transactions=[])["hash"] + tip_header = from_hex(CBlockHeader(), node.getblockheader(tip_hash, False)) + tip_headers_message = msg_headers([tip_header]) + + # Let the timeouts hit and check back + cur_mock_time += (CHAIN_SYNC_TIMEOUT + 1) + node.setmocktime(cur_mock_time) + for peer in protected_peers + misbehaving_unprotected_peers: + peer.sync_with_ping() + peer.wait_for_getheaders(block_hash=target_hash) + for peer in honest_unprotected_peers: + peer.send_and_ping(tip_headers_message) + peer.wait_for_getheaders(block_hash=target_hash) + + cur_mock_time += (HEADERS_RESPONSE_TIME + 1) + node.setmocktime(cur_mock_time) + self.log.info("Check how none of the honest nor protected peers was evicted but all the misbehaving unprotected were") + for peer in protected_peers + honest_unprotected_peers: + peer.sync_with_ping() + for peer in misbehaving_unprotected_peers: + peer.wait_for_disconnect() + + node.disconnect_p2ps() + + def test_outbound_eviction_blocks_relay_only(self): + # The logic for outbound eviction protection only applies to outbound-full-relay peers + # This tests that other types of peers (blocks-relay-only for instance) are not granted protection + node = self.nodes[0] + cur_mock_time = node.mocktime + tip_header = from_hex(CBlockHeader(), node.getblockheader(node.getbestblockhash(), False)) + + self.log.info("Create an blocks-only outbound connection to a peer that shares our tip. This would usually grant protection") + peer = node.add_outbound_p2p_connection(P2PInterface(), p2p_idx=0, connection_type="block-relay-only") + peer.send_and_ping(msg_headers([tip_header])) + + self.log.info("Mine a new block and sync with our peer") + self.generateblock(node, output="raw(42)", transactions=[]) + peer.sync_with_ping() + + self.log.info("Let enough time pass for the timeouts to go off") + # Trigger the timeouts and check how the peer gets evicted, since protection is only given to outbound-full-relay peers + cur_mock_time += (CHAIN_SYNC_TIMEOUT + 1) + node.setmocktime(cur_mock_time) + peer.sync_with_ping() + peer.wait_for_getheaders(block_hash=tip_header.hash) + cur_mock_time += (HEADERS_RESPONSE_TIME + 1) + node.setmocktime(cur_mock_time) + self.log.info("Test that the peer gets evicted") + peer.wait_for_disconnect() + + node.disconnect_p2ps() + + + def run_test(self): + self.nodes[0].setmocktime(int(time.time())) + self.test_outbound_eviction_unprotected() + self.test_outbound_eviction_protected() + self.test_outbound_eviction_mixed() + self.test_outbound_eviction_blocks_relay_only() + + +if __name__ == '__main__': + P2POutEvict().main() diff --git a/test/functional/p2p_segwit.py b/test/functional/p2p_segwit.py index 45bbd7f1c3..d20cf41a72 100755 --- a/test/functional/p2p_segwit.py +++ b/test/functional/p2p_segwit.py @@ -5,7 +5,6 @@ """Test segwit transactions and blocks on P2P network.""" from decimal import Decimal import random -import struct import time from test_framework.blocktools import ( @@ -1165,16 +1164,16 @@ class SegWitTest(BitcoinTestFramework): if not self.wit.is_null(): flags |= 1 r = b"" - r += struct.pack("<i", self.nVersion) + r += self.version.to_bytes(4, "little") if flags: dummy = [] r += ser_vector(dummy) - r += struct.pack("<B", flags) + r += flags.to_bytes(1, "little") r += ser_vector(self.vin) r += ser_vector(self.vout) if flags & 1: r += self.wit.serialize() - r += struct.pack("<I", self.nLockTime) + r += self.nLockTime.to_bytes(4, "little") return r tx2 = BrokenCTransaction() @@ -1976,11 +1975,11 @@ class SegWitTest(BitcoinTestFramework): def serialize_with_bogus_witness(tx): flags = 3 r = b"" - r += struct.pack("<i", tx.nVersion) + r += tx.version.to_bytes(4, "little") if flags: dummy = [] r += ser_vector(dummy) - r += struct.pack("<B", flags) + r += flags.to_bytes(1, "little") r += ser_vector(tx.vin) r += ser_vector(tx.vout) if flags & 1: @@ -1990,7 +1989,7 @@ class SegWitTest(BitcoinTestFramework): for _ in range(len(tx.wit.vtxinwit), len(tx.vin)): tx.wit.vtxinwit.append(CTxInWitness()) r += tx.wit.serialize() - r += struct.pack("<I", tx.nLockTime) + r += tx.nLockTime.to_bytes(4, "little") return r class msg_bogus_tx(msg_tx): diff --git a/test/functional/p2p_sendheaders.py b/test/functional/p2p_sendheaders.py index 27a3aa8fb9..5c463267a1 100755 --- a/test/functional/p2p_sendheaders.py +++ b/test/functional/p2p_sendheaders.py @@ -71,19 +71,13 @@ f. Announce 1 more header that builds on that fork. Expect: no response. Part 5: Test handling of headers that don't connect. -a. Repeat 10 times: +a. Repeat 100 times: 1. Announce a header that doesn't connect. Expect: getheaders message 2. Send headers chain. Expect: getdata for the missing blocks, tip update. -b. Then send 9 more headers that don't connect. +b. Then send 99 more headers that don't connect. Expect: getheaders message each time. -c. Announce a header that does connect. - Expect: no response. -d. Announce 49 headers that don't connect. - Expect: getheaders message each time. -e. Announce one more that doesn't connect. - Expect: disconnect. """ from test_framework.blocktools import create_block, create_coinbase from test_framework.messages import CInv @@ -526,7 +520,8 @@ class SendHeadersTest(BitcoinTestFramework): # First we test that receipt of an unconnecting header doesn't prevent # chain sync. expected_hash = tip - for i in range(10): + NUM_HEADERS = 100 + for i in range(NUM_HEADERS): self.log.debug("Part 5.{}: starting...".format(i)) test_node.last_message.pop("getdata", None) blocks = [] @@ -550,41 +545,24 @@ class SendHeadersTest(BitcoinTestFramework): blocks = [] # Now we test that if we repeatedly don't send connecting headers, we # don't go into an infinite loop trying to get them to connect. - MAX_NUM_UNCONNECTING_HEADERS_MSGS = 10 - for _ in range(MAX_NUM_UNCONNECTING_HEADERS_MSGS + 1): + for _ in range(NUM_HEADERS + 1): blocks.append(create_block(tip, create_coinbase(height), block_time)) blocks[-1].solve() tip = blocks[-1].sha256 block_time += 1 height += 1 - for i in range(1, MAX_NUM_UNCONNECTING_HEADERS_MSGS): - # Send a header that doesn't connect, check that we get a getheaders. + for i in range(1, NUM_HEADERS): + with p2p_lock: + test_node.last_message.pop("getheaders", None) + # Send an empty header as a failed response to the received getheaders + # (from the previous iteration). Otherwise, the new headers will be + # treated as a response instead of as an announcement. + test_node.send_header_for_blocks([]) + # Send the actual unconnecting header, which should trigger a new getheaders. test_node.send_header_for_blocks([blocks[i]]) test_node.wait_for_getheaders(block_hash=expected_hash) - # Next header will connect, should re-set our count: - test_node.send_header_for_blocks([blocks[0]]) - expected_hash = blocks[0].sha256 - - # Remove the first two entries (blocks[1] would connect): - blocks = blocks[2:] - - # Now try to see how many unconnecting headers we can send - # before we get disconnected. Should be 5*MAX_NUM_UNCONNECTING_HEADERS_MSGS - for i in range(5 * MAX_NUM_UNCONNECTING_HEADERS_MSGS - 1): - # Send a header that doesn't connect, check that we get a getheaders. - test_node.send_header_for_blocks([blocks[i % len(blocks)]]) - test_node.wait_for_getheaders(block_hash=expected_hash) - - # Eventually this stops working. - test_node.send_header_for_blocks([blocks[-1]]) - - # Should get disconnected - test_node.wait_for_disconnect() - - self.log.info("Part 5: success!") - # Finally, check that the inv node never received a getdata request, # throughout the test assert "getdata" not in inv_node.last_message diff --git a/test/functional/p2p_tx_download.py b/test/functional/p2p_tx_download.py index 7a50f1e605..0af6b1d2c9 100755 --- a/test/functional/p2p_tx_download.py +++ b/test/functional/p2p_tx_download.py @@ -8,6 +8,9 @@ Test transaction download behavior from decimal import Decimal import time +from test_framework.mempool_util import ( + fill_mempool, +) from test_framework.messages import ( CInv, MSG_TX, @@ -24,7 +27,6 @@ from test_framework.p2p import ( from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, - fill_mempool, ) from test_framework.wallet import MiniWallet @@ -248,7 +250,7 @@ class TxDownloadTest(BitcoinTestFramework): def test_rejects_filter_reset(self): self.log.info('Check that rejected tx is not requested again') node = self.nodes[0] - fill_mempool(self, node, self.wallet) + fill_mempool(self, node) self.wallet.rescan_utxos() mempoolminfee = node.getmempoolinfo()['mempoolminfee'] peer = node.add_p2p_connection(TestP2PConn()) diff --git a/test/functional/p2p_unrequested_blocks.py b/test/functional/p2p_unrequested_blocks.py index f368434895..776eaf5255 100755 --- a/test/functional/p2p_unrequested_blocks.py +++ b/test/functional/p2p_unrequested_blocks.py @@ -170,9 +170,11 @@ class AcceptBlockTest(BitcoinTestFramework): tip = next_block # Now send the block at height 5 and check that it wasn't accepted (missing header) - test_node.send_and_ping(msg_block(all_blocks[1])) + test_node.send_message(msg_block(all_blocks[1])) + test_node.wait_for_disconnect() assert_raises_rpc_error(-5, "Block not found", self.nodes[0].getblock, all_blocks[1].hash) assert_raises_rpc_error(-5, "Block not found", self.nodes[0].getblockheader, all_blocks[1].hash) + test_node = self.nodes[0].add_p2p_connection(P2PInterface()) # The block at height 5 should be accepted if we provide the missing header, though headers_message = msg_headers() diff --git a/test/functional/rpc_createmultisig.py b/test/functional/rpc_createmultisig.py index 65d7b4c422..37656341d2 100755 --- a/test/functional/rpc_createmultisig.py +++ b/test/functional/rpc_createmultisig.py @@ -9,10 +9,10 @@ import json import os from test_framework.address import address_to_scriptpubkey -from test_framework.blocktools import COINBASE_MATURITY -from test_framework.authproxy import JSONRPCException from test_framework.descriptors import descsum_create, drop_origins from test_framework.key import ECPubKey +from test_framework.messages import COIN +from test_framework.script_util import keys_to_multisig_script from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_raises_rpc_error, @@ -32,92 +32,54 @@ class RpcCreateMultiSigTest(BitcoinTestFramework): self.setup_clean_chain = True self.num_nodes = 3 self.supports_cli = False + self.enable_wallet_if_possible() - def get_keys(self): + def create_keys(self, num_keys): self.pub = [] self.priv = [] - node0, node1, node2 = self.nodes - for _ in range(self.nkeys): + for _ in range(num_keys): privkey, pubkey = generate_keypair(wif=True) self.pub.append(pubkey.hex()) self.priv.append(privkey) - if self.is_bdb_compiled(): - self.final = node2.getnewaddress() - else: - self.final = getnewdestination('bech32')[2] + + def create_wallet(self, node, wallet_name): + node.createwallet(wallet_name=wallet_name, disable_private_keys=True) + return node.get_wallet_rpc(wallet_name) def run_test(self): node0, node1, node2 = self.nodes self.wallet = MiniWallet(test_node=node0) - if self.is_bdb_compiled(): - self.import_deterministic_coinbase_privkeys() + if self.is_wallet_compiled(): self.check_addmultisigaddress_errors() self.log.info('Generating blocks ...') self.generate(self.wallet, 149) - self.moved = 0 - for self.nkeys in [3, 5]: - for self.nsigs in [2, 3]: - for self.output_type in ["bech32", "p2sh-segwit", "legacy"]: - self.get_keys() - self.do_multisig() - if self.is_bdb_compiled(): - self.checkbalances() - - # Test mixed compressed and uncompressed pubkeys - self.log.info('Mixed compressed and uncompressed multisigs are not allowed') - pk0, pk1, pk2 = [getnewdestination('bech32')[0].hex() for _ in range(3)] - - # decompress pk2 - pk_obj = ECPubKey() - pk_obj.set(bytes.fromhex(pk2)) - pk_obj.compressed = False - pk2 = pk_obj.get_bytes().hex() - - if self.is_bdb_compiled(): - node0.createwallet(wallet_name='wmulti0', disable_private_keys=True) - wmulti0 = node0.get_wallet_rpc('wmulti0') - - # Check all permutations of keys because order matters apparently - for keys in itertools.permutations([pk0, pk1, pk2]): - # Results should be the same as this legacy one - legacy_addr = node0.createmultisig(2, keys, 'legacy')['address'] - - if self.is_bdb_compiled(): - result = wmulti0.addmultisigaddress(2, keys, '', 'legacy') - assert_equal(legacy_addr, result['address']) - assert 'warnings' not in result - - # Generate addresses with the segwit types. These should all make legacy addresses - err_msg = ["Unable to make chosen address type, please ensure no uncompressed public keys are present."] - - for addr_type in ['bech32', 'p2sh-segwit']: - result = self.nodes[0].createmultisig(nrequired=2, keys=keys, address_type=addr_type) - assert_equal(legacy_addr, result['address']) - assert_equal(result['warnings'], err_msg) - - if self.is_bdb_compiled(): - result = wmulti0.addmultisigaddress(nrequired=2, keys=keys, address_type=addr_type) - assert_equal(legacy_addr, result['address']) - assert_equal(result['warnings'], err_msg) - - self.log.info('Testing sortedmulti descriptors with BIP 67 test vectors') - with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data/rpc_bip67.json'), encoding='utf-8') as f: - vectors = json.load(f) + wallet_multi = self.create_wallet(node1, 'wmulti') if self._requires_wallet else None + self.create_keys(21) # max number of allowed keys + 1 + m_of_n = [(2, 3), (3, 3), (2, 5), (3, 5), (10, 15), (15, 15)] + for (sigs, keys) in m_of_n: + for output_type in ["bech32", "p2sh-segwit", "legacy"]: + self.do_multisig(keys, sigs, output_type, wallet_multi) - for t in vectors: - key_str = ','.join(t['keys']) - desc = descsum_create('sh(sortedmulti(2,{}))'.format(key_str)) - assert_equal(self.nodes[0].deriveaddresses(desc)[0], t['address']) - sorted_key_str = ','.join(t['sorted_keys']) - sorted_key_desc = descsum_create('sh(multi(2,{}))'.format(sorted_key_str)) - assert_equal(self.nodes[0].deriveaddresses(sorted_key_desc)[0], t['address']) + self.test_multisig_script_limit(wallet_multi) + self.test_mixing_uncompressed_and_compressed_keys(node0, wallet_multi) + self.test_sortedmulti_descriptors_bip67() # Check that bech32m is currently not allowed assert_raises_rpc_error(-5, "createmultisig cannot create bech32m multisig addresses", self.nodes[0].createmultisig, 2, self.pub, "bech32m") + self.log.info('Check correct encoding of multisig script for all n (1..20)') + for nkeys in range(1, 20+1): + keys = [self.pub[0]]*nkeys + expected_ms_script = keys_to_multisig_script(keys, k=nkeys) # simply use n-of-n + # note that the 'legacy' address type fails for n values larger than 15 + # due to exceeding the P2SH size limit (520 bytes), so we use 'bech32' instead + # (for the purpose of this encoding test, we don't care about the resulting address) + res = self.nodes[0].createmultisig(nrequired=nkeys, keys=keys, address_type='bech32') + assert_equal(res['redeemScript'], expected_ms_script.hex()) + def check_addmultisigaddress_errors(self): if self.options.descriptors: return @@ -133,117 +95,165 @@ class RpcCreateMultiSigTest(BitcoinTestFramework): pubs = [self.nodes[1].getaddressinfo(addr)["pubkey"] for addr in addresses] assert_raises_rpc_error(-5, "Bech32m multisig addresses cannot be created with legacy wallets", self.nodes[0].addmultisigaddress, 2, pubs, "", "bech32m") - def checkbalances(self): - node0, node1, node2 = self.nodes - self.generate(node0, COINBASE_MATURITY) + def test_multisig_script_limit(self, wallet_multi): + node1 = self.nodes[1] + pubkeys = self.pub[0:20] - bal0 = node0.getbalance() - bal1 = node1.getbalance() - bal2 = node2.getbalance() - balw = self.wallet.get_balance() + self.log.info('Test legacy redeem script max size limit') + assert_raises_rpc_error(-8, "redeemScript exceeds size limit: 684 > 520", node1.createmultisig, 16, pubkeys, 'legacy') - height = node0.getblockchaininfo()["blocks"] - assert 150 < height < 350 - total = 149 * 50 + (height - 149 - 100) * 25 - assert bal1 == 0 - assert bal2 == self.moved - assert_equal(bal0 + bal1 + bal2 + balw, total) + self.log.info('Test valid 16-20 multisig p2sh-legacy and bech32 (no wallet)') + self.do_multisig(nkeys=20, nsigs=16, output_type="p2sh-segwit", wallet_multi=None) + self.do_multisig(nkeys=20, nsigs=16, output_type="bech32", wallet_multi=None) - def do_multisig(self): - node0, node1, node2 = self.nodes + self.log.info('Test invalid 16-21 multisig p2sh-legacy and bech32 (no wallet)') + assert_raises_rpc_error(-8, "Number of keys involved in the multisignature address creation > 20", node1.createmultisig, 16, self.pub, 'p2sh-segwit') + assert_raises_rpc_error(-8, "Number of keys involved in the multisignature address creation > 20", node1.createmultisig, 16, self.pub, 'bech32') - if self.is_bdb_compiled(): - if 'wmulti' not in node1.listwallets(): - try: - node1.loadwallet('wmulti') - except JSONRPCException as e: - path = self.nodes[1].wallets_path / "wmulti" - if e.error['code'] == -18 and "Wallet file verification failed. Failed to load database path '{}'. Path does not exist.".format(path) in e.error['message']: - node1.createwallet(wallet_name='wmulti', disable_private_keys=True) - else: - raise - wmulti = node1.get_wallet_rpc('wmulti') + # Check legacy wallet related command + self.log.info('Test legacy redeem script max size limit (with wallet)') + if wallet_multi is not None and not self.options.descriptors: + assert_raises_rpc_error(-8, "redeemScript exceeds size limit: 684 > 520", wallet_multi.addmultisigaddress, 16, pubkeys, '', 'legacy') + + self.log.info('Test legacy wallet unsupported operation. 16-20 multisig p2sh-legacy and bech32 generation') + # Due an internal limitation on legacy wallets, the redeem script limit also applies to p2sh-segwit and bech32 (even when the scripts are valid) + # We take this as a "good thing" to tell users to upgrade to descriptors. + assert_raises_rpc_error(-4, "Unsupported multisig script size for legacy wallet. Upgrade to descriptors to overcome this limitation for p2sh-segwit or bech32 scripts", wallet_multi.addmultisigaddress, 16, pubkeys, '', 'p2sh-segwit') + assert_raises_rpc_error(-4, "Unsupported multisig script size for legacy wallet. Upgrade to descriptors to overcome this limitation for p2sh-segwit or bech32 scripts", wallet_multi.addmultisigaddress, 16, pubkeys, '', 'bech32') + + def do_multisig(self, nkeys, nsigs, output_type, wallet_multi): + node0, node1, node2 = self.nodes + pub_keys = self.pub[0: nkeys] + priv_keys = self.priv[0: nkeys] # Construct the expected descriptor - desc = 'multi({},{})'.format(self.nsigs, ','.join(self.pub)) - if self.output_type == 'legacy': + desc = 'multi({},{})'.format(nsigs, ','.join(pub_keys)) + if output_type == 'legacy': desc = 'sh({})'.format(desc) - elif self.output_type == 'p2sh-segwit': + elif output_type == 'p2sh-segwit': desc = 'sh(wsh({}))'.format(desc) - elif self.output_type == 'bech32': + elif output_type == 'bech32': desc = 'wsh({})'.format(desc) desc = descsum_create(desc) - msig = node2.createmultisig(self.nsigs, self.pub, self.output_type) + msig = node2.createmultisig(nsigs, pub_keys, output_type) assert 'warnings' not in msig madd = msig["address"] mredeem = msig["redeemScript"] assert_equal(desc, msig['descriptor']) - if self.output_type == 'bech32': + if output_type == 'bech32': assert madd[0:4] == "bcrt" # actually a bech32 address - if self.is_bdb_compiled(): + if wallet_multi is not None: # compare against addmultisigaddress - msigw = wmulti.addmultisigaddress(self.nsigs, self.pub, None, self.output_type) + msigw = wallet_multi.addmultisigaddress(nsigs, pub_keys, None, output_type) maddw = msigw["address"] mredeemw = msigw["redeemScript"] assert_equal(desc, drop_origins(msigw['descriptor'])) # addmultisigiaddress and createmultisig work the same assert maddw == madd assert mredeemw == mredeem - wmulti.unloadwallet() spk = address_to_scriptpubkey(madd) - txid = self.wallet.send_to(from_node=self.nodes[0], scriptPubKey=spk, amount=1300)["txid"] - tx = node0.getrawtransaction(txid, True) - vout = [v["n"] for v in tx["vout"] if madd == v["scriptPubKey"]["address"]] - assert len(vout) == 1 - vout = vout[0] - scriptPubKey = tx["vout"][vout]["scriptPubKey"]["hex"] - value = tx["vout"][vout]["value"] - prevtxs = [{"txid": txid, "vout": vout, "scriptPubKey": scriptPubKey, "redeemScript": mredeem, "amount": value}] + value = decimal.Decimal("0.00004000") + tx = self.wallet.send_to(from_node=self.nodes[0], scriptPubKey=spk, amount=int(value * COIN)) + prevtxs = [{"txid": tx["txid"], "vout": tx["sent_vout"], "scriptPubKey": spk.hex(), "redeemScript": mredeem, "amount": value}] self.generate(node0, 1) - outval = value - decimal.Decimal("0.00001000") - rawtx = node2.createrawtransaction([{"txid": txid, "vout": vout}], [{self.final: outval}]) + outval = value - decimal.Decimal("0.00002000") # deduce fee (must be higher than the min relay fee) + # send coins to node2 when wallet is enabled + node2_balance = node2.getbalances()['mine']['trusted'] if self.is_wallet_compiled() else 0 + out_addr = node2.getnewaddress() if self.is_wallet_compiled() else getnewdestination('bech32')[2] + rawtx = node2.createrawtransaction([{"txid": tx["txid"], "vout": tx["sent_vout"]}], [{out_addr: outval}]) prevtx_err = dict(prevtxs[0]) del prevtx_err["redeemScript"] - assert_raises_rpc_error(-8, "Missing redeemScript/witnessScript", node2.signrawtransactionwithkey, rawtx, self.priv[0:self.nsigs-1], [prevtx_err]) + assert_raises_rpc_error(-8, "Missing redeemScript/witnessScript", node2.signrawtransactionwithkey, rawtx, priv_keys[0:nsigs-1], [prevtx_err]) # if witnessScript specified, all ok prevtx_err["witnessScript"] = prevtxs[0]["redeemScript"] - node2.signrawtransactionwithkey(rawtx, self.priv[0:self.nsigs-1], [prevtx_err]) + node2.signrawtransactionwithkey(rawtx, priv_keys[0:nsigs-1], [prevtx_err]) # both specified, also ok prevtx_err["redeemScript"] = prevtxs[0]["redeemScript"] - node2.signrawtransactionwithkey(rawtx, self.priv[0:self.nsigs-1], [prevtx_err]) + node2.signrawtransactionwithkey(rawtx, priv_keys[0:nsigs-1], [prevtx_err]) # redeemScript mismatch to witnessScript prevtx_err["redeemScript"] = "6a" # OP_RETURN - assert_raises_rpc_error(-8, "redeemScript does not correspond to witnessScript", node2.signrawtransactionwithkey, rawtx, self.priv[0:self.nsigs-1], [prevtx_err]) + assert_raises_rpc_error(-8, "redeemScript does not correspond to witnessScript", node2.signrawtransactionwithkey, rawtx, priv_keys[0:nsigs-1], [prevtx_err]) # redeemScript does not match scriptPubKey del prevtx_err["witnessScript"] - assert_raises_rpc_error(-8, "redeemScript/witnessScript does not match scriptPubKey", node2.signrawtransactionwithkey, rawtx, self.priv[0:self.nsigs-1], [prevtx_err]) + assert_raises_rpc_error(-8, "redeemScript/witnessScript does not match scriptPubKey", node2.signrawtransactionwithkey, rawtx, priv_keys[0:nsigs-1], [prevtx_err]) # witnessScript does not match scriptPubKey prevtx_err["witnessScript"] = prevtx_err["redeemScript"] del prevtx_err["redeemScript"] - assert_raises_rpc_error(-8, "redeemScript/witnessScript does not match scriptPubKey", node2.signrawtransactionwithkey, rawtx, self.priv[0:self.nsigs-1], [prevtx_err]) + assert_raises_rpc_error(-8, "redeemScript/witnessScript does not match scriptPubKey", node2.signrawtransactionwithkey, rawtx, priv_keys[0:nsigs-1], [prevtx_err]) - rawtx2 = node2.signrawtransactionwithkey(rawtx, self.priv[0:self.nsigs - 1], prevtxs) - rawtx3 = node2.signrawtransactionwithkey(rawtx2["hex"], [self.priv[-1]], prevtxs) + rawtx2 = node2.signrawtransactionwithkey(rawtx, priv_keys[0:nsigs - 1], prevtxs) + rawtx3 = node2.signrawtransactionwithkey(rawtx2["hex"], [priv_keys[-1]], prevtxs) + assert rawtx3['complete'] - self.moved += outval tx = node0.sendrawtransaction(rawtx3["hex"], 0) blk = self.generate(node0, 1)[0] assert tx in node0.getblock(blk)["tx"] + # When the wallet is enabled, assert node2 sees the incoming amount + if self.is_wallet_compiled(): + assert_equal(node2.getbalances()['mine']['trusted'], node2_balance + outval) + txinfo = node0.getrawtransaction(tx, True, blk) - self.log.info("n/m=%d/%d %s size=%d vsize=%d weight=%d" % (self.nsigs, self.nkeys, self.output_type, txinfo["size"], txinfo["vsize"], txinfo["weight"])) + self.log.info("n/m=%d/%d %s size=%d vsize=%d weight=%d" % (nsigs, nkeys, output_type, txinfo["size"], txinfo["vsize"], txinfo["weight"])) + + def test_mixing_uncompressed_and_compressed_keys(self, node, wallet_multi): + self.log.info('Mixed compressed and uncompressed multisigs are not allowed') + pk0, pk1, pk2 = [getnewdestination('bech32')[0].hex() for _ in range(3)] + + # decompress pk2 + pk_obj = ECPubKey() + pk_obj.set(bytes.fromhex(pk2)) + pk_obj.compressed = False + pk2 = pk_obj.get_bytes().hex() + + # Check all permutations of keys because order matters apparently + for keys in itertools.permutations([pk0, pk1, pk2]): + # Results should be the same as this legacy one + legacy_addr = node.createmultisig(2, keys, 'legacy')['address'] + + if wallet_multi is not None: + # 'addmultisigaddress' should return the same address + result = wallet_multi.addmultisigaddress(2, keys, '', 'legacy') + assert_equal(legacy_addr, result['address']) + assert 'warnings' not in result + + # Generate addresses with the segwit types. These should all make legacy addresses + err_msg = ["Unable to make chosen address type, please ensure no uncompressed public keys are present."] + + for addr_type in ['bech32', 'p2sh-segwit']: + result = self.nodes[0].createmultisig(nrequired=2, keys=keys, address_type=addr_type) + assert_equal(legacy_addr, result['address']) + assert_equal(result['warnings'], err_msg) + + if wallet_multi is not None: + result = wallet_multi.addmultisigaddress(nrequired=2, keys=keys, address_type=addr_type) + assert_equal(legacy_addr, result['address']) + assert_equal(result['warnings'], err_msg) + + def test_sortedmulti_descriptors_bip67(self): + self.log.info('Testing sortedmulti descriptors with BIP 67 test vectors') + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data/rpc_bip67.json'), encoding='utf-8') as f: + vectors = json.load(f) + + for t in vectors: + key_str = ','.join(t['keys']) + desc = descsum_create('sh(sortedmulti(2,{}))'.format(key_str)) + assert_equal(self.nodes[0].deriveaddresses(desc)[0], t['address']) + sorted_key_str = ','.join(t['sorted_keys']) + sorted_key_desc = descsum_create('sh(multi(2,{}))'.format(sorted_key_str)) + assert_equal(self.nodes[0].deriveaddresses(sorted_key_desc)[0], t['address']) if __name__ == '__main__': diff --git a/test/functional/rpc_dumptxoutset.py b/test/functional/rpc_dumptxoutset.py index 1ea6cf52d1..c92c8da357 100755 --- a/test/functional/rpc_dumptxoutset.py +++ b/test/functional/rpc_dumptxoutset.py @@ -43,7 +43,7 @@ class DumptxoutsetTest(BitcoinTestFramework): # UTXO snapshot hash should be deterministic based on mocked time. assert_equal( sha256sum_file(str(expected_path)).hex(), - 'b1bacb602eacf5fbc9a7c2ef6eeb0d229c04e98bdf0c2ea5929012cd0eae3830') + '2f775f82811150d310527b5ff773f81fb0fb517e941c543c1f7c4d38fd2717b3') assert_equal( out['txoutset_hash'], 'a0b7baa3bf5ccbd3279728f230d7ca0c44a76e9923fca8f32dbfd08d65ea496a') diff --git a/test/functional/rpc_generate.py b/test/functional/rpc_generate.py index 20f62079fd..3e250925e7 100755 --- a/test/functional/rpc_generate.py +++ b/test/functional/rpc_generate.py @@ -87,7 +87,7 @@ class RPCGenerateTest(BitcoinTestFramework): txid1 = miniwallet.send_self_transfer(from_node=node)['txid'] utxo1 = miniwallet.get_utxo(txid=txid1) rawtx2 = miniwallet.create_self_transfer(utxo_to_spend=utxo1)['hex'] - assert_raises_rpc_error(-25, 'TestBlockValidity failed: bad-txns-inputs-missingorspent', self.generateblock, node, address, [rawtx2, txid1]) + assert_raises_rpc_error(-25, 'testBlockValidity failed: bad-txns-inputs-missingorspent', self.generateblock, node, address, [rawtx2, txid1]) self.log.info('Fail to generate block with txid not in mempool') missing_txid = '0000000000000000000000000000000000000000000000000000000000000000' diff --git a/test/functional/rpc_packages.py b/test/functional/rpc_packages.py index 37c42f2533..1acd586d2c 100755 --- a/test/functional/rpc_packages.py +++ b/test/functional/rpc_packages.py @@ -8,6 +8,9 @@ from decimal import Decimal import random from test_framework.blocktools import COINBASE_MATURITY +from test_framework.mempool_util import ( + fill_mempool, +) from test_framework.messages import ( MAX_BIP125_RBF_SEQUENCE, tx_from_hex, @@ -18,14 +21,17 @@ from test_framework.util import ( assert_equal, assert_fee_amount, assert_raises_rpc_error, - fill_mempool, ) from test_framework.wallet import ( + COIN, DEFAULT_FEE, MiniWallet, ) +MAX_PACKAGE_COUNT = 25 + + class RPCPackagesTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 @@ -237,6 +243,37 @@ class RPCPackagesTest(BitcoinTestFramework): {"txid": tx2["txid"], "wtxid": tx2["wtxid"], "package-error": "conflict-in-package"} ]) + # Add a child that spends both at high feerate to submit via submitpackage + tx_child = self.wallet.create_self_transfer_multi( + fee_per_output=int(DEFAULT_FEE * 5 * COIN), + utxos_to_spend=[tx1["new_utxo"], tx2["new_utxo"]], + ) + + testres = node.testmempoolaccept([tx1["hex"], tx2["hex"], tx_child["hex"]]) + + assert_equal(testres, [ + {"txid": tx1["txid"], "wtxid": tx1["wtxid"], "package-error": "conflict-in-package"}, + {"txid": tx2["txid"], "wtxid": tx2["wtxid"], "package-error": "conflict-in-package"}, + {"txid": tx_child["txid"], "wtxid": tx_child["wtxid"], "package-error": "conflict-in-package"} + ]) + + submitres = node.submitpackage([tx1["hex"], tx2["hex"], tx_child["hex"]]) + assert_equal(submitres, {'package_msg': 'conflict-in-package', 'tx-results': {}, 'replaced-transactions': []}) + + # Submit tx1 to mempool, then try the same package again + node.sendrawtransaction(tx1["hex"]) + + submitres = node.submitpackage([tx1["hex"], tx2["hex"], tx_child["hex"]]) + assert_equal(submitres, {'package_msg': 'conflict-in-package', 'tx-results': {}, 'replaced-transactions': []}) + assert tx_child["txid"] not in node.getrawmempool() + + # ... and without the in-mempool ancestor tx1 included in the call + submitres = node.submitpackage([tx2["hex"], tx_child["hex"]]) + assert_equal(submitres, {'package_msg': 'package-not-child-with-unconfirmed-parents', 'tx-results': {}, 'replaced-transactions': []}) + + # Regardless of error type, the child can never enter the mempool + assert tx_child["txid"] not in node.getrawmempool() + def test_rbf(self): node = self.nodes[0] @@ -344,13 +381,20 @@ class RPCPackagesTest(BitcoinTestFramework): assert_raises_rpc_error(-25, "package topology disallowed", node.submitpackage, chain_hex) assert_equal(legacy_pool, node.getrawmempool()) + assert_raises_rpc_error(-8, f"Array must contain between 2 and {MAX_PACKAGE_COUNT} transactions.", node.submitpackage, []) + assert_raises_rpc_error(-8, f"Array must contain between 2 and {MAX_PACKAGE_COUNT} transactions.", node.submitpackage, [chain_hex[0]] * 1) + assert_raises_rpc_error( + -8, f"Array must contain between 2 and {MAX_PACKAGE_COUNT} transactions.", + node.submitpackage, [chain_hex[0]] * (MAX_PACKAGE_COUNT + 1) + ) + # Create a transaction chain such as only the parent gets accepted (by making the child's # version non-standard). Make sure the parent does get broadcast. self.log.info("If a package is partially submitted, transactions included in mempool get broadcast") peer = node.add_p2p_connection(P2PTxInvStore()) txs = self.wallet.create_self_transfer_chain(chain_length=2) bad_child = tx_from_hex(txs[1]["hex"]) - bad_child.nVersion = -1 + bad_child.version = 0xffffffff hex_partial_acceptance = [txs[0]["hex"], bad_child.serialize().hex()] res = node.submitpackage(hex_partial_acceptance) assert_equal(res["package_msg"], "transaction failed") @@ -388,7 +432,7 @@ class RPCPackagesTest(BitcoinTestFramework): ]) self.wallet.rescan_utxos() - fill_mempool(self, node, self.wallet) + fill_mempool(self, node) minrelay = node.getmempoolinfo()["minrelaytxfee"] parent = self.wallet.create_self_transfer( diff --git a/test/functional/rpc_rawtransaction.py b/test/functional/rpc_rawtransaction.py index 12697e9d0c..f974a05f7b 100755 --- a/test/functional/rpc_rawtransaction.py +++ b/test/functional/rpc_rawtransaction.py @@ -463,20 +463,34 @@ class RawTransactionsTest(BitcoinTestFramework): self.log.info("Test transaction version numbers") # Test the minimum transaction version number that fits in a signed 32-bit integer. - # As transaction version is unsigned, this should convert to its unsigned equivalent. + # As transaction version is serialized unsigned, this should convert to its unsigned equivalent. tx = CTransaction() - tx.nVersion = -0x80000000 + tx.version = 0x80000000 rawtx = tx.serialize().hex() decrawtx = self.nodes[0].decoderawtransaction(rawtx) assert_equal(decrawtx['version'], 0x80000000) # Test the maximum transaction version number that fits in a signed 32-bit integer. tx = CTransaction() - tx.nVersion = 0x7fffffff + tx.version = 0x7fffffff rawtx = tx.serialize().hex() decrawtx = self.nodes[0].decoderawtransaction(rawtx) assert_equal(decrawtx['version'], 0x7fffffff) + # Test the minimum transaction version number that fits in an unsigned 32-bit integer. + tx = CTransaction() + tx.version = 0 + rawtx = tx.serialize().hex() + decrawtx = self.nodes[0].decoderawtransaction(rawtx) + assert_equal(decrawtx['version'], 0) + + # Test the maximum transaction version number that fits in an unsigned 32-bit integer. + tx = CTransaction() + tx.version = 0xffffffff + rawtx = tx.serialize().hex() + decrawtx = self.nodes[0].decoderawtransaction(rawtx) + assert_equal(decrawtx['version'], 0xffffffff) + def raw_multisig_transaction_legacy_tests(self): self.log.info("Test raw multisig transactions (legacy)") # The traditional multisig workflow does not work with descriptor wallets so these are legacy only. @@ -490,11 +504,11 @@ class RawTransactionsTest(BitcoinTestFramework): addr2Obj = self.nodes[2].getaddressinfo(addr2) # Tests for createmultisig and addmultisigaddress - assert_raises_rpc_error(-5, "Invalid public key", self.nodes[0].createmultisig, 1, ["01020304"]) + assert_raises_rpc_error(-5, 'Pubkey "01020304" must have a length of either 33 or 65 bytes', self.nodes[0].createmultisig, 1, ["01020304"]) # createmultisig can only take public keys self.nodes[0].createmultisig(2, [addr1Obj['pubkey'], addr2Obj['pubkey']]) # addmultisigaddress can take both pubkeys and addresses so long as they are in the wallet, which is tested here - assert_raises_rpc_error(-5, "Invalid public key", self.nodes[0].createmultisig, 2, [addr1Obj['pubkey'], addr1]) + assert_raises_rpc_error(-5, f'Pubkey "{addr1}" must be a hex string', self.nodes[0].createmultisig, 2, [addr1Obj['pubkey'], addr1]) mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr1])['address'] @@ -585,6 +599,8 @@ class RawTransactionsTest(BitcoinTestFramework): rawTxPartialSigned2 = self.nodes[2].signrawtransactionwithwallet(rawTx2, inputs) self.log.debug(rawTxPartialSigned2) assert_equal(rawTxPartialSigned2['complete'], False) # node2 only has one key, can't comp. sign the tx + assert_raises_rpc_error(-22, "TX decode failed", self.nodes[0].combinerawtransaction, [rawTxPartialSigned1['hex'], rawTxPartialSigned2['hex'] + "00"]) + assert_raises_rpc_error(-22, "Missing transactions", self.nodes[0].combinerawtransaction, []) rawTxComb = self.nodes[2].combinerawtransaction([rawTxPartialSigned1['hex'], rawTxPartialSigned2['hex']]) self.log.debug(rawTxComb) self.nodes[2].sendrawtransaction(rawTxComb) @@ -592,6 +608,7 @@ class RawTransactionsTest(BitcoinTestFramework): self.sync_all() self.generate(self.nodes[0], 1) assert_equal(self.nodes[0].getbalance(), bal + Decimal('50.00000000') + Decimal('2.19000000')) # block reward + tx + assert_raises_rpc_error(-25, "Input not found or already spent", self.nodes[0].combinerawtransaction, [rawTxPartialSigned1['hex'], rawTxPartialSigned2['hex']]) if __name__ == '__main__': diff --git a/test/functional/rpc_signrawtransactionwithkey.py b/test/functional/rpc_signrawtransactionwithkey.py index 268584331e..f4fec13495 100755 --- a/test/functional/rpc_signrawtransactionwithkey.py +++ b/test/functional/rpc_signrawtransactionwithkey.py @@ -126,10 +126,20 @@ class SignRawTransactionWithKeyTest(BitcoinTestFramework): privkeys = [self.nodes[0].get_deterministic_priv_key().key] assert_raises_rpc_error(-8, "'all' is not a valid sighash parameter.", self.nodes[0].signrawtransactionwithkey, tx, privkeys, sighashtype="all") + def invalid_private_key_and_tx(self): + self.log.info("Test signing transaction with an invalid private key") + tx = self.nodes[0].createrawtransaction(INPUTS, OUTPUTS) + privkeys = ["123"] + assert_raises_rpc_error(-5, "Invalid private key", self.nodes[0].signrawtransactionwithkey, tx, privkeys) + self.log.info("Test signing transaction with an invalid tx hex") + privkeys = [self.nodes[0].get_deterministic_priv_key().key] + assert_raises_rpc_error(-22, "TX decode failed. Make sure the tx has at least one input.", self.nodes[0].signrawtransactionwithkey, tx + "00", privkeys) + def run_test(self): self.successful_signing_test() self.witness_script_test() self.invalid_sighashtype_test() + self.invalid_private_key_and_tx() if __name__ == '__main__': diff --git a/test/functional/test-shell.md b/test/functional/test-shell.md index b89b40f13d..4cd62c4ef3 100644 --- a/test/functional/test-shell.md +++ b/test/functional/test-shell.md @@ -123,11 +123,11 @@ We can also log custom events to the logger. ``` **Note: Please also consider the functional test -[readme](../test/functional/README.md), which provides an overview of the +[readme](/test/functional/README.md), which provides an overview of the test-framework**. Modules such as -[key.py](../test/functional/test_framework/key.py), -[script.py](../test/functional/test_framework/script.py) and -[messages.py](../test/functional/test_framework/messages.py) are particularly +[key.py](/test/functional/test_framework/key.py), +[script.py](/test/functional/test_framework/script.py) and +[messages.py](/test/functional/test_framework/messages.py) are particularly useful in constructing objects which can be passed to the bitcoind nodes managed by a running `TestShell` object. diff --git a/test/functional/test_framework/address.py b/test/functional/test_framework/address.py index 5b2e3289a9..bcb38b21cd 100644 --- a/test/functional/test_framework/address.py +++ b/test/functional/test_framework/address.py @@ -47,7 +47,7 @@ class AddressType(enum.Enum): b58chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' -def create_deterministic_address_bcrt1_p2tr_op_true(): +def create_deterministic_address_bcrt1_p2tr_op_true(explicit_internal_key=None): """ Generates a deterministic bech32m address (segwit v1 output) that can be spent with a witness stack of OP_TRUE and the control block @@ -55,9 +55,10 @@ def create_deterministic_address_bcrt1_p2tr_op_true(): Returns a tuple with the generated address and the internal key. """ - internal_key = (1).to_bytes(32, 'big') + internal_key = explicit_internal_key or (1).to_bytes(32, 'big') address = output_key_to_p2tr(taproot_construct(internal_key, [(None, CScript([OP_TRUE]))]).output_pubkey) - assert_equal(address, 'bcrt1p9yfmy5h72durp7zrhlw9lf7jpwjgvwdg0jr0lqmmjtgg83266lqsekaqka') + if explicit_internal_key is None: + assert_equal(address, 'bcrt1p9yfmy5h72durp7zrhlw9lf7jpwjgvwdg0jr0lqmmjtgg83266lqsekaqka') return (address, internal_key) diff --git a/test/functional/test_framework/authproxy.py b/test/functional/test_framework/authproxy.py index 03042877b2..a357ae4d34 100644 --- a/test/functional/test_framework/authproxy.py +++ b/test/functional/test_framework/authproxy.py @@ -26,7 +26,7 @@ ServiceProxy class: - HTTP connections persist for the life of the AuthServiceProxy object (if server supports HTTP/1.1) -- sends protocol 'version', per JSON-RPC 1.1 +- sends "jsonrpc":"2.0", per JSON-RPC 2.0 - sends proper, incrementing 'id' - sends Basic HTTP authentication headers - parses all JSON numbers that look like floats as Decimal @@ -117,7 +117,7 @@ class AuthServiceProxy(): params = dict(args=args, **argsn) else: params = args or argsn - return {'version': '1.1', + return {'jsonrpc': '2.0', 'method': self._service_name, 'params': params, 'id': AuthServiceProxy.__id_count} @@ -125,15 +125,28 @@ class AuthServiceProxy(): def __call__(self, *args, **argsn): postdata = json.dumps(self.get_request(*args, **argsn), default=serialization_fallback, ensure_ascii=self.ensure_ascii) response, status = self._request('POST', self.__url.path, postdata.encode('utf-8')) - if response['error'] is not None: - raise JSONRPCException(response['error'], status) - elif 'result' not in response: - raise JSONRPCException({ - 'code': -343, 'message': 'missing JSON-RPC result'}, status) - elif status != HTTPStatus.OK: - raise JSONRPCException({ - 'code': -342, 'message': 'non-200 HTTP status code but no JSON-RPC error'}, status) + # For backwards compatibility tests, accept JSON RPC 1.1 responses + if 'jsonrpc' not in response: + if response['error'] is not None: + raise JSONRPCException(response['error'], status) + elif 'result' not in response: + raise JSONRPCException({ + 'code': -343, 'message': 'missing JSON-RPC result'}, status) + elif status != HTTPStatus.OK: + raise JSONRPCException({ + 'code': -342, 'message': 'non-200 HTTP status code but no JSON-RPC error'}, status) + else: + return response['result'] else: + assert response['jsonrpc'] == '2.0' + if status != HTTPStatus.OK: + raise JSONRPCException({ + 'code': -342, 'message': 'non-200 HTTP status code'}, status) + if 'error' in response: + raise JSONRPCException(response['error'], status) + elif 'result' not in response: + raise JSONRPCException({ + 'code': -343, 'message': 'missing JSON-RPC 2.0 result and error'}, status) return response['result'] def batch(self, rpc_call_list): @@ -142,7 +155,7 @@ class AuthServiceProxy(): response, status = self._request('POST', self.__url.path, postdata.encode('utf-8')) if status != HTTPStatus.OK: raise JSONRPCException({ - 'code': -342, 'message': 'non-200 HTTP status code but no JSON-RPC error'}, status) + 'code': -342, 'message': 'non-200 HTTP status code'}, status) return response def _get_response(self): @@ -160,6 +173,15 @@ class AuthServiceProxy(): raise JSONRPCException({ 'code': -342, 'message': 'missing HTTP response from server'}) + # Check for no-content HTTP status code, which can be returned when an + # RPC client requests a JSON-RPC 2.0 "notification" with no response. + # Currently this is only possible if clients call the _request() method + # directly to send a raw request. + if http_response.status == HTTPStatus.NO_CONTENT: + if len(http_response.read()) != 0: + raise JSONRPCException({'code': -342, 'message': 'Content received with NO CONTENT status code'}) + return None, http_response.status + content_type = http_response.getheader('Content-Type') if content_type != 'application/json': raise JSONRPCException( diff --git a/test/functional/test_framework/crypto/secp256k1.py b/test/functional/test_framework/crypto/secp256k1.py index 2e9e419da5..50a46dce37 100644 --- a/test/functional/test_framework/crypto/secp256k1.py +++ b/test/functional/test_framework/crypto/secp256k1.py @@ -15,6 +15,8 @@ Exports: * G: the secp256k1 generator point """ +import unittest +from hashlib import sha256 class FE: """Objects of this class represent elements of the field GF(2**256 - 2**32 - 977). @@ -344,3 +346,9 @@ class FastGEMul: # Precomputed table with multiples of G for fast multiplication FAST_G = FastGEMul(G) + +class TestFrameworkSecp256k1(unittest.TestCase): + def test_H(self): + H = sha256(G.to_bytes_uncompressed()).digest() + assert GE.lift_x(FE.from_bytes(H)) is not None + self.assertEqual(H.hex(), "50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0") diff --git a/test/functional/test_framework/mempool_util.py b/test/functional/test_framework/mempool_util.py new file mode 100644 index 0000000000..148cc935ed --- /dev/null +++ b/test/functional/test_framework/mempool_util.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python3 +# Copyright (c) 2024 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +"""Helpful routines for mempool testing.""" +from decimal import Decimal + +from .blocktools import ( + COINBASE_MATURITY, +) +from .util import ( + assert_equal, + assert_greater_than, + create_lots_of_big_transactions, + gen_return_txouts, +) +from .wallet import ( + MiniWallet, +) + + +def fill_mempool(test_framework, node): + """Fill mempool until eviction. + + Allows for simpler testing of scenarios with floating mempoolminfee > minrelay + Requires -datacarriersize=100000 and + -maxmempool=5. + It will not ensure mempools become synced as it + is based on a single node and assumes -minrelaytxfee + is 1 sat/vbyte. + To avoid unintentional tx dependencies, the mempool filling txs are created with a + tagged ephemeral miniwallet instance. + """ + test_framework.log.info("Fill the mempool until eviction is triggered and the mempoolminfee rises") + txouts = gen_return_txouts() + relayfee = node.getnetworkinfo()['relayfee'] + + assert_equal(relayfee, Decimal('0.00001000')) + + tx_batch_size = 1 + num_of_batches = 75 + # Generate UTXOs to flood the mempool + # 1 to create a tx initially that will be evicted from the mempool later + # 75 transactions each with a fee rate higher than the previous one + ephemeral_miniwallet = MiniWallet(node, tag_name="fill_mempool_ephemeral_wallet") + test_framework.generate(ephemeral_miniwallet, 1 + num_of_batches * tx_batch_size) + + # Mine enough blocks so that the UTXOs are allowed to be spent + test_framework.generate(node, COINBASE_MATURITY - 1) + + # Get all UTXOs up front to ensure none of the transactions spend from each other, as that may + # change their effective feerate and thus the order in which they are selected for eviction. + confirmed_utxos = [ephemeral_miniwallet.get_utxo(confirmed_only=True) for _ in range(num_of_batches * tx_batch_size + 1)] + assert_equal(len(confirmed_utxos), num_of_batches * tx_batch_size + 1) + + test_framework.log.debug("Create a mempool tx that will be evicted") + tx_to_be_evicted_id = ephemeral_miniwallet.send_self_transfer( + from_node=node, utxo_to_spend=confirmed_utxos.pop(0), fee_rate=relayfee)["txid"] + + # Increase the tx fee rate to give the subsequent transactions a higher priority in the mempool + # The tx has an approx. vsize of 65k, i.e. multiplying the previous fee rate (in sats/kvB) + # by 130 should result in a fee that corresponds to 2x of that fee rate + base_fee = relayfee * 130 + + test_framework.log.debug("Fill up the mempool with txs with higher fee rate") + with node.assert_debug_log(["rolling minimum fee bumped"]): + for batch_of_txid in range(num_of_batches): + fee = (batch_of_txid + 1) * base_fee + utxos = confirmed_utxos[:tx_batch_size] + create_lots_of_big_transactions(ephemeral_miniwallet, node, fee, tx_batch_size, txouts, utxos) + del confirmed_utxos[:tx_batch_size] + + test_framework.log.debug("The tx should be evicted by now") + # The number of transactions created should be greater than the ones present in the mempool + assert_greater_than(tx_batch_size * num_of_batches, len(node.getrawmempool())) + # Initial tx created should not be present in the mempool anymore as it had a lower fee rate + assert tx_to_be_evicted_id not in node.getrawmempool() + + test_framework.log.debug("Check that mempoolminfee is larger than minrelaytxfee") + assert_equal(node.getmempoolinfo()['minrelaytxfee'], Decimal('0.00001000')) + assert_greater_than(node.getmempoolinfo()['mempoolminfee'], Decimal('0.00001000')) diff --git a/test/functional/test_framework/messages.py b/test/functional/test_framework/messages.py index 4e496a9275..005f7546a8 100755 --- a/test/functional/test_framework/messages.py +++ b/test/functional/test_framework/messages.py @@ -560,12 +560,12 @@ class CTxWitness: class CTransaction: - __slots__ = ("hash", "nLockTime", "nVersion", "sha256", "vin", "vout", + __slots__ = ("hash", "nLockTime", "version", "sha256", "vin", "vout", "wit") def __init__(self, tx=None): if tx is None: - self.nVersion = 2 + self.version = 2 self.vin = [] self.vout = [] self.wit = CTxWitness() @@ -573,7 +573,7 @@ class CTransaction: self.sha256 = None self.hash = None else: - self.nVersion = tx.nVersion + self.version = tx.version self.vin = copy.deepcopy(tx.vin) self.vout = copy.deepcopy(tx.vout) self.nLockTime = tx.nLockTime @@ -582,7 +582,7 @@ class CTransaction: self.wit = copy.deepcopy(tx.wit) def deserialize(self, f): - self.nVersion = int.from_bytes(f.read(4), "little", signed=True) + self.version = int.from_bytes(f.read(4), "little") self.vin = deser_vector(f, CTxIn) flags = 0 if len(self.vin) == 0: @@ -605,7 +605,7 @@ class CTransaction: def serialize_without_witness(self): r = b"" - r += self.nVersion.to_bytes(4, "little", signed=True) + r += self.version.to_bytes(4, "little") r += ser_vector(self.vin) r += ser_vector(self.vout) r += self.nLockTime.to_bytes(4, "little") @@ -617,7 +617,7 @@ class CTransaction: if not self.wit.is_null(): flags |= 1 r = b"" - r += self.nVersion.to_bytes(4, "little", signed=True) + r += self.version.to_bytes(4, "little") if flags: dummy = [] r += ser_vector(dummy) @@ -677,8 +677,8 @@ class CTransaction: return math.ceil(self.get_weight() / WITNESS_SCALE_FACTOR) def __repr__(self): - return "CTransaction(nVersion=%i vin=%s vout=%s wit=%s nLockTime=%i)" \ - % (self.nVersion, repr(self.vin), repr(self.vout), repr(self.wit), self.nLockTime) + return "CTransaction(version=%i vin=%s vout=%s wit=%s nLockTime=%i)" \ + % (self.version, repr(self.vin), repr(self.vout), repr(self.wit), self.nLockTime) class CBlockHeader: diff --git a/test/functional/test_framework/p2p.py b/test/functional/test_framework/p2p.py index 00bd1e4017..4b846df94a 100755 --- a/test/functional/test_framework/p2p.py +++ b/test/functional/test_framework/p2p.py @@ -411,7 +411,7 @@ class P2PConnection(asyncio.Protocol): tmsg = self.magic_bytes tmsg += msgtype tmsg += b"\x00" * (12 - len(msgtype)) - tmsg += struct.pack("<I", len(data)) + tmsg += len(data).to_bytes(4, "little") th = sha256(data) h = sha256(th) tmsg += h[:4] diff --git a/test/functional/test_framework/script.py b/test/functional/test_framework/script.py index 7b19d31e17..97d62f957b 100644 --- a/test/functional/test_framework/script.py +++ b/test/functional/test_framework/script.py @@ -8,7 +8,6 @@ This file is modified from python-bitcoinlib. """ from collections import namedtuple -import struct import unittest from .key import TaggedHash, tweak_add_pubkey, compute_xonly_pubkey @@ -58,9 +57,9 @@ class CScriptOp(int): elif len(d) <= 0xff: return b'\x4c' + bytes([len(d)]) + d # OP_PUSHDATA1 elif len(d) <= 0xffff: - return b'\x4d' + struct.pack(b'<H', len(d)) + d # OP_PUSHDATA2 + return b'\x4d' + len(d).to_bytes(2, "little") + d # OP_PUSHDATA2 elif len(d) <= 0xffffffff: - return b'\x4e' + struct.pack(b'<I', len(d)) + d # OP_PUSHDATA4 + return b'\x4e' + len(d).to_bytes(4, "little") + d # OP_PUSHDATA4 else: raise ValueError("Data too long to encode in a PUSHDATA op") @@ -670,7 +669,7 @@ def LegacySignatureMsg(script, txTo, inIdx, hashtype): txtmp.vin.append(tmp) s = txtmp.serialize_without_witness() - s += struct.pack(b"<I", hashtype) + s += hashtype.to_bytes(4, "little") return (s, None) @@ -726,7 +725,7 @@ def SegwitV0SignatureMsg(script, txTo, inIdx, hashtype, amount): if (not (hashtype & SIGHASH_ANYONECANPAY) and (hashtype & 0x1f) != SIGHASH_SINGLE and (hashtype & 0x1f) != SIGHASH_NONE): serialize_sequence = bytes() for i in txTo.vin: - serialize_sequence += struct.pack("<I", i.nSequence) + serialize_sequence += i.nSequence.to_bytes(4, "little") hashSequence = uint256_from_str(hash256(serialize_sequence)) if ((hashtype & 0x1f) != SIGHASH_SINGLE and (hashtype & 0x1f) != SIGHASH_NONE): @@ -739,16 +738,16 @@ def SegwitV0SignatureMsg(script, txTo, inIdx, hashtype, amount): hashOutputs = uint256_from_str(hash256(serialize_outputs)) ss = bytes() - ss += struct.pack("<i", txTo.nVersion) + ss += txTo.version.to_bytes(4, "little") ss += ser_uint256(hashPrevouts) ss += ser_uint256(hashSequence) ss += txTo.vin[inIdx].prevout.serialize() ss += ser_string(script) - ss += struct.pack("<q", amount) - ss += struct.pack("<I", txTo.vin[inIdx].nSequence) + ss += amount.to_bytes(8, "little", signed=True) + ss += txTo.vin[inIdx].nSequence.to_bytes(4, "little") ss += ser_uint256(hashOutputs) ss += txTo.nLockTime.to_bytes(4, "little") - ss += struct.pack("<I", hashtype) + ss += hashtype.to_bytes(4, "little") return ss def SegwitV0SignatureHash(*args, **kwargs): @@ -800,13 +799,13 @@ def BIP341_sha_prevouts(txTo): return sha256(b"".join(i.prevout.serialize() for i in txTo.vin)) def BIP341_sha_amounts(spent_utxos): - return sha256(b"".join(struct.pack("<q", u.nValue) for u in spent_utxos)) + return sha256(b"".join(u.nValue.to_bytes(8, "little", signed=True) for u in spent_utxos)) def BIP341_sha_scriptpubkeys(spent_utxos): return sha256(b"".join(ser_string(u.scriptPubKey) for u in spent_utxos)) def BIP341_sha_sequences(txTo): - return sha256(b"".join(struct.pack("<I", i.nSequence) for i in txTo.vin)) + return sha256(b"".join(i.nSequence.to_bytes(4, "little") for i in txTo.vin)) def BIP341_sha_outputs(txTo): return sha256(b"".join(o.serialize() for o in txTo.vout)) @@ -818,8 +817,8 @@ def TaprootSignatureMsg(txTo, spent_utxos, hash_type, input_index = 0, scriptpat in_type = hash_type & SIGHASH_ANYONECANPAY spk = spent_utxos[input_index].scriptPubKey ss = bytes([0, hash_type]) # epoch, hash_type - ss += struct.pack("<i", txTo.nVersion) - ss += struct.pack("<I", txTo.nLockTime) + ss += txTo.version.to_bytes(4, "little") + ss += txTo.nLockTime.to_bytes(4, "little") if in_type != SIGHASH_ANYONECANPAY: ss += BIP341_sha_prevouts(txTo) ss += BIP341_sha_amounts(spent_utxos) @@ -835,11 +834,11 @@ def TaprootSignatureMsg(txTo, spent_utxos, hash_type, input_index = 0, scriptpat ss += bytes([spend_type]) if in_type == SIGHASH_ANYONECANPAY: ss += txTo.vin[input_index].prevout.serialize() - ss += struct.pack("<q", spent_utxos[input_index].nValue) + ss += spent_utxos[input_index].nValue.to_bytes(8, "little", signed=True) ss += ser_string(spk) - ss += struct.pack("<I", txTo.vin[input_index].nSequence) + ss += txTo.vin[input_index].nSequence.to_bytes(4, "little") else: - ss += struct.pack("<I", input_index) + ss += input_index.to_bytes(4, "little") if (spend_type & 1): ss += sha256(ser_string(annex)) if out_type == SIGHASH_SINGLE: @@ -850,7 +849,7 @@ def TaprootSignatureMsg(txTo, spent_utxos, hash_type, input_index = 0, scriptpat if (scriptpath): ss += TaggedHash("TapLeaf", bytes([leaf_ver]) + ser_string(script)) ss += bytes([0]) - ss += struct.pack("<i", codeseparator_pos) + ss += codeseparator_pos.to_bytes(4, "little", signed=True) assert len(ss) == 175 - (in_type == SIGHASH_ANYONECANPAY) * 49 - (out_type != SIGHASH_ALL and out_type != SIGHASH_SINGLE) * 32 + (annex is not None) * 32 + scriptpath * 37 return ss diff --git a/test/functional/test_framework/script_util.py b/test/functional/test_framework/script_util.py index 62894cc0f4..855f3b8cf5 100755 --- a/test/functional/test_framework/script_util.py +++ b/test/functional/test_framework/script_util.py @@ -3,10 +3,13 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Useful Script constants and utils.""" +import unittest + from test_framework.script import ( CScript, - CScriptOp, OP_0, + OP_15, + OP_16, OP_CHECKMULTISIG, OP_CHECKSIG, OP_DUP, @@ -49,10 +52,8 @@ def keys_to_multisig_script(keys, *, k=None): if k is None: # n-of-n multisig by default k = n assert k <= n - op_k = CScriptOp.encode_op_n(k) - op_n = CScriptOp.encode_op_n(n) checked_keys = [check_key(key) for key in keys] - return CScript([op_k] + checked_keys + [op_n, OP_CHECKMULTISIG]) + return CScript([k] + checked_keys + [n, OP_CHECKMULTISIG]) def keyhash_to_p2pkh_script(hash): @@ -125,3 +126,19 @@ def check_script(script): if isinstance(script, bytes) or isinstance(script, CScript): return script assert False + + +class TestFrameworkScriptUtil(unittest.TestCase): + def test_multisig(self): + fake_pubkey = bytes([0]*33) + # check correct encoding of P2MS script with n,k <= 16 + normal_ms_script = keys_to_multisig_script([fake_pubkey]*16, k=15) + self.assertEqual(len(normal_ms_script), 1 + 16*34 + 1 + 1) + self.assertTrue(normal_ms_script.startswith(bytes([OP_15]))) + self.assertTrue(normal_ms_script.endswith(bytes([OP_16, OP_CHECKMULTISIG]))) + + # check correct encoding of P2MS script with n,k > 16 + max_ms_script = keys_to_multisig_script([fake_pubkey]*20, k=19) + self.assertEqual(len(max_ms_script), 2 + 20*34 + 2 + 1) + self.assertTrue(max_ms_script.startswith(bytes([1, 19]))) # using OP_PUSH1 + self.assertTrue(max_ms_script.endswith(bytes([1, 20, OP_CHECKMULTISIG]))) diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py index a2f767cc98..9e44a11143 100755 --- a/test/functional/test_framework/test_framework.py +++ b/test/functional/test_framework/test_framework.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2014-2022 The Bitcoin Core developers +# Copyright (c) 2014-present The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Base class for RPC testing.""" @@ -444,6 +444,10 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass): n.createwallet(wallet_name=wallet_name, descriptors=self.options.descriptors, load_on_startup=True) n.importprivkey(privkey=n.get_deterministic_priv_key().key, label='coinbase', rescan=True) + # Only enables wallet support when the module is available + def enable_wallet_if_possible(self): + self._requires_wallet = self.is_wallet_compiled() + def run_test(self): """Tests must override this method to define test logic""" raise NotImplementedError @@ -610,8 +614,6 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass): """ from_connection = self.nodes[a] to_connection = self.nodes[b] - from_num_peers = 1 + len(from_connection.getpeerinfo()) - to_num_peers = 1 + len(to_connection.getpeerinfo()) ip_port = "127.0.0.1:" + str(p2p_port(b)) if peer_advertises_v2 is None: @@ -627,19 +629,28 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass): if not wait_for_connect: return - # poll until version handshake complete to avoid race conditions - # with transaction relaying - # See comments in net_processing: - # * Must have a version message before anything else - # * Must have a verack message before anything else - self.wait_until(lambda: sum(peer['version'] != 0 for peer in from_connection.getpeerinfo()) == from_num_peers) - self.wait_until(lambda: sum(peer['version'] != 0 for peer in to_connection.getpeerinfo()) == to_num_peers) - self.wait_until(lambda: sum(peer['bytesrecv_per_msg'].pop('verack', 0) >= 21 for peer in from_connection.getpeerinfo()) == from_num_peers) - self.wait_until(lambda: sum(peer['bytesrecv_per_msg'].pop('verack', 0) >= 21 for peer in to_connection.getpeerinfo()) == to_num_peers) - # The message bytes are counted before processing the message, so make - # sure it was fully processed by waiting for a ping. - self.wait_until(lambda: sum(peer["bytesrecv_per_msg"].pop("pong", 0) >= 29 for peer in from_connection.getpeerinfo()) == from_num_peers) - self.wait_until(lambda: sum(peer["bytesrecv_per_msg"].pop("pong", 0) >= 29 for peer in to_connection.getpeerinfo()) == to_num_peers) + # Use subversion as peer id. Test nodes have their node number appended to the user agent string + from_connection_subver = from_connection.getnetworkinfo()['subversion'] + to_connection_subver = to_connection.getnetworkinfo()['subversion'] + + def find_conn(node, peer_subversion, inbound): + return next(filter(lambda peer: peer['subver'] == peer_subversion and peer['inbound'] == inbound, node.getpeerinfo()), None) + + self.wait_until(lambda: find_conn(from_connection, to_connection_subver, inbound=False) is not None) + self.wait_until(lambda: find_conn(to_connection, from_connection_subver, inbound=True) is not None) + + def check_bytesrecv(peer, msg_type, min_bytes_recv): + assert peer is not None, "Error: peer disconnected" + return peer['bytesrecv_per_msg'].pop(msg_type, 0) >= min_bytes_recv + + # Poll until version handshake (fSuccessfullyConnected) is complete to + # avoid race conditions, because some message types are blocked from + # being sent or received before fSuccessfullyConnected. + # + # As the flag fSuccessfullyConnected is not exposed, check it by + # waiting for a pong, which can only happen after the flag was set. + self.wait_until(lambda: check_bytesrecv(find_conn(from_connection, to_connection_subver, inbound=False), 'pong', 29)) + self.wait_until(lambda: check_bytesrecv(find_conn(to_connection, from_connection_subver, inbound=True), 'pong', 29)) def disconnect_nodes(self, a, b): def disconnect_nodes_helper(node_a, node_b): diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py index 67e0be5280..0ac0af27d5 100755 --- a/test/functional/test_framework/test_node.py +++ b/test/functional/test_framework/test_node.py @@ -106,7 +106,7 @@ class TestNode(): "-debugexclude=libevent", "-debugexclude=leveldb", "-debugexclude=rand", - "-uacomment=testnode%d" % i, + "-uacomment=testnode%d" % i, # required for subversion uniqueness across peers ] if self.descriptors is None: self.args.append("-disablewallet") @@ -241,7 +241,7 @@ class TestNode(): if self.start_perf: self._start_perf() - def wait_for_rpc_connection(self): + def wait_for_rpc_connection(self, *, wait_for_import=True): """Sets up an RPC connection to the bitcoind process. Returns False if unable to connect.""" # Poll at a rate of four times per second poll_per_s = 4 @@ -263,7 +263,7 @@ class TestNode(): ) rpc.getblockcount() # If the call to getblockcount() succeeds then the RPC connection is up - if self.version_is_at_least(190000): + if self.version_is_at_least(190000) and wait_for_import: # getmempoolinfo.loaded is available since commit # bb8ae2c (version 0.19.0) self.wait_until(lambda: rpc.getmempoolinfo()['loaded']) @@ -419,8 +419,9 @@ class TestNode(): return True def wait_until_stopped(self, *, timeout=BITCOIND_PROC_WAIT_TIMEOUT, expect_error=False, **kwargs): - expected_ret_code = 1 if expect_error else 0 # Whether node shutdown return EXIT_FAILURE or EXIT_SUCCESS - self.wait_until(lambda: self.is_node_stopped(expected_ret_code=expected_ret_code, **kwargs), timeout=timeout) + if "expected_ret_code" not in kwargs: + kwargs["expected_ret_code"] = 1 if expect_error else 0 # Whether node shutdown return EXIT_FAILURE or EXIT_SUCCESS + self.wait_until(lambda: self.is_node_stopped(**kwargs), timeout=timeout) def replace_in_config(self, replacements): """ @@ -490,7 +491,7 @@ class TestNode(): self._raise_assertion_error('Expected messages "{}" does not partially match log:\n\n{}\n\n'.format(str(expected_msgs), print_log)) @contextlib.contextmanager - def wait_for_debug_log(self, expected_msgs, timeout=60): + def busy_wait_for_debug_log(self, expected_msgs, timeout=60): """ Block until we see a particular debug log message fragment or until we exceed the timeout. Return: diff --git a/test/functional/test_framework/util.py b/test/functional/test_framework/util.py index 0de09b6440..c5b69a3954 100644 --- a/test/functional/test_framework/util.py +++ b/test/functional/test_framework/util.py @@ -496,65 +496,6 @@ def check_node_connections(*, node, num_in, num_out): assert_equal(info["connections_in"], num_in) assert_equal(info["connections_out"], num_out) -def fill_mempool(test_framework, node, miniwallet): - """Fill mempool until eviction. - - Allows for simpler testing of scenarios with floating mempoolminfee > minrelay - Requires -datacarriersize=100000 and - -maxmempool=5. - It will not ensure mempools become synced as it - is based on a single node and assumes -minrelaytxfee - is 1 sat/vbyte. - To avoid unintentional tx dependencies, it is recommended to use separate miniwallets for - mempool filling vs transactions in tests. - """ - test_framework.log.info("Fill the mempool until eviction is triggered and the mempoolminfee rises") - txouts = gen_return_txouts() - relayfee = node.getnetworkinfo()['relayfee'] - - assert_equal(relayfee, Decimal('0.00001000')) - - tx_batch_size = 1 - num_of_batches = 75 - # Generate UTXOs to flood the mempool - # 1 to create a tx initially that will be evicted from the mempool later - # 75 transactions each with a fee rate higher than the previous one - test_framework.generate(miniwallet, 1 + (num_of_batches * tx_batch_size)) - - # Mine COINBASE_MATURITY - 1 blocks so that the UTXOs are allowed to be spent - test_framework.generate(node, 100 - 1) - - # Get all UTXOs up front to ensure none of the transactions spend from each other, as that may - # change their effective feerate and thus the order in which they are selected for eviction. - confirmed_utxos = [miniwallet.get_utxo(confirmed_only=True) for _ in range(num_of_batches * tx_batch_size + 1)] - assert_equal(len(confirmed_utxos), num_of_batches * tx_batch_size + 1) - - test_framework.log.debug("Create a mempool tx that will be evicted") - tx_to_be_evicted_id = miniwallet.send_self_transfer(from_node=node, utxo_to_spend=confirmed_utxos[0], fee_rate=relayfee)["txid"] - del confirmed_utxos[0] - - # Increase the tx fee rate to give the subsequent transactions a higher priority in the mempool - # The tx has an approx. vsize of 65k, i.e. multiplying the previous fee rate (in sats/kvB) - # by 130 should result in a fee that corresponds to 2x of that fee rate - base_fee = relayfee * 130 - - test_framework.log.debug("Fill up the mempool with txs with higher fee rate") - with node.assert_debug_log(["rolling minimum fee bumped"]): - for batch_of_txid in range(num_of_batches): - fee = (batch_of_txid + 1) * base_fee - utxos = confirmed_utxos[:tx_batch_size] - create_lots_of_big_transactions(miniwallet, node, fee, tx_batch_size, txouts, utxos) - del confirmed_utxos[:tx_batch_size] - - test_framework.log.debug("The tx should be evicted by now") - # The number of transactions created should be greater than the ones present in the mempool - assert_greater_than(tx_batch_size * num_of_batches, len(node.getrawmempool())) - # Initial tx created should not be present in the mempool anymore as it had a lower fee rate - assert tx_to_be_evicted_id not in node.getrawmempool() - - test_framework.log.debug("Check that mempoolminfee is larger than minrelaytxfee") - assert_equal(node.getmempoolinfo()['minrelaytxfee'], Decimal('0.00001000')) - assert_greater_than(node.getmempoolinfo()['mempoolminfee'], Decimal('0.00001000')) # Transaction/Block functions ############################# diff --git a/test/functional/test_framework/wallet.py b/test/functional/test_framework/wallet.py index 470ed08ed4..cb0d291361 100644 --- a/test/functional/test_framework/wallet.py +++ b/test/functional/test_framework/wallet.py @@ -7,6 +7,7 @@ from copy import deepcopy from decimal import Decimal from enum import Enum +import math from typing import ( Any, Optional, @@ -32,10 +33,14 @@ from test_framework.messages import ( CTxIn, CTxInWitness, CTxOut, + hash256, + ser_compact_size, + WITNESS_SCALE_FACTOR, ) from test_framework.script import ( CScript, LEAF_VERSION_TAPSCRIPT, + OP_1, OP_NOP, OP_RETURN, OP_TRUE, @@ -51,6 +56,7 @@ from test_framework.script_util import ( from test_framework.util import ( assert_equal, assert_greater_than_or_equal, + get_fee, ) from test_framework.wallet_util import generate_keypair @@ -65,7 +71,10 @@ class MiniWalletMode(Enum): However, if the transactions need to be modified by the user (e.g. prepending scriptSig for testing opcodes that are activated by a soft-fork), or the txs should contain an actual signature, the raw modes RAW_OP_TRUE and RAW_P2PK - can be useful. Summary of modes: + can be useful. In order to avoid mixing of UTXOs between different MiniWallet + instances, a tag name can be passed to the default mode, to create different + output scripts. Note that the UTXOs from the pre-generated test chain can + only be spent if no tag is passed. Summary of modes: | output | | tx is | can modify | needs mode | description | address | standard | scriptSig | signing @@ -80,22 +89,25 @@ class MiniWalletMode(Enum): class MiniWallet: - def __init__(self, test_node, *, mode=MiniWalletMode.ADDRESS_OP_TRUE): + def __init__(self, test_node, *, mode=MiniWalletMode.ADDRESS_OP_TRUE, tag_name=None): self._test_node = test_node self._utxos = [] self._mode = mode assert isinstance(mode, MiniWalletMode) if mode == MiniWalletMode.RAW_OP_TRUE: + assert tag_name is None self._scriptPubKey = bytes(CScript([OP_TRUE])) elif mode == MiniWalletMode.RAW_P2PK: # use simple deterministic private key (k=1) + assert tag_name is None self._priv_key = ECKey() self._priv_key.set((1).to_bytes(32, 'big'), True) pub_key = self._priv_key.get_pubkey() self._scriptPubKey = key_to_p2pk_script(pub_key.get_bytes()) elif mode == MiniWalletMode.ADDRESS_OP_TRUE: - self._address, self._internal_key = create_deterministic_address_bcrt1_p2tr_op_true() + internal_key = None if tag_name is None else hash256(tag_name.encode()) + self._address, self._internal_key = create_deterministic_address_bcrt1_p2tr_op_true(internal_key) self._scriptPubKey = address_to_scriptpubkey(self._address) # When the pre-mined test framework chain is used, it contains coinbase @@ -112,13 +124,16 @@ class MiniWallet: """Pad a transaction with extra outputs until it reaches a target weight (or higher). returns the tx """ - tx.vout.append(CTxOut(nValue=0, scriptPubKey=CScript([OP_RETURN, b'a']))) + tx.vout.append(CTxOut(nValue=0, scriptPubKey=CScript([OP_RETURN]))) + # determine number of needed padding bytes by converting weight difference to vbytes dummy_vbytes = (target_weight - tx.get_weight() + 3) // 4 - tx.vout[-1].scriptPubKey = CScript([OP_RETURN, b'a' * dummy_vbytes]) - # Lower bound should always be off by at most 3 + # compensate for the increase of the compact-size encoded script length + # (note that the length encoding of the unpadded output script needs one byte) + dummy_vbytes -= len(ser_compact_size(dummy_vbytes)) - 1 + tx.vout[-1].scriptPubKey = CScript([OP_RETURN] + [OP_1] * dummy_vbytes) + # Actual weight should be at most 3 higher than target weight assert_greater_than_or_equal(tx.get_weight(), target_weight) - # Higher bound should always be off by at most 3 + 12 weight (for encoding the length) - assert_greater_than_or_equal(target_weight + 15, tx.get_weight()) + assert_greater_than_or_equal(target_weight + 3, tx.get_weight()) def get_balance(self): return sum(u['value'] for u in self._utxos) @@ -314,7 +329,7 @@ class MiniWallet: tx = CTransaction() tx.vin = [CTxIn(COutPoint(int(utxo_to_spend['txid'], 16), utxo_to_spend['vout']), nSequence=seq) for utxo_to_spend, seq in zip(utxos_to_spend, sequence)] tx.vout = [CTxOut(amount_per_output, bytearray(self._scriptPubKey)) for _ in range(num_outputs)] - tx.nVersion = version + tx.version = version tx.nLockTime = locktime self.sign_tx(tx) @@ -360,6 +375,10 @@ class MiniWallet: vsize = Decimal(168) # P2PK (73 bytes scriptSig + 35 bytes scriptPubKey + 60 bytes other) else: assert False + if target_weight and not fee: # respect fee_rate if target weight is passed + # the actual weight might be off by 3 WUs, so calculate based on that (see self._bulk_tx) + max_actual_weight = target_weight + 3 + fee = get_fee(math.ceil(max_actual_weight / WITNESS_SCALE_FACTOR), fee_rate) send_value = utxo_to_spend["value"] - (fee or (fee_rate * vsize / 1000)) # create tx diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index 2b0b24ec05..8475dc5faa 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -15,8 +15,10 @@ For a description of arguments recognized by test scripts, see import argparse from collections import deque import configparser +import csv import datetime import os +import pathlib import platform import time import shutil @@ -29,6 +31,13 @@ import logging os.environ["REQUIRE_WALLET_TYPE_SET"] = "1" +# Minimum amount of space to run the tests. +MIN_FREE_SPACE = 1.1 * 1024 * 1024 * 1024 +# Additional space to run an extra job. +ADDITIONAL_SPACE_PER_JOB = 100 * 1024 * 1024 +# Minimum amount of space required for --nocleanup +MIN_NO_CLEANUP_SPACE = 12 * 1024 * 1024 * 1024 + # Formatting. Default colors to empty strings. DEFAULT, BOLD, GREEN, RED = ("", ""), ("", ""), ("", ""), ("", "") try: @@ -176,6 +185,8 @@ BASE_SCRIPTS = [ 'mempool_resurrect.py', 'wallet_txn_doublespend.py --mineblock', 'tool_wallet.py --legacy-wallet', + 'tool_wallet.py --legacy-wallet --bdbro', + 'tool_wallet.py --legacy-wallet --bdbro --swap-bdb-endian', 'tool_wallet.py --descriptors', 'tool_signet_miner.py --legacy-wallet', 'tool_signet_miner.py --descriptors', @@ -271,6 +282,7 @@ BASE_SCRIPTS = [ 'mempool_packages.py', 'mempool_package_onemore.py', 'mempool_package_limits.py', + 'mempool_package_rbf.py', 'feature_versionbits_warning.py', 'rpc_preciousblock.py', 'wallet_importprunedfunds.py --legacy-wallet', @@ -278,6 +290,7 @@ BASE_SCRIPTS = [ 'p2p_leak_tx.py --v1transport', 'p2p_leak_tx.py --v2transport', 'p2p_eviction.py', + 'p2p_outbound_eviction.py', 'p2p_ibd_stalling.py --v1transport', 'p2p_ibd_stalling.py --v2transport', 'p2p_net_deadlock.py --v1transport', @@ -351,6 +364,7 @@ BASE_SCRIPTS = [ 'feature_addrman.py', 'feature_asmap.py', 'feature_fastprune.py', + 'feature_framework_miniwallet.py', 'mempool_unbroadcast.py', 'mempool_compatibility.py', 'mempool_accept_wtxid.py', @@ -426,6 +440,9 @@ def main(): parser.add_argument('--tmpdirprefix', '-t', default=tempfile.gettempdir(), help="Root directory for datadirs") parser.add_argument('--failfast', '-F', action='store_true', help='stop execution after the first test failure') parser.add_argument('--filter', help='filter scripts to run by regular expression') + parser.add_argument("--nocleanup", dest="nocleanup", default=False, action="store_true", + help="Leave bitcoinds and test.* datadir on exit or error") + parser.add_argument('--resultsfile', '-r', help='store test results (as CSV) to the provided file') args, unknown_args = parser.parse_known_args() @@ -458,6 +475,13 @@ def main(): logging.debug("Temporary test directory at %s" % tmpdir) + results_filepath = None + if args.resultsfile: + results_filepath = pathlib.Path(args.resultsfile) + # Stop early if the parent directory doesn't exist + assert results_filepath.parent.exists(), "Results file parent directory does not exist" + logging.debug("Test results will be written to " + str(results_filepath)) + enable_bitcoind = config["components"].getboolean("ENABLE_BITCOIND") if not enable_bitcoind: @@ -520,6 +544,13 @@ def main(): subprocess.check_call([sys.executable, os.path.join(config["environment"]["SRCDIR"], 'test', 'functional', test_list[0].split()[0]), '-h']) sys.exit(0) + # Warn if there is not enough space on tmpdir to run the tests with --nocleanup + if args.nocleanup: + if shutil.disk_usage(tmpdir).free < MIN_NO_CLEANUP_SPACE: + print(f"{BOLD[1]}WARNING!{BOLD[0]} There may be insufficient free space in {tmpdir} to run the functional test suite with --nocleanup. " + f"A minimum of {MIN_NO_CLEANUP_SPACE // (1024 * 1024 * 1024)} GB of free space is required.") + passon_args.append("--nocleanup") + check_script_list(src_dir=config["environment"]["SRCDIR"], fail_on_warn=args.ci) check_script_prefixes() @@ -537,9 +568,10 @@ def main(): combined_logs_len=args.combinedlogslen, failfast=args.failfast, use_term_control=args.ansi, + results_filepath=results_filepath, ) -def run_tests(*, test_list, src_dir, build_dir, tmpdir, jobs=1, enable_coverage=False, args=None, combined_logs_len=0, failfast=False, use_term_control): +def run_tests(*, test_list, src_dir, build_dir, tmpdir, jobs=1, enable_coverage=False, args=None, combined_logs_len=0, failfast=False, use_term_control, results_filepath=None): args = args or [] # Warn if bitcoind is already running @@ -556,6 +588,11 @@ def run_tests(*, test_list, src_dir, build_dir, tmpdir, jobs=1, enable_coverage= if os.path.isdir(cache_dir): print("%sWARNING!%s There is a cache directory here: %s. If tests fail unexpectedly, try deleting the cache directory." % (BOLD[1], BOLD[0], cache_dir)) + # Warn if there is not enough space on the testing dir + min_space = MIN_FREE_SPACE + (jobs - 1) * ADDITIONAL_SPACE_PER_JOB + if shutil.disk_usage(tmpdir).free < min_space: + print(f"{BOLD[1]}WARNING!{BOLD[0]} There may be insufficient free space in {tmpdir} to run the Bitcoin functional test suite. " + f"Running the test suite with fewer than {min_space // (1024 * 1024)} MB of free space might cause tests to fail.") tests_dir = src_dir + '/test/functional/' # This allows `test_runner.py` to work from an out-of-source build directory using a symlink, @@ -625,7 +662,15 @@ def run_tests(*, test_list, src_dir, build_dir, tmpdir, jobs=1, enable_coverage= logging.debug("Early exiting after test failure") break - print_results(test_results, max_len_name, (int(time.time() - start_time))) + if "[Errno 28] No space left on device" in stdout: + sys.exit(f"Early exiting after test failure due to insufficient free space in {tmpdir}\n" + f"Test execution data left in {tmpdir}.\n" + f"Additional storage is needed to execute testing.") + + runtime = int(time.time() - start_time) + print_results(test_results, max_len_name, runtime) + if results_filepath: + write_results(test_results, results_filepath, runtime) if coverage: coverage_passed = coverage.report_rpc_coverage() @@ -672,6 +717,17 @@ def print_results(test_results, max_len_name, runtime): results += "Runtime: %s s\n" % (runtime) print(results) + +def write_results(test_results, filepath, total_runtime): + with open(filepath, mode="w", encoding="utf8") as results_file: + results_writer = csv.writer(results_file) + results_writer.writerow(['test', 'status', 'duration(seconds)']) + all_passed = True + for test_result in test_results: + all_passed = all_passed and test_result.was_successful + results_writer.writerow([test_result.name, test_result.status, str(test_result.time)]) + results_writer.writerow(['ALL', ("Passed" if all_passed else "Failed"), str(total_runtime)]) + class TestHandler: """ Trigger the test scripts passed in via the list. diff --git a/test/functional/tool_wallet.py b/test/functional/tool_wallet.py index fc042bca66..dcf74f6075 100755 --- a/test/functional/tool_wallet.py +++ b/test/functional/tool_wallet.py @@ -5,6 +5,7 @@ """Test bitcoin-wallet.""" import os +import platform import stat import subprocess import textwrap @@ -14,6 +15,7 @@ from collections import OrderedDict from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, + assert_greater_than, sha256sum_file, ) @@ -21,11 +23,15 @@ from test_framework.util import ( class ToolWalletTest(BitcoinTestFramework): def add_options(self, parser): self.add_wallet_options(parser) + parser.add_argument("--bdbro", action="store_true", help="Use the BerkeleyRO internal parser when dumping a Berkeley DB wallet file") + parser.add_argument("--swap-bdb-endian", action="store_true",help="When making Legacy BDB wallets, always make then byte swapped internally") def set_test_params(self): self.num_nodes = 1 self.setup_clean_chain = True self.rpc_timeout = 120 + if self.options.swap_bdb_endian: + self.extra_args = [["-swapbdbendian"]] def skip_test_if_missing_module(self): self.skip_if_no_wallet() @@ -35,15 +41,21 @@ class ToolWalletTest(BitcoinTestFramework): default_args = ['-datadir={}'.format(self.nodes[0].datadir_path), '-chain=%s' % self.chain] if not self.options.descriptors and 'create' in args: default_args.append('-legacy') + if "dump" in args and self.options.bdbro: + default_args.append("-withinternalbdb") return subprocess.Popen([self.options.bitcoinwallet] + default_args + list(args), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) def assert_raises_tool_error(self, error, *args): p = self.bitcoin_wallet_process(*args) stdout, stderr = p.communicate() - assert_equal(p.poll(), 1) assert_equal(stdout, '') - assert_equal(stderr.strip(), error) + if isinstance(error, tuple): + assert_equal(p.poll(), error[0]) + assert error[1] in stderr.strip() + else: + assert_equal(p.poll(), 1) + assert error in stderr.strip() def assert_tool_output(self, output, *args): p = self.bitcoin_wallet_process(*args) @@ -451,6 +463,88 @@ class ToolWalletTest(BitcoinTestFramework): ''') self.assert_tool_output(expected_output, "-wallet=conflicts", "info") + def test_dump_endianness(self): + self.log.info("Testing dumps of the same contents with different BDB endianness") + + self.start_node(0) + self.nodes[0].createwallet("endian") + self.stop_node(0) + + wallet_dump = self.nodes[0].datadir_path / "endian.dump" + self.assert_tool_output("The dumpfile may contain private keys. To ensure the safety of your Bitcoin, do not share the dumpfile.\n", "-wallet=endian", f"-dumpfile={wallet_dump}", "dump") + expected_dump = self.read_dump(wallet_dump) + + self.do_tool_createfromdump("native_endian", "endian.dump", "bdb") + native_dump = self.read_dump(self.nodes[0].datadir_path / "rt-native_endian.dump") + self.assert_dump(expected_dump, native_dump) + + self.do_tool_createfromdump("other_endian", "endian.dump", "bdb_swap") + other_dump = self.read_dump(self.nodes[0].datadir_path / "rt-other_endian.dump") + self.assert_dump(expected_dump, other_dump) + + def test_dump_very_large_records(self): + self.log.info("Test that wallets with large records are successfully dumped") + + self.start_node(0) + self.nodes[0].createwallet("bigrecords") + wallet = self.nodes[0].get_wallet_rpc("bigrecords") + + # Both BDB and sqlite have maximum page sizes of 65536 bytes, with defaults of 4096 + # When a record exceeds some size threshold, both BDB and SQLite will store the data + # in one or more overflow pages. We want to make sure that our tooling can dump such + # records, even when they span multiple pages. To make a large record, we just need + # to make a very big transaction. + self.generate(self.nodes[0], 101) + def_wallet = self.nodes[0].get_wallet_rpc(self.default_wallet_name) + outputs = {} + for i in range(500): + outputs[wallet.getnewaddress(address_type="p2sh-segwit")] = 0.01 + def_wallet.sendmany(amounts=outputs) + self.generate(self.nodes[0], 1) + send_res = wallet.sendall([def_wallet.getnewaddress()]) + self.generate(self.nodes[0], 1) + assert_equal(send_res["complete"], True) + tx = wallet.gettransaction(txid=send_res["txid"], verbose=True) + assert_greater_than(tx["decoded"]["size"], 70000) + + self.stop_node(0) + + wallet_dump = self.nodes[0].datadir_path / "bigrecords.dump" + self.assert_tool_output("The dumpfile may contain private keys. To ensure the safety of your Bitcoin, do not share the dumpfile.\n", "-wallet=bigrecords", f"-dumpfile={wallet_dump}", "dump") + dump = self.read_dump(wallet_dump) + for k,v in dump.items(): + if tx["hex"] in v: + break + else: + assert False, "Big transaction was not found in wallet dump" + + def test_dump_unclean_lsns(self): + if not self.options.bdbro: + return + self.log.info("Test that a legacy wallet that has not been compacted is not dumped by bdbro") + + self.start_node(0, extra_args=["-flushwallet=0"]) + self.nodes[0].createwallet("unclean_lsn") + wallet = self.nodes[0].get_wallet_rpc("unclean_lsn") + # First unload and load normally to make sure everything is written + wallet.unloadwallet() + self.nodes[0].loadwallet("unclean_lsn") + # Next cause a bunch of writes by filling the keypool + wallet.keypoolrefill(wallet.getwalletinfo()["keypoolsize"] + 100) + # Lastly kill bitcoind so that the LSNs don't get reset + self.nodes[0].process.kill() + self.nodes[0].wait_until_stopped(expected_ret_code=1 if platform.system() == "Windows" else -9) + assert self.nodes[0].is_node_stopped() + + wallet_dump = self.nodes[0].datadir_path / "unclean_lsn.dump" + self.assert_raises_tool_error("LSNs are not reset, this database is not completely flushed. Please reopen then close the database with a version that has BDB support", "-wallet=unclean_lsn", f"-dumpfile={wallet_dump}", "dump") + + # File can be dumped after reload it normally + self.start_node(0) + self.nodes[0].loadwallet("unclean_lsn") + self.stop_node(0) + self.assert_tool_output("The dumpfile may contain private keys. To ensure the safety of your Bitcoin, do not share the dumpfile.\n", "-wallet=unclean_lsn", f"-dumpfile={wallet_dump}", "dump") + def run_test(self): self.wallet_path = self.nodes[0].wallets_path / self.default_wallet_name / self.wallet_data_filename self.test_invalid_tool_commands_and_args() @@ -462,8 +556,11 @@ class ToolWalletTest(BitcoinTestFramework): if not self.options.descriptors: # Salvage is a legacy wallet only thing self.test_salvage() + self.test_dump_endianness() + self.test_dump_unclean_lsns() self.test_dump_createfromdump() self.test_chainless_conflicts() + self.test_dump_very_large_records() if __name__ == '__main__': ToolWalletTest().main() diff --git a/test/functional/wallet_balance.py b/test/functional/wallet_balance.py index c322ae52c1..2c85773bf3 100755 --- a/test/functional/wallet_balance.py +++ b/test/functional/wallet_balance.py @@ -4,7 +4,6 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the wallet balance RPC methods.""" from decimal import Decimal -import struct from test_framework.address import ADDRESS_BCRT1_UNSPENDABLE as ADDRESS_WATCHONLY from test_framework.blocktools import COINBASE_MATURITY @@ -266,8 +265,8 @@ class WalletTest(BitcoinTestFramework): tx_orig = self.nodes[0].gettransaction(txid)['hex'] # Increase fee by 1 coin tx_replace = tx_orig.replace( - struct.pack("<q", 99 * 10**8).hex(), - struct.pack("<q", 98 * 10**8).hex(), + (99 * 10**8).to_bytes(8, "little", signed=True).hex(), + (98 * 10**8).to_bytes(8, "little", signed=True).hex(), ) tx_replace = self.nodes[0].signrawtransactionwithwallet(tx_replace)['hex'] # Total balance is given by the sum of outputs of the tx diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py index 56228d2bad..1b2b8ec1f3 100755 --- a/test/functional/wallet_basic.py +++ b/test/functional/wallet_basic.py @@ -461,10 +461,13 @@ class WalletTest(BitcoinTestFramework): assert_raises_rpc_error(-5, "Invalid Bitcoin address or script", self.nodes[0].importaddress, "invalid") # This will raise an exception for attempting to import a pubkey that isn't in hex - assert_raises_rpc_error(-5, "Pubkey must be a hex string", self.nodes[0].importpubkey, "not hex") + assert_raises_rpc_error(-5, 'Pubkey "not hex" must be a hex string', self.nodes[0].importpubkey, "not hex") - # This will raise an exception for importing an invalid pubkey - assert_raises_rpc_error(-5, "Pubkey is not a valid public key", self.nodes[0].importpubkey, "5361746f736869204e616b616d6f746f") + # This will raise exceptions for importing a pubkeys with invalid length / invalid coordinates + too_short_pubkey = "5361746f736869204e616b616d6f746f" + assert_raises_rpc_error(-5, f'Pubkey "{too_short_pubkey}" must have a length of either 33 or 65 bytes', self.nodes[0].importpubkey, too_short_pubkey) + not_on_curve_pubkey = bytes([4] + [0]*64).hex() # pubkey with coordinates (0,0) is not on curve + assert_raises_rpc_error(-5, f'Pubkey "{not_on_curve_pubkey}" must be cryptographically valid', self.nodes[0].importpubkey, not_on_curve_pubkey) # Bech32m addresses cannot be imported into a legacy wallet assert_raises_rpc_error(-5, "Bech32m addresses cannot be imported into legacy wallets", self.nodes[0].importaddress, "bcrt1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqc8gma6") diff --git a/test/functional/wallet_bumpfee.py b/test/functional/wallet_bumpfee.py index 5b7db55f45..6d45adc823 100755 --- a/test/functional/wallet_bumpfee.py +++ b/test/functional/wallet_bumpfee.py @@ -117,6 +117,7 @@ class BumpFeeTest(BitcoinTestFramework): # Context independent tests test_feerate_checks_replaced_outputs(self, rbf_node, peer_node) + test_bumpfee_with_feerate_ignores_walletincrementalrelayfee(self, rbf_node, peer_node) def test_invalid_parameters(self, rbf_node, peer_node, dest_address): self.log.info('Test invalid parameters') @@ -816,7 +817,7 @@ def test_feerate_checks_replaced_outputs(self, rbf_node, peer_node): # Since the bumped tx will replace all of the outputs with a single output, we can estimate that its size will 31 * (len(outputs) - 1) bytes smaller tx_size = tx_details["decoded"]["vsize"] est_bumped_size = tx_size - (len(tx_details["decoded"]["vout"]) - 1) * 31 - inc_fee_rate = max(rbf_node.getmempoolinfo()["incrementalrelayfee"], Decimal(0.00005000)) # Wallet has a fixed incremental relay fee of 5 sat/vb + inc_fee_rate = rbf_node.getmempoolinfo()["incrementalrelayfee"] # RPC gives us fee as negative min_fee = (-tx_details["fee"] + get_fee(est_bumped_size, inc_fee_rate)) * Decimal(1e8) min_fee_rate = (min_fee / est_bumped_size).quantize(Decimal("1.000")) @@ -830,5 +831,27 @@ def test_feerate_checks_replaced_outputs(self, rbf_node, peer_node): self.clear_mempool() +def test_bumpfee_with_feerate_ignores_walletincrementalrelayfee(self, rbf_node, peer_node): + self.log.info('Test that bumpfee with fee_rate ignores walletincrementalrelayfee') + # Make sure there is enough balance + peer_node.sendtoaddress(rbf_node.getnewaddress(), 2) + self.generate(peer_node, 1) + + dest_address = peer_node.getnewaddress(address_type="bech32") + tx = rbf_node.send(outputs=[{dest_address: 1}], fee_rate=2) + + # Ensure you can not fee bump with a fee_rate below or equal to the original fee_rate + assert_raises_rpc_error(-8, "Insufficient total fee", rbf_node.bumpfee, tx["txid"], {"fee_rate": 1}) + assert_raises_rpc_error(-8, "Insufficient total fee", rbf_node.bumpfee, tx["txid"], {"fee_rate": 2}) + + # Ensure you can not fee bump if the fee_rate is more than original fee_rate but the total fee from new fee_rate is + # less than (original fee + incrementalrelayfee) + assert_raises_rpc_error(-8, "Insufficient total fee", rbf_node.bumpfee, tx["txid"], {"fee_rate": 2.8}) + + # You can fee bump as long as the new fee set from fee_rate is atleast (original fee + incrementalrelayfee) + rbf_node.bumpfee(tx["txid"], {"fee_rate": 3}) + self.clear_mempool() + + if __name__ == "__main__": BumpFeeTest().main() diff --git a/test/functional/wallet_create_tx.py b/test/functional/wallet_create_tx.py index 4e31b48ec0..fa3e920c25 100755 --- a/test/functional/wallet_create_tx.py +++ b/test/functional/wallet_create_tx.py @@ -3,6 +3,9 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. +from test_framework.messages import ( + tx_from_hex, +) from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, @@ -33,6 +36,7 @@ class CreateTxWalletTest(BitcoinTestFramework): self.test_anti_fee_sniping() self.test_tx_size_too_large() self.test_create_too_long_mempool_chain() + self.test_version3() def test_anti_fee_sniping(self): self.log.info('Check that we have some (old) blocks and that anti-fee-sniping is disabled') @@ -106,6 +110,23 @@ class CreateTxWalletTest(BitcoinTestFramework): test_wallet.unloadwallet() + def test_version3(self): + self.log.info('Check wallet does not create transactions with version=3 yet') + wallet_rpc = self.nodes[0].get_wallet_rpc(self.default_wallet_name) + + self.nodes[0].createwallet("v3") + wallet_v3 = self.nodes[0].get_wallet_rpc("v3") + + tx_data = wallet_rpc.send(outputs=[{wallet_v3.getnewaddress(): 25}], options={"change_position": 0}) + wallet_tx_data = wallet_rpc.gettransaction(tx_data["txid"]) + tx_current_version = tx_from_hex(wallet_tx_data["hex"]) + + # While v3 transactions are standard, the CURRENT_VERSION is 2. + # This test can be removed if CURRENT_VERSION is changed, and replaced with tests that the + # wallet handles v3 rules properly. + assert_equal(tx_current_version.version, 2) + wallet_v3.unloadwallet() + if __name__ == '__main__': CreateTxWalletTest().main() diff --git a/test/functional/wallet_fundrawtransaction.py b/test/functional/wallet_fundrawtransaction.py index ff4648e638..3c1b2deb1d 100755 --- a/test/functional/wallet_fundrawtransaction.py +++ b/test/functional/wallet_fundrawtransaction.py @@ -114,6 +114,7 @@ class RawTransactionsTest(BitcoinTestFramework): self.test_add_inputs_default_value() self.test_preset_inputs_selection() self.test_weight_calculation() + self.test_weight_limits() self.test_change_position() self.test_simple() self.test_simple_two_coins() @@ -1054,8 +1055,8 @@ class RawTransactionsTest(BitcoinTestFramework): assert_raises_rpc_error(-4, "Not solvable pre-selected input COutPoint(%s, %s)" % (ext_utxo["txid"][0:10], ext_utxo["vout"]), wallet.fundrawtransaction, raw_tx) # Error conditions - assert_raises_rpc_error(-5, "'not a pubkey' is not hex", wallet.fundrawtransaction, raw_tx, solving_data={"pubkeys":["not a pubkey"]}) - assert_raises_rpc_error(-5, "'01234567890a0b0c0d0e0f' is not a valid public key", wallet.fundrawtransaction, raw_tx, solving_data={"pubkeys":["01234567890a0b0c0d0e0f"]}) + assert_raises_rpc_error(-5, 'Pubkey "not a pubkey" must be a hex string', wallet.fundrawtransaction, raw_tx, solving_data={"pubkeys":["not a pubkey"]}) + assert_raises_rpc_error(-5, 'Pubkey "01234567890a0b0c0d0e0f" must have a length of either 33 or 65 bytes', wallet.fundrawtransaction, raw_tx, solving_data={"pubkeys":["01234567890a0b0c0d0e0f"]}) assert_raises_rpc_error(-5, "'not a script' is not hex", wallet.fundrawtransaction, raw_tx, solving_data={"scripts":["not a script"]}) assert_raises_rpc_error(-8, "Unable to parse descriptor 'not a descriptor'", wallet.fundrawtransaction, raw_tx, solving_data={"descriptors":["not a descriptor"]}) assert_raises_rpc_error(-8, "Invalid parameter, missing vout key", wallet.fundrawtransaction, raw_tx, input_weights=[{"txid": ext_utxo["txid"]}]) @@ -1312,6 +1313,38 @@ class RawTransactionsTest(BitcoinTestFramework): self.nodes[2].unloadwallet("test_weight_calculation") + def test_weight_limits(self): + self.log.info("Test weight limits") + + self.nodes[2].createwallet("test_weight_limits") + wallet = self.nodes[2].get_wallet_rpc("test_weight_limits") + + outputs = [] + for _ in range(1472): + outputs.append({wallet.getnewaddress(address_type="legacy"): 0.1}) + txid = self.nodes[0].send(outputs=outputs)["txid"] + self.generate(self.nodes[0], 1) + + # 272 WU per input (273 when high-s); picking 1471 inputs will exceed the max standard tx weight. + rawtx = wallet.createrawtransaction([], [{wallet.getnewaddress(): 0.1 * 1471}]) + + # 1) Try to fund transaction only using the preset inputs + input_weights = [] + for i in range(1471): + input_weights.append({"txid": txid, "vout": i, "weight": 273}) + assert_raises_rpc_error(-4, "Transaction too large", wallet.fundrawtransaction, hexstring=rawtx, input_weights=input_weights) + + # 2) Let the wallet fund the transaction + assert_raises_rpc_error(-4, "The inputs size exceeds the maximum weight. Please try sending a smaller amount or manually consolidating your wallet's UTXOs", + wallet.fundrawtransaction, hexstring=rawtx) + + # 3) Pre-select some inputs and let the wallet fill-up the remaining amount + inputs = input_weights[0:1000] + assert_raises_rpc_error(-4, "The combination of the pre-selected inputs and the wallet automatic inputs selection exceeds the transaction maximum weight. Please try sending a smaller amount or manually consolidating your wallet's UTXOs", + wallet.fundrawtransaction, hexstring=rawtx, input_weights=inputs) + + self.nodes[2].unloadwallet("test_weight_limits") + def test_include_unsafe(self): self.log.info("Test fundrawtxn with unsafe inputs") diff --git a/test/functional/wallet_listsinceblock.py b/test/functional/wallet_listsinceblock.py index fd586d546e..15214539a9 100755 --- a/test/functional/wallet_listsinceblock.py +++ b/test/functional/wallet_listsinceblock.py @@ -40,6 +40,7 @@ class ListSinceBlockTest(BitcoinTestFramework): self.test_no_blockhash() self.test_invalid_blockhash() self.test_reorg() + self.test_cant_read_block() self.test_double_spend() self.test_double_send() self.double_spends_filtered() @@ -167,6 +168,31 @@ class ListSinceBlockTest(BitcoinTestFramework): found = next(tx for tx in transactions if tx['txid'] == senttx) assert_equal(found['blockheight'], self.nodes[0].getblockheader(nodes2_first_blockhash)['height']) + def test_cant_read_block(self): + self.log.info('Test the RPC error "Can\'t read block from disk"') + + # Split network into two + self.split_network() + + # generate on both sides + nodes1_last_blockhash = self.generate(self.nodes[1], 6, sync_fun=lambda: self.sync_all(self.nodes[:2]))[-1] + self.generate(self.nodes[2], 7, sync_fun=lambda: self.sync_all(self.nodes[2:]))[0] + + self.join_network() + + # Renaming the block file to induce unsuccessful block read + blk_dat = (self.nodes[0].blocks_path / "blk00000.dat") + blk_dat_moved = blk_dat.rename(self.nodes[0].blocks_path / "blk00000.dat.moved") + assert not blk_dat.exists() + + # listsinceblock(nodes1_last_blockhash) should now fail as blocks are not accessible + assert_raises_rpc_error(-32603, "Can't read block from disk", + self.nodes[0].listsinceblock, nodes1_last_blockhash) + + # Restoring block file + blk_dat_moved.rename(self.nodes[0].blocks_path / "blk00000.dat") + assert blk_dat.exists() + def test_double_spend(self): ''' This tests the case where the same UTXO is spent twice on two separate diff --git a/test/functional/wallet_send.py b/test/functional/wallet_send.py index 0a0a8dba0d..bbb0d658d9 100755 --- a/test/functional/wallet_send.py +++ b/test/functional/wallet_send.py @@ -577,5 +577,39 @@ class WalletSendTest(BitcoinTestFramework): # but rounded to nearest integer, it should be the same as the target fee rate assert_equal(round(actual_fee_rate_sat_vb), target_fee_rate_sat_vb) + # Check tx creation size limits + self.test_weight_limits() + + def test_weight_limits(self): + self.log.info("Test weight limits") + + self.nodes[1].createwallet("test_weight_limits") + wallet = self.nodes[1].get_wallet_rpc("test_weight_limits") + + # Generate future inputs; 272 WU per input (273 when high-s). + # Picking 1471 inputs will exceed the max standard tx weight. + outputs = [] + for _ in range(1472): + outputs.append({wallet.getnewaddress(address_type="legacy"): 0.1}) + self.nodes[0].send(outputs=outputs) + self.generate(self.nodes[0], 1) + + # 1) Try to fund transaction only using the preset inputs + inputs = wallet.listunspent() + assert_raises_rpc_error(-4, "Transaction too large", + wallet.send, outputs=[{wallet.getnewaddress(): 0.1 * 1471}], options={"inputs": inputs, "add_inputs": False}) + + # 2) Let the wallet fund the transaction + assert_raises_rpc_error(-4, "The inputs size exceeds the maximum weight. Please try sending a smaller amount or manually consolidating your wallet's UTXOs", + wallet.send, outputs=[{wallet.getnewaddress(): 0.1 * 1471}]) + + # 3) Pre-select some inputs and let the wallet fill-up the remaining amount + inputs = inputs[0:1000] + assert_raises_rpc_error(-4, "The combination of the pre-selected inputs and the wallet automatic inputs selection exceeds the transaction maximum weight. Please try sending a smaller amount or manually consolidating your wallet's UTXOs", + wallet.send, outputs=[{wallet.getnewaddress(): 0.1 * 1471}], options={"inputs": inputs, "add_inputs": True}) + + self.nodes[1].unloadwallet("test_weight_limits") + + if __name__ == '__main__': WalletSendTest().main() diff --git a/test/functional/wallet_sendall.py b/test/functional/wallet_sendall.py index c2b800df21..1d308c225d 100755 --- a/test/functional/wallet_sendall.py +++ b/test/functional/wallet_sendall.py @@ -379,6 +379,64 @@ class SendallTest(BitcoinTestFramework): assert_equal(len(self.wallet.listunspent()), 1) assert_equal(self.wallet.listunspent()[0]['confirmations'], 6) + @cleanup + def sendall_spends_unconfirmed_change(self): + self.log.info("Test that sendall spends unconfirmed change") + self.add_utxos([17]) + self.wallet.sendtoaddress(self.remainder_target, 10) + assert_greater_than(self.wallet.getbalances()["mine"]["trusted"], 6) + self.test_sendall_success(sendall_args = [self.remainder_target]) + + assert_equal(self.wallet.getbalance(), 0) + + @cleanup + def sendall_spends_unconfirmed_inputs_if_specified(self): + self.log.info("Test that sendall spends specified unconfirmed inputs") + self.def_wallet.sendtoaddress(self.wallet.getnewaddress(), 17) + self.wallet.syncwithvalidationinterfacequeue() + assert_equal(self.wallet.getbalances()["mine"]["untrusted_pending"], 17) + unspent = self.wallet.listunspent(minconf=0)[0] + + self.wallet.sendall(recipients=[self.remainder_target], inputs=[unspent]) + assert_equal(self.wallet.getbalance(), 0) + + @cleanup + def sendall_does_ancestor_aware_funding(self): + self.log.info("Test that sendall does ancestor aware funding for unconfirmed inputs") + + # higher parent feerate + self.def_wallet.sendtoaddress(address=self.wallet.getnewaddress(), amount=17, fee_rate=20) + self.wallet.syncwithvalidationinterfacequeue() + + assert_equal(self.wallet.getbalances()["mine"]["untrusted_pending"], 17) + unspent = self.wallet.listunspent(minconf=0)[0] + + parent_txid = unspent["txid"] + assert_equal(self.wallet.gettransaction(parent_txid)["confirmations"], 0) + + res_1 = self.wallet.sendall(recipients=[self.def_wallet.getnewaddress()], inputs=[unspent], fee_rate=20, add_to_wallet=False, lock_unspents=True) + child_hex = res_1["hex"] + + child_tx = self.wallet.decoderawtransaction(child_hex) + higher_parent_feerate_amount = child_tx["vout"][0]["value"] + + # lower parent feerate + self.def_wallet.sendtoaddress(address=self.wallet.getnewaddress(), amount=17, fee_rate=10) + self.wallet.syncwithvalidationinterfacequeue() + assert_equal(self.wallet.getbalances()["mine"]["untrusted_pending"], 34) + unspent = self.wallet.listunspent(minconf=0)[0] + + parent_txid = unspent["txid"] + assert_equal(self.wallet.gettransaction(parent_txid)["confirmations"], 0) + + res_2 = self.wallet.sendall(recipients=[self.def_wallet.getnewaddress()], inputs=[unspent], fee_rate=20, add_to_wallet=False, lock_unspents=True) + child_hex = res_2["hex"] + + child_tx = self.wallet.decoderawtransaction(child_hex) + lower_parent_feerate_amount = child_tx["vout"][0]["value"] + + assert_greater_than(higher_parent_feerate_amount, lower_parent_feerate_amount) + # This tests needs to be the last one otherwise @cleanup will fail with "Transaction too large" error def sendall_fails_with_transaction_too_large(self): self.log.info("Test that sendall fails if resulting transaction is too large") @@ -460,6 +518,15 @@ class SendallTest(BitcoinTestFramework): # Sendall only uses outputs with less than a given number of confirmation when using minconf self.sendall_with_maxconf() + # Sendall spends unconfirmed change + self.sendall_spends_unconfirmed_change() + + # Sendall spends unconfirmed inputs if they are specified + self.sendall_spends_unconfirmed_inputs_if_specified() + + # Sendall does ancestor aware funding when spending an unconfirmed UTXO + self.sendall_does_ancestor_aware_funding() + # Sendall fails when many inputs result to too large transaction self.sendall_fails_with_transaction_too_large() diff --git a/test/fuzz/test_runner.py b/test/fuzz/test_runner.py index a635175e7c..c74246ef45 100755 --- a/test/fuzz/test_runner.py +++ b/test/fuzz/test_runner.py @@ -215,12 +215,12 @@ def transform_process_message_target(targets, src_dir): p2p_msg_target = "process_message" if (p2p_msg_target, {}) in targets: lines = subprocess.run( - ["git", "grep", "--function-context", "g_all_net_message_types{", src_dir / "src" / "protocol.cpp"], + ["git", "grep", "--function-context", "ALL_NET_MESSAGE_TYPES{", src_dir / "src" / "protocol.h"], check=True, stdout=subprocess.PIPE, text=True, ).stdout.splitlines() - lines = [l.split("::", 1)[1].split(",")[0].lower() for l in lines if l.startswith("src/protocol.cpp- NetMsgType::")] + lines = [l.split("::", 1)[1].split(",")[0].lower() for l in lines if l.startswith("src/protocol.h- NetMsgType::")] assert len(lines) targets += [(p2p_msg_target, {"LIMIT_TO_MESSAGE_TYPE": m}) for m in lines] return targets diff --git a/test/lint/README.md b/test/lint/README.md index 9d167bac72..04a836c4d2 100644 --- a/test/lint/README.md +++ b/test/lint/README.md @@ -26,17 +26,33 @@ Then you can use: ( cd ./test/lint/test_runner/ && cargo fmt && cargo clippy && RUST_BACKTRACE=1 cargo run ) ``` +If you wish to run individual lint checks, run the test_runner with +`--lint=TEST_TO_RUN` arguments. If running with `cargo run`, arguments after +`--` are passed to the binary you are running e.g.: + +```sh +( cd ./test/lint/test_runner/ && RUST_BACKTRACE=1 cargo run -- --lint=doc --lint=trailing_whitespace ) +``` + +To see a list of all individual lint checks available in test_runner, use `-h` +or `--help`: + +```sh +( cd ./test/lint/test_runner/ && RUST_BACKTRACE=1 cargo run -- --help ) +``` + #### Dependencies | Lint test | Dependency | |-----------|:----------:| -| [`lint-python.py`](lint/lint-python.py) | [flake8](https://gitlab.com/pycqa/flake8) -| [`lint-python.py`](lint/lint-python.py) | [lief](https://github.com/lief-project/LIEF) -| [`lint-python.py`](lint/lint-python.py) | [mypy](https://github.com/python/mypy) -| [`lint-python.py`](lint/lint-python.py) | [pyzmq](https://github.com/zeromq/pyzmq) -| [`lint-python-dead-code.py`](lint/lint-python-dead-code.py) | [vulture](https://github.com/jendrikseipp/vulture) -| [`lint-shell.py`](lint/lint-shell.py) | [ShellCheck](https://github.com/koalaman/shellcheck) -| [`lint-spelling.py`](lint/lint-spelling.py) | [codespell](https://github.com/codespell-project/codespell) +| [`lint-python.py`](/test/lint/lint-python.py) | [flake8](https://github.com/PyCQA/flake8) +| [`lint-python.py`](/test/lint/lint-python.py) | [lief](https://github.com/lief-project/LIEF) +| [`lint-python.py`](/test/lint/lint-python.py) | [mypy](https://github.com/python/mypy) +| [`lint-python.py`](/test/lint/lint-python.py) | [pyzmq](https://github.com/zeromq/pyzmq) +| [`lint-python-dead-code.py`](/test/lint/lint-python-dead-code.py) | [vulture](https://github.com/jendrikseipp/vulture) +| [`lint-shell.py`](/test/lint/lint-shell.py) | [ShellCheck](https://github.com/koalaman/shellcheck) +| [`lint-spelling.py`](/test/lint/lint-spelling.py) | [codespell](https://github.com/codespell-project/codespell) +| markdown link check | [mlc](https://github.com/becheran/mlc) In use versions and install instructions are available in the [CI setup](../../ci/lint/04_install.sh). diff --git a/test/lint/test_runner/src/main.rs b/test/lint/test_runner/src/main.rs index d5dd98effe..9c35898c1f 100644 --- a/test/lint/test_runner/src/main.rs +++ b/test/lint/test_runner/src/main.rs @@ -4,14 +4,121 @@ use std::env; use std::fs; +use std::io::ErrorKind; use std::path::{Path, PathBuf}; -use std::process::Command; -use std::process::ExitCode; +use std::process::{Command, ExitCode, Stdio}; type LintError = String; type LintResult = Result<(), LintError>; type LintFn = fn() -> LintResult; +struct Linter { + pub description: &'static str, + pub name: &'static str, + pub lint_fn: LintFn, +} + +fn get_linter_list() -> Vec<&'static Linter> { + vec![ + &Linter { + description: "Check that all command line arguments are documented.", + name: "doc", + lint_fn: lint_doc + }, + &Linter { + description: "Check that no symbol from bitcoin-config.h is used without the header being included", + name: "includes_build_config", + lint_fn: lint_includes_build_config + }, + &Linter { + description: "Check that markdown links resolve", + name: "markdown", + lint_fn: lint_markdown + }, + &Linter { + description: "Check that std::filesystem is not used directly", + name: "std_filesystem", + lint_fn: lint_std_filesystem + }, + &Linter { + description: "Check that subtrees are pure subtrees", + name: "subtree", + lint_fn: lint_subtree + }, + &Linter { + description: "Check that tabs are not used as whitespace", + name: "tabs_whitespace", + lint_fn: lint_tabs_whitespace + }, + &Linter { + description: "Check for trailing whitespace", + name: "trailing_whitespace", + lint_fn: lint_trailing_whitespace + }, + &Linter { + description: "Run all linters of the form: test/lint/lint-*.py", + name: "all_python_linters", + lint_fn: run_all_python_linters + }, + ] +} + +fn print_help_and_exit() { + print!( + r#" +Usage: test_runner [--lint=LINTER_TO_RUN] +Runs all linters in the lint test suite, printing any errors +they detect. + +If you wish to only run some particular lint tests, pass +'--lint=' with the name of the lint test you wish to run. +You can set as many '--lint=' values as you wish, e.g.: +test_runner --lint=doc --lint=subtree + +The individual linters available to run are: +"# + ); + for linter in get_linter_list() { + println!("{}: \"{}\"", linter.name, linter.description) + } + + std::process::exit(1); +} + +fn parse_lint_args(args: &[String]) -> Vec<&'static Linter> { + let linter_list = get_linter_list(); + let mut lint_values = Vec::new(); + + for arg in args { + #[allow(clippy::if_same_then_else)] + if arg.starts_with("--lint=") { + let lint_arg_value = arg + .trim_start_matches("--lint=") + .trim_matches('"') + .trim_matches('\''); + + let try_find_linter = linter_list + .iter() + .find(|linter| linter.name == lint_arg_value); + match try_find_linter { + Some(linter) => { + lint_values.push(*linter); + } + None => { + println!("No linter {lint_arg_value} found!"); + print_help_and_exit(); + } + } + } else if arg.eq("--help") || arg.eq("-h") { + print_help_and_exit(); + } else { + print_help_and_exit(); + } + } + + lint_values +} + /// Return the git command fn git() -> Command { let mut git = Command::new("git"); @@ -292,7 +399,52 @@ fn lint_doc() -> LintResult { } } -fn lint_all() -> LintResult { +fn lint_markdown() -> LintResult { + let bin_name = "mlc"; + let mut md_ignore_paths = get_subtrees(); + md_ignore_paths.push("./doc/README_doxygen.md"); + let md_ignore_path_str = md_ignore_paths.join(","); + + let mut cmd = Command::new(bin_name); + cmd.args([ + "--offline", + "--ignore-path", + md_ignore_path_str.as_str(), + "--root-dir", + ".", + ]) + .stdout(Stdio::null()); // Suppress overly-verbose output + + match cmd.output() { + Ok(output) if output.status.success() => Ok(()), + Ok(output) => { + let stderr = String::from_utf8_lossy(&output.stderr); + let filtered_stderr: String = stderr // Filter out this annoying trailing line + .lines() + .filter(|&line| line != "The following links could not be resolved:") + .collect::<Vec<&str>>() + .join("\n"); + Err(format!( + r#" +One or more markdown links are broken. + +Relative links are preferred (but not required) as jumping to file works natively within Emacs. + +Markdown link errors found: +{} + "#, + filtered_stderr + )) + } + Err(e) if e.kind() == ErrorKind::NotFound => { + println!("`mlc` was not found in $PATH, skipping markdown lint check."); + Ok(()) + } + Err(e) => Err(format!("Error running mlc: {}", e)), // Misc errors + } +} + +fn run_all_python_linters() -> LintResult { let mut good = true; let lint_dir = get_git_root().join("test/lint"); for entry in fs::read_dir(lint_dir).unwrap() { @@ -307,7 +459,7 @@ fn lint_all() -> LintResult { .success() { good = false; - println!("^---- failure generated from {}", entry_fn); + println!("^---- ⚠️ Failure generated from {}", entry_fn); } } if good { @@ -318,24 +470,26 @@ fn lint_all() -> LintResult { } fn main() -> ExitCode { - let test_list: Vec<(&str, LintFn)> = vec![ - ("subtree check", lint_subtree), - ("std::filesystem check", lint_std_filesystem), - ("trailing whitespace check", lint_trailing_whitespace), - ("no-tabs check", lint_tabs_whitespace), - ("build config includes check", lint_includes_build_config), - ("-help=1 documentation check", lint_doc), - ("lint-*.py scripts", lint_all), - ]; + let linters_to_run: Vec<&Linter> = if env::args().count() > 1 { + let args: Vec<String> = env::args().skip(1).collect(); + parse_lint_args(&args) + } else { + // If no arguments are passed, run all linters. + get_linter_list() + }; let git_root = get_git_root(); let mut test_failed = false; - for (lint_name, lint_fn) in test_list { + for linter in linters_to_run { // chdir to root before each lint test env::set_current_dir(&git_root).unwrap(); - if let Err(err) = lint_fn() { - println!("{err}\n^---- ⚠️ Failure generated from {lint_name}!"); + if let Err(err) = (linter.lint_fn)() { + println!( + "{err}\n^---- ⚠️ Failure generated from lint check '{}'!", + linter.name + ); + println!("{}", linter.description); test_failed = true; } } diff --git a/test/sanitizer_suppressions/ubsan b/test/sanitizer_suppressions/ubsan index 482667a26a..9818d73fdf 100644 --- a/test/sanitizer_suppressions/ubsan +++ b/test/sanitizer_suppressions/ubsan @@ -58,6 +58,7 @@ unsigned-integer-overflow:TxConfirmStats::EstimateMedianVal unsigned-integer-overflow:prevector.h unsigned-integer-overflow:EvalScript unsigned-integer-overflow:xoroshiro128plusplus.h +unsigned-integer-overflow:bitset_detail::PopCount implicit-integer-sign-change:CBlockPolicyEstimator::processBlockTx implicit-integer-sign-change:SetStdinEcho implicit-integer-sign-change:compressor.h |