Merge branch 'dev'

This commit is contained in:
XMRig 2021-05-31 12:57:55 +07:00
commit 4d87555398
No known key found for this signature in database
GPG key ID: 446A53638BE94409
28 changed files with 987 additions and 506 deletions

View file

@ -1,3 +1,18 @@
# v6.12.2
- [#2280](https://github.com/xmrig/xmrig/issues/2280) GPU backends are now disabled in benchmark mode.
- [#2322](https://github.com/xmrig/xmrig/pull/2322) Improved MSR compatibility with recent Linux kernels and updated `randomx_boost.sh`.
- [#2340](https://github.com/xmrig/xmrig/pull/2340) Fixed AES detection on FreeBSD on ARM.
- [#2341](https://github.com/xmrig/xmrig/pull/2341) `sse2neon` updated to the latest version.
- [#2351](https://github.com/xmrig/xmrig/issues/2351) Fixed help output for `--cpu-priority` and `--cpu-affinity` option.
- [#2375](https://github.com/xmrig/xmrig/pull/2375) Fixed macOS CUDA backend default loader name.
- [#2378](https://github.com/xmrig/xmrig/pull/2378) Fixed broken light mode mining on x86.
- [#2379](https://github.com/xmrig/xmrig/pull/2379) Fixed CL code for KawPow where it assumes everything is AMD.
- [#2386](https://github.com/xmrig/xmrig/pull/2386) RandomX: enabled `IMUL_RCP` optimization for light mode mining.
- [#2393](https://github.com/xmrig/xmrig/pull/2393) RandomX: added BMI2 version for scratchpad prefetch.
- [#2395](https://github.com/xmrig/xmrig/pull/2395) RandomX: rewrote dataset read code.
- [#2398](https://github.com/xmrig/xmrig/pull/2398) RandomX: optimized ARMv8 dataset read.
- Added `argon2/ninja` alias for `argon2/wrkz` algorithm.
# v6.12.1
- [#2296](https://github.com/xmrig/xmrig/pull/2296) Fixed Zen3 assembly code for `cn/upx2` algorithm.

View file

@ -1,6 +1,6 @@
#!/bin/bash -e
OPENSSL_VERSION="1.1.1j"
OPENSSL_VERSION="1.1.1k"
mkdir -p deps
mkdir -p deps/include

View file

@ -1,28 +1,34 @@
#!/bin/bash
modprobe msr
MSR_FILE=/sys/module/msr/parameters/allow_writes
if cat /proc/cpuinfo | grep "AMD Ryzen" > /dev/null;
if test -e "$MSR_FILE"; then
echo on > $MSR_FILE
else
modprobe msr allow_writes=on
fi
if cat /proc/cpuinfo | grep -E 'AMD Ryzen|AMD EPYC' > /dev/null;
then
if cat /proc/cpuinfo | grep "cpu family[[:space:]]:[[:space:]]25" > /dev/null;
then
echo "Detected Ryzen (Zen3)"
echo "Detected Zen3 CPU"
wrmsr -a 0xc0011020 0x4480000000000
wrmsr -a 0xc0011021 0x1c000200000040
wrmsr -a 0xc0011022 0xc000000401500000
wrmsr -a 0xc001102b 0x2000cc14
echo "MSR register values for Ryzen (Zen3) applied"
echo "MSR register values for Zen3 applied"
else
echo "Detected Ryzen (Zen1/Zen2)"
echo "Detected Zen1/Zen2 CPU"
wrmsr -a 0xc0011020 0
wrmsr -a 0xc0011021 0x40
wrmsr -a 0xc0011022 0x1510000
wrmsr -a 0xc001102b 0x2000cc16
echo "MSR register values for Ryzen (Zen1/Zen2) applied"
echo "MSR register values for Zen1/Zen2 applied"
fi
elif cat /proc/cpuinfo | grep "Intel" > /dev/null;
then
echo "Detected Intel"
echo "Detected Intel CPU"
wrmsr -a 0x1a4 0xf
echo "MSR register values for Intel applied"
else

View file

@ -28,7 +28,15 @@
#if __ARM_FEATURE_CRYPTO && !defined(__APPLE__)
# include <sys/auxv.h>
# ifndef __FreeBSD__
# include <asm/hwcap.h>
# else
# include <stdint.h>
# include <machine/armreg.h>
# ifndef ID_AA64ISAR0_AES_VAL
# define ID_AA64ISAR0_AES_VAL ID_AA64ISAR0_AES
# endif
# endif
#endif
@ -62,10 +70,13 @@ xmrig::BasicCpuInfo::BasicCpuInfo() :
# endif
# if __ARM_FEATURE_CRYPTO
# if !defined(__APPLE__)
m_flags.set(FLAG_AES, getauxval(AT_HWCAP) & HWCAP_AES);
# else
# if defined(__APPLE__)
m_flags.set(FLAG_AES, true);
# elif defined(__FreeBSD__)
uint64_t isar0 = READ_SPECIALREG(id_aa64isar0_el1);
m_flags.set(FLAG_AES, ID_AA64ISAR0_AES_VAL(isar0) >= ID_AA64ISAR0_AES_BASE);
# else
m_flags.set(FLAG_AES, getauxval(AT_HWCAP) & HWCAP_AES);
# endif
# endif

View file

@ -48,7 +48,7 @@ enum Version : uint32_t
static uv_lib_t cudaLib;
#if defined(__APPLE__)
static String defaultLoader = "/System/Library/Frameworks/OpenCL.framework/OpenCL";
static String defaultLoader = "libxmrig-cuda.dylib";
#elif defined(_WIN32)
static String defaultLoader = "xmrig-cuda.dll";
#else

View file

@ -29,7 +29,11 @@ typedef unsigned long uint64_t;
#endif
#ifndef PLATFORM
#ifdef cl_amd_media_ops
#define PLATFORM OPENCL_PLATFORM_AMD
#else
#define PLATFORM OPENCL_PLATFORM_UNKNOWN
#endif
#endif
#define HASHES_PER_GROUP (GROUP_SIZE / PROGPOW_LANES)

View file

@ -2,7 +2,7 @@
namespace xmrig {
static const char kawpow_cl[5870] = {
static const char kawpow_cl[5948] = {
0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x63,0x6c,0x5f,0x63,0x6c,0x61,0x6e,0x67,0x5f,0x73,0x74,0x6f,0x72,0x61,0x67,0x65,0x5f,0x63,0x6c,0x61,0x73,0x73,0x5f,0x73,0x70,
0x65,0x63,0x69,0x66,0x69,0x65,0x72,0x73,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,
0x4e,0x20,0x63,0x6c,0x5f,0x63,0x6c,0x61,0x6e,0x67,0x5f,0x73,0x74,0x6f,0x72,0x61,0x67,0x65,0x5f,0x63,0x6c,0x61,0x73,0x73,0x5f,0x73,0x70,0x65,0x63,0x69,0x66,0x69,
@ -25,168 +25,170 @@ static const char kawpow_cl[5870] = {
0x4e,0x43,0x4c,0x5f,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x5f,0x41,0x4d,0x44,0x20,0x32,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x4f,0x50,0x45,0x4e,0x43,
0x4c,0x5f,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x5f,0x43,0x4c,0x4f,0x56,0x45,0x52,0x20,0x33,0x0a,0x23,0x69,0x66,0x6e,0x64,0x65,0x66,0x20,0x4d,0x41,0x58,0x5f,
0x4f,0x55,0x54,0x50,0x55,0x54,0x53,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x4d,0x41,0x58,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x53,0x20,0x36,0x33,0x55,0x0a,
0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x23,0x69,0x66,0x6e,0x64,0x65,0x66,0x20,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,
0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x5f,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x5f,0x41,0x4d,0x44,0x0a,0x23,0x65,0x6e,
0x64,0x69,0x66,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x48,0x41,0x53,0x48,0x45,0x53,0x5f,0x50,0x45,0x52,0x5f,0x47,0x52,0x4f,0x55,0x50,0x20,0x28,0x47,0x52,
0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x20,0x2f,0x20,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,
0x65,0x20,0x46,0x4e,0x56,0x5f,0x50,0x52,0x49,0x4d,0x45,0x20,0x30,0x78,0x31,0x30,0x30,0x30,0x31,0x39,0x33,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x46,0x4e,
0x56,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x5f,0x42,0x41,0x53,0x49,0x53,0x20,0x30,0x78,0x38,0x31,0x31,0x63,0x39,0x64,0x63,0x35,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,
0x66,0x20,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x20,0x28,0x28,0x61,0x6c,0x69,0x67,0x6e,0x65,0x64,
0x28,0x31,0x36,0x29,0x29,0x29,0x20,0x7b,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x5b,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,0x47,0x5f,0x4c,
0x4f,0x41,0x44,0x53,0x5d,0x3b,0x7d,0x20,0x64,0x61,0x67,0x5f,0x74,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,
0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x5f,0x72,0x6e,0x64,0x63,0x5b,0x32,0x34,0x5d,0x3d,0x7b,0x30,0x78,0x30,0x30,0x30,
0x30,0x30,0x30,0x30,0x31,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x32,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x61,0x2c,0x30,0x78,0x38,0x30,
0x30,0x30,0x38,0x30,0x30,0x30,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x62,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x2c,0x30,0x78,
0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x31,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x39,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x61,0x2c,0x30,
0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x38,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x39,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x61,0x2c,
0x0a,0x30,0x78,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x62,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x62,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x38,
0x39,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x33,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x32,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,
0x38,0x30,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x61,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x61,0x2c,0x0a,0x30,0x78,0x38,0x30,0x30,0x30,
0x38,0x30,0x38,0x31,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x30,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x2c,0x30,0x78,0x38,0x30,0x30,
0x30,0x38,0x30,0x30,0x38,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
0x74,0x20,0x72,0x61,0x76,0x65,0x6e,0x63,0x6f,0x69,0x6e,0x5f,0x72,0x6e,0x64,0x63,0x5b,0x31,0x35,0x5d,0x3d,0x7b,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x37,
0x32,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x31,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x35,0x36,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,
0x30,0x30,0x30,0x34,0x35,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x45,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x33,0x2c,0x0a,0x30,
0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x46,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x39,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,
0x45,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x42,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x31,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,
0x30,0x30,0x30,0x35,0x37,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x35,0x30,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x46,0x2c,0x0a,0x30,
0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x35,0x37,0x2c,0x0a,0x7d,0x3b,0x0a,0x76,0x6f,0x69,0x64,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x38,0x30,0x30,0x5f,0x72,
0x6f,0x75,0x6e,0x64,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x74,0x5b,0x32,0x35,0x5d,0x2c,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,
0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x5f,0x72,0x6f,0x74,0x63,0x5b,
0x32,0x34,0x5d,0x3d,0x7b,0x0a,0x31,0x2c,0x33,0x2c,0x36,0x2c,0x31,0x30,0x2c,0x31,0x35,0x2c,0x32,0x31,0x2c,0x32,0x38,0x2c,0x33,0x36,0x2c,0x34,0x35,0x2c,0x35,0x35,
0x2c,0x32,0x2c,0x31,0x34,0x2c,0x32,0x37,0x2c,0x34,0x31,0x2c,0x35,0x36,0x2c,0x38,0x2c,0x32,0x35,0x2c,0x34,0x33,0x2c,0x36,0x32,0x2c,0x31,0x38,0x2c,0x33,0x39,0x2c,
0x36,0x31,0x2c,0x32,0x30,0x2c,0x34,0x34,0x7d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,
0x66,0x5f,0x70,0x69,0x6c,0x6e,0x5b,0x32,0x34,0x5d,0x3d,0x7b,0x0a,0x31,0x30,0x2c,0x37,0x2c,0x31,0x31,0x2c,0x31,0x37,0x2c,0x31,0x38,0x2c,0x33,0x2c,0x35,0x2c,0x31,
0x36,0x2c,0x38,0x2c,0x32,0x31,0x2c,0x32,0x34,0x2c,0x34,0x2c,0x31,0x35,0x2c,0x32,0x33,0x2c,0x31,0x39,0x2c,0x31,0x33,0x2c,0x31,0x32,0x2c,0x32,0x2c,0x32,0x30,0x2c,
0x31,0x34,0x2c,0x32,0x32,0x2c,0x39,0x2c,0x36,0x2c,0x31,0x7d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x2c,0x62,0x63,0x5b,0x35,0x5d,0x3b,0x0a,
0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x35,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x62,0x63,0x5b,0x69,0x5d,0x3d,0x73,0x74,
0x5b,0x69,0x5d,0x5e,0x73,0x74,0x5b,0x69,0x2b,0x35,0x5d,0x5e,0x73,0x74,0x5b,0x69,0x2b,0x31,0x30,0x5d,0x5e,0x73,0x74,0x5b,0x69,0x2b,0x31,0x35,0x5d,0x5e,0x73,0x74,
0x5b,0x69,0x2b,0x32,0x30,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x35,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,
0x7b,0x0a,0x74,0x3d,0x62,0x63,0x5b,0x28,0x69,0x2b,0x34,0x29,0x20,0x25,0x20,0x35,0x5d,0x5e,0x52,0x4f,0x54,0x4c,0x33,0x32,0x28,0x62,0x63,0x5b,0x28,0x69,0x2b,0x31,
0x29,0x20,0x25,0x20,0x35,0x5d,0x2c,0x31,0x75,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x3d,0x30,0x3b,0x20,0x6a,
0x3c,0x32,0x35,0x3b,0x20,0x6a,0x2b,0x3d,0x35,0x29,0x0a,0x73,0x74,0x5b,0x6a,0x2b,0x69,0x5d,0x20,0x5e,0x3d,0x20,0x74,0x3b,0x0a,0x7d,0x0a,0x74,0x3d,0x73,0x74,0x5b,
0x31,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x32,0x34,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x7b,0x0a,0x75,
0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x3d,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x5f,0x70,0x69,0x6c,0x6e,0x5b,0x69,0x5d,0x3b,0x0a,0x62,0x63,0x5b,0x30,0x5d,
0x3d,0x73,0x74,0x5b,0x6a,0x5d,0x3b,0x0a,0x73,0x74,0x5b,0x6a,0x5d,0x3d,0x52,0x4f,0x54,0x4c,0x33,0x32,0x28,0x74,0x2c,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x5f,0x72,
0x6f,0x74,0x63,0x5b,0x69,0x5d,0x29,0x3b,0x0a,0x74,0x3d,0x62,0x63,0x5b,0x30,0x5d,0x3b,0x0a,0x7d,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
0x74,0x20,0x6a,0x3d,0x30,0x3b,0x20,0x6a,0x3c,0x32,0x35,0x3b,0x20,0x6a,0x2b,0x3d,0x35,0x29,0x0a,0x7b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,
0x30,0x3b,0x20,0x69,0x3c,0x35,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x62,0x63,0x5b,0x69,0x5d,0x3d,0x73,0x74,0x5b,0x6a,0x2b,0x69,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,
0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x35,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,0x74,0x5b,0x6a,0x2b,0x69,0x5d,0x20,0x5e,0x3d,0x20,0x28,
0x7e,0x62,0x63,0x5b,0x28,0x69,0x2b,0x31,0x29,0x20,0x25,0x20,0x35,0x5d,0x29,0x26,0x62,0x63,0x5b,0x28,0x69,0x2b,0x32,0x29,0x20,0x25,0x20,0x35,0x5d,0x3b,0x0a,0x7d,
0x0a,0x73,0x74,0x5b,0x30,0x5d,0x20,0x5e,0x3d,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x5f,0x72,0x6e,0x64,0x63,0x5b,0x72,0x5d,0x3b,0x0a,0x7d,0x0a,0x75,0x69,0x6e,
0x74,0x36,0x34,0x5f,0x74,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x38,0x30,0x30,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x73,0x74,0x29,0x0a,
0x7b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x72,0x3d,0x30,0x3b,0x20,0x72,0x3c,0x32,0x32,0x3b,0x20,0x72,0x2b,0x2b,0x29,0x20,0x7b,0x0a,0x6b,0x65,0x63,
0x63,0x61,0x6b,0x5f,0x66,0x38,0x30,0x30,0x5f,0x72,0x6f,0x75,0x6e,0x64,0x28,0x73,0x74,0x2c,0x72,0x29,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,
0x65,0x20,0x66,0x6e,0x76,0x31,0x61,0x28,0x68,0x2c,0x20,0x64,0x29,0x20,0x28,0x68,0x20,0x3d,0x20,0x28,0x68,0x20,0x5e,0x20,0x64,0x29,0x20,0x2a,0x20,0x46,0x4e,0x56,
0x5f,0x50,0x52,0x49,0x4d,0x45,0x29,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x73,0x74,0x72,0x75,0x63,0x74,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
0x74,0x20,0x7a,0x2c,0x77,0x2c,0x6a,0x73,0x72,0x2c,0x6a,0x63,0x6f,0x6e,0x67,0x3b,0x0a,0x7d,0x20,0x6b,0x69,0x73,0x73,0x39,0x39,0x5f,0x74,0x3b,0x0a,0x75,0x69,0x6e,
0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x69,0x73,0x73,0x39,0x39,0x28,0x6b,0x69,0x73,0x73,0x39,0x39,0x5f,0x74,0x2a,0x20,0x73,0x74,0x29,0x0a,0x7b,0x0a,0x73,0x74,0x2d,
0x3e,0x7a,0x3d,0x33,0x36,0x39,0x36,0x39,0x2a,0x28,0x73,0x74,0x2d,0x3e,0x7a,0x26,0x36,0x35,0x35,0x33,0x35,0x29,0x2b,0x28,0x73,0x74,0x2d,0x3e,0x7a,0x3e,0x3e,0x31,
0x36,0x29,0x3b,0x0a,0x73,0x74,0x2d,0x3e,0x77,0x3d,0x31,0x38,0x30,0x30,0x30,0x2a,0x28,0x73,0x74,0x2d,0x3e,0x77,0x26,0x36,0x35,0x35,0x33,0x35,0x29,0x2b,0x28,0x73,
0x74,0x2d,0x3e,0x77,0x3e,0x3e,0x31,0x36,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x4d,0x57,0x43,0x3d,0x28,0x28,0x73,0x74,0x2d,0x3e,0x7a,0x3c,
0x3c,0x31,0x36,0x29,0x2b,0x73,0x74,0x2d,0x3e,0x77,0x29,0x3b,0x0a,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,0x20,0x5e,0x3d,0x20,0x28,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,
0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,0x20,0x5e,0x3d,0x20,0x28,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,0x3e,0x3e,0x31,0x33,0x29,0x3b,
0x0a,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,0x20,0x5e,0x3d,0x20,0x28,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,0x3c,0x3c,0x35,0x29,0x3b,0x0a,0x73,0x74,0x2d,0x3e,0x6a,0x63,
0x6f,0x6e,0x67,0x3d,0x36,0x39,0x30,0x36,0x39,0x2a,0x73,0x74,0x2d,0x3e,0x6a,0x63,0x6f,0x6e,0x67,0x2b,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x3b,0x0a,0x72,0x65,0x74,
0x75,0x72,0x6e,0x20,0x28,0x28,0x4d,0x57,0x43,0x5e,0x73,0x74,0x2d,0x3e,0x6a,0x63,0x6f,0x6e,0x67,0x29,0x2b,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,0x29,0x3b,0x0a,0x7d,
0x0a,0x76,0x6f,0x69,0x64,0x20,0x66,0x69,0x6c,0x6c,0x5f,0x6d,0x69,0x78,0x28,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x73,
0x65,0x65,0x64,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x6d,
0x69,0x78,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x6e,0x76,0x5f,0x68,0x61,0x73,0x68,0x3d,0x46,0x4e,0x56,0x5f,0x4f,0x46,0x46,0x53,
0x45,0x54,0x5f,0x42,0x41,0x53,0x49,0x53,0x3b,0x0a,0x6b,0x69,0x73,0x73,0x39,0x39,0x5f,0x74,0x20,0x73,0x74,0x3b,0x0a,0x73,0x74,0x2e,0x7a,0x3d,0x66,0x6e,0x76,0x31,
0x61,0x28,0x66,0x6e,0x76,0x5f,0x68,0x61,0x73,0x68,0x2c,0x73,0x65,0x65,0x64,0x5b,0x30,0x5d,0x29,0x3b,0x0a,0x73,0x74,0x2e,0x77,0x3d,0x66,0x6e,0x76,0x31,0x61,0x28,
0x66,0x6e,0x76,0x5f,0x68,0x61,0x73,0x68,0x2c,0x73,0x65,0x65,0x64,0x5b,0x31,0x5d,0x29,0x3b,0x0a,0x73,0x74,0x2e,0x6a,0x73,0x72,0x3d,0x66,0x6e,0x76,0x31,0x61,0x28,
0x66,0x6e,0x76,0x5f,0x68,0x61,0x73,0x68,0x2c,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x29,0x3b,0x0a,0x73,0x74,0x2e,0x6a,0x63,0x6f,0x6e,0x67,0x3d,0x66,0x6e,0x76,0x31,
0x61,0x28,0x66,0x6e,0x76,0x5f,0x68,0x61,0x73,0x68,0x2c,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x29,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,
0x6f,0x6c,0x6c,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x52,0x45,0x47,0x53,
0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x6d,0x69,0x78,0x5b,0x69,0x5d,0x3d,0x6b,0x69,0x73,0x73,0x39,0x39,0x28,0x26,0x73,0x74,0x29,0x3b,0x0a,0x7d,0x0a,0x74,0x79,0x70,
0x65,0x64,0x65,0x66,0x20,0x73,0x74,0x72,0x75,0x63,0x74,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x50,
0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x5d,0x3b,0x0a,0x7d,0x20,0x73,0x68,0x75,0x66,0x66,0x6c,0x65,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,
0x64,0x65,0x66,0x20,0x73,0x74,0x72,0x75,0x63,0x74,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x33,0x32,
0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x5d,0x3b,0x0a,0x7d,0x20,0x68,0x61,0x73,0x68,0x33,0x32,0x5f,0x74,0x3b,0x0a,
0x23,0x69,0x66,0x20,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x20,0x21,0x3d,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x5f,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x5f,
0x4e,0x56,0x49,0x44,0x49,0x41,0x20,0x0a,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x72,0x65,0x71,0x64,0x5f,0x77,0x6f,0x72,0x6b,
0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x23,0x65,
0x6e,0x64,0x69,0x66,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x70,0x72,0x6f,0x67,0x70,0x6f,0x77,0x5f,0x73,0x65,0x61,0x72,0x63,
0x68,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x64,0x61,0x67,0x5f,0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,0x2a,0x20,0x67,0x5f,0x64,0x61,0x67,0x2c,0x5f,0x5f,
0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x6a,0x6f,0x62,0x5f,0x62,0x6c,0x6f,0x62,0x2c,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x74,0x61,0x72,0x67,
0x65,0x74,0x2c,0x75,0x69,0x6e,0x74,0x20,0x68,0x61,0x63,0x6b,0x5f,0x66,0x61,0x6c,0x73,0x65,0x2c,0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,0x20,0x5f,0x5f,0x67,0x6c,
0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x73,0x2c,0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,0x20,0x5f,0x5f,0x67,0x6c,
0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x73,0x74,0x6f,0x70,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
0x74,0x20,0x6c,0x69,0x64,0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,
0x74,0x33,0x32,0x5f,0x74,0x20,0x67,0x69,0x64,0x3d,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x69,0x66,0x28,0x73,
0x74,0x6f,0x70,0x5b,0x30,0x5d,0x29,0x20,0x7b,0x0a,0x69,0x66,0x28,0x6c,0x69,0x64,0x3d,0x3d,0x30,0x29,0x20,0x7b,0x0a,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x69,0x6e,
0x63,0x28,0x73,0x74,0x6f,0x70,0x2b,0x31,0x29,0x3b,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x73,
0x68,0x75,0x66,0x66,0x6c,0x65,0x5f,0x74,0x20,0x73,0x68,0x61,0x72,0x65,0x5b,0x48,0x41,0x53,0x48,0x45,0x53,0x5f,0x50,0x45,0x52,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5d,
0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x63,0x5f,0x64,0x61,0x67,0x5b,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,
0x5f,0x43,0x41,0x43,0x48,0x45,0x5f,0x57,0x4f,0x52,0x44,0x53,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x61,
0x6e,0x65,0x5f,0x69,0x64,0x3d,0x6c,0x69,0x64,0x26,0x28,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x2d,0x31,0x29,0x3b,0x0a,0x63,0x6f,0x6e,
0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x3d,0x6c,0x69,0x64,0x2f,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,
0x5f,0x4c,0x41,0x4e,0x45,0x53,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x77,0x6f,0x72,0x64,0x3d,0x6c,0x69,0x64,0x2a,0x50,
0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,0x47,0x5f,0x4c,0x4f,0x41,0x44,0x53,0x3b,0x20,0x77,0x6f,0x72,0x64,0x3c,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x43,
0x41,0x43,0x48,0x45,0x5f,0x57,0x4f,0x52,0x44,0x53,0x3b,0x20,0x77,0x6f,0x72,0x64,0x2b,0x3d,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x2a,0x50,0x52,0x4f,
0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,0x47,0x5f,0x4c,0x4f,0x41,0x44,0x53,0x29,0x0a,0x7b,0x0a,0x64,0x61,0x67,0x5f,0x74,0x20,0x6c,0x6f,0x61,0x64,0x3d,0x67,0x5f,0x64,
0x61,0x67,0x5b,0x77,0x6f,0x72,0x64,0x2f,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,0x47,0x5f,0x4c,0x4f,0x41,0x44,0x53,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,
0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,0x47,0x5f,0x4c,0x4f,0x41,0x44,0x53,0x3b,0x20,0x69,
0x2b,0x2b,0x29,0x0a,0x63,0x5f,0x64,0x61,0x67,0x5b,0x77,0x6f,0x72,0x64,0x2b,0x69,0x5d,0x3d,0x6c,0x6f,0x61,0x64,0x2e,0x73,0x5b,0x69,0x5d,0x3b,0x0a,0x7d,0x0a,0x75,
0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x68,0x61,0x73,0x68,0x5f,0x73,0x65,0x65,0x64,0x5b,0x32,0x5d,0x3b,0x20,0x0a,0x68,0x61,0x73,0x68,0x33,0x32,0x5f,0x74,0x20,
0x64,0x69,0x67,0x65,0x73,0x74,0x3b,0x20,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x74,0x61,0x74,0x65,0x32,0x5b,0x38,0x5d,0x3b,0x0a,0x7b,0x0a,0x75,
0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x74,0x61,0x74,0x65,0x5b,0x32,0x35,0x5d,0x3b,0x20,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,
0x3b,0x20,0x69,0x3c,0x31,0x30,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3d,0x6a,0x6f,0x62,0x5f,0x62,0x6c,0x6f,0x62,0x5b,0x69,
0x5d,0x3b,0x0a,0x73,0x74,0x61,0x74,0x65,0x5b,0x38,0x5d,0x3d,0x67,0x69,0x64,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x31,0x30,0x3b,0x20,
0x69,0x3c,0x32,0x35,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3d,0x72,0x61,0x76,0x65,0x6e,0x63,0x6f,0x69,0x6e,0x5f,0x72,0x6e,
0x64,0x63,0x5b,0x69,0x2d,0x31,0x30,0x5d,0x3b,0x0a,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x38,0x30,0x30,0x28,0x73,0x74,0x61,0x74,0x65,0x29,0x3b,0x0a,0x66,0x6f,
0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x38,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,0x32,0x5b,0x69,0x5d,0x3d,
0x73,0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3b,0x0a,0x7d,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x31,0x0a,0x66,0x6f,0x72,
0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x68,0x3d,0x30,0x3b,0x20,0x68,0x3c,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x3b,
0x20,0x68,0x2b,0x2b,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6d,0x69,0x78,0x5b,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x52,0x45,0x47,
0x53,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x3d,0x3d,0x68,0x29,0x20,0x7b,0x0a,0x73,0x68,0x61,0x72,0x65,0x5b,0x67,0x72,0x6f,0x75,0x70,
0x5f,0x69,0x64,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x30,0x5d,0x3d,0x73,0x74,0x61,0x74,0x65,0x32,0x5b,0x30,0x5d,0x3b,0x0a,0x73,0x68,0x61,0x72,0x65,
0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x31,0x5d,0x3d,0x73,0x74,0x61,0x74,0x65,0x32,0x5b,0x31,0x5d,0x3b,
0x0a,0x7d,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,
0x0a,0x66,0x69,0x6c,0x6c,0x5f,0x6d,0x69,0x78,0x28,0x73,0x68,0x61,0x72,0x65,0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,
0x73,0x2c,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x2c,0x6d,0x69,0x78,0x29,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x32,
0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x6f,0x6f,0x70,0x3d,0x30,0x3b,0x20,0x6c,0x6f,0x6f,0x70,0x3c,0x50,0x52,0x4f,0x47,
0x50,0x4f,0x57,0x5f,0x43,0x4e,0x54,0x5f,0x44,0x41,0x47,0x3b,0x20,0x2b,0x2b,0x6c,0x6f,0x6f,0x70,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x6c,0x61,0x6e,0x65,0x5f,0x69,
0x64,0x3d,0x3d,0x28,0x6c,0x6f,0x6f,0x70,0x20,0x25,0x20,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x29,0x29,0x0a,0x73,0x68,0x61,0x72,0x65,
0x5b,0x30,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x5d,0x3d,0x6d,0x69,0x78,0x5b,0x30,0x5d,0x3b,0x0a,0x62,0x61,
0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,
0x33,0x32,0x5f,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x73,0x68,0x61,0x72,0x65,0x5b,0x30,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x67,0x72,0x6f,
0x75,0x70,0x5f,0x69,0x64,0x5d,0x3b,0x0a,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x25,0x3d,0x20,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,0x47,0x5f,0x45,0x4c,
0x45,0x4d,0x45,0x4e,0x54,0x53,0x3b,0x0a,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,
0x4e,0x45,0x53,0x2b,0x28,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x5e,0x6c,0x6f,0x6f,0x70,0x29,0x20,0x25,0x20,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,
0x45,0x53,0x3b,0x0a,0x64,0x61,0x67,0x5f,0x74,0x20,0x64,0x61,0x74,0x61,0x5f,0x64,0x61,0x67,0x3d,0x67,0x5f,0x64,0x61,0x67,0x5b,0x6f,0x66,0x66,0x73,0x65,0x74,0x5d,
0x3b,0x0a,0x69,0x66,0x28,0x68,0x61,0x63,0x6b,0x5f,0x66,0x61,0x6c,0x73,0x65,0x29,0x20,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,
0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x64,0x61,0x74,0x61,0x3b,0x0a,0x58,0x4d,
0x52,0x49,0x47,0x5f,0x49,0x4e,0x43,0x4c,0x55,0x44,0x45,0x5f,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x5f,0x4d,0x41,0x54,0x48,0x0a,
0x69,0x66,0x28,0x68,0x61,0x63,0x6b,0x5f,0x66,0x61,0x6c,0x73,0x65,0x29,0x20,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,
0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x58,0x4d,0x52,0x49,0x47,0x5f,0x49,0x4e,0x43,0x4c,0x55,0x44,0x45,0x5f,0x50,0x52,0x4f,0x47,0x50,
0x4f,0x57,0x5f,0x44,0x41,0x54,0x41,0x5f,0x4c,0x4f,0x41,0x44,0x53,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6d,0x69,0x78,0x5f,0x68,0x61,0x73,
0x68,0x3d,0x46,0x4e,0x56,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x5f,0x42,0x41,0x53,0x49,0x53,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,
0x6c,0x6c,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x52,0x45,0x47,0x53,0x3b,
0x20,0x69,0x2b,0x2b,0x29,0x0a,0x66,0x6e,0x76,0x31,0x61,0x28,0x6d,0x69,0x78,0x5f,0x68,0x61,0x73,0x68,0x2c,0x6d,0x69,0x78,0x5b,0x69,0x5d,0x29,0x3b,0x0a,0x68,0x61,
0x73,0x68,0x33,0x32,0x5f,0x74,0x20,0x64,0x69,0x67,0x65,0x73,0x74,0x5f,0x74,0x65,0x6d,0x70,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,
0x3b,0x20,0x69,0x3c,0x38,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x64,0x69,0x67,0x65,0x73,0x74,0x5f,0x74,0x65,0x6d,0x70,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,
0x69,0x5d,0x3d,0x46,0x4e,0x56,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x5f,0x42,0x41,0x53,0x49,0x53,0x3b,0x0a,0x73,0x68,0x61,0x72,0x65,0x5b,0x67,0x72,0x6f,0x75,0x70,
0x5f,0x69,0x64,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x5d,0x3d,0x6d,0x69,0x78,0x5f,0x68,0x61,0x73,0x68,0x3b,0x0a,
0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x23,0x70,
0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x50,0x52,0x4f,
0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x66,0x6e,0x76,0x31,0x61,0x28,0x64,0x69,0x67,0x65,0x73,0x74,0x5f,0x74,0x65,
0x6d,0x70,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x69,0x20,0x25,0x20,0x38,0x5d,0x2c,0x73,0x68,0x61,0x72,0x65,0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,
0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x69,0x5d,0x29,0x3b,0x0a,0x69,0x66,0x28,0x68,0x3d,0x3d,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x29,0x0a,0x64,0x69,
0x67,0x65,0x73,0x74,0x3d,0x64,0x69,0x67,0x65,0x73,0x74,0x5f,0x74,0x65,0x6d,0x70,0x3b,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x72,0x65,0x73,
0x75,0x6c,0x74,0x3b,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x74,0x61,0x74,0x65,0x5b,0x32,0x35,0x5d,0x3d,0x7b,0x30,0x78,0x30,0x7d,0x3b,
0x20,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x38,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,0x5b,
0x69,0x5d,0x3d,0x73,0x74,0x61,0x74,0x65,0x32,0x5b,0x69,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x38,0x3b,0x20,0x69,0x3c,0x31,0x36,
0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3d,0x64,0x69,0x67,0x65,0x73,0x74,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x69,
0x2d,0x38,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x31,0x36,0x3b,0x20,0x69,0x3c,0x32,0x35,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,
0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3d,0x72,0x61,0x76,0x65,0x6e,0x63,0x6f,0x69,0x6e,0x5f,0x72,0x6e,0x64,0x63,0x5b,0x69,0x2d,0x31,0x36,0x5d,0x3b,0x0a,0x6b,0x65,
0x63,0x63,0x61,0x6b,0x5f,0x66,0x38,0x30,0x30,0x28,0x73,0x74,0x61,0x74,0x65,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x72,0x65,0x73,0x3d,0x28,
0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x73,0x74,0x61,0x74,0x65,0x5b,0x31,0x5d,0x3c,0x3c,0x33,0x32,0x7c,0x73,0x74,0x61,0x74,0x65,0x5b,0x30,0x5d,0x3b,0x0a,
0x72,0x65,0x73,0x75,0x6c,0x74,0x3d,0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67,0x28,0x61,0x73,0x5f,0x75,0x63,0x68,0x61,0x72,0x38,0x28,0x72,0x65,0x73,0x29,0x2e,0x73,
0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x3c,0x3d,0x74,0x61,0x72,0x67,0x65,0x74,0x29,0x0a,
0x7b,0x0a,0x2a,0x73,0x74,0x6f,0x70,0x3d,0x31,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6b,0x3d,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x69,
0x6e,0x63,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x73,0x29,0x2b,0x31,0x3b,0x0a,0x69,0x66,0x28,0x6b,0x3c,0x3d,0x31,0x35,0x29,0x0a,0x72,0x65,0x73,0x75,0x6c,0x74,0x73,
0x5b,0x6b,0x5d,0x3d,0x67,0x69,0x64,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x00
0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x23,0x69,0x66,0x6e,0x64,0x65,0x66,0x20,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x0a,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x63,
0x6c,0x5f,0x61,0x6d,0x64,0x5f,0x6d,0x65,0x64,0x69,0x61,0x5f,0x6f,0x70,0x73,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,
0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x5f,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x5f,0x41,0x4d,0x44,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x23,0x64,0x65,0x66,0x69,
0x6e,0x65,0x20,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x5f,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x5f,0x55,0x4e,0x4b,0x4e,
0x4f,0x57,0x4e,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x48,0x41,0x53,0x48,0x45,0x53,
0x5f,0x50,0x45,0x52,0x5f,0x47,0x52,0x4f,0x55,0x50,0x20,0x28,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x20,0x2f,0x20,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,
0x5f,0x4c,0x41,0x4e,0x45,0x53,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x46,0x4e,0x56,0x5f,0x50,0x52,0x49,0x4d,0x45,0x20,0x30,0x78,0x31,0x30,0x30,0x30,
0x31,0x39,0x33,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x46,0x4e,0x56,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x5f,0x42,0x41,0x53,0x49,0x53,0x20,0x30,0x78,0x38,
0x31,0x31,0x63,0x39,0x64,0x63,0x35,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,
0x74,0x65,0x5f,0x5f,0x20,0x28,0x28,0x61,0x6c,0x69,0x67,0x6e,0x65,0x64,0x28,0x31,0x36,0x29,0x29,0x29,0x20,0x7b,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,
0x5b,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,0x47,0x5f,0x4c,0x4f,0x41,0x44,0x53,0x5d,0x3b,0x7d,0x20,0x64,0x61,0x67,0x5f,0x74,0x3b,0x0a,0x5f,0x5f,0x63,
0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x5f,0x72,
0x6e,0x64,0x63,0x5b,0x32,0x34,0x5d,0x3d,0x7b,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x32,0x2c,0x30,
0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x61,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x62,
0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x31,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x30,
0x39,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x61,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x38,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x38,0x30,
0x30,0x39,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x61,0x2c,0x0a,0x30,0x78,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x62,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,
0x30,0x30,0x38,0x62,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x39,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x33,0x2c,0x30,0x78,0x30,0x30,0x30,
0x30,0x38,0x30,0x30,0x32,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x61,0x2c,0x30,0x78,0x38,0x30,
0x30,0x30,0x30,0x30,0x30,0x61,0x2c,0x0a,0x30,0x78,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x31,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x30,0x2c,0x30,0x78,
0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x38,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,
0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x72,0x61,0x76,0x65,0x6e,0x63,0x6f,0x69,0x6e,0x5f,0x72,0x6e,0x64,0x63,0x5b,0x31,
0x35,0x5d,0x3d,0x7b,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x37,0x32,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x31,0x2c,0x0a,0x30,0x78,0x30,
0x30,0x30,0x30,0x30,0x30,0x35,0x36,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x35,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x45,0x2c,
0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x33,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x46,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,
0x30,0x34,0x39,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x45,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x42,0x2c,0x0a,0x30,0x78,0x30,
0x30,0x30,0x30,0x30,0x30,0x34,0x31,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x35,0x37,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x35,0x30,0x2c,
0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x46,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x35,0x37,0x2c,0x0a,0x7d,0x3b,0x0a,0x76,0x6f,0x69,0x64,
0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x38,0x30,0x30,0x5f,0x72,0x6f,0x75,0x6e,0x64,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x74,0x5b,0x32,
0x35,0x5d,0x2c,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,
0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x5f,0x72,0x6f,0x74,0x63,0x5b,0x32,0x34,0x5d,0x3d,0x7b,0x0a,0x31,0x2c,0x33,0x2c,0x36,0x2c,0x31,0x30,0x2c,0x31,0x35,0x2c,
0x32,0x31,0x2c,0x32,0x38,0x2c,0x33,0x36,0x2c,0x34,0x35,0x2c,0x35,0x35,0x2c,0x32,0x2c,0x31,0x34,0x2c,0x32,0x37,0x2c,0x34,0x31,0x2c,0x35,0x36,0x2c,0x38,0x2c,0x32,
0x35,0x2c,0x34,0x33,0x2c,0x36,0x32,0x2c,0x31,0x38,0x2c,0x33,0x39,0x2c,0x36,0x31,0x2c,0x32,0x30,0x2c,0x34,0x34,0x7d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,
0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x5f,0x70,0x69,0x6c,0x6e,0x5b,0x32,0x34,0x5d,0x3d,0x7b,0x0a,0x31,0x30,0x2c,0x37,0x2c,
0x31,0x31,0x2c,0x31,0x37,0x2c,0x31,0x38,0x2c,0x33,0x2c,0x35,0x2c,0x31,0x36,0x2c,0x38,0x2c,0x32,0x31,0x2c,0x32,0x34,0x2c,0x34,0x2c,0x31,0x35,0x2c,0x32,0x33,0x2c,
0x31,0x39,0x2c,0x31,0x33,0x2c,0x31,0x32,0x2c,0x32,0x2c,0x32,0x30,0x2c,0x31,0x34,0x2c,0x32,0x32,0x2c,0x39,0x2c,0x36,0x2c,0x31,0x7d,0x3b,0x0a,0x75,0x69,0x6e,0x74,
0x33,0x32,0x5f,0x74,0x20,0x74,0x2c,0x62,0x63,0x5b,0x35,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x35,0x3b,
0x20,0x69,0x2b,0x2b,0x29,0x0a,0x62,0x63,0x5b,0x69,0x5d,0x3d,0x73,0x74,0x5b,0x69,0x5d,0x5e,0x73,0x74,0x5b,0x69,0x2b,0x35,0x5d,0x5e,0x73,0x74,0x5b,0x69,0x2b,0x31,
0x30,0x5d,0x5e,0x73,0x74,0x5b,0x69,0x2b,0x31,0x35,0x5d,0x5e,0x73,0x74,0x5b,0x69,0x2b,0x32,0x30,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,
0x3d,0x30,0x3b,0x20,0x69,0x3c,0x35,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x7b,0x0a,0x74,0x3d,0x62,0x63,0x5b,0x28,0x69,0x2b,0x34,0x29,0x20,0x25,0x20,0x35,0x5d,0x5e,
0x52,0x4f,0x54,0x4c,0x33,0x32,0x28,0x62,0x63,0x5b,0x28,0x69,0x2b,0x31,0x29,0x20,0x25,0x20,0x35,0x5d,0x2c,0x31,0x75,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,
0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x3d,0x30,0x3b,0x20,0x6a,0x3c,0x32,0x35,0x3b,0x20,0x6a,0x2b,0x3d,0x35,0x29,0x0a,0x73,0x74,0x5b,0x6a,0x2b,0x69,0x5d,
0x20,0x5e,0x3d,0x20,0x74,0x3b,0x0a,0x7d,0x0a,0x74,0x3d,0x73,0x74,0x5b,0x31,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,
0x69,0x3c,0x32,0x34,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x3d,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x5f,
0x70,0x69,0x6c,0x6e,0x5b,0x69,0x5d,0x3b,0x0a,0x62,0x63,0x5b,0x30,0x5d,0x3d,0x73,0x74,0x5b,0x6a,0x5d,0x3b,0x0a,0x73,0x74,0x5b,0x6a,0x5d,0x3d,0x52,0x4f,0x54,0x4c,
0x33,0x32,0x28,0x74,0x2c,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x5f,0x72,0x6f,0x74,0x63,0x5b,0x69,0x5d,0x29,0x3b,0x0a,0x74,0x3d,0x62,0x63,0x5b,0x30,0x5d,0x3b,0x0a,
0x7d,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x3d,0x30,0x3b,0x20,0x6a,0x3c,0x32,0x35,0x3b,0x20,0x6a,0x2b,0x3d,0x35,0x29,
0x0a,0x7b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x35,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x62,0x63,0x5b,0x69,0x5d,
0x3d,0x73,0x74,0x5b,0x6a,0x2b,0x69,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x35,0x3b,0x20,0x69,0x2b,0x2b,
0x29,0x0a,0x73,0x74,0x5b,0x6a,0x2b,0x69,0x5d,0x20,0x5e,0x3d,0x20,0x28,0x7e,0x62,0x63,0x5b,0x28,0x69,0x2b,0x31,0x29,0x20,0x25,0x20,0x35,0x5d,0x29,0x26,0x62,0x63,
0x5b,0x28,0x69,0x2b,0x32,0x29,0x20,0x25,0x20,0x35,0x5d,0x3b,0x0a,0x7d,0x0a,0x73,0x74,0x5b,0x30,0x5d,0x20,0x5e,0x3d,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x5f,
0x72,0x6e,0x64,0x63,0x5b,0x72,0x5d,0x3b,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x38,0x30,0x30,0x28,
0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x73,0x74,0x29,0x0a,0x7b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x72,0x3d,0x30,0x3b,0x20,0x72,0x3c,
0x32,0x32,0x3b,0x20,0x72,0x2b,0x2b,0x29,0x20,0x7b,0x0a,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x38,0x30,0x30,0x5f,0x72,0x6f,0x75,0x6e,0x64,0x28,0x73,0x74,0x2c,
0x72,0x29,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x66,0x6e,0x76,0x31,0x61,0x28,0x68,0x2c,0x20,0x64,0x29,0x20,0x28,0x68,0x20,0x3d,
0x20,0x28,0x68,0x20,0x5e,0x20,0x64,0x29,0x20,0x2a,0x20,0x46,0x4e,0x56,0x5f,0x50,0x52,0x49,0x4d,0x45,0x29,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x73,0x74,
0x72,0x75,0x63,0x74,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x7a,0x2c,0x77,0x2c,0x6a,0x73,0x72,0x2c,0x6a,0x63,0x6f,0x6e,0x67,0x3b,0x0a,0x7d,
0x20,0x6b,0x69,0x73,0x73,0x39,0x39,0x5f,0x74,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x69,0x73,0x73,0x39,0x39,0x28,0x6b,0x69,0x73,0x73,0x39,
0x39,0x5f,0x74,0x2a,0x20,0x73,0x74,0x29,0x0a,0x7b,0x0a,0x73,0x74,0x2d,0x3e,0x7a,0x3d,0x33,0x36,0x39,0x36,0x39,0x2a,0x28,0x73,0x74,0x2d,0x3e,0x7a,0x26,0x36,0x35,
0x35,0x33,0x35,0x29,0x2b,0x28,0x73,0x74,0x2d,0x3e,0x7a,0x3e,0x3e,0x31,0x36,0x29,0x3b,0x0a,0x73,0x74,0x2d,0x3e,0x77,0x3d,0x31,0x38,0x30,0x30,0x30,0x2a,0x28,0x73,
0x74,0x2d,0x3e,0x77,0x26,0x36,0x35,0x35,0x33,0x35,0x29,0x2b,0x28,0x73,0x74,0x2d,0x3e,0x77,0x3e,0x3e,0x31,0x36,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
0x74,0x20,0x4d,0x57,0x43,0x3d,0x28,0x28,0x73,0x74,0x2d,0x3e,0x7a,0x3c,0x3c,0x31,0x36,0x29,0x2b,0x73,0x74,0x2d,0x3e,0x77,0x29,0x3b,0x0a,0x73,0x74,0x2d,0x3e,0x6a,
0x73,0x72,0x20,0x5e,0x3d,0x20,0x28,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,0x20,0x5e,0x3d,0x20,
0x28,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,0x3e,0x3e,0x31,0x33,0x29,0x3b,0x0a,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,0x20,0x5e,0x3d,0x20,0x28,0x73,0x74,0x2d,0x3e,0x6a,
0x73,0x72,0x3c,0x3c,0x35,0x29,0x3b,0x0a,0x73,0x74,0x2d,0x3e,0x6a,0x63,0x6f,0x6e,0x67,0x3d,0x36,0x39,0x30,0x36,0x39,0x2a,0x73,0x74,0x2d,0x3e,0x6a,0x63,0x6f,0x6e,
0x67,0x2b,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x28,0x28,0x4d,0x57,0x43,0x5e,0x73,0x74,0x2d,0x3e,0x6a,0x63,0x6f,0x6e,
0x67,0x29,0x2b,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,0x29,0x3b,0x0a,0x7d,0x0a,0x76,0x6f,0x69,0x64,0x20,0x66,0x69,0x6c,0x6c,0x5f,0x6d,0x69,0x78,0x28,0x6c,0x6f,0x63,
0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x73,0x65,0x65,0x64,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x61,0x6e,0x65,0x5f,
0x69,0x64,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x6d,0x69,0x78,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x6e,0x76,
0x5f,0x68,0x61,0x73,0x68,0x3d,0x46,0x4e,0x56,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x5f,0x42,0x41,0x53,0x49,0x53,0x3b,0x0a,0x6b,0x69,0x73,0x73,0x39,0x39,0x5f,0x74,
0x20,0x73,0x74,0x3b,0x0a,0x73,0x74,0x2e,0x7a,0x3d,0x66,0x6e,0x76,0x31,0x61,0x28,0x66,0x6e,0x76,0x5f,0x68,0x61,0x73,0x68,0x2c,0x73,0x65,0x65,0x64,0x5b,0x30,0x5d,
0x29,0x3b,0x0a,0x73,0x74,0x2e,0x77,0x3d,0x66,0x6e,0x76,0x31,0x61,0x28,0x66,0x6e,0x76,0x5f,0x68,0x61,0x73,0x68,0x2c,0x73,0x65,0x65,0x64,0x5b,0x31,0x5d,0x29,0x3b,
0x0a,0x73,0x74,0x2e,0x6a,0x73,0x72,0x3d,0x66,0x6e,0x76,0x31,0x61,0x28,0x66,0x6e,0x76,0x5f,0x68,0x61,0x73,0x68,0x2c,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x29,0x3b,
0x0a,0x73,0x74,0x2e,0x6a,0x63,0x6f,0x6e,0x67,0x3d,0x66,0x6e,0x76,0x31,0x61,0x28,0x66,0x6e,0x76,0x5f,0x68,0x61,0x73,0x68,0x2c,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,
0x29,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,
0x69,0x3c,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x52,0x45,0x47,0x53,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x6d,0x69,0x78,0x5b,0x69,0x5d,0x3d,0x6b,0x69,0x73,0x73,
0x39,0x39,0x28,0x26,0x73,0x74,0x29,0x3b,0x0a,0x7d,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x73,0x74,0x72,0x75,0x63,0x74,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,
0x33,0x32,0x5f,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x5d,0x3b,0x0a,0x7d,0x20,0x73,
0x68,0x75,0x66,0x66,0x6c,0x65,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x73,0x74,0x72,0x75,0x63,0x74,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,
0x32,0x5f,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x33,0x32,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x5d,
0x3b,0x0a,0x7d,0x20,0x68,0x61,0x73,0x68,0x33,0x32,0x5f,0x74,0x3b,0x0a,0x23,0x69,0x66,0x20,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x20,0x21,0x3d,0x20,0x4f,0x50,
0x45,0x4e,0x43,0x4c,0x5f,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x5f,0x4e,0x56,0x49,0x44,0x49,0x41,0x20,0x0a,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,
0x65,0x5f,0x5f,0x28,0x28,0x72,0x65,0x71,0x64,0x5f,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x47,0x52,0x4f,0x55,0x50,0x5f,
0x53,0x49,0x5a,0x45,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,
0x20,0x70,0x72,0x6f,0x67,0x70,0x6f,0x77,0x5f,0x73,0x65,0x61,0x72,0x63,0x68,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x64,0x61,0x67,0x5f,0x74,0x20,0x63,
0x6f,0x6e,0x73,0x74,0x2a,0x20,0x67,0x5f,0x64,0x61,0x67,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x6a,0x6f,0x62,0x5f,0x62,
0x6c,0x6f,0x62,0x2c,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x74,0x61,0x72,0x67,0x65,0x74,0x2c,0x75,0x69,0x6e,0x74,0x20,0x68,0x61,0x63,0x6b,0x5f,0x66,0x61,0x6c,0x73,0x65,
0x2c,0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x73,
0x2c,0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x73,0x74,0x6f,0x70,0x29,0x0a,0x7b,
0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x69,0x64,0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,
0x28,0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x67,0x69,0x64,0x3d,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,
0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x69,0x66,0x28,0x73,0x74,0x6f,0x70,0x5b,0x30,0x5d,0x29,0x20,0x7b,0x0a,0x69,0x66,0x28,0x6c,0x69,0x64,0x3d,0x3d,
0x30,0x29,0x20,0x7b,0x0a,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x69,0x6e,0x63,0x28,0x73,0x74,0x6f,0x70,0x2b,0x31,0x29,0x3b,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,
0x6e,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x73,0x68,0x75,0x66,0x66,0x6c,0x65,0x5f,0x74,0x20,0x73,0x68,0x61,0x72,0x65,0x5b,0x48,0x41,0x53,
0x48,0x45,0x53,0x5f,0x50,0x45,0x52,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,
0x20,0x63,0x5f,0x64,0x61,0x67,0x5b,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x43,0x41,0x43,0x48,0x45,0x5f,0x57,0x4f,0x52,0x44,0x53,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,
0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x3d,0x6c,0x69,0x64,0x26,0x28,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,
0x5f,0x4c,0x41,0x4e,0x45,0x53,0x2d,0x31,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x67,0x72,0x6f,0x75,0x70,0x5f,
0x69,0x64,0x3d,0x6c,0x69,0x64,0x2f,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,
0x32,0x5f,0x74,0x20,0x77,0x6f,0x72,0x64,0x3d,0x6c,0x69,0x64,0x2a,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,0x47,0x5f,0x4c,0x4f,0x41,0x44,0x53,0x3b,0x20,
0x77,0x6f,0x72,0x64,0x3c,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x43,0x41,0x43,0x48,0x45,0x5f,0x57,0x4f,0x52,0x44,0x53,0x3b,0x20,0x77,0x6f,0x72,0x64,0x2b,0x3d,
0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x2a,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,0x47,0x5f,0x4c,0x4f,0x41,0x44,0x53,0x29,0x0a,0x7b,0x0a,
0x64,0x61,0x67,0x5f,0x74,0x20,0x6c,0x6f,0x61,0x64,0x3d,0x67,0x5f,0x64,0x61,0x67,0x5b,0x77,0x6f,0x72,0x64,0x2f,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,
0x47,0x5f,0x4c,0x4f,0x41,0x44,0x53,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x50,0x52,0x4f,0x47,0x50,0x4f,
0x57,0x5f,0x44,0x41,0x47,0x5f,0x4c,0x4f,0x41,0x44,0x53,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x63,0x5f,0x64,0x61,0x67,0x5b,0x77,0x6f,0x72,0x64,0x2b,0x69,0x5d,0x3d,
0x6c,0x6f,0x61,0x64,0x2e,0x73,0x5b,0x69,0x5d,0x3b,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x68,0x61,0x73,0x68,0x5f,0x73,0x65,0x65,0x64,0x5b,
0x32,0x5d,0x3b,0x20,0x0a,0x68,0x61,0x73,0x68,0x33,0x32,0x5f,0x74,0x20,0x64,0x69,0x67,0x65,0x73,0x74,0x3b,0x20,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,
0x73,0x74,0x61,0x74,0x65,0x32,0x5b,0x38,0x5d,0x3b,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x74,0x61,0x74,0x65,0x5b,0x32,0x35,0x5d,0x3b,
0x20,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x31,0x30,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,
0x5b,0x69,0x5d,0x3d,0x6a,0x6f,0x62,0x5f,0x62,0x6c,0x6f,0x62,0x5b,0x69,0x5d,0x3b,0x0a,0x73,0x74,0x61,0x74,0x65,0x5b,0x38,0x5d,0x3d,0x67,0x69,0x64,0x3b,0x0a,0x66,
0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x31,0x30,0x3b,0x20,0x69,0x3c,0x32,0x35,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,0x5b,0x69,
0x5d,0x3d,0x72,0x61,0x76,0x65,0x6e,0x63,0x6f,0x69,0x6e,0x5f,0x72,0x6e,0x64,0x63,0x5b,0x69,0x2d,0x31,0x30,0x5d,0x3b,0x0a,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,
0x38,0x30,0x30,0x28,0x73,0x74,0x61,0x74,0x65,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x38,0x3b,0x20,0x69,
0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,0x32,0x5b,0x69,0x5d,0x3d,0x73,0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3b,0x0a,0x7d,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,
0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x31,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x68,0x3d,0x30,0x3b,0x20,0x68,0x3c,
0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x3b,0x20,0x68,0x2b,0x2b,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6d,
0x69,0x78,0x5b,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x52,0x45,0x47,0x53,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x3d,0x3d,0x68,0x29,
0x20,0x7b,0x0a,0x73,0x68,0x61,0x72,0x65,0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x30,0x5d,0x3d,0x73,0x74,
0x61,0x74,0x65,0x32,0x5b,0x30,0x5d,0x3b,0x0a,0x73,0x68,0x61,0x72,0x65,0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,
0x5b,0x31,0x5d,0x3d,0x73,0x74,0x61,0x74,0x65,0x32,0x5b,0x31,0x5d,0x3b,0x0a,0x7d,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,
0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x66,0x69,0x6c,0x6c,0x5f,0x6d,0x69,0x78,0x28,0x73,0x68,0x61,0x72,0x65,0x5b,0x67,0x72,
0x6f,0x75,0x70,0x5f,0x69,0x64,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x2c,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x2c,0x6d,0x69,0x78,0x29,0x3b,0x0a,0x23,0x70,
0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x32,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x6f,0x6f,
0x70,0x3d,0x30,0x3b,0x20,0x6c,0x6f,0x6f,0x70,0x3c,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x43,0x4e,0x54,0x5f,0x44,0x41,0x47,0x3b,0x20,0x2b,0x2b,0x6c,0x6f,0x6f,
0x70,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x3d,0x3d,0x28,0x6c,0x6f,0x6f,0x70,0x20,0x25,0x20,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,
0x5f,0x4c,0x41,0x4e,0x45,0x53,0x29,0x29,0x0a,0x73,0x68,0x61,0x72,0x65,0x5b,0x30,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,
0x69,0x64,0x5d,0x3d,0x6d,0x69,0x78,0x5b,0x30,0x5d,0x3b,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,
0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x73,0x68,0x61,0x72,0x65,0x5b,
0x30,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x5d,0x3b,0x0a,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x25,0x3d,0x20,
0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,0x47,0x5f,0x45,0x4c,0x45,0x4d,0x45,0x4e,0x54,0x53,0x3b,0x0a,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x6f,0x66,0x66,
0x73,0x65,0x74,0x2a,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x2b,0x28,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x5e,0x6c,0x6f,0x6f,0x70,0x29,
0x20,0x25,0x20,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x3b,0x0a,0x64,0x61,0x67,0x5f,0x74,0x20,0x64,0x61,0x74,0x61,0x5f,0x64,0x61,0x67,
0x3d,0x67,0x5f,0x64,0x61,0x67,0x5b,0x6f,0x66,0x66,0x73,0x65,0x74,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x68,0x61,0x63,0x6b,0x5f,0x66,0x61,0x6c,0x73,0x65,0x29,0x20,0x62,
0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x75,0x69,0x6e,
0x74,0x33,0x32,0x5f,0x74,0x20,0x64,0x61,0x74,0x61,0x3b,0x0a,0x58,0x4d,0x52,0x49,0x47,0x5f,0x49,0x4e,0x43,0x4c,0x55,0x44,0x45,0x5f,0x50,0x52,0x4f,0x47,0x50,0x4f,
0x57,0x5f,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x5f,0x4d,0x41,0x54,0x48,0x0a,0x69,0x66,0x28,0x68,0x61,0x63,0x6b,0x5f,0x66,0x61,0x6c,0x73,0x65,0x29,0x20,0x62,0x61,0x72,
0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x58,0x4d,0x52,0x49,0x47,
0x5f,0x49,0x4e,0x43,0x4c,0x55,0x44,0x45,0x5f,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,0x54,0x41,0x5f,0x4c,0x4f,0x41,0x44,0x53,0x0a,0x7d,0x0a,0x75,0x69,
0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6d,0x69,0x78,0x5f,0x68,0x61,0x73,0x68,0x3d,0x46,0x4e,0x56,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x5f,0x42,0x41,0x53,0x49,0x53,
0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,
0x3c,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x52,0x45,0x47,0x53,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x66,0x6e,0x76,0x31,0x61,0x28,0x6d,0x69,0x78,0x5f,0x68,0x61,
0x73,0x68,0x2c,0x6d,0x69,0x78,0x5b,0x69,0x5d,0x29,0x3b,0x0a,0x68,0x61,0x73,0x68,0x33,0x32,0x5f,0x74,0x20,0x64,0x69,0x67,0x65,0x73,0x74,0x5f,0x74,0x65,0x6d,0x70,
0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x38,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x64,0x69,0x67,0x65,0x73,0x74,
0x5f,0x74,0x65,0x6d,0x70,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x69,0x5d,0x3d,0x46,0x4e,0x56,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x5f,0x42,0x41,0x53,0x49,
0x53,0x3b,0x0a,0x73,0x68,0x61,0x72,0x65,0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x6c,0x61,0x6e,0x65,0x5f,
0x69,0x64,0x5d,0x3d,0x6d,0x69,0x78,0x5f,0x68,0x61,0x73,0x68,0x3b,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,
0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x0a,0x66,0x6f,0x72,0x20,0x28,
0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x66,
0x6e,0x76,0x31,0x61,0x28,0x64,0x69,0x67,0x65,0x73,0x74,0x5f,0x74,0x65,0x6d,0x70,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x69,0x20,0x25,0x20,0x38,0x5d,0x2c,
0x73,0x68,0x61,0x72,0x65,0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x69,0x5d,0x29,0x3b,0x0a,0x69,0x66,0x28,
0x68,0x3d,0x3d,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x29,0x0a,0x64,0x69,0x67,0x65,0x73,0x74,0x3d,0x64,0x69,0x67,0x65,0x73,0x74,0x5f,0x74,0x65,0x6d,0x70,0x3b,0x0a,
0x7d,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x74,
0x61,0x74,0x65,0x5b,0x32,0x35,0x5d,0x3d,0x7b,0x30,0x78,0x30,0x7d,0x3b,0x20,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,
0x38,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3d,0x73,0x74,0x61,0x74,0x65,0x32,0x5b,0x69,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,
0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x38,0x3b,0x20,0x69,0x3c,0x31,0x36,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3d,0x64,0x69,
0x67,0x65,0x73,0x74,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x69,0x2d,0x38,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x31,0x36,
0x3b,0x20,0x69,0x3c,0x32,0x35,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3d,0x72,0x61,0x76,0x65,0x6e,0x63,0x6f,0x69,0x6e,0x5f,
0x72,0x6e,0x64,0x63,0x5b,0x69,0x2d,0x31,0x36,0x5d,0x3b,0x0a,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x38,0x30,0x30,0x28,0x73,0x74,0x61,0x74,0x65,0x29,0x3b,0x0a,
0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x72,0x65,0x73,0x3d,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x73,0x74,0x61,0x74,0x65,0x5b,0x31,0x5d,0x3c,
0x3c,0x33,0x32,0x7c,0x73,0x74,0x61,0x74,0x65,0x5b,0x30,0x5d,0x3b,0x0a,0x72,0x65,0x73,0x75,0x6c,0x74,0x3d,0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67,0x28,0x61,0x73,
0x5f,0x75,0x63,0x68,0x61,0x72,0x38,0x28,0x72,0x65,0x73,0x29,0x2e,0x73,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x72,0x65,
0x73,0x75,0x6c,0x74,0x3c,0x3d,0x74,0x61,0x72,0x67,0x65,0x74,0x29,0x0a,0x7b,0x0a,0x2a,0x73,0x74,0x6f,0x70,0x3d,0x31,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,
0x69,0x6e,0x74,0x20,0x6b,0x3d,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x69,0x6e,0x63,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x73,0x29,0x2b,0x31,0x3b,0x0a,0x69,0x66,0x28,
0x6b,0x3c,0x3d,0x31,0x35,0x29,0x0a,0x72,0x65,0x73,0x75,0x6c,0x74,0x73,0x5b,0x6b,0x5d,0x3d,0x67,0x69,0x64,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x00
};
} // namespace xmrig

View file

@ -2,7 +2,7 @@
namespace xmrig {
static const char kawpow_dag_cl[5990] = {
static const char kawpow_dag_cl[6068] = {
0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x63,0x6c,0x5f,0x63,0x6c,0x61,0x6e,0x67,0x5f,0x73,0x74,0x6f,0x72,0x61,0x67,0x65,0x5f,0x63,0x6c,0x61,0x73,0x73,0x5f,0x73,0x70,
0x65,0x63,0x69,0x66,0x69,0x65,0x72,0x73,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,
0x4e,0x20,0x63,0x6c,0x5f,0x63,0x6c,0x61,0x6e,0x67,0x5f,0x73,0x74,0x6f,0x72,0x61,0x67,0x65,0x5f,0x63,0x6c,0x61,0x73,0x73,0x5f,0x73,0x70,0x65,0x63,0x69,0x66,0x69,
@ -25,172 +25,174 @@ static const char kawpow_dag_cl[5990] = {
0x4e,0x43,0x4c,0x5f,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x5f,0x41,0x4d,0x44,0x20,0x32,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x4f,0x50,0x45,0x4e,0x43,
0x4c,0x5f,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x5f,0x43,0x4c,0x4f,0x56,0x45,0x52,0x20,0x33,0x0a,0x23,0x69,0x66,0x6e,0x64,0x65,0x66,0x20,0x4d,0x41,0x58,0x5f,
0x4f,0x55,0x54,0x50,0x55,0x54,0x53,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x4d,0x41,0x58,0x5f,0x4f,0x55,0x54,0x50,0x55,0x54,0x53,0x20,0x36,0x33,0x55,0x0a,
0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x23,0x69,0x66,0x6e,0x64,0x65,0x66,0x20,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,
0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x5f,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x5f,0x41,0x4d,0x44,0x0a,0x23,0x65,0x6e,
0x64,0x69,0x66,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x48,0x41,0x53,0x48,0x45,0x53,0x5f,0x50,0x45,0x52,0x5f,0x47,0x52,0x4f,0x55,0x50,0x20,0x28,0x47,0x52,
0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x20,0x2f,0x20,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,
0x65,0x20,0x46,0x4e,0x56,0x5f,0x50,0x52,0x49,0x4d,0x45,0x20,0x30,0x78,0x31,0x30,0x30,0x30,0x31,0x39,0x33,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x46,0x4e,
0x56,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x5f,0x42,0x41,0x53,0x49,0x53,0x20,0x30,0x78,0x38,0x31,0x31,0x63,0x39,0x64,0x63,0x35,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,
0x65,0x20,0x45,0x54,0x48,0x41,0x53,0x48,0x5f,0x44,0x41,0x54,0x41,0x53,0x45,0x54,0x5f,0x50,0x41,0x52,0x45,0x4e,0x54,0x53,0x20,0x35,0x31,0x32,0x0a,0x23,0x64,0x65,
0x66,0x69,0x6e,0x65,0x20,0x4e,0x4f,0x44,0x45,0x5f,0x57,0x4f,0x52,0x44,0x53,0x20,0x28,0x36,0x34,0x20,0x2f,0x20,0x34,0x29,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,
0x61,0x6e,0x74,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x4b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x31,0x36,0x30,0x30,0x5f,0x52,0x43,0x5b,
0x32,0x34,0x5d,0x3d,0x7b,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x32,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x61,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x62,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x31,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x39,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x61,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x38,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x39,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x61,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x62,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x62,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x39,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x33,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x32,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x61,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x61,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x31,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x30,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x38,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x2c,0x0a,0x7d,0x3b,0x0a,0x23,0x69,0x66,0x20,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x20,0x3d,0x3d,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x5f,
0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x5f,0x4e,0x56,0x49,0x44,0x49,0x41,0x20,0x26,0x26,0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x20,0x3e,0x3d,0x20,0x33,0x35,
0x0a,0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x52,0x4f,0x4c,0x32,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x61,
0x2c,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x72,0x65,0x73,0x75,0x6c,
0x74,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x3e,0x3d,0x33,0x32,0x29,0x0a,0x7b,0x0a,0x61,0x73,0x6d,0x28,0x22,0x73,0x68,0x66,0x2e,0x6c,0x2e,0x77,
0x72,0x61,0x70,0x2e,0x62,0x33,0x32,0x20,0x25,0x30,0x2c,0x25,0x31,0x2c,0x25,0x32,0x2c,0x25,0x33,0x3b,0x22,0x3a,0x22,0x3d,0x72,0x22,0x28,0x72,0x65,0x73,0x75,0x6c,
0x74,0x2e,0x78,0x29,0x3a,0x22,0x72,0x22,0x28,0x61,0x2e,0x78,0x29,0x2c,0x22,0x72,0x22,0x28,0x61,0x2e,0x79,0x29,0x2c,0x22,0x72,0x22,0x28,0x6f,0x66,0x66,0x73,0x65,
0x74,0x29,0x29,0x3b,0x0a,0x61,0x73,0x6d,0x28,0x22,0x73,0x68,0x66,0x2e,0x6c,0x2e,0x77,0x72,0x61,0x70,0x2e,0x62,0x33,0x32,0x20,0x25,0x30,0x2c,0x25,0x31,0x2c,0x25,
0x32,0x2c,0x25,0x33,0x3b,0x22,0x3a,0x22,0x3d,0x72,0x22,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x79,0x29,0x3a,0x22,0x72,0x22,0x28,0x61,0x2e,0x79,0x29,0x2c,0x22,
0x72,0x22,0x28,0x61,0x2e,0x78,0x29,0x2c,0x22,0x72,0x22,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x61,
0x73,0x6d,0x28,0x22,0x73,0x68,0x66,0x2e,0x6c,0x2e,0x77,0x72,0x61,0x70,0x2e,0x62,0x33,0x32,0x20,0x25,0x30,0x2c,0x25,0x31,0x2c,0x25,0x32,0x2c,0x25,0x33,0x3b,0x22,
0x3a,0x22,0x3d,0x72,0x22,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x29,0x3a,0x22,0x72,0x22,0x28,0x61,0x2e,0x79,0x29,0x2c,0x22,0x72,0x22,0x28,0x61,0x2e,0x78,
0x29,0x2c,0x22,0x72,0x22,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0x0a,0x61,0x73,0x6d,0x28,0x22,0x73,0x68,0x66,0x2e,0x6c,0x2e,0x77,0x72,0x61,0x70,0x2e,
0x62,0x33,0x32,0x20,0x25,0x30,0x2c,0x25,0x31,0x2c,0x25,0x32,0x2c,0x25,0x33,0x3b,0x22,0x3a,0x22,0x3d,0x72,0x22,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x79,0x29,
0x3a,0x22,0x72,0x22,0x28,0x61,0x2e,0x78,0x29,0x2c,0x22,0x72,0x22,0x28,0x61,0x2e,0x79,0x29,0x2c,0x22,0x72,0x22,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,
0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x7d,0x0a,0x23,0x65,0x6c,0x69,0x66,0x20,0x50,0x4c,0x41,0x54,0x46,0x4f,
0x52,0x4d,0x20,0x3d,0x3d,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x5f,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x5f,0x41,0x4d,0x44,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,
0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,0x20,0x63,0x6c,0x5f,0x61,0x6d,0x64,0x5f,0x6d,0x65,0x64,0x69,0x61,0x5f,
0x6f,0x70,0x73,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0x0a,0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x52,0x4f,0x4c,0x32,0x28,0x63,
0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x76,0x76,0x2c,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,
0x72,0x3c,0x3d,0x33,0x32,0x29,0x0a,0x7b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x61,0x6d,0x64,0x5f,0x62,0x69,0x74,0x61,0x6c,0x69,0x67,0x6e,0x28,0x28,0x76,0x76,
0x29,0x2e,0x78,0x79,0x2c,0x28,0x76,0x76,0x29,0x2e,0x79,0x78,0x2c,0x33,0x32,0x2d,0x72,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x72,0x65,0x74,
0x75,0x72,0x6e,0x20,0x61,0x6d,0x64,0x5f,0x62,0x69,0x74,0x61,0x6c,0x69,0x67,0x6e,0x28,0x28,0x76,0x76,0x29,0x2e,0x79,0x78,0x2c,0x28,0x76,0x76,0x29,0x2e,0x78,0x79,
0x2c,0x36,0x34,0x2d,0x72,0x29,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x52,
0x4f,0x4c,0x32,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x76,0x2c,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6e,0x29,0x0a,0x7b,
0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x69,0x66,0x28,0x6e,0x3c,0x3d,0x33,0x32,0x29,0x0a,0x7b,0x0a,0x72,0x65,0x73,0x75,0x6c,
0x74,0x2e,0x79,0x3d,0x28,0x28,0x76,0x2e,0x79,0x3c,0x3c,0x28,0x6e,0x29,0x29,0x7c,0x28,0x76,0x2e,0x78,0x3e,0x3e,0x28,0x33,0x32,0x2d,0x6e,0x29,0x29,0x29,0x3b,0x0a,
0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x3d,0x28,0x28,0x76,0x2e,0x78,0x3c,0x3c,0x28,0x6e,0x29,0x29,0x7c,0x28,0x76,0x2e,0x79,0x3e,0x3e,0x28,0x33,0x32,0x2d,0x6e,
0x29,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x79,0x3d,0x28,0x28,0x76,0x2e,0x78,0x3c,0x3c,0x28,0x6e,
0x2d,0x33,0x32,0x29,0x29,0x7c,0x28,0x76,0x2e,0x79,0x3e,0x3e,0x28,0x36,0x34,0x2d,0x6e,0x29,0x29,0x29,0x3b,0x0a,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x3d,0x28,
0x28,0x76,0x2e,0x79,0x3c,0x3c,0x28,0x6e,0x2d,0x33,0x32,0x29,0x29,0x7c,0x28,0x76,0x2e,0x78,0x3e,0x3e,0x28,0x36,0x34,0x2d,0x6e,0x29,0x29,0x29,0x3b,0x0a,0x7d,0x0a,
0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x7d,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x76,
0x6f,0x69,0x64,0x20,0x63,0x68,0x69,0x28,0x75,0x69,0x6e,0x74,0x32,0x2a,0x20,0x61,0x2c,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6e,0x2c,0x63,0x6f,
0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x32,0x2a,0x20,0x74,0x29,0x0a,0x7b,0x0a,0x61,0x5b,0x6e,0x2b,0x30,0x5d,0x3d,0x62,0x69,0x74,0x73,0x65,0x6c,0x65,0x63,0x74,
0x28,0x74,0x5b,0x6e,0x2b,0x30,0x5d,0x5e,0x74,0x5b,0x6e,0x2b,0x32,0x5d,0x2c,0x74,0x5b,0x6e,0x2b,0x30,0x5d,0x2c,0x74,0x5b,0x6e,0x2b,0x31,0x5d,0x29,0x3b,0x0a,0x61,
0x5b,0x6e,0x2b,0x31,0x5d,0x3d,0x62,0x69,0x74,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x74,0x5b,0x6e,0x2b,0x31,0x5d,0x5e,0x74,0x5b,0x6e,0x2b,0x33,0x5d,0x2c,0x74,0x5b,
0x6e,0x2b,0x31,0x5d,0x2c,0x74,0x5b,0x6e,0x2b,0x32,0x5d,0x29,0x3b,0x0a,0x61,0x5b,0x6e,0x2b,0x32,0x5d,0x3d,0x62,0x69,0x74,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x74,
0x5b,0x6e,0x2b,0x32,0x5d,0x5e,0x74,0x5b,0x6e,0x2b,0x34,0x5d,0x2c,0x74,0x5b,0x6e,0x2b,0x32,0x5d,0x2c,0x74,0x5b,0x6e,0x2b,0x33,0x5d,0x29,0x3b,0x0a,0x61,0x5b,0x6e,
0x2b,0x33,0x5d,0x3d,0x62,0x69,0x74,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x74,0x5b,0x6e,0x2b,0x33,0x5d,0x5e,0x74,0x5b,0x6e,0x2b,0x30,0x5d,0x2c,0x74,0x5b,0x6e,0x2b,
0x33,0x5d,0x2c,0x74,0x5b,0x6e,0x2b,0x34,0x5d,0x29,0x3b,0x0a,0x61,0x5b,0x6e,0x2b,0x34,0x5d,0x3d,0x62,0x69,0x74,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x74,0x5b,0x6e,
0x2b,0x34,0x5d,0x5e,0x74,0x5b,0x6e,0x2b,0x31,0x5d,0x2c,0x74,0x5b,0x6e,0x2b,0x34,0x5d,0x2c,0x74,0x5b,0x6e,0x2b,0x30,0x5d,0x29,0x3b,0x0a,0x7d,0x0a,0x73,0x74,0x61,
0x74,0x69,0x63,0x20,0x76,0x6f,0x69,0x64,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x31,0x36,0x30,0x30,0x5f,0x72,0x6f,0x75,0x6e,0x64,0x28,0x75,0x69,0x6e,0x74,
0x32,0x2a,0x20,0x61,0x2c,0x75,0x69,0x6e,0x74,0x20,0x72,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x74,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,
0x32,0x20,0x75,0x3b,0x0a,0x74,0x5b,0x30,0x5d,0x3d,0x61,0x5b,0x30,0x5d,0x5e,0x61,0x5b,0x35,0x5d,0x5e,0x61,0x5b,0x31,0x30,0x5d,0x5e,0x61,0x5b,0x31,0x35,0x5d,0x5e,
0x61,0x5b,0x32,0x30,0x5d,0x3b,0x0a,0x74,0x5b,0x31,0x5d,0x3d,0x61,0x5b,0x31,0x5d,0x5e,0x61,0x5b,0x36,0x5d,0x5e,0x61,0x5b,0x31,0x31,0x5d,0x5e,0x61,0x5b,0x31,0x36,
0x5d,0x5e,0x61,0x5b,0x32,0x31,0x5d,0x3b,0x0a,0x74,0x5b,0x32,0x5d,0x3d,0x61,0x5b,0x32,0x5d,0x5e,0x61,0x5b,0x37,0x5d,0x5e,0x61,0x5b,0x31,0x32,0x5d,0x5e,0x61,0x5b,
0x31,0x37,0x5d,0x5e,0x61,0x5b,0x32,0x32,0x5d,0x3b,0x0a,0x74,0x5b,0x33,0x5d,0x3d,0x61,0x5b,0x33,0x5d,0x5e,0x61,0x5b,0x38,0x5d,0x5e,0x61,0x5b,0x31,0x33,0x5d,0x5e,
0x61,0x5b,0x31,0x38,0x5d,0x5e,0x61,0x5b,0x32,0x33,0x5d,0x3b,0x0a,0x74,0x5b,0x34,0x5d,0x3d,0x61,0x5b,0x34,0x5d,0x5e,0x61,0x5b,0x39,0x5d,0x5e,0x61,0x5b,0x31,0x34,
0x5d,0x5e,0x61,0x5b,0x31,0x39,0x5d,0x5e,0x61,0x5b,0x32,0x34,0x5d,0x3b,0x0a,0x75,0x3d,0x74,0x5b,0x34,0x5d,0x5e,0x52,0x4f,0x4c,0x32,0x28,0x74,0x5b,0x31,0x5d,0x2c,
0x31,0x29,0x3b,0x0a,0x61,0x5b,0x30,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x35,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x30,0x5d,0x20,
0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x35,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x32,0x30,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x75,0x3d,
0x74,0x5b,0x30,0x5d,0x5e,0x52,0x4f,0x4c,0x32,0x28,0x74,0x5b,0x32,0x5d,0x2c,0x31,0x29,0x3b,0x0a,0x61,0x5b,0x31,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,
0x36,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x31,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x36,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,
0x0a,0x61,0x5b,0x32,0x31,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x75,0x3d,0x74,0x5b,0x31,0x5d,0x5e,0x52,0x4f,0x4c,0x32,0x28,0x74,0x5b,0x33,0x5d,0x2c,0x31,0x29,
0x3b,0x0a,0x61,0x5b,0x32,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x37,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x32,0x5d,0x20,0x5e,0x3d,
0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x37,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x32,0x32,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x75,0x3d,0x74,0x5b,
0x32,0x5d,0x5e,0x52,0x4f,0x4c,0x32,0x28,0x74,0x5b,0x34,0x5d,0x2c,0x31,0x29,0x3b,0x0a,0x61,0x5b,0x33,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x38,0x5d,
0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x33,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x38,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,
0x5b,0x32,0x33,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x75,0x3d,0x74,0x5b,0x33,0x5d,0x5e,0x52,0x4f,0x4c,0x32,0x28,0x74,0x5b,0x30,0x5d,0x2c,0x31,0x29,0x3b,0x0a,
0x61,0x5b,0x34,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x39,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x34,0x5d,0x20,0x5e,0x3d,0x20,0x75,
0x3b,0x0a,0x61,0x5b,0x31,0x39,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x32,0x34,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x74,0x5b,0x30,0x5d,0x3d,0x61,
0x5b,0x30,0x5d,0x3b,0x0a,0x74,0x5b,0x31,0x30,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,0x5d,0x2c,0x31,0x29,0x3b,0x0a,0x74,0x5b,0x32,0x30,0x5d,0x3d,0x52,
0x4f,0x4c,0x32,0x28,0x61,0x5b,0x32,0x5d,0x2c,0x36,0x32,0x29,0x3b,0x0a,0x74,0x5b,0x35,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x33,0x5d,0x2c,0x32,0x38,0x29,
0x3b,0x0a,0x74,0x5b,0x31,0x35,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x34,0x5d,0x2c,0x32,0x37,0x29,0x3b,0x0a,0x74,0x5b,0x31,0x36,0x5d,0x3d,0x52,0x4f,0x4c,
0x32,0x28,0x61,0x5b,0x35,0x5d,0x2c,0x33,0x36,0x29,0x3b,0x0a,0x74,0x5b,0x31,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x36,0x5d,0x2c,0x34,0x34,0x29,0x3b,0x0a,
0x74,0x5b,0x31,0x31,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x37,0x5d,0x2c,0x36,0x29,0x3b,0x0a,0x74,0x5b,0x32,0x31,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,
0x5b,0x38,0x5d,0x2c,0x35,0x35,0x29,0x3b,0x0a,0x74,0x5b,0x36,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x39,0x5d,0x2c,0x32,0x30,0x29,0x3b,0x0a,0x74,0x5b,0x37,
0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,0x30,0x5d,0x2c,0x33,0x29,0x3b,0x0a,0x74,0x5b,0x31,0x37,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,0x31,
0x5d,0x2c,0x31,0x30,0x29,0x3b,0x0a,0x74,0x5b,0x32,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,0x32,0x5d,0x2c,0x34,0x33,0x29,0x3b,0x0a,0x74,0x5b,0x31,0x32,
0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,0x33,0x5d,0x2c,0x32,0x35,0x29,0x3b,0x0a,0x74,0x5b,0x32,0x32,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,
0x34,0x5d,0x2c,0x33,0x39,0x29,0x3b,0x0a,0x74,0x5b,0x32,0x33,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,0x35,0x5d,0x2c,0x34,0x31,0x29,0x3b,0x0a,0x74,0x5b,
0x38,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,0x36,0x5d,0x2c,0x34,0x35,0x29,0x3b,0x0a,0x74,0x5b,0x31,0x38,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,
0x31,0x37,0x5d,0x2c,0x31,0x35,0x29,0x3b,0x0a,0x74,0x5b,0x33,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,0x38,0x5d,0x2c,0x32,0x31,0x29,0x3b,0x0a,0x74,0x5b,
0x31,0x33,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,0x39,0x5d,0x2c,0x38,0x29,0x3b,0x0a,0x74,0x5b,0x31,0x34,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,
0x32,0x30,0x5d,0x2c,0x31,0x38,0x29,0x3b,0x0a,0x74,0x5b,0x32,0x34,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x32,0x31,0x5d,0x2c,0x32,0x29,0x3b,0x0a,0x74,0x5b,
0x39,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x32,0x32,0x5d,0x2c,0x36,0x31,0x29,0x3b,0x0a,0x74,0x5b,0x31,0x39,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,
0x32,0x33,0x5d,0x2c,0x35,0x36,0x29,0x3b,0x0a,0x74,0x5b,0x34,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x32,0x34,0x5d,0x2c,0x31,0x34,0x29,0x3b,0x0a,0x63,0x68,
0x69,0x28,0x61,0x2c,0x30,0x2c,0x74,0x29,0x3b,0x0a,0x61,0x5b,0x30,0x5d,0x20,0x5e,0x3d,0x20,0x4b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x31,0x36,0x30,0x30,0x5f,0x52,
0x43,0x5b,0x72,0x5d,0x3b,0x0a,0x63,0x68,0x69,0x28,0x61,0x2c,0x35,0x2c,0x74,0x29,0x3b,0x0a,0x63,0x68,0x69,0x28,0x61,0x2c,0x31,0x30,0x2c,0x74,0x29,0x3b,0x0a,0x63,
0x68,0x69,0x28,0x61,0x2c,0x31,0x35,0x2c,0x74,0x29,0x3b,0x0a,0x63,0x68,0x69,0x28,0x61,0x2c,0x32,0x30,0x2c,0x74,0x29,0x3b,0x0a,0x7d,0x0a,0x73,0x74,0x61,0x74,0x69,
0x63,0x20,0x76,0x6f,0x69,0x64,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x31,0x36,0x30,0x30,0x5f,0x6e,0x6f,0x5f,0x61,0x62,0x73,0x6f,0x72,0x62,0x28,0x75,0x69,
0x6e,0x74,0x32,0x2a,0x20,0x61,0x2c,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2c,0x75,0x69,0x6e,0x74,0x20,0x69,0x73,0x6f,0x6c,0x61,0x74,
0x65,0x29,0x0a,0x7b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x20,0x72,0x3d,0x30,0x3b,0x20,0x72,0x3c,0x32,0x34,0x3b,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,
0x69,0x73,0x6f,0x6c,0x61,0x74,0x65,0x29,0x0a,0x7b,0x0a,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x31,0x36,0x30,0x30,0x5f,0x72,0x6f,0x75,0x6e,0x64,0x28,0x61,0x2c,
0x72,0x2b,0x2b,0x29,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x7d,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x63,0x6f,0x70,0x79,0x28,0x64,0x73,0x74,0x2c,0x20,0x73,0x72,
0x63,0x2c,0x20,0x63,0x6f,0x75,0x6e,0x74,0x29,0x20,0x5c,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x21,0x3d,0x63,0x6f,
0x75,0x6e,0x74,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x20,0x5c,0x0a,0x7b,0x20,0x5c,0x0a,0x28,0x64,0x73,0x74,0x29,0x5b,0x69,0x5d,0x3d,0x28,0x73,0x72,0x63,0x29,0x5b,0x69,
0x5d,0x3b,0x20,0x5c,0x0a,0x7d,0x0a,0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x6e,0x76,0x28,0x75,0x69,0x6e,0x74,0x20,0x78,0x2c,0x75,0x69,
0x6e,0x74,0x20,0x79,0x29,0x0a,0x7b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x78,0x2a,0x46,0x4e,0x56,0x5f,0x50,0x52,0x49,0x4d,0x45,0x5e,0x79,0x3b,0x0a,0x7d,0x0a,
0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x75,0x69,0x6e,0x74,0x34,0x20,0x66,0x6e,0x76,0x34,0x28,0x75,0x69,0x6e,0x74,0x34,0x20,0x78,0x2c,0x75,0x69,0x6e,0x74,0x34,0x20,
0x79,0x29,0x0a,0x7b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x78,0x2a,0x46,0x4e,0x56,0x5f,0x50,0x52,0x49,0x4d,0x45,0x5e,0x79,0x3b,0x0a,0x7d,0x0a,0x74,0x79,0x70,
0x65,0x64,0x65,0x66,0x20,0x75,0x6e,0x69,0x6f,0x6e,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x20,0x77,0x6f,0x72,0x64,0x73,0x5b,0x36,0x34,0x2f,0x73,0x69,0x7a,0x65,0x6f,
0x66,0x28,0x75,0x69,0x6e,0x74,0x29,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x75,0x69,0x6e,0x74,0x32,0x73,0x5b,0x36,0x34,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,
0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x34,0x20,0x75,0x69,0x6e,0x74,0x34,0x73,0x5b,0x36,0x34,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,
0x28,0x75,0x69,0x6e,0x74,0x34,0x29,0x5d,0x3b,0x0a,0x7d,0x20,0x68,0x61,0x73,0x68,0x36,0x34,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,0x6e,
0x69,0x6f,0x6e,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x20,0x77,0x6f,0x72,0x64,0x73,0x5b,0x32,0x30,0x30,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,
0x29,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x75,0x69,0x6e,0x74,0x32,0x73,0x5b,0x32,0x30,0x30,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,
0x32,0x29,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x34,0x20,0x75,0x69,0x6e,0x74,0x34,0x73,0x5b,0x32,0x30,0x30,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,
0x74,0x34,0x29,0x5d,0x3b,0x0a,0x7d,0x20,0x68,0x61,0x73,0x68,0x32,0x30,0x30,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x73,0x74,0x72,0x75,0x63,
0x74,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x34,0x20,0x75,0x69,0x6e,0x74,0x34,0x73,0x5b,0x31,0x32,0x38,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,
0x34,0x29,0x5d,0x3b,0x0a,0x7d,0x20,0x68,0x61,0x73,0x68,0x31,0x32,0x38,0x5f,0x74,0x3b,0x0a,0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x76,0x6f,0x69,0x64,0x20,0x53,0x48,
0x41,0x33,0x5f,0x35,0x31,0x32,0x28,0x75,0x69,0x6e,0x74,0x32,0x2a,0x20,0x73,0x2c,0x75,0x69,0x6e,0x74,0x20,0x69,0x73,0x6f,0x6c,0x61,0x74,0x65,0x29,0x0a,0x7b,0x0a,
0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x20,0x69,0x3d,0x38,0x3b,0x20,0x69,0x21,0x3d,0x32,0x35,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x73,0x5b,0x69,
0x5d,0x3d,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x7b,0x30,0x2c,0x30,0x7d,0x3b,0x0a,0x7d,0x0a,0x73,0x5b,0x38,0x5d,0x2e,0x78,0x3d,0x30,0x78,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x31,0x3b,0x0a,0x73,0x5b,0x38,0x5d,0x2e,0x79,0x3d,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3b,0x0a,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,
0x31,0x36,0x30,0x30,0x5f,0x6e,0x6f,0x5f,0x61,0x62,0x73,0x6f,0x72,0x62,0x28,0x73,0x2c,0x38,0x2c,0x69,0x73,0x6f,0x6c,0x61,0x74,0x65,0x29,0x3b,0x0a,0x7d,0x0a,0x73,
0x74,0x61,0x74,0x69,0x63,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x61,0x73,0x74,0x5f,0x6d,0x6f,0x64,0x28,0x75,0x69,0x6e,0x74,0x20,0x61,0x2c,0x75,0x69,0x6e,0x74,0x34,
0x20,0x64,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x74,0x3d,0x61,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,
0x74,0x20,0x71,0x3d,0x28,0x28,0x74,0x2b,0x64,0x2e,0x79,0x29,0x2a,0x64,0x2e,0x78,0x29,0x3e,0x3e,0x64,0x2e,0x7a,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x61,
0x2d,0x71,0x2a,0x64,0x2e,0x77,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x65,0x74,0x68,0x61,0x73,0x68,0x5f,0x63,
0x61,0x6c,0x63,0x75,0x6c,0x61,0x74,0x65,0x5f,0x64,0x61,0x67,0x5f,0x69,0x74,0x65,0x6d,0x28,0x75,0x69,0x6e,0x74,0x20,0x73,0x74,0x61,0x72,0x74,0x2c,0x5f,0x5f,0x67,
0x6c,0x6f,0x62,0x61,0x6c,0x20,0x68,0x61,0x73,0x68,0x36,0x34,0x5f,0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,0x2a,0x20,0x67,0x5f,0x6c,0x69,0x67,0x68,0x74,0x2c,0x5f,0x5f,
0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x68,0x61,0x73,0x68,0x36,0x34,0x5f,0x74,0x2a,0x20,0x67,0x5f,0x64,0x61,0x67,0x2c,0x75,0x69,0x6e,0x74,0x20,0x69,0x73,0x6f,0x6c,
0x61,0x74,0x65,0x2c,0x75,0x69,0x6e,0x74,0x20,0x64,0x61,0x67,0x5f,0x77,0x6f,0x72,0x64,0x73,0x2c,0x75,0x69,0x6e,0x74,0x34,0x20,0x6c,0x69,0x67,0x68,0x74,0x5f,0x77,
0x6f,0x72,0x64,0x73,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x6e,0x6f,0x64,0x65,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3d,0x73,0x74,
0x61,0x72,0x74,0x2b,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x69,0x66,0x28,0x6e,0x6f,0x64,0x65,0x5f,0x69,0x6e,
0x64,0x65,0x78,0x3e,0x3d,0x64,0x61,0x67,0x5f,0x77,0x6f,0x72,0x64,0x73,0x29,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x0a,0x68,0x61,0x73,0x68,0x32,0x30,0x30,0x5f,
0x74,0x20,0x64,0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x3b,0x0a,0x63,0x6f,0x70,0x79,0x28,0x64,0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x2e,0x75,0x69,0x6e,0x74,0x34,0x73,
0x2c,0x67,0x5f,0x6c,0x69,0x67,0x68,0x74,0x5b,0x66,0x61,0x73,0x74,0x5f,0x6d,0x6f,0x64,0x28,0x6e,0x6f,0x64,0x65,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2c,0x6c,0x69,0x67,
0x68,0x74,0x5f,0x77,0x6f,0x72,0x64,0x73,0x29,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x34,0x73,0x2c,0x34,0x29,0x3b,0x0a,0x64,0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x2e,0x77,
0x6f,0x72,0x64,0x73,0x5b,0x30,0x5d,0x20,0x5e,0x3d,0x20,0x6e,0x6f,0x64,0x65,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3b,0x0a,0x53,0x48,0x41,0x33,0x5f,0x35,0x31,0x32,0x28,
0x64,0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x2e,0x75,0x69,0x6e,0x74,0x32,0x73,0x2c,0x69,0x73,0x6f,0x6c,0x61,0x74,0x65,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,
0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x21,0x3d,0x45,0x54,0x48,0x41,0x53,0x48,0x5f,0x44,0x41,0x54,0x41,0x53,0x45,0x54,0x5f,0x50,0x41,0x52,0x45,0x4e,
0x54,0x53,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x20,0x70,0x61,0x72,0x65,0x6e,0x74,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3d,0x66,0x61,0x73,
0x74,0x5f,0x6d,0x6f,0x64,0x28,0x66,0x6e,0x76,0x28,0x6e,0x6f,0x64,0x65,0x5f,0x69,0x6e,0x64,0x65,0x78,0x5e,0x69,0x2c,0x64,0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x2e,
0x77,0x6f,0x72,0x64,0x73,0x5b,0x69,0x20,0x25,0x20,0x4e,0x4f,0x44,0x45,0x5f,0x57,0x4f,0x52,0x44,0x53,0x5d,0x29,0x2c,0x6c,0x69,0x67,0x68,0x74,0x5f,0x77,0x6f,0x72,
0x64,0x73,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x20,0x77,0x3d,0x30,0x3b,0x20,0x77,0x21,0x3d,0x34,0x3b,0x20,0x2b,0x2b,0x77,0x29,0x0a,0x64,
0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x2e,0x75,0x69,0x6e,0x74,0x34,0x73,0x5b,0x77,0x5d,0x3d,0x66,0x6e,0x76,0x34,0x28,0x64,0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x2e,
0x75,0x69,0x6e,0x74,0x34,0x73,0x5b,0x77,0x5d,0x2c,0x67,0x5f,0x6c,0x69,0x67,0x68,0x74,0x5b,0x70,0x61,0x72,0x65,0x6e,0x74,0x5f,0x69,0x6e,0x64,0x65,0x78,0x5d,0x2e,
0x75,0x69,0x6e,0x74,0x34,0x73,0x5b,0x77,0x5d,0x29,0x3b,0x0a,0x7d,0x0a,0x53,0x48,0x41,0x33,0x5f,0x35,0x31,0x32,0x28,0x64,0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x2e,
0x75,0x69,0x6e,0x74,0x32,0x73,0x2c,0x69,0x73,0x6f,0x6c,0x61,0x74,0x65,0x29,0x3b,0x0a,0x63,0x6f,0x70,0x79,0x28,0x67,0x5f,0x64,0x61,0x67,0x5b,0x6e,0x6f,0x64,0x65,
0x5f,0x69,0x6e,0x64,0x65,0x78,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x34,0x73,0x2c,0x64,0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x2e,0x75,0x69,0x6e,0x74,0x34,0x73,0x2c,0x34,
0x29,0x3b,0x0a,0x7d,0x0a,0x00
0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x23,0x69,0x66,0x6e,0x64,0x65,0x66,0x20,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x0a,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x63,
0x6c,0x5f,0x61,0x6d,0x64,0x5f,0x6d,0x65,0x64,0x69,0x61,0x5f,0x6f,0x70,0x73,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,
0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x5f,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x5f,0x41,0x4d,0x44,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x23,0x64,0x65,0x66,0x69,
0x6e,0x65,0x20,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x5f,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x5f,0x55,0x4e,0x4b,0x4e,
0x4f,0x57,0x4e,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x48,0x41,0x53,0x48,0x45,0x53,
0x5f,0x50,0x45,0x52,0x5f,0x47,0x52,0x4f,0x55,0x50,0x20,0x28,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x20,0x2f,0x20,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,
0x5f,0x4c,0x41,0x4e,0x45,0x53,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x46,0x4e,0x56,0x5f,0x50,0x52,0x49,0x4d,0x45,0x20,0x30,0x78,0x31,0x30,0x30,0x30,
0x31,0x39,0x33,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x46,0x4e,0x56,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x5f,0x42,0x41,0x53,0x49,0x53,0x20,0x30,0x78,0x38,
0x31,0x31,0x63,0x39,0x64,0x63,0x35,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x45,0x54,0x48,0x41,0x53,0x48,0x5f,0x44,0x41,0x54,0x41,0x53,0x45,0x54,0x5f,0x50,
0x41,0x52,0x45,0x4e,0x54,0x53,0x20,0x35,0x31,0x32,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x4e,0x4f,0x44,0x45,0x5f,0x57,0x4f,0x52,0x44,0x53,0x20,0x28,0x36,
0x34,0x20,0x2f,0x20,0x34,0x29,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x4b,0x65,
0x63,0x63,0x61,0x6b,0x5f,0x66,0x31,0x36,0x30,0x30,0x5f,0x52,0x43,0x5b,0x32,0x34,0x5d,0x3d,0x7b,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,
0x30,0x30,0x30,0x30,0x30,0x31,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,
0x30,0x30,0x38,0x30,0x38,0x32,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,
0x30,0x30,0x38,0x30,0x38,0x61,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,
0x30,0x30,0x38,0x30,0x30,0x30,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,
0x30,0x30,0x38,0x30,0x38,0x62,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,
0x30,0x30,0x30,0x30,0x30,0x31,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,
0x30,0x30,0x38,0x30,0x38,0x31,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,
0x30,0x30,0x38,0x30,0x30,0x39,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,
0x30,0x30,0x30,0x30,0x38,0x61,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,
0x30,0x30,0x30,0x30,0x38,0x38,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,
0x30,0x30,0x38,0x30,0x30,0x39,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,
0x30,0x30,0x30,0x30,0x30,0x61,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,
0x30,0x30,0x38,0x30,0x38,0x62,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,
0x30,0x30,0x30,0x30,0x38,0x62,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,
0x30,0x30,0x38,0x30,0x38,0x39,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,
0x30,0x30,0x38,0x30,0x30,0x33,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,
0x30,0x30,0x38,0x30,0x30,0x32,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,
0x30,0x30,0x30,0x30,0x38,0x30,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,
0x30,0x30,0x38,0x30,0x30,0x61,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,
0x30,0x30,0x30,0x30,0x30,0x61,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,
0x30,0x30,0x38,0x30,0x38,0x31,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x30,0x30,
0x30,0x30,0x38,0x30,0x38,0x30,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,
0x30,0x30,0x30,0x30,0x30,0x31,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x78,0x38,0x30,
0x30,0x30,0x38,0x30,0x30,0x38,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x2c,0x0a,0x7d,0x3b,0x0a,0x23,0x69,0x66,0x20,0x50,0x4c,0x41,0x54,0x46,
0x4f,0x52,0x4d,0x20,0x3d,0x3d,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x5f,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x5f,0x4e,0x56,0x49,0x44,0x49,0x41,0x20,0x26,0x26,
0x20,0x43,0x4f,0x4d,0x50,0x55,0x54,0x45,0x20,0x3e,0x3d,0x20,0x33,0x35,0x0a,0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x52,0x4f,0x4c,0x32,
0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x61,0x2c,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,
0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x3e,0x3d,0x33,0x32,0x29,0x0a,
0x7b,0x0a,0x61,0x73,0x6d,0x28,0x22,0x73,0x68,0x66,0x2e,0x6c,0x2e,0x77,0x72,0x61,0x70,0x2e,0x62,0x33,0x32,0x20,0x25,0x30,0x2c,0x25,0x31,0x2c,0x25,0x32,0x2c,0x25,
0x33,0x3b,0x22,0x3a,0x22,0x3d,0x72,0x22,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x29,0x3a,0x22,0x72,0x22,0x28,0x61,0x2e,0x78,0x29,0x2c,0x22,0x72,0x22,0x28,
0x61,0x2e,0x79,0x29,0x2c,0x22,0x72,0x22,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0x0a,0x61,0x73,0x6d,0x28,0x22,0x73,0x68,0x66,0x2e,0x6c,0x2e,0x77,0x72,
0x61,0x70,0x2e,0x62,0x33,0x32,0x20,0x25,0x30,0x2c,0x25,0x31,0x2c,0x25,0x32,0x2c,0x25,0x33,0x3b,0x22,0x3a,0x22,0x3d,0x72,0x22,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,
0x2e,0x79,0x29,0x3a,0x22,0x72,0x22,0x28,0x61,0x2e,0x79,0x29,0x2c,0x22,0x72,0x22,0x28,0x61,0x2e,0x78,0x29,0x2c,0x22,0x72,0x22,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,
0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x61,0x73,0x6d,0x28,0x22,0x73,0x68,0x66,0x2e,0x6c,0x2e,0x77,0x72,0x61,0x70,0x2e,0x62,0x33,0x32,
0x20,0x25,0x30,0x2c,0x25,0x31,0x2c,0x25,0x32,0x2c,0x25,0x33,0x3b,0x22,0x3a,0x22,0x3d,0x72,0x22,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x29,0x3a,0x22,0x72,
0x22,0x28,0x61,0x2e,0x79,0x29,0x2c,0x22,0x72,0x22,0x28,0x61,0x2e,0x78,0x29,0x2c,0x22,0x72,0x22,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0x0a,0x61,0x73,
0x6d,0x28,0x22,0x73,0x68,0x66,0x2e,0x6c,0x2e,0x77,0x72,0x61,0x70,0x2e,0x62,0x33,0x32,0x20,0x25,0x30,0x2c,0x25,0x31,0x2c,0x25,0x32,0x2c,0x25,0x33,0x3b,0x22,0x3a,
0x22,0x3d,0x72,0x22,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x79,0x29,0x3a,0x22,0x72,0x22,0x28,0x61,0x2e,0x78,0x29,0x2c,0x22,0x72,0x22,0x28,0x61,0x2e,0x79,0x29,
0x2c,0x22,0x72,0x22,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,
0x7d,0x0a,0x23,0x65,0x6c,0x69,0x66,0x20,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x20,0x3d,0x3d,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x5f,0x50,0x4c,0x41,0x54,0x46,
0x4f,0x52,0x4d,0x5f,0x41,0x4d,0x44,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,
0x20,0x63,0x6c,0x5f,0x61,0x6d,0x64,0x5f,0x6d,0x65,0x64,0x69,0x61,0x5f,0x6f,0x70,0x73,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0x0a,0x73,0x74,0x61,0x74,0x69,
0x63,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x52,0x4f,0x4c,0x32,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x76,0x76,0x2c,0x63,0x6f,0x6e,0x73,
0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x72,0x3c,0x3d,0x33,0x32,0x29,0x0a,0x7b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x61,0x6d,
0x64,0x5f,0x62,0x69,0x74,0x61,0x6c,0x69,0x67,0x6e,0x28,0x28,0x76,0x76,0x29,0x2e,0x78,0x79,0x2c,0x28,0x76,0x76,0x29,0x2e,0x79,0x78,0x2c,0x33,0x32,0x2d,0x72,0x29,
0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x61,0x6d,0x64,0x5f,0x62,0x69,0x74,0x61,0x6c,0x69,0x67,0x6e,0x28,0x28,
0x76,0x76,0x29,0x2e,0x79,0x78,0x2c,0x28,0x76,0x76,0x29,0x2e,0x78,0x79,0x2c,0x36,0x34,0x2d,0x72,0x29,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,
0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x52,0x4f,0x4c,0x32,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x76,0x2c,
0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6e,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x69,0x66,0x28,
0x6e,0x3c,0x3d,0x33,0x32,0x29,0x0a,0x7b,0x0a,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x79,0x3d,0x28,0x28,0x76,0x2e,0x79,0x3c,0x3c,0x28,0x6e,0x29,0x29,0x7c,0x28,0x76,
0x2e,0x78,0x3e,0x3e,0x28,0x33,0x32,0x2d,0x6e,0x29,0x29,0x29,0x3b,0x0a,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x3d,0x28,0x28,0x76,0x2e,0x78,0x3c,0x3c,0x28,0x6e,
0x29,0x29,0x7c,0x28,0x76,0x2e,0x79,0x3e,0x3e,0x28,0x33,0x32,0x2d,0x6e,0x29,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x72,0x65,0x73,0x75,
0x6c,0x74,0x2e,0x79,0x3d,0x28,0x28,0x76,0x2e,0x78,0x3c,0x3c,0x28,0x6e,0x2d,0x33,0x32,0x29,0x29,0x7c,0x28,0x76,0x2e,0x79,0x3e,0x3e,0x28,0x36,0x34,0x2d,0x6e,0x29,
0x29,0x29,0x3b,0x0a,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x3d,0x28,0x28,0x76,0x2e,0x79,0x3c,0x3c,0x28,0x6e,0x2d,0x33,0x32,0x29,0x29,0x7c,0x28,0x76,0x2e,0x78,
0x3e,0x3e,0x28,0x36,0x34,0x2d,0x6e,0x29,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x7d,0x0a,0x23,
0x65,0x6e,0x64,0x69,0x66,0x0a,0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x76,0x6f,0x69,0x64,0x20,0x63,0x68,0x69,0x28,0x75,0x69,0x6e,0x74,0x32,0x2a,0x20,0x61,0x2c,0x63,
0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6e,0x2c,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x32,0x2a,0x20,0x74,0x29,0x0a,0x7b,0x0a,0x61,0x5b,
0x6e,0x2b,0x30,0x5d,0x3d,0x62,0x69,0x74,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x74,0x5b,0x6e,0x2b,0x30,0x5d,0x5e,0x74,0x5b,0x6e,0x2b,0x32,0x5d,0x2c,0x74,0x5b,0x6e,
0x2b,0x30,0x5d,0x2c,0x74,0x5b,0x6e,0x2b,0x31,0x5d,0x29,0x3b,0x0a,0x61,0x5b,0x6e,0x2b,0x31,0x5d,0x3d,0x62,0x69,0x74,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x74,0x5b,
0x6e,0x2b,0x31,0x5d,0x5e,0x74,0x5b,0x6e,0x2b,0x33,0x5d,0x2c,0x74,0x5b,0x6e,0x2b,0x31,0x5d,0x2c,0x74,0x5b,0x6e,0x2b,0x32,0x5d,0x29,0x3b,0x0a,0x61,0x5b,0x6e,0x2b,
0x32,0x5d,0x3d,0x62,0x69,0x74,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x74,0x5b,0x6e,0x2b,0x32,0x5d,0x5e,0x74,0x5b,0x6e,0x2b,0x34,0x5d,0x2c,0x74,0x5b,0x6e,0x2b,0x32,
0x5d,0x2c,0x74,0x5b,0x6e,0x2b,0x33,0x5d,0x29,0x3b,0x0a,0x61,0x5b,0x6e,0x2b,0x33,0x5d,0x3d,0x62,0x69,0x74,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x74,0x5b,0x6e,0x2b,
0x33,0x5d,0x5e,0x74,0x5b,0x6e,0x2b,0x30,0x5d,0x2c,0x74,0x5b,0x6e,0x2b,0x33,0x5d,0x2c,0x74,0x5b,0x6e,0x2b,0x34,0x5d,0x29,0x3b,0x0a,0x61,0x5b,0x6e,0x2b,0x34,0x5d,
0x3d,0x62,0x69,0x74,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x74,0x5b,0x6e,0x2b,0x34,0x5d,0x5e,0x74,0x5b,0x6e,0x2b,0x31,0x5d,0x2c,0x74,0x5b,0x6e,0x2b,0x34,0x5d,0x2c,
0x74,0x5b,0x6e,0x2b,0x30,0x5d,0x29,0x3b,0x0a,0x7d,0x0a,0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x76,0x6f,0x69,0x64,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x31,
0x36,0x30,0x30,0x5f,0x72,0x6f,0x75,0x6e,0x64,0x28,0x75,0x69,0x6e,0x74,0x32,0x2a,0x20,0x61,0x2c,0x75,0x69,0x6e,0x74,0x20,0x72,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,
0x74,0x32,0x20,0x74,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x75,0x3b,0x0a,0x74,0x5b,0x30,0x5d,0x3d,0x61,0x5b,0x30,0x5d,0x5e,0x61,0x5b,0x35,
0x5d,0x5e,0x61,0x5b,0x31,0x30,0x5d,0x5e,0x61,0x5b,0x31,0x35,0x5d,0x5e,0x61,0x5b,0x32,0x30,0x5d,0x3b,0x0a,0x74,0x5b,0x31,0x5d,0x3d,0x61,0x5b,0x31,0x5d,0x5e,0x61,
0x5b,0x36,0x5d,0x5e,0x61,0x5b,0x31,0x31,0x5d,0x5e,0x61,0x5b,0x31,0x36,0x5d,0x5e,0x61,0x5b,0x32,0x31,0x5d,0x3b,0x0a,0x74,0x5b,0x32,0x5d,0x3d,0x61,0x5b,0x32,0x5d,
0x5e,0x61,0x5b,0x37,0x5d,0x5e,0x61,0x5b,0x31,0x32,0x5d,0x5e,0x61,0x5b,0x31,0x37,0x5d,0x5e,0x61,0x5b,0x32,0x32,0x5d,0x3b,0x0a,0x74,0x5b,0x33,0x5d,0x3d,0x61,0x5b,
0x33,0x5d,0x5e,0x61,0x5b,0x38,0x5d,0x5e,0x61,0x5b,0x31,0x33,0x5d,0x5e,0x61,0x5b,0x31,0x38,0x5d,0x5e,0x61,0x5b,0x32,0x33,0x5d,0x3b,0x0a,0x74,0x5b,0x34,0x5d,0x3d,
0x61,0x5b,0x34,0x5d,0x5e,0x61,0x5b,0x39,0x5d,0x5e,0x61,0x5b,0x31,0x34,0x5d,0x5e,0x61,0x5b,0x31,0x39,0x5d,0x5e,0x61,0x5b,0x32,0x34,0x5d,0x3b,0x0a,0x75,0x3d,0x74,
0x5b,0x34,0x5d,0x5e,0x52,0x4f,0x4c,0x32,0x28,0x74,0x5b,0x31,0x5d,0x2c,0x31,0x29,0x3b,0x0a,0x61,0x5b,0x30,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x35,
0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x30,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x35,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,
0x61,0x5b,0x32,0x30,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x75,0x3d,0x74,0x5b,0x30,0x5d,0x5e,0x52,0x4f,0x4c,0x32,0x28,0x74,0x5b,0x32,0x5d,0x2c,0x31,0x29,0x3b,
0x0a,0x61,0x5b,0x31,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x36,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x31,0x5d,0x20,0x5e,0x3d,0x20,
0x75,0x3b,0x0a,0x61,0x5b,0x31,0x36,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x32,0x31,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x75,0x3d,0x74,0x5b,0x31,
0x5d,0x5e,0x52,0x4f,0x4c,0x32,0x28,0x74,0x5b,0x33,0x5d,0x2c,0x31,0x29,0x3b,0x0a,0x61,0x5b,0x32,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x37,0x5d,0x20,
0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x32,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x37,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,
0x32,0x32,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x75,0x3d,0x74,0x5b,0x32,0x5d,0x5e,0x52,0x4f,0x4c,0x32,0x28,0x74,0x5b,0x34,0x5d,0x2c,0x31,0x29,0x3b,0x0a,0x61,
0x5b,0x33,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x38,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x33,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,
0x0a,0x61,0x5b,0x31,0x38,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x32,0x33,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x75,0x3d,0x74,0x5b,0x33,0x5d,0x5e,
0x52,0x4f,0x4c,0x32,0x28,0x74,0x5b,0x30,0x5d,0x2c,0x31,0x29,0x3b,0x0a,0x61,0x5b,0x34,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x39,0x5d,0x20,0x5e,0x3d,
0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x34,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x31,0x39,0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x61,0x5b,0x32,0x34,
0x5d,0x20,0x5e,0x3d,0x20,0x75,0x3b,0x0a,0x74,0x5b,0x30,0x5d,0x3d,0x61,0x5b,0x30,0x5d,0x3b,0x0a,0x74,0x5b,0x31,0x30,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,
0x31,0x5d,0x2c,0x31,0x29,0x3b,0x0a,0x74,0x5b,0x32,0x30,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x32,0x5d,0x2c,0x36,0x32,0x29,0x3b,0x0a,0x74,0x5b,0x35,0x5d,
0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x33,0x5d,0x2c,0x32,0x38,0x29,0x3b,0x0a,0x74,0x5b,0x31,0x35,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x34,0x5d,0x2c,
0x32,0x37,0x29,0x3b,0x0a,0x74,0x5b,0x31,0x36,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x35,0x5d,0x2c,0x33,0x36,0x29,0x3b,0x0a,0x74,0x5b,0x31,0x5d,0x3d,0x52,
0x4f,0x4c,0x32,0x28,0x61,0x5b,0x36,0x5d,0x2c,0x34,0x34,0x29,0x3b,0x0a,0x74,0x5b,0x31,0x31,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x37,0x5d,0x2c,0x36,0x29,
0x3b,0x0a,0x74,0x5b,0x32,0x31,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x38,0x5d,0x2c,0x35,0x35,0x29,0x3b,0x0a,0x74,0x5b,0x36,0x5d,0x3d,0x52,0x4f,0x4c,0x32,
0x28,0x61,0x5b,0x39,0x5d,0x2c,0x32,0x30,0x29,0x3b,0x0a,0x74,0x5b,0x37,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,0x30,0x5d,0x2c,0x33,0x29,0x3b,0x0a,0x74,
0x5b,0x31,0x37,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,0x31,0x5d,0x2c,0x31,0x30,0x29,0x3b,0x0a,0x74,0x5b,0x32,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,
0x5b,0x31,0x32,0x5d,0x2c,0x34,0x33,0x29,0x3b,0x0a,0x74,0x5b,0x31,0x32,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,0x33,0x5d,0x2c,0x32,0x35,0x29,0x3b,0x0a,
0x74,0x5b,0x32,0x32,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,0x34,0x5d,0x2c,0x33,0x39,0x29,0x3b,0x0a,0x74,0x5b,0x32,0x33,0x5d,0x3d,0x52,0x4f,0x4c,0x32,
0x28,0x61,0x5b,0x31,0x35,0x5d,0x2c,0x34,0x31,0x29,0x3b,0x0a,0x74,0x5b,0x38,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,0x36,0x5d,0x2c,0x34,0x35,0x29,0x3b,
0x0a,0x74,0x5b,0x31,0x38,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,0x37,0x5d,0x2c,0x31,0x35,0x29,0x3b,0x0a,0x74,0x5b,0x33,0x5d,0x3d,0x52,0x4f,0x4c,0x32,
0x28,0x61,0x5b,0x31,0x38,0x5d,0x2c,0x32,0x31,0x29,0x3b,0x0a,0x74,0x5b,0x31,0x33,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x31,0x39,0x5d,0x2c,0x38,0x29,0x3b,
0x0a,0x74,0x5b,0x31,0x34,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x32,0x30,0x5d,0x2c,0x31,0x38,0x29,0x3b,0x0a,0x74,0x5b,0x32,0x34,0x5d,0x3d,0x52,0x4f,0x4c,
0x32,0x28,0x61,0x5b,0x32,0x31,0x5d,0x2c,0x32,0x29,0x3b,0x0a,0x74,0x5b,0x39,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x32,0x32,0x5d,0x2c,0x36,0x31,0x29,0x3b,
0x0a,0x74,0x5b,0x31,0x39,0x5d,0x3d,0x52,0x4f,0x4c,0x32,0x28,0x61,0x5b,0x32,0x33,0x5d,0x2c,0x35,0x36,0x29,0x3b,0x0a,0x74,0x5b,0x34,0x5d,0x3d,0x52,0x4f,0x4c,0x32,
0x28,0x61,0x5b,0x32,0x34,0x5d,0x2c,0x31,0x34,0x29,0x3b,0x0a,0x63,0x68,0x69,0x28,0x61,0x2c,0x30,0x2c,0x74,0x29,0x3b,0x0a,0x61,0x5b,0x30,0x5d,0x20,0x5e,0x3d,0x20,
0x4b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x31,0x36,0x30,0x30,0x5f,0x52,0x43,0x5b,0x72,0x5d,0x3b,0x0a,0x63,0x68,0x69,0x28,0x61,0x2c,0x35,0x2c,0x74,0x29,0x3b,0x0a,
0x63,0x68,0x69,0x28,0x61,0x2c,0x31,0x30,0x2c,0x74,0x29,0x3b,0x0a,0x63,0x68,0x69,0x28,0x61,0x2c,0x31,0x35,0x2c,0x74,0x29,0x3b,0x0a,0x63,0x68,0x69,0x28,0x61,0x2c,
0x32,0x30,0x2c,0x74,0x29,0x3b,0x0a,0x7d,0x0a,0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x76,0x6f,0x69,0x64,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x31,0x36,0x30,
0x30,0x5f,0x6e,0x6f,0x5f,0x61,0x62,0x73,0x6f,0x72,0x62,0x28,0x75,0x69,0x6e,0x74,0x32,0x2a,0x20,0x61,0x2c,0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x73,0x69,
0x7a,0x65,0x2c,0x75,0x69,0x6e,0x74,0x20,0x69,0x73,0x6f,0x6c,0x61,0x74,0x65,0x29,0x0a,0x7b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x20,0x72,0x3d,0x30,
0x3b,0x20,0x72,0x3c,0x32,0x34,0x3b,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x69,0x73,0x6f,0x6c,0x61,0x74,0x65,0x29,0x0a,0x7b,0x0a,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,
0x66,0x31,0x36,0x30,0x30,0x5f,0x72,0x6f,0x75,0x6e,0x64,0x28,0x61,0x2c,0x72,0x2b,0x2b,0x29,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x7d,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,
0x65,0x20,0x63,0x6f,0x70,0x79,0x28,0x64,0x73,0x74,0x2c,0x20,0x73,0x72,0x63,0x2c,0x20,0x63,0x6f,0x75,0x6e,0x74,0x29,0x20,0x5c,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,
0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x21,0x3d,0x63,0x6f,0x75,0x6e,0x74,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x20,0x5c,0x0a,0x7b,0x20,0x5c,0x0a,0x28,0x64,
0x73,0x74,0x29,0x5b,0x69,0x5d,0x3d,0x28,0x73,0x72,0x63,0x29,0x5b,0x69,0x5d,0x3b,0x20,0x5c,0x0a,0x7d,0x0a,0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x75,0x69,0x6e,0x74,
0x20,0x66,0x6e,0x76,0x28,0x75,0x69,0x6e,0x74,0x20,0x78,0x2c,0x75,0x69,0x6e,0x74,0x20,0x79,0x29,0x0a,0x7b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x78,0x2a,0x46,
0x4e,0x56,0x5f,0x50,0x52,0x49,0x4d,0x45,0x5e,0x79,0x3b,0x0a,0x7d,0x0a,0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x75,0x69,0x6e,0x74,0x34,0x20,0x66,0x6e,0x76,0x34,0x28,
0x75,0x69,0x6e,0x74,0x34,0x20,0x78,0x2c,0x75,0x69,0x6e,0x74,0x34,0x20,0x79,0x29,0x0a,0x7b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x78,0x2a,0x46,0x4e,0x56,0x5f,
0x50,0x52,0x49,0x4d,0x45,0x5e,0x79,0x3b,0x0a,0x7d,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,0x6e,0x69,0x6f,0x6e,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x20,
0x77,0x6f,0x72,0x64,0x73,0x5b,0x36,0x34,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x29,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x75,0x69,
0x6e,0x74,0x32,0x73,0x5b,0x36,0x34,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x34,0x20,0x75,0x69,
0x6e,0x74,0x34,0x73,0x5b,0x36,0x34,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x34,0x29,0x5d,0x3b,0x0a,0x7d,0x20,0x68,0x61,0x73,0x68,0x36,0x34,
0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,0x6e,0x69,0x6f,0x6e,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x20,0x77,0x6f,0x72,0x64,0x73,0x5b,0x32,
0x30,0x30,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x29,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x75,0x69,0x6e,0x74,0x32,0x73,0x5b,0x32,
0x30,0x30,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x34,0x20,0x75,0x69,0x6e,0x74,0x34,0x73,0x5b,
0x32,0x30,0x30,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x34,0x29,0x5d,0x3b,0x0a,0x7d,0x20,0x68,0x61,0x73,0x68,0x32,0x30,0x30,0x5f,0x74,0x3b,
0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x73,0x74,0x72,0x75,0x63,0x74,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x34,0x20,0x75,0x69,0x6e,0x74,0x34,0x73,0x5b,0x31,
0x32,0x38,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x34,0x29,0x5d,0x3b,0x0a,0x7d,0x20,0x68,0x61,0x73,0x68,0x31,0x32,0x38,0x5f,0x74,0x3b,0x0a,
0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x76,0x6f,0x69,0x64,0x20,0x53,0x48,0x41,0x33,0x5f,0x35,0x31,0x32,0x28,0x75,0x69,0x6e,0x74,0x32,0x2a,0x20,0x73,0x2c,0x75,0x69,
0x6e,0x74,0x20,0x69,0x73,0x6f,0x6c,0x61,0x74,0x65,0x29,0x0a,0x7b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x20,0x69,0x3d,0x38,0x3b,0x20,0x69,0x21,0x3d,
0x32,0x35,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x73,0x5b,0x69,0x5d,0x3d,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x7b,0x30,0x2c,0x30,0x7d,0x3b,0x0a,0x7d,0x0a,
0x73,0x5b,0x38,0x5d,0x2e,0x78,0x3d,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x3b,0x0a,0x73,0x5b,0x38,0x5d,0x2e,0x79,0x3d,0x30,0x78,0x38,0x30,0x30,0x30,
0x30,0x30,0x30,0x30,0x3b,0x0a,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x31,0x36,0x30,0x30,0x5f,0x6e,0x6f,0x5f,0x61,0x62,0x73,0x6f,0x72,0x62,0x28,0x73,0x2c,0x38,
0x2c,0x69,0x73,0x6f,0x6c,0x61,0x74,0x65,0x29,0x3b,0x0a,0x7d,0x0a,0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x75,0x69,0x6e,0x74,0x20,0x66,0x61,0x73,0x74,0x5f,0x6d,0x6f,
0x64,0x28,0x75,0x69,0x6e,0x74,0x20,0x61,0x2c,0x75,0x69,0x6e,0x74,0x34,0x20,0x64,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x20,
0x74,0x3d,0x61,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x71,0x3d,0x28,0x28,0x74,0x2b,0x64,0x2e,0x79,0x29,0x2a,0x64,0x2e,0x78,0x29,0x3e,
0x3e,0x64,0x2e,0x7a,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x61,0x2d,0x71,0x2a,0x64,0x2e,0x77,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,
0x20,0x76,0x6f,0x69,0x64,0x20,0x65,0x74,0x68,0x61,0x73,0x68,0x5f,0x63,0x61,0x6c,0x63,0x75,0x6c,0x61,0x74,0x65,0x5f,0x64,0x61,0x67,0x5f,0x69,0x74,0x65,0x6d,0x28,
0x75,0x69,0x6e,0x74,0x20,0x73,0x74,0x61,0x72,0x74,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x68,0x61,0x73,0x68,0x36,0x34,0x5f,0x74,0x20,0x63,0x6f,0x6e,
0x73,0x74,0x2a,0x20,0x67,0x5f,0x6c,0x69,0x67,0x68,0x74,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x68,0x61,0x73,0x68,0x36,0x34,0x5f,0x74,0x2a,0x20,0x67,
0x5f,0x64,0x61,0x67,0x2c,0x75,0x69,0x6e,0x74,0x20,0x69,0x73,0x6f,0x6c,0x61,0x74,0x65,0x2c,0x75,0x69,0x6e,0x74,0x20,0x64,0x61,0x67,0x5f,0x77,0x6f,0x72,0x64,0x73,
0x2c,0x75,0x69,0x6e,0x74,0x34,0x20,0x6c,0x69,0x67,0x68,0x74,0x5f,0x77,0x6f,0x72,0x64,0x73,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,
0x20,0x6e,0x6f,0x64,0x65,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3d,0x73,0x74,0x61,0x72,0x74,0x2b,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,
0x30,0x29,0x3b,0x0a,0x69,0x66,0x28,0x6e,0x6f,0x64,0x65,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3e,0x3d,0x64,0x61,0x67,0x5f,0x77,0x6f,0x72,0x64,0x73,0x29,0x0a,0x72,0x65,
0x74,0x75,0x72,0x6e,0x3b,0x0a,0x68,0x61,0x73,0x68,0x32,0x30,0x30,0x5f,0x74,0x20,0x64,0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x3b,0x0a,0x63,0x6f,0x70,0x79,0x28,0x64,
0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x2e,0x75,0x69,0x6e,0x74,0x34,0x73,0x2c,0x67,0x5f,0x6c,0x69,0x67,0x68,0x74,0x5b,0x66,0x61,0x73,0x74,0x5f,0x6d,0x6f,0x64,0x28,
0x6e,0x6f,0x64,0x65,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2c,0x6c,0x69,0x67,0x68,0x74,0x5f,0x77,0x6f,0x72,0x64,0x73,0x29,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x34,0x73,0x2c,
0x34,0x29,0x3b,0x0a,0x64,0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x2e,0x77,0x6f,0x72,0x64,0x73,0x5b,0x30,0x5d,0x20,0x5e,0x3d,0x20,0x6e,0x6f,0x64,0x65,0x5f,0x69,0x6e,
0x64,0x65,0x78,0x3b,0x0a,0x53,0x48,0x41,0x33,0x5f,0x35,0x31,0x32,0x28,0x64,0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x2e,0x75,0x69,0x6e,0x74,0x32,0x73,0x2c,0x69,0x73,
0x6f,0x6c,0x61,0x74,0x65,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x21,0x3d,0x45,0x54,0x48,0x41,0x53,0x48,
0x5f,0x44,0x41,0x54,0x41,0x53,0x45,0x54,0x5f,0x50,0x41,0x52,0x45,0x4e,0x54,0x53,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x20,0x70,0x61,
0x72,0x65,0x6e,0x74,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3d,0x66,0x61,0x73,0x74,0x5f,0x6d,0x6f,0x64,0x28,0x66,0x6e,0x76,0x28,0x6e,0x6f,0x64,0x65,0x5f,0x69,0x6e,0x64,
0x65,0x78,0x5e,0x69,0x2c,0x64,0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x2e,0x77,0x6f,0x72,0x64,0x73,0x5b,0x69,0x20,0x25,0x20,0x4e,0x4f,0x44,0x45,0x5f,0x57,0x4f,0x52,
0x44,0x53,0x5d,0x29,0x2c,0x6c,0x69,0x67,0x68,0x74,0x5f,0x77,0x6f,0x72,0x64,0x73,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x20,0x77,0x3d,0x30,
0x3b,0x20,0x77,0x21,0x3d,0x34,0x3b,0x20,0x2b,0x2b,0x77,0x29,0x0a,0x64,0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x2e,0x75,0x69,0x6e,0x74,0x34,0x73,0x5b,0x77,0x5d,0x3d,
0x66,0x6e,0x76,0x34,0x28,0x64,0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x2e,0x75,0x69,0x6e,0x74,0x34,0x73,0x5b,0x77,0x5d,0x2c,0x67,0x5f,0x6c,0x69,0x67,0x68,0x74,0x5b,
0x70,0x61,0x72,0x65,0x6e,0x74,0x5f,0x69,0x6e,0x64,0x65,0x78,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x34,0x73,0x5b,0x77,0x5d,0x29,0x3b,0x0a,0x7d,0x0a,0x53,0x48,0x41,0x33,
0x5f,0x35,0x31,0x32,0x28,0x64,0x61,0x67,0x5f,0x6e,0x6f,0x64,0x65,0x2e,0x75,0x69,0x6e,0x74,0x32,0x73,0x2c,0x69,0x73,0x6f,0x6c,0x61,0x74,0x65,0x29,0x3b,0x0a,0x63,
0x6f,0x70,0x79,0x28,0x67,0x5f,0x64,0x61,0x67,0x5b,0x6e,0x6f,0x64,0x65,0x5f,0x69,0x6e,0x64,0x65,0x78,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x34,0x73,0x2c,0x64,0x61,0x67,
0x5f,0x6e,0x6f,0x64,0x65,0x2e,0x75,0x69,0x6e,0x74,0x34,0x73,0x2c,0x34,0x29,0x3b,0x0a,0x7d,0x0a,0x00
};
} // namespace xmrig

View file

@ -117,6 +117,7 @@ static AlgoName const algorithm_names[] = {
{ "chukwa", nullptr, Algorithm::AR2_CHUKWA },
{ "argon2/chukwav2", nullptr, Algorithm::AR2_CHUKWA_V2 },
{ "chukwav2", nullptr, Algorithm::AR2_CHUKWA_V2 },
{ "argon2/ninja", nullptr, Algorithm::AR2_WRKZ },
{ "argon2/wrkz", nullptr, Algorithm::AR2_WRKZ },
# endif
# ifdef XMRIG_ALGO_ASTROBWT

View file

@ -57,6 +57,12 @@ public:
Pools();
# ifdef XMRIG_FEATURE_BENCHMARK
inline bool isBenchmark() const { return !!m_benchmark; }
# else
inline constexpr bool isBenchmark() const { return false; }
# endif
inline const std::vector<Pool> &data() const { return m_data; }
inline int retries() const { return m_retries; }
inline int retryPause() const { return m_retryPause; }

View file

@ -225,11 +225,15 @@ bool xmrig::Config::read(const IJsonReader &reader, const char *fileName)
# endif
# ifdef XMRIG_FEATURE_OPENCL
if (!pools().isBenchmark()) {
d_ptr->cl.read(reader.getValue(kOcl));
}
# endif
# ifdef XMRIG_FEATURE_CUDA
if (!pools().isBenchmark()) {
d_ptr->cuda.read(reader.getValue(kCuda));
}
# endif
# if defined(XMRIG_FEATURE_NVML) || defined (XMRIG_FEATURE_ADL)

View file

@ -79,9 +79,9 @@ static inline const std::string &usage()
u += " --no-cpu disable CPU mining backend\n";
u += " -t, --threads=N number of CPU threads, proper CPU affinity required for some optimizations.\n";
u += " --cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1\n";
u += " --cpu-affinity=N set process affinity to CPU core(s), mask 0x3 for cores 0 and 1\n";
u += " -v, --av=N algorithm variation, 0 auto select\n";
u += " --cpu-priority set process priority (0 idle, 2 normal to 5 highest)\n";
u += " --cpu-priority=N set process priority (0 idle, 2 normal to 5 highest)\n";
u += " --cpu-max-threads-hint=N maximum CPU threads count (in percentage) hint for autoconfig\n";
u += " --cpu-memory-pool=N number of 2 MB pages for persistent memory pool, -1 (auto), 0 (disable)\n";
u += " --cpu-no-yield prefer maximum hashrate rather than system response/stability\n";

View file

@ -278,6 +278,7 @@ typedef int64x2_t __m128i; /* 128-bit vector containing integers */
#define vreinterpretq_s64_m128d(x) vreinterpretq_s64_f64(x)
#define vreinterpretq_u32_m128d(x) vreinterpretq_u32_f64(x)
#define vreinterpretq_u64_m128d(x) vreinterpretq_u64_f64(x)
#define vreinterpretq_f64_m128d(x) (x)
@ -343,9 +344,9 @@ typedef union ALIGN_STRUCT(16) SIMDVec {
// Older gcc does not define vld1q_u8_x4 type
#if defined(__GNUC__) && !defined(__clang__) && \
((__GNUC__ == 10 && (__GNUC_MINOR__ <= 2)) || \
(__GNUC__ == 9 && (__GNUC_MINOR__ <= 3)) || \
(__GNUC__ == 8 && (__GNUC_MINOR__ <= 4)) || __GNUC__ <= 7)
((__GNUC__ <= 10 && defined(__arm__)) || \
(__GNUC__ == 10 && __GNUC_MINOR__ < 3 && defined(__aarch64__)) || \
(__GNUC__ <= 9 && defined(__aarch64__)))
FORCE_INLINE uint8x16x4_t _sse2neon_vld1q_u8_x4(const uint8_t *p)
{
uint8x16x4_t ret;
@ -955,13 +956,34 @@ FORCE_INLINE void _mm_store_si128(__m128i *p, __m128i a)
vst1q_s32((int32_t *) p, vreinterpretq_s32_m128i(a));
}
// Stores four 32-bit integer values as (as a __m128i value) at the address p.
// https://msdn.microsoft.com/en-us/library/vstudio/edk11s13(v=vs.100).aspx
// Stores 128-bits of integer data a at the address p.
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeu_si128
FORCE_INLINE void _mm_storeu_si128(__m128i *p, __m128i a)
{
vst1q_s32((int32_t *) p, vreinterpretq_s32_m128i(a));
}
// Stores 64-bits of integer data a at the address p.
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeu_si64
FORCE_INLINE void _mm_storeu_si64(void *p, __m128i a)
{
vst1q_lane_s64((int64_t *) p, vreinterpretq_s64_m128i(a), 0);
}
// Stores 32-bits of integer data a at the address p.
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeu_si32
FORCE_INLINE void _mm_storeu_si32(void *p, __m128i a)
{
vst1q_lane_s32((int32_t *) p, vreinterpretq_s32_m128i(a), 0);
}
// Stores 16-bits of integer data a at the address p.
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeu_si16
FORCE_INLINE void _mm_storeu_si16(void *p, __m128i a)
{
vst1q_lane_s16((int16_t *) p, vreinterpretq_s16_m128i(a), 0);
}
// Stores the lower single - precision, floating - point value.
// https://msdn.microsoft.com/en-us/library/tzz10fbx(v=vs.100).aspx
FORCE_INLINE void _mm_store_ss(float *p, __m128 a)
@ -2319,20 +2341,34 @@ FORCE_INLINE __m128i _mm_shuffle_epi8(__m128i a, __m128i b)
// __constrange(0,255) int imm)
#define _mm_blend_epi16(a, b, imm) \
__extension__({ \
const uint16_t _mask[8] = {((imm) & (1 << 0)) ? 0xFFFF : 0x0000, \
((imm) & (1 << 1)) ? 0xFFFF : 0x0000, \
((imm) & (1 << 2)) ? 0xFFFF : 0x0000, \
((imm) & (1 << 3)) ? 0xFFFF : 0x0000, \
((imm) & (1 << 4)) ? 0xFFFF : 0x0000, \
((imm) & (1 << 5)) ? 0xFFFF : 0x0000, \
((imm) & (1 << 6)) ? 0xFFFF : 0x0000, \
((imm) & (1 << 7)) ? 0xFFFF : 0x0000}; \
const uint16_t _mask[8] = {((imm) & (1 << 0)) ? (uint16_t) -1 : 0x0, \
((imm) & (1 << 1)) ? (uint16_t) -1 : 0x0, \
((imm) & (1 << 2)) ? (uint16_t) -1 : 0x0, \
((imm) & (1 << 3)) ? (uint16_t) -1 : 0x0, \
((imm) & (1 << 4)) ? (uint16_t) -1 : 0x0, \
((imm) & (1 << 5)) ? (uint16_t) -1 : 0x0, \
((imm) & (1 << 6)) ? (uint16_t) -1 : 0x0, \
((imm) & (1 << 7)) ? (uint16_t) -1 : 0x0}; \
uint16x8_t _mask_vec = vld1q_u16(_mask); \
uint16x8_t _a = vreinterpretq_u16_m128i(a); \
uint16x8_t _b = vreinterpretq_u16_m128i(b); \
vreinterpretq_m128i_u16(vbslq_u16(_mask_vec, _b, _a)); \
})
// Blend packed double-precision (64-bit) floating-point elements from a and b
// using control mask imm8, and store the results in dst.
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_blend_pd
#define _mm_blend_pd(a, b, imm) \
__extension__({ \
const uint64_t _mask[2] = { \
((imm) & (1 << 0)) ? ~UINT64_C(0) : UINT64_C(0), \
((imm) & (1 << 1)) ? ~UINT64_C(0) : UINT64_C(0)}; \
uint64x2_t _mask_vec = vld1q_u64(_mask); \
uint64x2_t _a = vreinterpretq_u64_m128d(a); \
uint64x2_t _b = vreinterpretq_u64_m128d(b); \
vreinterpretq_m128d_u64(vbslq_u64(_mask_vec, _b, _a)); \
})
// Blend packed 8-bit integers from a and b using mask, and store the results in
// dst.
//
@ -2434,8 +2470,7 @@ FORCE_INLINE __m128i _mm_slli_epi64(__m128i a, int imm)
__m128i ret; \
if (unlikely(imm) == 0) { \
ret = a; \
} \
if (likely(0 < (imm) && (imm) < 16)) { \
} else if (likely(0 < (imm) && (imm) < 16)) { \
ret = vreinterpretq_m128i_u16( \
vshlq_u16(vreinterpretq_u16_m128i(a), vdupq_n_s16(-imm))); \
} else { \
@ -2463,8 +2498,7 @@ FORCE_INLINE __m128i _mm_slli_epi64(__m128i a, int imm)
__m128i ret; \
if (unlikely((imm) == 0)) { \
ret = a; \
} \
if (likely(0 < (imm) && (imm) < 32)) { \
} else if (likely(0 < (imm) && (imm) < 32)) { \
ret = vreinterpretq_m128i_u32( \
vshlq_u32(vreinterpretq_u32_m128i(a), vdupq_n_s32(-imm))); \
} else { \
@ -2491,8 +2525,7 @@ FORCE_INLINE __m128i _mm_slli_epi64(__m128i a, int imm)
__m128i ret; \
if (unlikely((imm) == 0)) { \
ret = a; \
} \
if (likely(0 < (imm) && (imm) < 64)) { \
} else if (likely(0 < (imm) && (imm) < 64)) { \
ret = vreinterpretq_m128i_u64( \
vshlq_u64(vreinterpretq_u64_m128i(a), vdupq_n_s64(-imm))); \
} else { \
@ -2520,8 +2553,7 @@ FORCE_INLINE __m128i _mm_slli_epi64(__m128i a, int imm)
__m128i ret; \
if (unlikely((imm) == 0)) { \
ret = a; \
} \
if (likely(0 < (imm) && (imm) < 32)) { \
} else if (likely(0 < (imm) && (imm) < 32)) { \
ret = vreinterpretq_m128i_s32( \
vshlq_s32(vreinterpretq_s32_m128i(a), vdupq_n_s32(-imm))); \
} else { \
@ -2575,6 +2607,33 @@ FORCE_INLINE __m128i _mm_slli_epi64(__m128i a, int imm)
ret; \
})
// Compute the square root of packed double-precision (64-bit) floating-point
// elements in a, and store the results in dst.
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sqrt_pd
FORCE_INLINE __m128d _mm_sqrt_pd(__m128d a)
{
#if defined(__aarch64__)
return vreinterpretq_m128d_f64(vsqrtq_f64(vreinterpretq_f64_m128d(a)));
#else
double a0 = sqrt(((double *) &a)[0]);
double a1 = sqrt(((double *) &a)[1]);
return _mm_set_pd(a1, a0);
#endif
}
// Compute the square root of the lower double-precision (64-bit) floating-point
// element in b, store the result in the lower element of dst, and copy the
// upper element from a to the upper element of dst.
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sqrt_sd
FORCE_INLINE __m128d _mm_sqrt_sd(__m128d a, __m128d b)
{
#if defined(__aarch64__)
return _mm_move_sd(a, _mm_sqrt_pd(b));
#else
return _mm_set_pd(((double *) &a)[1], sqrt(((double *) &b)[0]));
#endif
}
// Shifts the 8 signed or unsigned 16-bit integers in a left by count bits while
// shifting in zeros.
//
@ -2769,6 +2828,16 @@ FORCE_INLINE int _mm_movemask_epi8(__m128i a)
return vgetq_lane_u8(paired64, 0) | ((int) vgetq_lane_u8(paired64, 8) << 8);
}
// Set each bit of mask dst based on the most significant bit of the
// corresponding packed double-precision (64-bit) floating-point element in a.
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_movemask_pd
FORCE_INLINE int _mm_movemask_pd(__m128d a)
{
uint64x2_t input = vreinterpretq_u64_m128d(a);
uint64x2_t high_bits = vshrq_n_u64(input, 63);
return vgetq_lane_u64(high_bits, 0) | (vgetq_lane_u64(high_bits, 1) << 1);
}
// Copy the lower 64-bit integer in a to dst.
//
// dst[63:0] := a[63:0]
@ -2944,6 +3013,13 @@ FORCE_INLINE __m128i _mm_subs_epu8(__m128i a, __m128i b)
vqsubq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b)));
}
#define _mm_ucomieq_sd _mm_comieq_sd
#define _mm_ucomige_sd _mm_comige_sd
#define _mm_ucomigt_sd _mm_comigt_sd
#define _mm_ucomile_sd _mm_comile_sd
#define _mm_ucomilt_sd _mm_comilt_sd
#define _mm_ucomineq_sd _mm_comineq_sd
// Subtracts the 16 signed 8-bit integers of b from the 16 signed 8-bit integers
// of a and saturates.
//
@ -3805,6 +3881,32 @@ FORCE_INLINE __m128 _mm_fmadd_ps(__m128 a, __m128 b, __m128 c)
#endif
}
// Alternatively add and subtract packed double-precision (64-bit)
// floating-point elements in a to/from packed elements in b, and store the
// results in dst.
//
// FOR j := 0 to 1
// i := j*64
// IF ((j & 1) == 0)
// dst[i+63:i] := a[i+63:i] - b[i+63:i]
// ELSE
// dst[i+63:i] := a[i+63:i] + b[i+63:i]
// FI
// ENDFOR
//
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_addsub_pd
FORCE_INLINE __m128d _mm_addsub_pd(__m128d a, __m128d b)
{
__m128d mask = _mm_set_pd(1.0f, -1.0f);
#if defined(__aarch64__)
return vreinterpretq_m128d_f64(vfmaq_f64(vreinterpretq_f64_m128d(a),
vreinterpretq_f64_m128d(b),
vreinterpretq_f64_m128d(mask)));
#else
return _mm_add_pd(_mm_mul_pd(b, mask), a);
#endif
}
// Alternatively add and subtract packed single-precision (32-bit)
// floating-point elements in a to/from packed elements in b, and store the
// results in dst.
@ -4032,6 +4134,7 @@ FORCE_INLINE __m128 _mm_sqrt_ss(__m128 in)
// Computes the approximations of the reciprocal square roots of the four
// single-precision floating point values of in.
// The current precision is 1% error.
// https://msdn.microsoft.com/en-us/library/22hfsh53(v=vs.100).aspx
FORCE_INLINE __m128 _mm_rsqrt_ps(__m128 in)
{
@ -4240,6 +4343,22 @@ FORCE_INLINE __m128d _mm_max_pd(__m128d a, __m128d b)
#endif
}
// Compare the lower double-precision (64-bit) floating-point elements in a and
// b, store the maximum value in the lower element of dst, and copy the upper
// element from a to the upper element of dst.
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_sd
FORCE_INLINE __m128d _mm_max_sd(__m128d a, __m128d b)
{
#if defined(__aarch64__)
return _mm_move_sd(a, _mm_max_pd(a, b));
#else
double *da = (double *) &a;
double *db = (double *) &b;
double c[2] = {fmax(da[0], db[0]), da[1]};
return vld1q_f32((float32_t *) c);
#endif
}
// Computes the pairwise minima of the 16 unsigned 8-bit integers from a and the
// 16 unsigned 8-bit integers from b.
// https://msdn.microsoft.com/ko-kr/library/17k8cf58(v=vs.100).aspxx
@ -4249,6 +4368,42 @@ FORCE_INLINE __m128i _mm_min_epu8(__m128i a, __m128i b)
vminq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b)));
}
// Compare packed double-precision (64-bit) floating-point elements in a and b,
// and store packed minimum values in dst.
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_pd
FORCE_INLINE __m128d _mm_min_pd(__m128d a, __m128d b)
{
#if defined(__aarch64__)
return vreinterpretq_m128d_f64(
vminq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)));
#else
uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a));
uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a));
uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b));
uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b));
uint64_t d[2];
d[0] = (*(double *) &a0) < (*(double *) &b0) ? a0 : b0;
d[1] = (*(double *) &a1) < (*(double *) &b1) ? a1 : b1;
return vreinterpretq_m128d_u64(vld1q_u64(d));
#endif
}
// Compare the lower double-precision (64-bit) floating-point elements in a and
// b, store the minimum value in the lower element of dst, and copy the upper
// element from a to the upper element of dst.
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_sd
FORCE_INLINE __m128d _mm_min_sd(__m128d a, __m128d b)
{
#if defined(__aarch64__)
return _mm_move_sd(a, _mm_min_pd(a, b));
#else
double *da = (double *) &a;
double *db = (double *) &b;
double c[2] = {fmin(da[0], db[0]), da[1]};
return vld1q_f32((float32_t *) c);
#endif
}
// Computes the pairwise minima of the 8 signed 16-bit integers from a and the 8
// signed 16-bit integers from b.
// https://msdn.microsoft.com/en-us/library/vstudio/6te997ew(v=vs.100).aspx
@ -4448,6 +4603,23 @@ FORCE_INLINE __m128i _mm_hadd_epi16(__m128i _a, __m128i _b)
#endif
}
// Horizontally subtract adjacent pairs of double-precision (64-bit)
// floating-point elements in a and b, and pack the results in dst.
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hsub_pd
FORCE_INLINE __m128d _mm_hsub_pd(__m128d _a, __m128d _b)
{
#if defined(__aarch64__)
return vreinterpretq_m128d_f64(vsubq_f64(
vuzp1q_f64(vreinterpretq_f64_m128d(_a), vreinterpretq_f64_m128d(_b)),
vuzp2q_f64(vreinterpretq_f64_m128d(_a), vreinterpretq_f64_m128d(_b))));
#else
double *da = (double *) &_a;
double *db = (double *) &_b;
double c[] = {da[0] - da[1], db[0] - db[1]};
return vreinterpretq_m128d_u64(vld1q_u64((uint64_t *) c));
#endif
}
// Horizontally substract adjacent pairs of single-precision (32-bit)
// floating-point elements in a and b, and pack the results in dst.
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hsub_ps
@ -4808,6 +4980,57 @@ FORCE_INLINE __m128d _mm_cmpeq_pd(__m128d a, __m128d b)
#endif
}
// Compare the lower double-precision (64-bit) floating-point elements in a and
// b for equality, store the result in the lower element of dst, and copy the
// upper element from a to the upper element of dst.
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpeq_sd
FORCE_INLINE __m128d _mm_cmpeq_sd(__m128d a, __m128d b)
{
return _mm_move_sd(a, _mm_cmpeq_pd(a, b));
}
// Compare packed double-precision (64-bit) floating-point elements in a and b
// for greater-than-or-equal, and store the results in dst.
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpge_pd
FORCE_INLINE __m128d _mm_cmpge_pd(__m128d a, __m128d b)
{
#if defined(__aarch64__)
return vreinterpretq_m128d_u64(
vcgeq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)));
#else
uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a));
uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a));
uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b));
uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b));
uint64_t d[2];
d[0] = (*(double *) &a0) >= (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0);
d[1] = (*(double *) &a1) >= (*(double *) &b1) ? ~UINT64_C(0) : UINT64_C(0);
return vreinterpretq_m128d_u64(vld1q_u64(d));
#endif
}
// Compare the lower double-precision (64-bit) floating-point elements in a and
// b for greater-than-or-equal, store the result in the lower element of dst,
// and copy the upper element from a to the upper element of dst.
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpge_sd
FORCE_INLINE __m128d _mm_cmpge_sd(__m128d a, __m128d b)
{
#if defined(__aarch64__)
return _mm_move_sd(a, _mm_cmpge_pd(a, b));
#else
// expand "_mm_cmpge_pd()" to reduce unnecessary operations
uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a));
uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a));
uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b));
uint64_t d[2];
d[0] = (*(double *) &a0) >= (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0);
d[1] = a1;
return vreinterpretq_m128d_u64(vld1q_u64(d));
#endif
}
// Compares the 8 signed or unsigned 16-bit integers in a and the 8 signed or
// unsigned 16-bit integers in b for equality.
// https://msdn.microsoft.com/en-us/library/2ay060te(v=vs.100).aspx
@ -4872,6 +5095,95 @@ FORCE_INLINE __m128d _mm_cmplt_pd(__m128d a, __m128d b)
#endif
}
// Compare the lower double-precision (64-bit) floating-point elements in a and
// b for less-than, store the result in the lower element of dst, and copy the
// upper element from a to the upper element of dst.
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmplt_sd
FORCE_INLINE __m128d _mm_cmplt_sd(__m128d a, __m128d b)
{
#if defined(__aarch64__)
return _mm_move_sd(a, _mm_cmplt_pd(a, b));
#else
uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a));
uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a));
uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b));
uint64_t d[2];
d[0] = (*(double *) &a0) < (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0);
d[1] = a1;
return vreinterpretq_m128d_u64(vld1q_u64(d));
#endif
}
// Compare packed double-precision (64-bit) floating-point elements in a and b
// for not-equal, and store the results in dst.
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpneq_pd
FORCE_INLINE __m128d _mm_cmpneq_pd(__m128d a, __m128d b)
{
#if defined(__aarch64__)
return vreinterpretq_m128d_s32(vmvnq_s32(vreinterpretq_s32_u64(
vceqq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)))));
#else
// (a == b) -> (a_lo == b_lo) && (a_hi == b_hi)
uint32x4_t cmp =
vceqq_u32(vreinterpretq_u32_m128d(a), vreinterpretq_u32_m128d(b));
uint32x4_t swapped = vrev64q_u32(cmp);
return vreinterpretq_m128d_u32(vmvnq_u32(vandq_u32(cmp, swapped)));
#endif
}
// Compare the lower double-precision (64-bit) floating-point elements in a and
// b for not-equal, store the result in the lower element of dst, and copy the
// upper element from a to the upper element of dst.
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpneq_sd
FORCE_INLINE __m128d _mm_cmpneq_sd(__m128d a, __m128d b)
{
return _mm_move_sd(a, _mm_cmpneq_pd(a, b));
}
// Compare packed double-precision (64-bit) floating-point elements in a and b
// for not-greater-than-or-equal, and store the results in dst.
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpnge_pd
FORCE_INLINE __m128d _mm_cmpnge_pd(__m128d a, __m128d b)
{
return _mm_cmplt_pd(a, b);
}
// Compare the lower double-precision (64-bit) floating-point elements in a and
// b for not-greater-than-or-equal, store the result in the lower element of
// dst, and copy the upper element from a to the upper element of dst.
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpnge_sd
FORCE_INLINE __m128d _mm_cmpnge_sd(__m128d a, __m128d b)
{
return _mm_cmplt_sd(a, b);
}
// Compare packed double-precision (64-bit) floating-point elements in a and b
// for not-greater-than, and store the results in dst.
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_cmpngt_pd
#define _mm_cmpngt_pd(a, b) _mm_cmple_pd(a, b)
// Compare the lower double-precision (64-bit) floating-point element in a and b
// for equality, and return the boolean result (0 or 1).
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_comieq_sd
FORCE_INLINE int _mm_comieq_sd(__m128d a, __m128d b)
{
#if defined(__aarch64__)
return !!vgetq_lane_u64(vceqq_f64(a, b), 0);
#else
uint32x4_t a_not_nan =
vceqq_u32(vreinterpretq_u32_m128d(a), vreinterpretq_u32_m128d(a));
uint32x4_t b_not_nan =
vceqq_u32(vreinterpretq_u32_m128d(b), vreinterpretq_u32_m128d(b));
uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan);
uint32x4_t a_eq_b =
vceqq_u32(vreinterpretq_u32_m128d(a), vreinterpretq_u32_m128d(b));
uint64x2_t and_results = vandq_u64(vreinterpretq_u64_u32(a_and_b_not_nan),
vreinterpretq_u64_u32(a_eq_b));
return !!vgetq_lane_u64(and_results, 0);
#endif
}
// Compares the 16 signed 8-bit integers in a and the 16 signed 8-bit integers
// in b for greater than.
//
@ -4887,6 +5199,90 @@ FORCE_INLINE __m128i _mm_cmpgt_epi8(__m128i a, __m128i b)
vcgtq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b)));
}
// Compare packed double-precision (64-bit) floating-point elements in a and b
// for greater-than, and store the results in dst.
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpgt_pd
FORCE_INLINE __m128d _mm_cmpgt_pd(__m128d a, __m128d b)
{
#if defined(__aarch64__)
return vreinterpretq_m128d_u64(
vcgtq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)));
#else
uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a));
uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a));
uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b));
uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b));
uint64_t d[2];
d[0] = (*(double *) &a0) > (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0);
d[1] = (*(double *) &a1) > (*(double *) &b1) ? ~UINT64_C(0) : UINT64_C(0);
return vreinterpretq_m128d_u64(vld1q_u64(d));
#endif
}
// Compare the lower double-precision (64-bit) floating-point elements in a and
// b for greater-than, store the result in the lower element of dst, and copy
// the upper element from a to the upper element of dst.
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpgt_sd
FORCE_INLINE __m128d _mm_cmpgt_sd(__m128d a, __m128d b)
{
#if defined(__aarch64__)
return _mm_move_sd(a, _mm_cmpgt_pd(a, b));
#else
// expand "_mm_cmpge_pd()" to reduce unnecessary operations
uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a));
uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a));
uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b));
uint64_t d[2];
d[0] = (*(double *) &a0) > (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0);
d[1] = a1;
return vreinterpretq_m128d_u64(vld1q_u64(d));
#endif
}
// Compare packed double-precision (64-bit) floating-point elements in a and b
// for less-than-or-equal, and store the results in dst.
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmple_pd
FORCE_INLINE __m128d _mm_cmple_pd(__m128d a, __m128d b)
{
#if defined(__aarch64__)
return vreinterpretq_m128d_u64(
vcleq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)));
#else
uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a));
uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a));
uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b));
uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b));
uint64_t d[2];
d[0] = (*(double *) &a0) <= (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0);
d[1] = (*(double *) &a1) <= (*(double *) &b1) ? ~UINT64_C(0) : UINT64_C(0);
return vreinterpretq_m128d_u64(vld1q_u64(d));
#endif
}
// Compare the lower double-precision (64-bit) floating-point elements in a and
// b for less-than-or-equal, store the result in the lower element of dst, and
// copy the upper element from a to the upper element of dst.
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmple_sd
FORCE_INLINE __m128d _mm_cmple_sd(__m128d a, __m128d b)
{
#if defined(__aarch64__)
return _mm_move_sd(a, _mm_cmple_pd(a, b));
#else
// expand "_mm_cmpge_pd()" to reduce unnecessary operations
uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a));
uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a));
uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b));
uint64_t d[2];
d[0] = (*(double *) &a0) <= (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0);
d[1] = a1;
return vreinterpretq_m128d_u64(vld1q_u64(d));
#endif
}
// Compares the 8 signed 16-bit integers in a and the 8 signed 16-bit integers
// in b for less than.
//
@ -4944,31 +5340,9 @@ FORCE_INLINE __m128i _mm_cmpgt_epi64(__m128i a, __m128i b)
return vreinterpretq_m128i_u64(
vcgtq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(b)));
#else
// ARMv7 lacks vcgtq_s64.
// This is based off of Clang's SSE2 polyfill:
// (a > b) -> ((a_hi > b_hi) || (a_lo > b_lo && a_hi == b_hi))
// Mask the sign bit out since we need a signed AND an unsigned comparison
// and it is ugly to try and split them.
int32x4_t mask = vreinterpretq_s32_s64(vdupq_n_s64(0x80000000ull));
int32x4_t a_mask = veorq_s32(vreinterpretq_s32_m128i(a), mask);
int32x4_t b_mask = veorq_s32(vreinterpretq_s32_m128i(b), mask);
// Check if a > b
int64x2_t greater = vreinterpretq_s64_u32(vcgtq_s32(a_mask, b_mask));
// Copy upper mask to lower mask
// a_hi > b_hi
int64x2_t gt_hi = vshrq_n_s64(greater, 63);
// Copy lower mask to upper mask
// a_lo > b_lo
int64x2_t gt_lo = vsliq_n_s64(greater, greater, 32);
// Compare for equality
int64x2_t equal = vreinterpretq_s64_u32(vceqq_s32(a_mask, b_mask));
// Copy upper mask to lower mask
// a_hi == b_hi
int64x2_t eq_hi = vshrq_n_s64(equal, 63);
// a_hi > b_hi || (a_lo > b_lo && a_hi == b_hi)
int64x2_t ret = vorrq_s64(gt_hi, vandq_s64(gt_lo, eq_hi));
return vreinterpretq_m128i_s64(ret);
return vreinterpretq_m128i_s64(vshrq_n_s64(
vqsubq_s64(vreinterpretq_s64_m128i(b), vreinterpretq_s64_m128i(a)),
63));
#endif
}
@ -5368,6 +5742,28 @@ FORCE_INLINE __m128d _mm_cvtepi32_pd(__m128i a)
#endif
}
// Convert packed signed 32-bit integers in a to packed double-precision
// (64-bit) floating-point elements, and store the results in dst.
//
// FOR j := 0 to 1
// i := j*32
// m := j*64
// dst[m+63:m] := Convert_Int32_To_FP64(a[i+31:i])
// ENDFOR
//
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi32_pd
FORCE_INLINE __m128d _mm_cvtpi32_pd(__m64 a)
{
#if defined(__aarch64__)
return vreinterpretq_m128d_f64(
vcvtq_f64_s64(vmovl_s32(vreinterpret_s32_m64(a))));
#else
double a0 = (double) vget_lane_s32(vreinterpret_s32_m64(a), 0);
double a1 = (double) vget_lane_s32(vreinterpret_s32_m64(a), 1);
return _mm_set_pd(a1, a0);
#endif
}
// Converts the four unsigned 8-bit integers in the lower 16 bits to four
// unsigned 32-bit integers.
FORCE_INLINE __m128i _mm_cvtepu8_epi16(__m128i a)
@ -5647,6 +6043,15 @@ FORCE_INLINE __m128d _mm_load1_pd(const double *p)
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load_pd1
#define _mm_load_pd1 _mm_load1_pd
// Load a double-precision (64-bit) floating-point element from memory into both
// elements of dst.
//
// dst[63:0] := MEM[mem_addr+63:mem_addr]
// dst[127:64] := MEM[mem_addr+63:mem_addr]
//
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loaddup_pd
#define _mm_loaddup_pd _mm_load1_pd
// Load a double-precision (64-bit) floating-point element from memory into the
// upper element of dst, and copy the lower element from a to dst. mem_addr does
// not need to be aligned on any particular boundary.
@ -6986,6 +7391,14 @@ FORCE_INLINE void _mm_sfence(void)
__sync_synchronize();
}
// Store 64-bits of integer data from a into memory using a non-temporal memory
// hint.
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_stream_pi
FORCE_INLINE void _mm_stream_pi(__m64 *p, __m64 a)
{
vst1_s64((int64_t *) p, vreinterpret_s64_m64(a));
}
// Store 128-bits (composed of 4 packed single-precision (32-bit) floating-
// point elements) from a into memory using a non-temporal memory hint.
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_stream_ps
@ -6998,6 +7411,22 @@ FORCE_INLINE void _mm_stream_ps(float *p, __m128 a)
#endif
}
// Store 128-bits (composed of 2 packed double-precision (64-bit) floating-point
// elements) from a into memory using a non-temporal memory hint. mem_addr must
// be aligned on a 16-byte boundary or a general-protection exception may be
// generated.
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_stream_pd
FORCE_INLINE void _mm_stream_pd(double *p, __m128d a)
{
#if __has_builtin(__builtin_nontemporal_store)
__builtin_nontemporal_store(a, (float32x4_t *) p);
#elif defined(__aarch64__)
vst1q_f64(p, vreinterpretq_f64_m128d(a));
#else
vst1q_s64((int64_t *) p, vreinterpretq_s64_m128d(a));
#endif
}
// Stores the data in a to the address p without polluting the caches. If the
// cache line containing address p is already in the cache, the cache will be
// updated.
@ -7011,6 +7440,15 @@ FORCE_INLINE void _mm_stream_si128(__m128i *p, __m128i a)
#endif
}
// Store 32-bit integer a into memory using a non-temporal hint to minimize
// cache pollution. If the cache line containing address mem_addr is already in
// the cache, the cache will be updated.
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_stream_si32
FORCE_INLINE void _mm_stream_si32(int *p, int a)
{
vst1q_lane_s32((int32_t *) p, vdupq_n_s32(a), 0);
}
// Load 128-bits of integer data from memory into dst using a non-temporal
// memory hint. mem_addr must be aligned on a 16-byte boundary or a
// general-protection exception may be generated.
@ -7065,6 +7503,12 @@ FORCE_INLINE void _mm_maskmove_si64(__m64 a, __m64 mask, char *mem_addr)
vst1_s8((int8_t *) mem_addr, masked);
}
// Conditionally store 8-bit integer elements from a into memory using mask
// (elements are not stored when the highest bit is not set in the corresponding
// element) and a non-temporal memory hint.
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_maskmovq
#define _m_maskmovq(a, mask, mem_addr) _mm_maskmove_si64(a, mask, mem_addr)
// Free aligned memory that was allocated with _mm_malloc.
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_free
FORCE_INLINE void _mm_free(void *addr)

View file

@ -22,6 +22,7 @@
mov rsi, rdx ;# uint8_t* scratchpad
mov rax, rbp
ror rbp, 32
;# zero integer registers
xor r8, r8

View file

@ -35,6 +35,7 @@
mov rbx, r9 ;# loop counter
mov rax, rbp
ror rbp, 32
;# zero integer registers
xor r8, r8

View file

@ -1,17 +1,16 @@
mov ecx, ebp ;# ecx = ma
and ecx, RANDOMX_DATASET_BASE_MASK
xor r8, qword ptr [rdi+rcx]
ror rbp, 32 ;# swap "ma" and "mx"
xor rbp, rax ;# modify "mx"
mov edx, ebp ;# edx = mx
and edx, RANDOMX_DATASET_BASE_MASK
prefetchnta byte ptr [rdi+rdx]
ror rbp, 32 ;# swap "ma" and "mx"
mov edx, ebp ;# edx = ma
and edx, RANDOMX_DATASET_BASE_MASK
lea rcx, [rdi+rdx] ;# dataset cache line
xor r8, qword ptr [rcx+0]
xor r9, qword ptr [rcx+8]
xor r10, qword ptr [rcx+16]
xor r11, qword ptr [rcx+24]
xor r12, qword ptr [rcx+32]
xor r13, qword ptr [rcx+40]
xor r14, qword ptr [rcx+48]
xor r15, qword ptr [rcx+56]
xor r9, qword ptr [rdi+rcx+8]
xor r10, qword ptr [rdi+rcx+16]
xor r11, qword ptr [rdi+rcx+24]
xor r12, qword ptr [rdi+rcx+32]
xor r13, qword ptr [rdi+rcx+40]
xor r14, qword ptr [rdi+rcx+48]
xor r15, qword ptr [rdi+rcx+56]

View file

@ -1,17 +0,0 @@
mov rcx, rbp ;# ecx = ma
shr rcx, 32
and ecx, RANDOMX_DATASET_BASE_MASK
xor r8, qword ptr [rdi+rcx]
xor rbp, rax ;# modify "mx"
mov edx, ebp ;# edx = mx
and edx, RANDOMX_DATASET_BASE_MASK
prefetchnta byte ptr [rdi+rdx]
ror rbp, 32 ;# swap "ma" and "mx"
xor r9, qword ptr [rdi+rcx+8]
xor r10, qword ptr [rdi+rcx+16]
xor r11, qword ptr [rdi+rcx+24]
xor r12, qword ptr [rdi+rcx+32]
xor r13, qword ptr [rdi+rcx+40]
xor r14, qword ptr [rdi+rcx+48]
xor r15, qword ptr [rdi+rcx+56]

View file

@ -7,4 +7,4 @@
xor r13, qword ptr [rsp+16]
xor r14, qword ptr [rsp+8]
xor r15, qword ptr [rsp+0]
add rsp, 72
add rsp, 200

View file

@ -1,4 +1,4 @@
sub rsp, 72
sub rsp, 200
mov qword ptr [rsp+64], rbx
mov qword ptr [rsp+56], r8
mov qword ptr [rsp+48], r9
@ -8,10 +8,10 @@
mov qword ptr [rsp+16], r13
mov qword ptr [rsp+8], r14
mov qword ptr [rsp+0], r15
xor rbp, rax ;# modify "mx"
ror rbp, 32 ;# swap "ma" and "mx"
mov ebx, ebp ;# ecx = ma
and ebx, RANDOMX_DATASET_BASE_MASK
shr ebx, 6 ;# ebx = Dataset block number
xor rbp, rax ;# modify "mx"
mov rbx, rbp ;# ebx = ma
shr rbx, 38
and ebx, RANDOMX_DATASET_BASE_MASK / 64 ;# ebx = Dataset block number
;# add ebx, datasetOffset / 64
;# call 32768

View file

@ -304,6 +304,9 @@ literal_v14: .fill 2,8,0
literal_v15: .fill 2,8,0
DECL(randomx_program_aarch64_vm_instructions_end):
# Calculate dataset pointer for dataset read
# Do it here to break false dependency from readReg2 and readReg3 (see next line)
lsr x10, x9, 32
# mx ^= r[readReg2] ^ r[readReg3];
eor x9, x9, x18
@ -321,8 +324,6 @@ DECL(randomx_program_aarch64_cacheline_align_mask1):
# mx <-> ma
ror x9, x9, 32
# Calculate dataset pointer for dataset read
mov w10, w9
DECL(randomx_program_aarch64_cacheline_align_mask2):
# Actual mask will be inserted by JIT compiler
and x10, x10, 1

View file

@ -110,13 +110,12 @@ namespace randomx {
#define ADDR(x) ((uint8_t*)&x)
# endif
#define codePrefetchScratchpad ADDR(randomx_prefetch_scratchpad)
#define codePrefetchScratchpadEnd ADDR(randomx_prefetch_scratchpad_end)
#define codePrologue ADDR(randomx_program_prologue)
#define codeLoopBegin ADDR(randomx_program_loop_begin)
#define codeLoopLoad ADDR(randomx_program_loop_load)
#define codeLoopLoadXOP ADDR(randomx_program_loop_load_xop)
#define codeProgamStart ADDR(randomx_program_start)
#define codeReadDataset ADDR(randomx_program_read_dataset)
#define codeReadDatasetLightSshInit ADDR(randomx_program_read_dataset_sshash_init)
#define codeReadDatasetLightSshFin ADDR(randomx_program_read_dataset_sshash_fin)
#define codeDatasetInit ADDR(randomx_dataset_init)
@ -134,10 +133,10 @@ namespace randomx {
#define codeShhEnd ADDR(randomx_sshash_end)
#define codeShhInit ADDR(randomx_sshash_init)
#define prefetchScratchpadSize (codePrefetchScratchpadEnd - codePrefetchScratchpad)
#define prologueSize (codeLoopBegin - codePrologue)
#define loopLoadSize (codeLoopLoadXOP - codeLoopLoad)
#define loopLoadXOPSize (codeProgamStart - codeLoopLoadXOP)
#define readDatasetSize (codeReadDatasetLightSshInit - codeReadDataset)
#define readDatasetLightInitSize (codeReadDatasetLightSshFin - codeReadDatasetLightSshInit)
#define readDatasetLightFinSize (codeLoopStore - codeReadDatasetLightSshFin)
#define loopStoreSize (codeLoopEnd - codeLoopStore)
@ -321,26 +320,13 @@ namespace randomx {
vm_flags = flags;
generateProgramPrologue(prog, pcfg);
uint8_t* p;
uint32_t n;
if (flags & RANDOMX_FLAG_AMD) {
p = RandomX_CurrentConfig.codeReadDatasetRyzenTweaked;
n = RandomX_CurrentConfig.codeReadDatasetRyzenTweakedSize;
}
else {
p = RandomX_CurrentConfig.codeReadDatasetTweaked;
n = RandomX_CurrentConfig.codeReadDatasetTweakedSize;
}
memcpy(code + codePos, p, n);
codePos += n;
emit(codeReadDataset, readDatasetSize, code, codePos);
generateProgramEpilogue(prog, pcfg);
}
void JitCompilerX86::generateProgramLight(Program& prog, ProgramConfiguration& pcfg, uint32_t datasetOffset) {
generateProgramPrologue(prog, pcfg);
emit(RandomX_CurrentConfig.codeReadDatasetLightSshInitTweaked, readDatasetLightInitSize, code, codePos);
emit(codeReadDatasetLightSshInit, readDatasetLightInitSize, code, codePos);
*(uint32_t*)(code + codePos) = 0xc381;
codePos += 2;
emit32(datasetOffset / CacheLineSize, code, codePos);
@ -467,7 +453,7 @@ namespace randomx {
void JitCompilerX86::generateProgramEpilogue(Program& prog, ProgramConfiguration& pcfg) {
*(uint64_t*)(code + codePos) = 0xc03349c08b49ull + (static_cast<uint64_t>(pcfg.readReg0) << 16) + (static_cast<uint64_t>(pcfg.readReg1) << 40);
codePos += 6;
emit(RandomX_CurrentConfig.codePrefetchScratchpadTweaked, prefetchScratchpadSize, code, codePos);
emit(RandomX_CurrentConfig.codePrefetchScratchpadTweaked, RandomX_CurrentConfig.codePrefetchScratchpadTweakedSize, code, codePos);
memcpy(code + codePos, codeLoopStore, loopStoreSize);
codePos += loopStoreSize;

View file

@ -38,6 +38,7 @@
#endif
.global DECL(randomx_prefetch_scratchpad)
.global DECL(randomx_prefetch_scratchpad_bmi2)
.global DECL(randomx_prefetch_scratchpad_end)
.global DECL(randomx_program_prologue)
.global DECL(randomx_program_prologue_first_load)
@ -47,7 +48,6 @@
.global DECL(randomx_program_loop_load_xop)
.global DECL(randomx_program_start)
.global DECL(randomx_program_read_dataset)
.global DECL(randomx_program_read_dataset_ryzen)
.global DECL(randomx_program_read_dataset_sshash_init)
.global DECL(randomx_program_read_dataset_sshash_fin)
.global DECL(randomx_program_loop_store)
@ -80,6 +80,13 @@ DECL(randomx_prefetch_scratchpad):
and edx, RANDOMX_SCRATCHPAD_MASK
prefetcht0 [rsi+rdx]
DECL(randomx_prefetch_scratchpad_bmi2):
rorx rdx, rax, 32
and eax, RANDOMX_SCRATCHPAD_MASK
prefetcht0 [rsi+rax]
and edx, RANDOMX_SCRATCHPAD_MASK
prefetcht0 [rsi+rdx]
DECL(randomx_prefetch_scratchpad_end):
.balign 64
@ -132,9 +139,6 @@ DECL(randomx_program_start):
DECL(randomx_program_read_dataset):
#include "asm/program_read_dataset.inc"
DECL(randomx_program_read_dataset_ryzen):
#include "asm/program_read_dataset_ryzen.inc"
DECL(randomx_program_read_dataset_sshash_init):
#include "asm/program_read_dataset_sshash_init.inc"

View file

@ -29,6 +29,7 @@ IFDEF RAX
_RANDOMX_JITX86_STATIC SEGMENT PAGE READ EXECUTE
PUBLIC randomx_prefetch_scratchpad
PUBLIC randomx_prefetch_scratchpad_bmi2
PUBLIC randomx_prefetch_scratchpad_end
PUBLIC randomx_program_prologue
PUBLIC randomx_program_prologue_first_load
@ -38,7 +39,6 @@ PUBLIC randomx_program_loop_load
PUBLIC randomx_program_loop_load_xop
PUBLIC randomx_program_start
PUBLIC randomx_program_read_dataset
PUBLIC randomx_program_read_dataset_ryzen
PUBLIC randomx_program_read_dataset_sshash_init
PUBLIC randomx_program_read_dataset_sshash_fin
PUBLIC randomx_dataset_init
@ -70,6 +70,14 @@ randomx_prefetch_scratchpad PROC
prefetcht0 [rsi+rdx]
randomx_prefetch_scratchpad ENDP
randomx_prefetch_scratchpad_bmi2 PROC
rorx rdx, rax, 32
and eax, RANDOMX_SCRATCHPAD_MASK
prefetcht0 [rsi+rax]
and edx, RANDOMX_SCRATCHPAD_MASK
prefetcht0 [rsi+rdx]
randomx_prefetch_scratchpad_bmi2 ENDP
randomx_prefetch_scratchpad_end PROC
randomx_prefetch_scratchpad_end ENDP
@ -127,10 +135,6 @@ randomx_program_read_dataset PROC
include asm/program_read_dataset.inc
randomx_program_read_dataset ENDP
randomx_program_read_dataset_ryzen PROC
include asm/program_read_dataset_ryzen.inc
randomx_program_read_dataset_ryzen ENDP
randomx_program_read_dataset_sshash_init PROC
include asm/program_read_dataset_sshash_init.inc
randomx_program_read_dataset_sshash_init ENDP

View file

@ -30,6 +30,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
extern "C" {
void randomx_prefetch_scratchpad();
void randomx_prefetch_scratchpad_bmi2();
void randomx_prefetch_scratchpad_end();
void randomx_program_prologue();
void randomx_program_prologue_first_load();
@ -39,7 +40,6 @@ extern "C" {
void randomx_program_loop_load_xop();
void randomx_program_start();
void randomx_program_read_dataset();
void randomx_program_read_dataset_ryzen();
void randomx_program_read_dataset_sshash_init();
void randomx_program_read_dataset_sshash_fin();
void randomx_program_loop_store();

View file

@ -165,27 +165,17 @@ RandomX_ConfigurationBase::RandomX_ConfigurationBase()
const uint8_t* b = addr(randomx_sshash_end);
memcpy(codeShhPrefetchTweaked, a, b - a);
}
{
const uint8_t* a = addr(randomx_program_read_dataset);
const uint8_t* b = addr(randomx_program_read_dataset_ryzen);
memcpy(codeReadDatasetTweaked, a, b - a);
codeReadDatasetTweakedSize = b - a;
}
{
const uint8_t* a = addr(randomx_program_read_dataset_ryzen);
const uint8_t* b = addr(randomx_program_read_dataset_sshash_init);
memcpy(codeReadDatasetRyzenTweaked, a, b - a);
codeReadDatasetRyzenTweakedSize = b - a;
}
{
const uint8_t* a = addr(randomx_program_read_dataset_sshash_init);
const uint8_t* b = addr(randomx_program_read_dataset_sshash_fin);
memcpy(codeReadDatasetLightSshInitTweaked, a, b - a);
}
{
const uint8_t* a = addr(randomx_prefetch_scratchpad);
if (xmrig::Cpu::info()->hasBMI2()) {
const uint8_t* a = addr(randomx_prefetch_scratchpad_bmi2);
const uint8_t* b = addr(randomx_prefetch_scratchpad_end);
memcpy(codePrefetchScratchpadTweaked, a, b - a);
codePrefetchScratchpadTweakedSize = b - a;
}
else {
const uint8_t* a = addr(randomx_prefetch_scratchpad);
const uint8_t* b = addr(randomx_prefetch_scratchpad_bmi2);
memcpy(codePrefetchScratchpadTweaked, a, b - a);
codePrefetchScratchpadTweakedSize = b - a;
}
# endif
}
@ -222,13 +212,15 @@ void RandomX_ConfigurationBase::Apply()
//*(uint32_t*)(codeReadDatasetTweaked + 24) = DatasetBaseMask;
//*(uint32_t*)(codeReadDatasetLightSshInitTweaked + 59) = DatasetBaseMask;
*(uint32_t*)(codePrefetchScratchpadTweaked + 4) = ScratchpadL3Mask64_Calculated;
*(uint32_t*)(codePrefetchScratchpadTweaked + 18) = ScratchpadL3Mask64_Calculated;
const bool hasBMI2 = xmrig::Cpu::info()->hasBMI2();
*(uint32_t*)(codePrefetchScratchpadTweaked + (hasBMI2 ? 7 : 4)) = ScratchpadL3Mask64_Calculated;
*(uint32_t*)(codePrefetchScratchpadTweaked + (hasBMI2 ? 17 : 18)) = ScratchpadL3Mask64_Calculated;
// Apply scratchpad prefetch mode
{
uint32_t* a = (uint32_t*)(codePrefetchScratchpadTweaked + 8);
uint32_t* b = (uint32_t*)(codePrefetchScratchpadTweaked + 22);
uint32_t* a = (uint32_t*)(codePrefetchScratchpadTweaked + (hasBMI2 ? 11 : 8));
uint32_t* b = (uint32_t*)(codePrefetchScratchpadTweaked + (hasBMI2 ? 21 : 22));
switch (scratchpadPrefetchMode)
{
@ -295,7 +287,7 @@ typedef void(randomx::JitCompilerX86::* InstructionGeneratorX86_2)(const randomx
INST_HANDLE(IMUL_M, IMUL_R);
#if defined(_M_X64) || defined(__x86_64__)
if (xmrig::Cpu::info()->hasBMI2()) {
if (hasBMI2) {
INST_HANDLE2(IMULH_R, IMULH_R_BMI2, IMUL_M);
INST_HANDLE2(IMULH_M, IMULH_M_BMI2, IMULH_R);
}
@ -337,7 +329,7 @@ typedef void(randomx::JitCompilerX86::* InstructionGeneratorX86_2)(const randomx
#endif
#if defined(_M_X64) || defined(__x86_64__)
if (xmrig::Cpu::info()->hasBMI2()) {
if (hasBMI2) {
INST_HANDLE2(CFROUND, CFROUND_BMI2, CBRANCH);
}
else

View file

@ -125,12 +125,8 @@ struct RandomX_ConfigurationBase
rx_vec_i128 fillAes4Rx4_Key[8];
uint8_t codeShhPrefetchTweaked[20];
uint8_t codeReadDatasetTweaked[64];
uint32_t codeReadDatasetTweakedSize;
uint8_t codeReadDatasetRyzenTweaked[72];
uint32_t codeReadDatasetRyzenTweakedSize;
uint8_t codeReadDatasetLightSshInitTweaked[68];
uint8_t codePrefetchScratchpadTweaked[32];
uint8_t codePrefetchScratchpadTweaked[28];
uint32_t codePrefetchScratchpadTweakedSize;
uint32_t AddressMask_Calculated[4];
uint32_t ScratchpadL3Mask_Calculated;

View file

@ -29,6 +29,7 @@
#include <cstdio>
#include <dirent.h>
#include <fcntl.h>
#include <fstream>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
@ -48,7 +49,27 @@ static int msr_open(int32_t cpu, int flags)
class MsrPrivate
{
public:
bool available = true;
inline MsrPrivate() : m_available(msr_allow_writes() || msr_modprobe()) {}
inline bool isAvailable() const { return m_available; }
private:
inline bool msr_allow_writes()
{
std::ofstream file("/sys/module/msr/parameters/allow_writes", std::ios::out | std::ios::binary | std::ios::trunc);
if (file.is_open()) {
file << "on";
}
return file.good();
}
inline bool msr_modprobe()
{
return system("/sbin/modprobe msr allow_writes=on > /dev/null 2>&1") == 0;
}
const bool m_available;
};
@ -57,10 +78,8 @@ public:
xmrig::Msr::Msr() : d_ptr(new MsrPrivate())
{
if (system("/sbin/modprobe msr allow_writes=on > /dev/null 2>&1") != 0) {
LOG_WARN("%s " YELLOW_BOLD("msr kernel module is not available"), Msr::tag());
d_ptr->available = false;
if (!isAvailable()) {
LOG_WARN("%s " YELLOW_BOLD("msr kernel module is not available"), tag());
}
}
@ -73,7 +92,7 @@ xmrig::Msr::~Msr()
bool xmrig::Msr::isAvailable() const
{
return d_ptr->available;
return d_ptr->isAvailable();
}

View file

@ -28,7 +28,7 @@
#define APP_ID "xmrig"
#define APP_NAME "XMRig"
#define APP_DESC "XMRig miner"
#define APP_VERSION "6.12.1"
#define APP_VERSION "6.12.2-dev"
#define APP_DOMAIN "xmrig.com"
#define APP_SITE "www.xmrig.com"
#define APP_COPYRIGHT "Copyright (C) 2016-2021 xmrig.com"
@ -36,7 +36,7 @@
#define APP_VER_MAJOR 6
#define APP_VER_MINOR 12
#define APP_VER_PATCH 1
#define APP_VER_PATCH 2
#ifdef _MSC_VER
# if (_MSC_VER >= 1920)