diff --git a/docs/contribute/backend.md b/docs/contribute/backend.md index 2179e679a..b54f177f6 100644 --- a/docs/contribute/backend.md +++ b/docs/contribute/backend.md @@ -177,7 +177,7 @@ virtual void onResizeBegin(); /** * @brief callback after resize ops. */ -virtual void onResizeEnd(); +virtual ErrorCode onResizeEnd(); /** * @brief callback before executing ops. */ diff --git a/docs/inference/module.md b/docs/inference/module.md index efc881b7d..48cf1c020 100644 --- a/docs/inference/module.md +++ b/docs/inference/module.md @@ -10,34 +10,52 @@ - `VARP` 作为`Module`的输入输出,也是[Expr API](expr.md)中的基础数据结构 ## 工作流程 -创建Executor(可选) -> 创建Module -> 创建输入VARP -> 使用Module::forwad推理 -> 使用输出VARP -> 销毁Module -> 销毁Executor(可选) -### 创建Executor +配置Executor(可选) -> 创建 RuntimeManager(可选) -> 创建Module -> 创建输入VARP -> 使用Module::forwad推理 -> 使用输出VARP -> 销毁Module +### (可选)配置Executor `Executor`给用户提供接口来配置推理后端、线程数等属性,以及做性能统计、算子执行的回调函数、内存回收等功能。 提供一个全局的Exector对象,用户不用创建或持有对象即可直接使用。 ```cpp -// 新建Exector -NNForwardType type = MNN_FORWARD_CPU; -MNN::BackendConfig backend_config; // default backend config -std::shared_ptr executor( - MNN::Express::Executor::newExecutor(type, backend_config, 4)); -MNN::Express::ExecutorScope scope(executor); -// 使用默认全局Exector +// 配置默认全局Exector MNN::BackendConfig backend_config; // default backend config -MNN::Express::Executor::getGlobalExecutor()->setGlobalExecutorConfig(type, backend_config, 4); +// 设置使用4线程+CPU +MNN::Express::Executor::getGlobalExecutor()->setGlobalExecutorConfig(MNN_FORWARD_CPU, backend_config, 4); ``` + +### (可选)创建 RuntimeManager +Executor 的配置会同时影响Module和表达式计算的后端配置。 + +*** 如下示例会触发表达式计算,若 Executor 设置为 OPENCL ,则该计算会用OpenCL后端实现 +```cpp +MNN::Express::VARP X; +MNN::Express::VARP Y = MNN::Express::_Sign(X); +float* yPtr = Y->readMap(); +``` + +若希望仅在该Module中采用某种后端配置(比如Module使用GPU但表达式计算使用CPU),可额外创建 RuntimeManager ,并在创建 Module 时传入 +```cpp +MNN::ScheduleConfig sConfig; +sConfig.type = MNN_FORWARD_OPENCL; + +std::shared_ptr rtmgr(MNN::Express::Executor::RuntimeManager::createRuntimeManager(sConfig), MNN::Express::Executor::RuntimeManager::destroy); +rtmgr->setCache(".cachefile"); +``` + ### 创建Module -`Module`可以通过制定模型,输入输出的名称,配置文件创建;也可以从现有的`Module`对象`clone` +`Module`可以通过指定模型,输入输出的名称,配置文件创建 ```cpp // 从模型文件加载并创建新Module const std::string model_file = "/tmp/mymodule.mnn"; // model file with path + +// 输入名,可以为空,为空时 MNN 自动搜索模型中的输入,多输入情况下无法保证顺序,需要通过 getInfo 接口查看 const std::vector input_names{"input_1", "input_2", "input_3"}; +// 输出名,可以为空,为空时 MNN 自动搜索模型中的输出,多输出情况下无法保证顺序,需要通过 getInfo 接口查看 const std::vector output_names{"output_1"}; + Module::Config mdconfig; // default module config std::unique_ptr module; // module -module.reset(Module::load(input_names, output_names, model_filename.c_str(), &mdconfig)); -// 从现有Module创建新Module,可用于多进程并发 -std::unique_ptr module_shallow_copy; -module_shallow_copy.reset(Module::clone(module.get())); +// 若 rtMgr 为 nullptr ,Module 会使用Executor的后端配置 +module.reset(Module::load(input_names, output_names, model_filename.c_str(), rtMgr, &mdconfig)); ``` + ### 获取模型信息 调用`getInfo`函数可获取`Module`信息,可以参考代码:`tools/cpp/GetMNNInfo.cpp`,[工具](../tools/test.html#getmnninfo) ```cpp @@ -57,41 +75,96 @@ struct Info { }; const Info* getInfo() const; ``` + ### 执行推理 调用`onForward`执行推理。 -**注意:当`Module`析构之后使用`onForward`返回的`VARP`将不可用** - ```cpp -std::vector onForward(const std::vector& inputs); +std::vector onForward(const std::vector& inputs); ``` -## 使用Module进行模型推理 -使用Module进行推理时支持控制流算子,所以对于语音模型常用Module进行推理。示例代码: +示例代码: ```cpp int dim = 224; std::vector inputs(3); -inputs[0] = _Input({1, dim}, NHWC, halide_type_of()); -inputs[1] = _Input({1, dim}, NHWC, halide_type_of()); -inputs[2] = _Input({1, dim}, NHWC, halide_type_of()); +// 对于 tensoflow 转换过来的模型用 NHWC ,由 onnx 转换过来的模型用 NCHW +inputs[0] = MNN::Express::_Input({1, dim}, NHWC, halide_type_of()); +inputs[1] = MNN::Express::_Input({1, dim}, NHWC, halide_type_of()); +inputs[2] = MNN::Express::_Input({1, dim}, NHWC, halide_type_of()); // 设置输入数据 std::vector input_pointer = {inputs[0]->writeMap(), inputs[1]->writeMap(), inputs[2]->writeMap()}; -for (int i = 0; i < inputs[0]->getInfo->size; ++i) { +for (int i = 0; i < dim; ++i) { input_pointer[0] = i + 1; input_pointer[1] = i + 2; input_pointer[2] = i + 3; } // 执行推理 -std::vector outputs = module->onForward(inputs); +std::vector outputs = module->onForward(inputs); // 获取输出 auto output_ptr = outputs[0]->readMap(); ``` -可以使用回调函数进行调试,与[runSessionWithCallBack](session.html#id19)相似。示例代码: +## 多实例推理 + +Module API 支持同个模型创建多个实例,分发到不同线程推理。具体步骤如下: + +- 【启动】主线程创建基准Module: 配置Executor(可选) -> 创建 RuntimeManager(可选) -> 创建Module +- 【启动】创建子线程,在子线程中创建 Executor +- 【启动】子线程绑定该线程的Executor , Clone Module +- 【使用】子线程绑定该线程的executor,使用 Clone 出来的 Module进行推理:创建输入VARP -> 使用Module::forwad推理 -> 使用输出VARP +- 【结束】子线程绑定该线程的executor,销毁 Module +- 【结束】子线程销毁 Executor ,销毁子线程 +- 【结束】主线程销毁 Module + +### 创建基准Module +第一个实例的创建过程不需要变更 + +### 每个实例新建Exector +```cpp +NNForwardType type = MNN_FORWARD_CPU; +MNN::BackendConfig backend_config; // default backend config +std::shared_ptr executor( + MNN::Express::Executor::newExecutor(type, backend_config, 1)); +``` + +** 若一个算法流程中有多个模型运行,每份实例单独建一个 Executor 即可。 + +### 每个实例克隆基准Module + +```cpp +// 绑定这个实例的executor,这样不会与其他实例产生内存冲突 +MNN::Express::ExecutorScope scope(executor); +std::unique_ptr module_thread(MNN::Express::Module::clone(module.get()), MNN::Express::Module::destroy); +``` + +克隆出来的 Module 与基准 Module 共享不变的权重与常量数据,可以较大地降低新增实例若需的内存。 + + +### 每个实例推理 +```cpp +// 每个实例推理之前用 ExecutorScope 绑定这个实例的 executor +MNN::Express::ExecutorScope scope(executor); +std::vector inputs; +/* 构建输入......*/ +// 执行推理 +std::vector outputs = module_thread->onForward(inputs); +/* 使用输出......*/ +``` + +### 销毁 +```cpp +//每个实例销毁Module之前,也需要用 ExecutorScope 绑定这个实例的 executor +MNN::Express::ExecutorScope scope(executor); +module_thread.reset(); +``` + +## 调试 + +Module API 也支持使用回调函数进行调试,与[runSessionWithCallBack](session.html#id19)相似。示例代码: ```cpp MNN::TensorCallBackWithInfo beforeCallBack = [&](const std::vector& ntensors, const OperatorInfo* info) { @@ -114,7 +187,7 @@ MNN::TensorCallBackWithInfo callBack = [&](const std::vector& nten return true; }; -// set callback function +// 设置回调函数,需要是创建该 Module 时的 executor ,非多实例情况下用全局 executor 即可: Express::Executor::getGlobalExecutor()->setCallBack(std::move(beforeCallBack), std::move(callBack)); // forward would trigger callback @@ -126,4 +199,4 @@ std::vector outputs = user_module->onForward(inputs); - `pictureRecognition_module.cpp` 使用`Module`执行图像分类,使用`ImageProcess`进行前处理,`Expr`进行后处理 - `pictureRecognition_batch.cpp` 使用`Module`执行图像分类,使用`ImageProcess`进行前处理,`Expr`进行后处理 - `multithread_imgrecog.cpp` 使用`Module`多线程并发执行图像分类,使用`ImageProcess`进行前处理,`Expr`进行后处理 -- `transformerDemo.cpp` 使用`Module`执行Transformer模型推理 \ No newline at end of file +- `transformerDemo.cpp` 使用`Module`执行Transformer模型推理 diff --git a/express/Expr.cpp b/express/Expr.cpp index 3a4bb571e..72f3e0d44 100644 --- a/express/Expr.cpp +++ b/express/Expr.cpp @@ -177,7 +177,9 @@ EXPRP Expr::create(Variable::Info&& info, const void* ptr, VARP::InputType type, } expr->mInside->mContentDirty = false; if (memtype == COPY) { - ::memcpy(expr->mInside->mOutputTensors[0]->buffer().host, originPtr, dstInfo.size * dstInfo.type.bytes()); + size_t total_size = dstInfo.size; + total_size *= dstInfo.type.bytes(); + ::memcpy(expr->mInside->mOutputTensors[0]->buffer().host, originPtr, total_size); } else { expr->mInside->mOutputTensors[0]->buffer().host = (uint8_t*)originPtr; if (memtype == REF) { @@ -227,6 +229,9 @@ EXPRP Expr::create(const OpT* op, std::vector inputs, int outputSize) { case DataType_DT_FLOAT: ptr = (void*)op->main.AsBlob()->float32s.data(); break; + case DataType_DT_BFLOAT16: + ptr = (void*)op->main.AsBlob()->uint8s.data(); + break; default: break; } @@ -1081,9 +1086,15 @@ void Variable::save(const std::vector& vars, NetT* dest) { blob->dataFormat = (MNN_DATA_FORMAT)Utils::convertFormat(info.order); blob->dims = info.dim; if (info.type.code == halide_type_float) { - blob->dataType = DataType_DT_FLOAT; - blob->float32s.resize(info.size); - ::memcpy(blob->float32s.data(), ptr, info.size * sizeof(float)); + if (info.type.bits == 16) { + blob->dataType = DataType_DT_BFLOAT16; + blob->uint8s.resize(info.size * 2); + ::memcpy(blob->uint8s.data(), ptr, info.size * sizeof(int16_t)); + } else { + blob->dataType = DataType_DT_FLOAT; + blob->float32s.resize(info.size); + ::memcpy(blob->float32s.data(), ptr, info.size * sizeof(float)); + } } else if (info.type.code == halide_type_int && info.type.bits == 32) { blob->dataType = DataType_DT_INT32; blob->int32s.resize(info.size); diff --git a/express/Utils.cpp b/express/Utils.cpp index 21ef92025..b4bf18896 100644 --- a/express/Utils.cpp +++ b/express/Utils.cpp @@ -81,6 +81,7 @@ halide_type_t Utils::revertDataType(DataType dataType) { CONVERT(DataType_DT_UINT8, halide_type_of(), dataType); CONVERT(DataType_DT_INT8, halide_type_of(), dataType); CONVERT(DataType_DT_HALF, halide_type_of(), dataType); + CONVERT(DataType_DT_BFLOAT16, halide_type_t(halide_type_float, 16), dataType); return halide_type_of(); } Express::Dimensionformat Utils::revertFormat(int format) { diff --git a/include/MNN/MNNDefine.h b/include/MNN/MNNDefine.h index b4fd34f71..3d04e2bfa 100644 --- a/include/MNN/MNNDefine.h +++ b/include/MNN/MNNDefine.h @@ -69,6 +69,6 @@ MNN_ERROR("Check failed: %s ==> %s\n", #success, #log); \ #define STR(x) STR_IMP(x) #define MNN_VERSION_MAJOR 2 #define MNN_VERSION_MINOR 7 -#define MNN_VERSION_PATCH 0 +#define MNN_VERSION_PATCH 1 #define MNN_VERSION STR(MNN_VERSION_MAJOR) "." STR(MNN_VERSION_MINOR) "." STR(MNN_VERSION_PATCH) #endif /* MNNDefine_h */ diff --git a/include/MNN/Tensor.hpp b/include/MNN/Tensor.hpp index 70cff7fe6..e4431097b 100644 --- a/include/MNN/Tensor.hpp +++ b/include/MNN/Tensor.hpp @@ -227,6 +227,7 @@ class MNN_PUBLIC Tensor { * @return bytes needed to store data */ int size() const; + size_t usize() const; /** * @brief calculate number of elements needed to store data taking reordering flag into account. diff --git a/package_scripts/win/build_lib_release.ps1 b/package_scripts/win/build_lib_release.ps1 index f28e13b81..9e655cb09 100644 --- a/package_scripts/win/build_lib_release.ps1 +++ b/package_scripts/win/build_lib_release.ps1 @@ -13,7 +13,8 @@ Param( [Parameter(Mandatory=$true)][String]$path, [String]$backends, - [Switch]$x86 + [Switch]$x86, + [Switch]$cibuild ) $erroractionpreference = "stop" @@ -25,14 +26,18 @@ mkdir -p $PACKAGE_LIB_PATH #clear and create package directory powershell ./schema/generate.ps1 -Remove-Item -Path $PACKAGE_PATH/include -Recurse -ErrorAction Ignore -cp -r include $PACKAGE_PATH -cp -r tools/cv/include/cv $PACKAGE_PATH/include pushd $PACKAGE_LIB_PATH -mkdir -p Release\Dynamic\MT, Release\Dynamic\MD, Release\Static\MD, Release\Static\MT +if ($cibuild) { + mkdir -p Release\Dynamic\MT +} else { + Remove-Item -Path $PACKAGE_PATH/include -Recurse -ErrorAction Ignore + cp -r include $PACKAGE_PATH + cp -r tools/cv/include/cv $PACKAGE_PATH/include + mkdir -p Release\Dynamic\MT, Release\Dynamic\MD, Release\Static\MD, Release\Static\MT +} popd -$CMAKE_ARGS = "-DMNN_SEP_BUILD=OFF -DMNN_BUILD_TRAIN=ON -DMNN_BUILD_OPENCV=ON -DMNN_IMGCODECS=ON -DMNN_OPENCL=ON -DMNN_VULKAN=ON -DMNN_AVX512=ON" +$CMAKE_ARGS = "-DMNN_SEP_BUILD=OFF -DMNN_BUILD_TRAIN=ON -DMNN_BUILD_OPENCV=ON -DMNN_IMGCODECS=ON -DMNN_OPENCL=ON -DMNN_VULKAN=ON -DMNN_AVX512=ON -DMNN_LOW_MEMORY=ON" if ($backends -ne $null) { Foreach ($backend in $backends.Split(",")) { if ($backend -eq "cuda") { @@ -78,6 +83,12 @@ Build "cmake -G Ninja $CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release -DMNN_WIN_RUNTIME_M cp MNN.lib, MNN.dll, MNN.pdb $PACKAGE_LIB_PATH\Release\Dynamic\MT rm MNN.* +# cibuild just build single type for build test +if ($cibuild) { + popd + return +} + ##### Release/Dynamic/MD #### log "Release/Dynamic/MD" Remove-Item CMakeCache.txt -ErrorAction Ignore @@ -97,4 +108,4 @@ Remove-Item CMakeCache.txt -ErrorAction Ignore Build "cmake -G Ninja $CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release -DMNN_WIN_RUNTIME_MT=OFF -DMNN_BUILD_SHARED_LIBS=OFF .." cp MNN.lib $PACKAGE_LIB_PATH\Release\Static\MD -popd +popd \ No newline at end of file diff --git a/pymnn/pip_package/build_deps.py b/pymnn/pip_package/build_deps.py index 681ef04a4..f44f31b3f 100644 --- a/pymnn/pip_package/build_deps.py +++ b/pymnn/pip_package/build_deps.py @@ -44,7 +44,7 @@ def build_deps(): shutil.rmtree(cmake_build_dir) os.makedirs(cmake_build_dir) os.chdir(cmake_build_dir) - extra_opts = '-DMNN_LOW_MEMORY=OFF' + extra_opts = '-DMNN_LOW_MEMORY=ON' extra_opts += ' -DMNN_VULKAN=ON -DMNN_VULKAN_IMAGE=OFF' extra_opts += ' -DMNN_OPENCL=ON' if IS_WINDOWS: diff --git a/pymnn/src/MNN.cc b/pymnn/src/MNN.cc index ff591b2b8..29cc56100 100644 --- a/pymnn/src/MNN.cc +++ b/pymnn/src/MNN.cc @@ -2157,7 +2157,7 @@ static PyObject* PyMNNCVMatrix_repr(PyObject *self) { ((PyMNNCVMatrix *)self)->matrix->get9(mat); char buffer [100]; sprintf(buffer, "[[%f\t%f\t%f]\n [%f\t%f\t%f]\n [%f\t%f\t%f]]", - mat[0], mat[1], mat[2], mat[3], mat[4], mat[5], mat[5], mat[6], mat[7], mat[8]); + mat[0], mat[1], mat[2], mat[3], mat[4], mat[5], mat[6], mat[7], mat[8]); return toPyObj(buffer); } // type: 0 set; 1 pre; 2 post diff --git a/source/backend/arm82/Arm82Backend.cpp b/source/backend/arm82/Arm82Backend.cpp index a6dc8ff93..ea2c81863 100644 --- a/source/backend/arm82/Arm82Backend.cpp +++ b/source/backend/arm82/Arm82Backend.cpp @@ -80,11 +80,11 @@ Execution* Arm82Backend::onCreate(const std::vector& inputs, const std: return exe; } -static int _getAliginSize(const halide_buffer_t& buffer, MNN_DATA_FORMAT format) { +static size_t _getAliginSize(const halide_buffer_t& buffer, MNN_DATA_FORMAT format) { // The default data type of input tensor for arm82 backend is FLOAT32. // However, Arm82Backend default data type is FLOAT16, so check whether data type is FLOAT32, // then divide size by 2 - int size = sizeof(int16_t); + size_t size = sizeof(int16_t); const int dimensions = buffer.dimensions; for (int i = 0; i < dimensions; i++) { int currentDimSize = buffer.dim[i].extent; diff --git a/source/backend/arm82/asm/arm64/low_memory/MNNPackedMatMulFP16_int4.S b/source/backend/arm82/asm/arm64/low_memory/MNNPackedMatMulFP16_int4.S index fa6532eea..bc88a4318 100644 --- a/source/backend/arm82/asm/arm64/low_memory/MNNPackedMatMulFP16_int4.S +++ b/source/backend/arm82/asm/arm64/low_memory/MNNPackedMatMulFP16_int4.S @@ -53,7 +53,7 @@ LoopH: mov w17, #0x0f dup v3.16b, w17 and v2.16b, v0.16b, v3.16b - mov w17, #7 + mov w17, #8 dup v0.16b, w17 sub v1.16b, v1.16b, v0.16b sub v2.16b, v2.16b, v0.16b @@ -145,7 +145,7 @@ LoopH: mov w17, #0x0f dup v3.16b, w17 and v2.16b, v0.16b, v3.16b - mov w17, #7 + mov w17, #8 dup v0.16b, w17 sub v1.16b, v1.16b, v0.16b sub v2.16b, v2.16b, v0.16b @@ -347,7 +347,7 @@ LoopHRemain: ld1 {v21.8h}, [x20], #16 // bias mov w17, #0x0f dup v22.16b, w17 - mov w17, #7 + mov w17, #8 dup v23.16b, w17 // ld1 {v3.8h}, [x2] ld1 {v3.8h}, [x2], #16 diff --git a/source/backend/arm82/asm/arm64/low_memory/MNNPackedMatMulRemainFP16_int4.S b/source/backend/arm82/asm/arm64/low_memory/MNNPackedMatMulRemainFP16_int4.S index 9045381af..d1f8ffb30 100644 --- a/source/backend/arm82/asm/arm64/low_memory/MNNPackedMatMulRemainFP16_int4.S +++ b/source/backend/arm82/asm/arm64/low_memory/MNNPackedMatMulRemainFP16_int4.S @@ -69,7 +69,7 @@ LoopE8: ld1 {v12.8h, v13.8h}, [x14], #32 // alpha mov w17, #0x0f dup v3.16b, w17 - mov w17, #7 + mov w17, #8 dup v4.16b, w17 ld1 {v14.8h, v15.8h}, [x16], #32 // bias subs x12, x9, #2 @@ -382,7 +382,7 @@ blt E1 ld1 {v24.8h, v25.8h}, [x14], #32 // alpha mov w17, #0x0f dup v30.16b, w17 - mov w17, #7 + mov w17, #8 dup v31.16b, w17 ld1 {v26.8h, v27.8h}, [x16], #32 // bias subs x12, x9, #2 @@ -565,7 +565,7 @@ blt E1 // mov v4.d[1], v4.d[0] mov w17, #0x0f dup v30.8b, w17 - mov w17, #7 + mov w17, #8 dup v31.8b, w17 ld1 {v14.8h}, [x16], #16 // bias // mov v14.d[1], v14.d[0] @@ -690,7 +690,7 @@ LoopE1: ld1 {v24.8h, v25.8h}, [x14], #32 // alpha mov w17, #0x0f dup v30.16b, w17 - mov w17, #7 + mov w17, #8 dup v31.16b, w17 ld1 {v26.8h, v27.8h}, [x16], #32 // bias subs x12, x9, #2 diff --git a/source/backend/coreml/backend/CoreMLBackend.cpp b/source/backend/coreml/backend/CoreMLBackend.cpp index 4abcb632b..0a8ee125e 100644 --- a/source/backend/coreml/backend/CoreMLBackend.cpp +++ b/source/backend/coreml/backend/CoreMLBackend.cpp @@ -127,8 +127,8 @@ namespace MNN { mCoreMLLayerPtrs.clear(); } - void CoreMLBackend::onResizeEnd() { - buildModel(); + ErrorCode CoreMLBackend::onResizeEnd() { + return buildModel(); } std::string CoreMLBackend::getTensorName(const Tensor* t) { @@ -226,7 +226,7 @@ namespace MNN { } *describe = des; } - void CoreMLBackend::buildModel() { + ErrorCode CoreMLBackend::buildModel() { mInputTensors.resize(mInputIdxMap.size()); mCoreMLModel_->description = create(); core_ml__specification__model_description__init(mCoreMLModel_->description); @@ -257,9 +257,14 @@ namespace MNN { } #endif if (mCoreMLModel_->neuralnetwork->n_layers <= 0) { - return; + return NO_EXECUTION; + } + bool success = mCoreMLExecutor->compileModel(mCoreMLModel_.get()); + if (success) { + return NO_ERROR; + } else { + return NO_EXECUTION; } - mCoreMLExecutor->compileModel(mCoreMLModel_.get()); } void CoreMLBackend::invokeModel() const { if (mCoreMLModel_->neuralnetwork->n_layers <= 0) { diff --git a/source/backend/coreml/backend/CoreMLBackend.hpp b/source/backend/coreml/backend/CoreMLBackend.hpp index 110cd72ca..121b18192 100644 --- a/source/backend/coreml/backend/CoreMLBackend.hpp +++ b/source/backend/coreml/backend/CoreMLBackend.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -57,7 +58,7 @@ namespace MNN { virtual void onCopyBuffer(const Tensor* srcTensor, const Tensor* dstTensor) const override; virtual void onResizeBegin() override; - virtual void onResizeEnd() override; + virtual ErrorCode onResizeEnd() override; public: // TODO: using memory pool instead static factory @@ -95,7 +96,7 @@ namespace MNN { } std::string getTensorName(const Tensor* t); void addLayer(CoreML__Specification__NeuralNetworkLayer* layer); - void buildModel(); + ErrorCode buildModel(); void invokeModel() const; void setIO(CoreML__Specification__FeatureDescription** describe, const Tensor* t); void setLayerName(CoreML__Specification__NeuralNetworkLayer* layer, std::string&& name); diff --git a/source/backend/coreml/execution/CoreMLConvolution.cpp b/source/backend/coreml/execution/CoreMLConvolution.cpp index ef3a490d0..560dba414 100644 --- a/source/backend/coreml/execution/CoreMLConvolution.cpp +++ b/source/backend/coreml/execution/CoreMLConvolution.cpp @@ -29,7 +29,7 @@ void CoreMLConvolution::loadWeightBias(const std::vector &inputs) { } auto conv2D = mOp->main_as_Convolution2D(); if (nullptr != conv2D->quanParameter()) { - quanCommon = ConvolutionCommon::load(conv2D->quanParameter(), true); + quanCommon = ConvolutionCommon::load(conv2D, backend(), true); if (nullptr == quanCommon) { MNN_ERROR("Memory not Enough, can't extract IDST Convolution: %s \n", mOp->name()->c_str()); } diff --git a/source/backend/cpu/CPUBackend.cpp b/source/backend/cpu/CPUBackend.cpp index e0ff195dc..6387335c7 100644 --- a/source/backend/cpu/CPUBackend.cpp +++ b/source/backend/cpu/CPUBackend.cpp @@ -247,12 +247,12 @@ void CPUBackend::onResizeBegin() { mDynamicAllocator->reset(); } -void CPUBackend::onResizeEnd() { +ErrorCode CPUBackend::onResizeEnd() { getCache()->release(); - mDynamicAllocator->compute(); + return mDynamicAllocator->compute(); } -Backend::MemObj* CPUBackend::allocBuffer(int size, Tensor* dest, StorageType storageType) { +Backend::MemObj* CPUBackend::allocBuffer(size_t size, Tensor* dest, StorageType storageType) { auto originMem = TensorUtils::getDescribe(dest)->mem.get(); if (nullptr != originMem) { if (static_cast(originMem)->getSize() >= size) { @@ -263,7 +263,7 @@ Backend::MemObj* CPUBackend::allocBuffer(int size, Tensor* dest, StorageType sto } // MNN_PRINT("Acquire size = %d\n", size); if (size <= 0) { - MNN_PRINT("Acquire buffer size = %d\n", size); + MNN_PRINT("Acquire buffer size = %lu\n", size); MNN_ASSERT(false); return nullptr; } @@ -337,19 +337,19 @@ static OpType _getRealOpType(OpType opType) { return opType; } } -int CPUBackend::getTensorSize(const Tensor* tensor, bool multiBytes) const { +size_t CPUBackend::getTensorSize(const Tensor* tensor, bool multiBytes) const { auto core = mCoreFunctions; - int dataSize = 1; + size_t dataSize = 1; auto des = TensorUtils::getDescribe(tensor); for (int i = 0; i < tensor->dimensions(); i++) { - int currentDimSize = tensor->length(i); + size_t currentDimSize = tensor->length(i); if (des->dimensionFormat == MNN_DATA_FORMAT_NC4HW4 && 1 == i) { currentDimSize = UP_DIV(currentDimSize, core->pack) * core->pack; } dataSize *= currentDimSize; } if (multiBytes) { - int bytes = tensor->getType().bytes(); + size_t bytes = tensor->getType().bytes(); if (TensorUtils::getDescribe(tensor)->quantAttr != nullptr) { if (TensorUtils::getDescribe(tensor)->type == DataType_DT_FLOAT) { bytes = 4; diff --git a/source/backend/cpu/CPUBackend.hpp b/source/backend/cpu/CPUBackend.hpp index 99bcf411a..f5746c4d1 100644 --- a/source/backend/cpu/CPUBackend.hpp +++ b/source/backend/cpu/CPUBackend.hpp @@ -91,13 +91,13 @@ class CPUBackend : public Backend { virtual void onExecuteEnd() const override; virtual void onResizeBegin() override; - virtual void onResizeEnd() override; + virtual ErrorCode onResizeEnd() override; const CoreFunctions* functions() const { return mCoreFunctions; } // Return element size for Tensor, conside pack - int getTensorSize(const Tensor* tensor, bool multiBytes = false) const; + size_t getTensorSize(const Tensor* tensor, bool multiBytes = false) const; const CoreInt8Functions* int8Functions() const { return mInt8CoreFunctions; } @@ -139,7 +139,7 @@ class CPUBackend : public Backend { protected: - MemObj* allocBuffer(int size, Tensor* dest, StorageType storageType); + MemObj* allocBuffer(size_t size, Tensor* dest, StorageType storageType); const CoreFunctions* mCoreFunctions; const CoreInt8Functions* mInt8CoreFunctions; private: diff --git a/source/backend/cpu/CPUCast.cpp b/source/backend/cpu/CPUCast.cpp index a109ebff0..f4bd13748 100644 --- a/source/backend/cpu/CPUCast.cpp +++ b/source/backend/cpu/CPUCast.cpp @@ -107,6 +107,27 @@ class Bit32ToBool : public Execution { return NO_ERROR; } }; +class BF16ToFP32 : public Execution { +public: + BF16ToFP32(Backend *b) : Execution(b) { + // nothing to do + } + virtual ~BF16ToFP32() = default; + + virtual ErrorCode onExecute(const std::vector &inputs, const std::vector &outputs) override { + auto input = inputs[0]; + auto output = outputs[0]; + auto srcData = input->host(); + auto dstData = output->host(); + const auto inputDataSize = input->elementSize(); + MNN_ASSERT(inputDataSize == output->elementSize()); + for (int i = 0; i < inputDataSize; i++) { + dstData[i * 2] = 0; + dstData[i * 2 + 1] = srcData[i]; + } + return NO_ERROR; + } +}; class CopyExecution : public Execution { public: CopyExecution(Backend *b) : Execution(b) { @@ -168,6 +189,9 @@ Execution *CPUCastCreator::onCreate(const std::vector &inputs, const s if (dstT == MNN::DataType_DT_FLOAT && halide_type_of() == inputDataType) { return new CastDataType(backend); } + if (dstT == MNN::DataType_DT_FLOAT && halide_type_t(halide_type_float, 16) == inputDataType) { + return new BF16ToFP32(backend); + } if (dstT == MNN::DataType_DT_INT8 && halide_type_of() == inputDataType) { return new CastDataType(backend); } diff --git a/source/backend/cpu/CPUConvolution.cpp b/source/backend/cpu/CPUConvolution.cpp index 652c03cb5..07c59450f 100644 --- a/source/backend/cpu/CPUConvolution.cpp +++ b/source/backend/cpu/CPUConvolution.cpp @@ -143,7 +143,7 @@ std::shared_ptr CPUConvolution::makeResourceInt8(B int weightSize = 0; std::shared_ptr quanCommon; resource->mOutputCount = outputCount; - if (!ConvolutionCommon::getConvInt8Parameters(convParam, quanCommon, weightSrc, weightSize, scalePtr, biasPtr)) { + if (!ConvolutionCommon::getConvInt8Parameters(convParam, quanCommon, backend, weightSrc, weightSize, scalePtr, biasPtr)) { return nullptr; } if (convParam->bias() && convParam->quanParameter()->alpha()) { diff --git a/source/backend/cpu/CPUConvolutionDepthwise.cpp b/source/backend/cpu/CPUConvolutionDepthwise.cpp index 5734a7a71..c4f97fd46 100644 --- a/source/backend/cpu/CPUConvolutionDepthwise.cpp +++ b/source/backend/cpu/CPUConvolutionDepthwise.cpp @@ -263,7 +263,7 @@ class CPUConvolutionDepthwiseCreator : public CPUBackend::Creator { std::shared_ptr quanCommon; std::unique_ptr externalWeightTensor, externalBiasTensor; if (nullptr != conv2d->quanParameter()) { - quanCommon = ConvolutionCommon::load(conv2d->quanParameter(), true); + quanCommon = ConvolutionCommon::load(conv2d, backend, true); // Back to float originWeight = quanCommon->weightFloat.get(); originWeightSize = quanCommon->weightFloat.size(); diff --git a/source/backend/cpu/CPUDeconvolution.cpp b/source/backend/cpu/CPUDeconvolution.cpp index 5d5b076c6..8ea929e8a 100644 --- a/source/backend/cpu/CPUDeconvolution.cpp +++ b/source/backend/cpu/CPUDeconvolution.cpp @@ -168,7 +168,7 @@ CPUDeconvolution::CPUDeconvolution(const Tensor* input, const Op* convOp, Backen auto biasPtr = _bias.data(); auto scalePtr = _scale.data(); - if (USE_EXTERNAL_DATA(conv2d)) { + if (USE_EXTERNAL_DATA(conv2d) && conv2d->quanParameter() == nullptr) { auto bytes = conv2d->external()->Get(1); tempWeightSize = static_cast(bytes / sizeof(float)); externalWeightTensor.reset(Tensor::createDevice({tempWeightSize})); @@ -181,10 +181,10 @@ CPUDeconvolution::CPUDeconvolution(const Tensor* input, const Op* convOp, Backen tempWeight = externalWeightTensor->host(); } else { if (CPUBackend::getDataType(input) == DataType_DT_INT8 || input->getType().bytes() == 1) { - ConvolutionCommon::getConvInt8Parameters(conv2d, quanCommon, quanWeightInt8, tempWeightSize, scalePtr, biasPtr); + ConvolutionCommon::getConvInt8Parameters(conv2d, quanCommon, backend, quanWeightInt8, tempWeightSize, scalePtr, biasPtr); ModeInt8 = true; } else { - ConvolutionCommon::getConvParameters(&quanCommon, conv2d, &tempWeight, &tempWeightSize); + ConvolutionCommon::getConvParameters(&quanCommon, backend, conv2d, &tempWeight, &tempWeightSize); } } diff --git a/source/backend/cpu/CPUDeconvolutionDepthwise.cpp b/source/backend/cpu/CPUDeconvolutionDepthwise.cpp index 35e9e64fa..b25112433 100644 --- a/source/backend/cpu/CPUDeconvolutionDepthwise.cpp +++ b/source/backend/cpu/CPUDeconvolutionDepthwise.cpp @@ -27,7 +27,7 @@ CPUDeconvolutionDepthwise::CPUDeconvolutionDepthwise(const Tensor* input, const const float* tempWeight = nullptr; int tempWeightSize = 0; std::shared_ptr quanCommon; - ConvolutionCommon::getConvParameters(&quanCommon, conv, &tempWeight, &tempWeightSize); + ConvolutionCommon::getConvParameters(&quanCommon, b, conv, &tempWeight, &tempWeightSize); // Reorder weight from whc -> pwhc4 int kernelSize = depthQuad * core->pack * kw * kh; diff --git a/source/backend/cpu/CPURaster.cpp b/source/backend/cpu/CPURaster.cpp index a1c8375c8..d49b7795f 100644 --- a/source/backend/cpu/CPURaster.cpp +++ b/source/backend/cpu/CPURaster.cpp @@ -805,7 +805,7 @@ class CPULoop : public Execution { auto inputSize = input->elementSize(); auto output = mStack[cmd->indexes()->data()[0]]; auto bytes = input->getType().bytes(); - if (halide_type_float == input->getType().code) { + if (halide_type_float == input->getType().code && bytes == 4) { bytes = cpubackend->functions()->bytes; } auto proc = _selectUnitProc(bytes); @@ -844,7 +844,7 @@ class CPULoop : public Execution { auto inputSize = input->elementSize(); auto output = mStack[cmd->indexes()->data()[0]]; auto bytes = input->getType().bytes(); - if (halide_type_float == input->getType().code) { + if (halide_type_float == input->getType().code && bytes == 4) { bytes = static_cast(backend())->functions()->bytes; } auto proc = _selectUnitProc(bytes); diff --git a/source/backend/cpu/CPUTensorConvert.cpp b/source/backend/cpu/CPUTensorConvert.cpp index 4e90eb7ca..10faca0f6 100644 --- a/source/backend/cpu/CPUTensorConvert.cpp +++ b/source/backend/cpu/CPUTensorConvert.cpp @@ -288,9 +288,9 @@ ErrorCode CPUTensorConverter::convert(const Tensor* input, const Tensor* output, if (nullptr == core) { core = MNNGetCoreFunctions(); } - int bitLength = _getBytes(core, input); + size_t bitLength = _getBytes(core, input); if (ib.dimensions <= 1 || source == dest) { - int dataSize = 1; + size_t dataSize = 1; for (int i = 0; i < input->dimensions(); i++) { int currentDimSize = input->length(i); if (source == MNN_DATA_FORMAT_NC4HW4 && 1 == i) { @@ -298,6 +298,8 @@ ErrorCode CPUTensorConverter::convert(const Tensor* input, const Tensor* output, } dataSize *= currentDimSize; } + // printf("convert # dataSize, bitLength = %d, %d\n", dataSize, bitLength); + // fflush(stdout); ::memcpy(ob.host, ib.host, dataSize * bitLength); return NO_ERROR; } diff --git a/source/backend/cpu/OneDNNConvInt8.cpp b/source/backend/cpu/OneDNNConvInt8.cpp index 7bc09d19a..db8a5ec43 100644 --- a/source/backend/cpu/OneDNNConvInt8.cpp +++ b/source/backend/cpu/OneDNNConvInt8.cpp @@ -68,7 +68,7 @@ Execution* OneDNNConvInt8::create(Backend* backend, const MNN::Convolution2D* co } std::shared_ptr quanCommon; if (convParam->quanParameter() != nullptr) { - quanCommon = ConvolutionCommon::load(convParam->quanParameter(), false); + quanCommon = ConvolutionCommon::load(convParam, backend(), false); weightSrc = quanCommon->weight.get(); } auto user_weights = memory(user_weights_md, eng, (int8_t*)weightSrc); diff --git a/source/backend/cpu/arm/arm64/low_memory/MNNPackedMatMulRemain_int4.S b/source/backend/cpu/arm/arm64/low_memory/MNNPackedMatMulRemain_int4.S index 1d8ec8e1e..3c4a6ffcc 100644 --- a/source/backend/cpu/arm/arm64/low_memory/MNNPackedMatMulRemain_int4.S +++ b/source/backend/cpu/arm/arm64/low_memory/MNNPackedMatMulRemain_int4.S @@ -65,7 +65,7 @@ LoopE8: ld1 {v12.4s, v13.4s}, [x14], #32 // alpha mov w17, #0x0f dup v3.8b, w17 - mov w17, #7 + mov w17, #8 dup v4.8b, w17 ld1 {v14.4s, v15.4s}, [x16], #32 // bias subs x12, x9, #2 @@ -299,7 +299,7 @@ LoopE8: ld1 {v4.4s}, [x14], #16 // alpha mov w17, #0x0f dup v30.8b, w17 - mov w17, #7 + mov w17, #8 dup v31.8b, w17 ld1 {v14.4s}, [x16], #16 // bias subs x12, x9, #4 @@ -544,7 +544,7 @@ blt E1 ld1 {v24.4s, v25.4s}, [x14], #32 // alpha mov w17, #0x0f dup v30.8b, w17 - mov w17, #7 + mov w17, #8 dup v31.8b, w17 ld1 {v26.4s, v27.4s}, [x16], #32 // bias subs x12, x9, #2 @@ -734,7 +734,7 @@ blt E1 ld1 {v4.4s}, [x14], #16 // alpha mov w17, #0x0f dup v30.8b, w17 - mov w17, #7 + mov w17, #8 dup v31.8b, w17 ld1 {v14.4s}, [x16], #16 // bias subs x12, x9, #4 @@ -933,7 +933,7 @@ LoopE1: ld1 {v24.4s, v25.4s}, [x14], #32 // alpha mov w17, #0x0f dup v30.8b, w17 - mov w17, #7 + mov w17, #8 dup v31.8b, w17 ld1 {v26.4s, v27.4s}, [x16], #32 // bias subs x12, x9, #2 @@ -1039,7 +1039,7 @@ LoopE1: ld1 {v4.4s}, [x14], #16 // alpha mov w17, #0x0f dup v30.8b, w17 - mov w17, #7 + mov w17, #8 dup v31.8b, w17 ld1 {v14.4s}, [x16], #16 // bias subs x12, x9, #4 diff --git a/source/backend/cpu/arm/arm64/low_memory/MNNPackedMatMul_int4.S b/source/backend/cpu/arm/arm64/low_memory/MNNPackedMatMul_int4.S index a92a23c35..b178eecc7 100644 --- a/source/backend/cpu/arm/arm64/low_memory/MNNPackedMatMul_int4.S +++ b/source/backend/cpu/arm/arm64/low_memory/MNNPackedMatMul_int4.S @@ -57,7 +57,7 @@ LoopH: mov w17, #0x0f dup v3.8b, w17 and v2.8b, v0.8b, v3.8b - mov w17, #7 + mov w17, #8 dup v3.8b, w17 sub v0.8b, v1.8b, v3.8b sub v1.8b, v2.8b, v3.8b @@ -153,7 +153,7 @@ LoopH: mov w17, #0x0f dup v3.8b, w17 and v2.8b, v0.8b, v3.8b - mov w17, #7 + mov w17, #8 dup v3.8b, w17 sub v0.8b, v1.8b, v3.8b sub v1.8b, v2.8b, v3.8b @@ -370,7 +370,7 @@ LoopHRemain: ld1 {v21.4s}, [x20], #16 // bias mov w17, #0x0f dup v22.16b, w17 - mov w17, #7 + mov w17, #8 dup v23.16b, w17 // ld1 {v3.4s}, [x2] ld1 {v3.8h}, [x2], #16 diff --git a/source/backend/cpu/bf16/BF16Backend.cpp b/source/backend/cpu/bf16/BF16Backend.cpp index 2b99ab4ae..81f3b8305 100644 --- a/source/backend/cpu/bf16/BF16Backend.cpp +++ b/source/backend/cpu/bf16/BF16Backend.cpp @@ -48,11 +48,11 @@ Execution* BF16Backend::onCreate(const std::vector& inputs, const std:: return nullptr; } -static int _getAliginSize(const halide_buffer_t& buffer, MNN_DATA_FORMAT format) { +static size_t _getAliginSize(const halide_buffer_t& buffer, MNN_DATA_FORMAT format) { // The default data type of input tensor for arm82 backend is FLOAT32. // However, BF16Backend default data type is FLOAT16, so check whether data type is FLOAT32, // then divide size by 2 - int size = sizeof(int16_t); + size_t size = sizeof(int16_t); const int dimensions = buffer.dimensions; for (int i = 0; i < dimensions; i++) { int currentDimSize = buffer.dim[i].extent; diff --git a/source/backend/cpu/compute/ConvolutionFloatFactory.cpp b/source/backend/cpu/compute/ConvolutionFloatFactory.cpp index e5f1e355f..8fe542259 100644 --- a/source/backend/cpu/compute/ConvolutionFloatFactory.cpp +++ b/source/backend/cpu/compute/ConvolutionFloatFactory.cpp @@ -102,7 +102,7 @@ Execution* ConvolutionFloatFactory::create(const std::vector& inputs, c // The weight is storage as float sparse, but the backend don't support sparse compute, expand it forceFloat = true; } - quanCommon = ConvolutionCommon::load(conv2d->quanParameter(), forceFloat, lowMemory); + quanCommon = ConvolutionCommon::load(conv2d, backend, forceFloat, lowMemory); if (nullptr == quanCommon) { MNN_ERROR("Memory not Enough, can't extract IDST Convolution: %s \n", op->name()->c_str()); return nullptr; diff --git a/source/backend/cpu/compute/DeconvolutionWithStride.cpp b/source/backend/cpu/compute/DeconvolutionWithStride.cpp index 8c1605060..0e5bef65f 100644 --- a/source/backend/cpu/compute/DeconvolutionWithStride.cpp +++ b/source/backend/cpu/compute/DeconvolutionWithStride.cpp @@ -177,7 +177,7 @@ DeconvolutionWithStride::DeconvolutionWithStride(const Tensor* input, const Op* int tempWeightSize = 0; int srcCount = 0; std::shared_ptr quanCommon; - ConvolutionCommon::getConvParameters(&quanCommon, conv2D, &tempWeight, &tempWeightSize); + ConvolutionCommon::getConvParameters(&quanCommon, b, conv2D, &tempWeight, &tempWeightSize); srcCount = tempWeightSize / kx / ky / outputCount; int sy = common->strideY(); @@ -270,7 +270,7 @@ void DeconvolutionWithStride::_extract(const Op* convOp) { int tempWeightSize = 0; int srcCount = 0; std::shared_ptr quanCommon; - ConvolutionCommon::getConvParameters(&quanCommon, conv2D, &tempWeight, &tempWeightSize); + ConvolutionCommon::getConvParameters(&quanCommon, backend(), conv2D, &tempWeight, &tempWeightSize); srcCount = tempWeightSize / kx / ky / outputCount; std::shared_ptr weightWrap( diff --git a/source/backend/cpu/compute/DenseConvolutionTiledExecutor.cpp b/source/backend/cpu/compute/DenseConvolutionTiledExecutor.cpp index ea6a2c700..615d33ddb 100644 --- a/source/backend/cpu/compute/DenseConvolutionTiledExecutor.cpp +++ b/source/backend/cpu/compute/DenseConvolutionTiledExecutor.cpp @@ -109,7 +109,7 @@ static bool _initQuantizeResource(std::shared_ptr for (int i=0; imWeight = weightLow; diff --git a/source/backend/cpu/compute/SparseConvolutionTiledExecutor.cpp b/source/backend/cpu/compute/SparseConvolutionTiledExecutor.cpp index 68b2b766b..c74ac33a5 100644 --- a/source/backend/cpu/compute/SparseConvolutionTiledExecutor.cpp +++ b/source/backend/cpu/compute/SparseConvolutionTiledExecutor.cpp @@ -211,8 +211,6 @@ SparseConvolutionTiledExecutor::SparseConvolutionTiledExecutor(const Convolution weightNNZElement = optimalWeightNNZElement; weightBlockNumber = optimalWeightBlockNumber; } - MNN_ASSERT(weightNNZElement > 0); - MNN_ASSERT(weightBlockNumber > 0); mSparseIndexData.reset(new SparseIndexData(sparseBlockOC, weightNNZElement, weightBlockNumber, backend())); diff --git a/source/backend/cpu/x86_x64/avx/GemmFunction.hpp b/source/backend/cpu/x86_x64/avx/GemmFunction.hpp index e699ee615..3d45a2ec1 100644 --- a/source/backend/cpu/x86_x64/avx/GemmFunction.hpp +++ b/source/backend/cpu/x86_x64/avx/GemmFunction.hpp @@ -832,7 +832,7 @@ static inline __m128 _load_int4x4(const uint8_t* src, __m128 alpha, __m128 bias) int iw2 = iw23 / 16; int iw3 = iw23 % 16; auto ws = _mm_set_ps(iw3, iw2, iw1, iw0); - ws = _mm_sub_ps(ws, _mm_set1_ps(7)); + ws = _mm_sub_ps(ws, _mm_set1_ps(8)); ws = _mm_add_ps(_mm_mul_ps(ws, alpha), bias); return ws; } @@ -843,8 +843,8 @@ static inline __m256 _load_int4x8(const uint8_t* src, __m256 alpha, __m256 bias) int x = src[i]; int a = x / 16; int b = x % 16; - w[i * 2] = a - 7; - w[i * 2 + 1] = b - 7; + w[i * 2] = a - 8; + w[i * 2 + 1] = b - 8; } auto w8 = LOAD8(w); return _mm256_add_ps(_mm256_mul_ps(w8, alpha), bias); @@ -860,6 +860,7 @@ static void _AVX_MNNPackedMatMul_Main_int4(TYPE* C, const TYPE* A, const TYPE* f auto bExtraStride = parameter[5] / sizeof(TYPE); auto bStride = bExtraStride + l * 4; auto hC4 = UP_DIV(h, 4); + float ws_tmp[4]; for (int y = 0; y < hC4; ++y) { auto weight = B + y * bStride / 2; auto dst = C + (y / 2) * cStride + 4 * (y % 2); @@ -869,10 +870,11 @@ static void _AVX_MNNPackedMatMul_Main_int4(TYPE* C, const TYPE* A, const TYPE* f auto s1 = LOAD8(A + 0 * 24 + 8); auto s2 = LOAD8(A + 0 * 24 + 16); auto ws = _load_int4x4(weight, alpha, bias); - auto w0 = _mm256_set1_ps(ws[0]); - auto w1 = _mm256_set1_ps(ws[1]); - auto w2 = _mm256_set1_ps(ws[2]); - auto w3 = _mm256_set1_ps(ws[3]); + _mm_storeu_ps(ws_tmp, ws); + auto w0 = _mm256_set1_ps(ws_tmp[0]); + auto w1 = _mm256_set1_ps(ws_tmp[1]); + auto w2 = _mm256_set1_ps(ws_tmp[2]); + auto w3 = _mm256_set1_ps(ws_tmp[3]); auto z0 = _mm256_mul_ps(s0, w0); auto z1 = _mm256_mul_ps(s1, w0); auto z2 = _mm256_mul_ps(s2, w0); @@ -891,10 +893,11 @@ static void _AVX_MNNPackedMatMul_Main_int4(TYPE* C, const TYPE* A, const TYPE* f s1 = LOAD8(A + sy * 24 + 8); s2 = LOAD8(A + sy * 24 + 16); ws = _load_int4x4(weight + sy * 2, alpha, bias); - w0 = _mm256_set1_ps(ws[0]); - w1 = _mm256_set1_ps(ws[1]); - w2 = _mm256_set1_ps(ws[2]); - w3 = _mm256_set1_ps(ws[3]); + _mm_storeu_ps(ws_tmp, ws); + w0 = _mm256_set1_ps(ws_tmp[0]); + w1 = _mm256_set1_ps(ws_tmp[1]); + w2 = _mm256_set1_ps(ws_tmp[2]); + w3 = _mm256_set1_ps(ws_tmp[3]); z0 = MNNAVXFMA(s0, w0, z0); z1 = MNNAVXFMA(s1, w0, z1); z2 = MNNAVXFMA(s2, w0, z2); @@ -927,6 +930,7 @@ static void _AVX_MNNPackedMatMul_int4_20(TYPE* C, const TYPE* A, const uint8_t* auto bExtraStride = parameter[5] / sizeof(TYPE); auto bStride = bExtraStride + l * 4; auto hC4 = UP_DIV(h, 4); + float ws_tmp[4]; for (int y = 0; y < hC4; ++y) { auto weight = B + y * bStride / 2; auto dst = C + (y / 2) * cStride + 4 * (y % 2); @@ -936,10 +940,11 @@ static void _AVX_MNNPackedMatMul_int4_20(TYPE* C, const TYPE* A, const uint8_t* auto s1 = LOAD8(A + 0 * aStride + 8); auto s2 = EXPAND_128(LOAD4(A + 0 * aStride + 16)); auto ws = _load_int4x4(weight, alpha, bias); - auto w0 = _mm256_set1_ps(ws[0]); - auto w1 = _mm256_set1_ps(ws[1]); - auto w2 = _mm256_set1_ps(ws[2]); - auto w3 = _mm256_set1_ps(ws[3]); + _mm_storeu_ps(ws_tmp, ws); + auto w0 = _mm256_set1_ps(ws_tmp[0]); + auto w1 = _mm256_set1_ps(ws_tmp[1]); + auto w2 = _mm256_set1_ps(ws_tmp[2]); + auto w3 = _mm256_set1_ps(ws_tmp[3]); auto z0 = _mm256_mul_ps(s0, w0); auto z1 = _mm256_mul_ps(s1, w0); auto z2 = _mm256_mul_ps(s2, w0); @@ -957,10 +962,11 @@ static void _AVX_MNNPackedMatMul_int4_20(TYPE* C, const TYPE* A, const uint8_t* s1 = LOAD8(A + sy * aStride + 8); s2 = EXPAND_128(LOAD4(A + sy * aStride + 16)); ws = _load_int4x4(weight + sy * 2, alpha, bias); - w0 = _mm256_set1_ps(ws[0]); - w1 = _mm256_set1_ps(ws[1]); - w2 = _mm256_set1_ps(ws[2]); - w3 = _mm256_set1_ps(ws[3]); + _mm_storeu_ps(ws_tmp, ws); + w0 = _mm256_set1_ps(ws_tmp[0]); + w1 = _mm256_set1_ps(ws_tmp[1]); + w2 = _mm256_set1_ps(ws_tmp[2]); + w3 = _mm256_set1_ps(ws_tmp[3]); z0 = MNNAVXFMA(s0, w0, z0); z1 = MNNAVXFMA(s1, w0, z1); z2 = MNNAVXFMA(s2, w0, z2); @@ -991,6 +997,7 @@ static void _AVX_MNNPackedMatMul_int4_16(TYPE* C, const TYPE* A, const uint8_t* auto bExtraStride = parameter[5] / sizeof(TYPE); auto bStride = bExtraStride + l * 4; auto hC4 = UP_DIV(h, 4); + float ws_tmp[4]; for (int y = 0; y < hC4; ++y) { auto weight = B + y * bStride; auto dst = C + (y / 2) * cStride + 4 * (y % 2); @@ -999,10 +1006,11 @@ static void _AVX_MNNPackedMatMul_int4_16(TYPE* C, const TYPE* A, const uint8_t* auto s0 = LOAD8(A + 0 * aStride); auto s1 = LOAD8(A + 0 * aStride + 8); auto ws = _load_int4x4(weight, alpha, bias); - auto w0 = _mm256_set1_ps(ws[0]); - auto w1 = _mm256_set1_ps(ws[1]); - auto w2 = _mm256_set1_ps(ws[2]); - auto w3 = _mm256_set1_ps(ws[3]); + _mm_storeu_ps(ws_tmp, ws); + auto w0 = _mm256_set1_ps(ws_tmp[0]); + auto w1 = _mm256_set1_ps(ws_tmp[1]); + auto w2 = _mm256_set1_ps(ws_tmp[2]); + auto w3 = _mm256_set1_ps(ws_tmp[3]); auto z0 = _mm256_mul_ps(s0, w0); auto z1 = _mm256_mul_ps(s1, w0); auto z3 = _mm256_mul_ps(s0, w1); @@ -1015,10 +1023,11 @@ static void _AVX_MNNPackedMatMul_int4_16(TYPE* C, const TYPE* A, const uint8_t* s0 = LOAD8(A + sy * aStride); s1 = LOAD8(A + sy * aStride + 8); ws = _load_int4x4(weight + sy * 2, alpha, bias); - w0 = _mm256_set1_ps(ws[0]); - w1 = _mm256_set1_ps(ws[1]); - w2 = _mm256_set1_ps(ws[2]); - w3 = _mm256_set1_ps(ws[3]); + _mm_storeu_ps(ws_tmp, ws); + w0 = _mm256_set1_ps(ws_tmp[0]); + w1 = _mm256_set1_ps(ws_tmp[1]); + w2 = _mm256_set1_ps(ws_tmp[2]); + w3 = _mm256_set1_ps(ws_tmp[3]); z0 = MNNAVXFMA(s0, w0, z0); z1 = MNNAVXFMA(s1, w0, z1); z3 = MNNAVXFMA(s0, w1, z3); @@ -1226,6 +1235,7 @@ static void _AVX_MNNPackedMatMul_int4_4(TYPE* C, const TYPE* A, const uint8_t* B STORE_8(dst2 + 16, sumAvx21); STORE_8(dst2 + 24, sumAvx31); } + float ws_tmp[4]; for (int y = hR; y < hC4; ++y) { auto weight = B + y * bStride / 2; auto dst = C + (y / 2) * cStride + 4 * (y % 2); @@ -1233,10 +1243,11 @@ static void _AVX_MNNPackedMatMul_int4_4(TYPE* C, const TYPE* A, const uint8_t* B auto bias = _mm_loadu_ps(b + y * 4); auto s0 = LOAD4(A + 0 * aStride); auto ws = _load_int4x4(weight, alpha, bias); - auto w0 = _mm_set1_ps(ws[0]); - auto w1 = _mm_set1_ps(ws[1]); - auto w2 = _mm_set1_ps(ws[2]); - auto w3 = _mm_set1_ps(ws[3]); + _mm_storeu_ps(ws_tmp, ws); + auto w0 = _mm_set1_ps(ws_tmp[0]); + auto w1 = _mm_set1_ps(ws_tmp[1]); + auto w2 = _mm_set1_ps(ws_tmp[2]); + auto w3 = _mm_set1_ps(ws_tmp[3]); auto z0 = _mm_mul_ps(s0, w0); auto z3 = _mm_mul_ps(s0, w1); auto z6 = _mm_mul_ps(s0, w2); @@ -1245,10 +1256,11 @@ static void _AVX_MNNPackedMatMul_int4_4(TYPE* C, const TYPE* A, const uint8_t* B for (int sy = 1; sy < l; ++sy) { s0 = LOAD4(A + sy * aStride); ws = _load_int4x4(weight + sy * 2, alpha, bias); - w0 = _mm_set1_ps(ws[0]); - w1 = _mm_set1_ps(ws[1]); - w2 = _mm_set1_ps(ws[2]); - w3 = _mm_set1_ps(ws[3]); + _mm_storeu_ps(ws_tmp, ws); + w0 = _mm_set1_ps(ws_tmp[0]); + w1 = _mm_set1_ps(ws_tmp[1]); + w2 = _mm_set1_ps(ws_tmp[2]); + w3 = _mm_set1_ps(ws_tmp[3]); z0 = MNNSSEFMA(s0, w0, z0); z3 = MNNSSEFMA(s0, w1, z3); z6 = MNNSSEFMA(s0, w2, z6); @@ -1666,6 +1678,7 @@ static void _AVX_MNNPackedMatMul_Main_int8(TYPE* C, const TYPE* A, const TYPE* f auto bExtraStride = parameter[5] / sizeof(TYPE); auto bStride = bExtraStride + l * 4; auto hC4 = UP_DIV(h, 4); + float ws_tmp[4]; for (int y = 0; y < hC4; ++y) { auto weight = B + y * bStride; auto dst = C + (y / 2) * cStride + 4 * (y % 2); @@ -1675,10 +1688,11 @@ static void _AVX_MNNPackedMatMul_Main_int8(TYPE* C, const TYPE* A, const TYPE* f auto s1 = LOAD8(A + 0 * 24 + 8); auto s2 = LOAD8(A + 0 * 24 + 16); auto ws = _load_int8x4(weight, alpha, bias); - auto w0 = _mm256_set1_ps(ws[0]); - auto w1 = _mm256_set1_ps(ws[1]); - auto w2 = _mm256_set1_ps(ws[2]); - auto w3 = _mm256_set1_ps(ws[3]); + _mm_storeu_ps(ws_tmp, ws); + auto w0 = _mm256_set1_ps(ws_tmp[0]); + auto w1 = _mm256_set1_ps(ws_tmp[1]); + auto w2 = _mm256_set1_ps(ws_tmp[2]); + auto w3 = _mm256_set1_ps(ws_tmp[3]); auto z0 = _mm256_mul_ps(s0, w0); auto z1 = _mm256_mul_ps(s1, w0); auto z2 = _mm256_mul_ps(s2, w0); @@ -1697,10 +1711,11 @@ static void _AVX_MNNPackedMatMul_Main_int8(TYPE* C, const TYPE* A, const TYPE* f s1 = LOAD8(A + sy * 24 + 8); s2 = LOAD8(A + sy * 24 + 16); ws = _load_int8x4(weight + sy * 4, alpha, bias); - w0 = _mm256_set1_ps(ws[0]); - w1 = _mm256_set1_ps(ws[1]); - w2 = _mm256_set1_ps(ws[2]); - w3 = _mm256_set1_ps(ws[3]); + _mm_storeu_ps(ws_tmp, ws); + w0 = _mm256_set1_ps(ws_tmp[0]); + w1 = _mm256_set1_ps(ws_tmp[1]); + w2 = _mm256_set1_ps(ws_tmp[2]); + w3 = _mm256_set1_ps(ws_tmp[3]); z0 = MNNAVXFMA(s0, w0, z0); z1 = MNNAVXFMA(s1, w0, z1); z2 = MNNAVXFMA(s2, w0, z2); @@ -1733,6 +1748,7 @@ static void _AVX_MNNPackedMatMul_int8_20(TYPE* C, const TYPE* A, const int8_t* B auto bExtraStride = parameter[5] / sizeof(TYPE); auto bStride = bExtraStride + l * 4; auto hC4 = UP_DIV(h, 4); + float ws_tmp[4]; for (int y = 0; y < hC4; ++y) { auto weight = B + y * bStride; auto dst = C + (y / 2) * cStride + 4 * (y % 2); @@ -1742,10 +1758,11 @@ static void _AVX_MNNPackedMatMul_int8_20(TYPE* C, const TYPE* A, const int8_t* B auto s1 = LOAD8(A + 0 * aStride + 8); auto s2 = EXPAND_128(LOAD4(A + 0 * aStride + 16)); auto ws = _load_int8x4(weight, alpha, bias); - auto w0 = _mm256_set1_ps(ws[0]); - auto w1 = _mm256_set1_ps(ws[1]); - auto w2 = _mm256_set1_ps(ws[2]); - auto w3 = _mm256_set1_ps(ws[3]); + _mm_storeu_ps(ws_tmp, ws); + auto w0 = _mm256_set1_ps(ws_tmp[0]); + auto w1 = _mm256_set1_ps(ws_tmp[1]); + auto w2 = _mm256_set1_ps(ws_tmp[2]); + auto w3 = _mm256_set1_ps(ws_tmp[3]); auto z0 = _mm256_mul_ps(s0, w0); auto z1 = _mm256_mul_ps(s1, w0); auto z2 = _mm256_mul_ps(s2, w0); @@ -1763,10 +1780,11 @@ static void _AVX_MNNPackedMatMul_int8_20(TYPE* C, const TYPE* A, const int8_t* B s1 = LOAD8(A + sy * aStride + 8); s2 = EXPAND_128(LOAD4(A + sy * aStride + 16)); ws = _load_int8x4(weight + sy * 4, alpha, bias); - w0 = _mm256_set1_ps(ws[0]); - w1 = _mm256_set1_ps(ws[1]); - w2 = _mm256_set1_ps(ws[2]); - w3 = _mm256_set1_ps(ws[3]); + _mm_storeu_ps(ws_tmp, ws); + w0 = _mm256_set1_ps(ws_tmp[0]); + w1 = _mm256_set1_ps(ws_tmp[1]); + w2 = _mm256_set1_ps(ws_tmp[2]); + w3 = _mm256_set1_ps(ws_tmp[3]); z0 = MNNAVXFMA(s0, w0, z0); z1 = MNNAVXFMA(s1, w0, z1); z2 = MNNAVXFMA(s2, w0, z2); @@ -1797,6 +1815,7 @@ static void _AVX_MNNPackedMatMul_int8_16(TYPE* C, const TYPE* A, const int8_t* B auto bExtraStride = parameter[5] / sizeof(TYPE); auto bStride = bExtraStride + l * 4; auto hC4 = UP_DIV(h, 4); + float ws_tmp[4]; for (int y = 0; y < hC4; ++y) { auto weight = B + y * bStride; auto dst = C + (y / 2) * cStride + 4 * (y % 2); @@ -1805,10 +1824,11 @@ static void _AVX_MNNPackedMatMul_int8_16(TYPE* C, const TYPE* A, const int8_t* B auto s0 = LOAD8(A + 0 * aStride); auto s1 = LOAD8(A + 0 * aStride + 8); auto ws = _load_int8x4(weight, alpha, bias); - auto w0 = _mm256_set1_ps(ws[0]); - auto w1 = _mm256_set1_ps(ws[1]); - auto w2 = _mm256_set1_ps(ws[2]); - auto w3 = _mm256_set1_ps(ws[3]); + _mm_storeu_ps(ws_tmp, ws); + auto w0 = _mm256_set1_ps(ws_tmp[0]); + auto w1 = _mm256_set1_ps(ws_tmp[1]); + auto w2 = _mm256_set1_ps(ws_tmp[2]); + auto w3 = _mm256_set1_ps(ws_tmp[3]); auto z0 = _mm256_mul_ps(s0, w0); auto z1 = _mm256_mul_ps(s1, w0); auto z3 = _mm256_mul_ps(s0, w1); @@ -1821,10 +1841,11 @@ static void _AVX_MNNPackedMatMul_int8_16(TYPE* C, const TYPE* A, const int8_t* B s0 = LOAD8(A + sy * aStride); s1 = LOAD8(A + sy * aStride + 8); ws = _load_int8x4(weight + sy * 4, alpha, bias); - w0 = _mm256_set1_ps(ws[0]); - w1 = _mm256_set1_ps(ws[1]); - w2 = _mm256_set1_ps(ws[2]); - w3 = _mm256_set1_ps(ws[3]); + _mm_storeu_ps(ws_tmp, ws); + w0 = _mm256_set1_ps(ws_tmp[0]); + w1 = _mm256_set1_ps(ws_tmp[1]); + w2 = _mm256_set1_ps(ws_tmp[2]); + w3 = _mm256_set1_ps(ws_tmp[3]); z0 = MNNAVXFMA(s0, w0, z0); z1 = MNNAVXFMA(s1, w0, z1); z3 = MNNAVXFMA(s0, w1, z3); @@ -2032,6 +2053,7 @@ static void _AVX_MNNPackedMatMul_int8_4(TYPE* C, const TYPE* A, const int8_t* B, STORE_8(dst2 + 16, sumAvx21); STORE_8(dst2 + 24, sumAvx31); } + float ws_tmp[4]; for (int y = hR; y < hC4; ++y) { auto weight = B + y * bStride; auto dst = C + (y / 2) * cStride + 4 * (y % 2); @@ -2039,10 +2061,11 @@ static void _AVX_MNNPackedMatMul_int8_4(TYPE* C, const TYPE* A, const int8_t* B, auto bias = _mm_loadu_ps(b + y * 4); auto s0 = LOAD4(A + 0 * aStride); auto ws = _load_int8x4(weight, alpha, bias); - auto w0 = _mm_set1_ps(ws[0]); - auto w1 = _mm_set1_ps(ws[1]); - auto w2 = _mm_set1_ps(ws[2]); - auto w3 = _mm_set1_ps(ws[3]); + _mm_storeu_ps(ws_tmp, ws); + auto w0 = _mm_set1_ps(ws_tmp[0]); + auto w1 = _mm_set1_ps(ws_tmp[1]); + auto w2 = _mm_set1_ps(ws_tmp[2]); + auto w3 = _mm_set1_ps(ws_tmp[3]); auto z0 = _mm_mul_ps(s0, w0); auto z3 = _mm_mul_ps(s0, w1); auto z6 = _mm_mul_ps(s0, w2); @@ -2051,10 +2074,11 @@ static void _AVX_MNNPackedMatMul_int8_4(TYPE* C, const TYPE* A, const int8_t* B, for (int sy = 1; sy < l; ++sy) { s0 = LOAD4(A + sy * aStride); ws = _load_int8x4(weight + sy * 4, alpha, bias); - w0 = _mm_set1_ps(ws[0]); - w1 = _mm_set1_ps(ws[1]); - w2 = _mm_set1_ps(ws[2]); - w3 = _mm_set1_ps(ws[3]); + _mm_storeu_ps(ws_tmp, ws); + w0 = _mm_set1_ps(ws_tmp[0]); + w1 = _mm_set1_ps(ws_tmp[1]); + w2 = _mm_set1_ps(ws_tmp[2]); + w3 = _mm_set1_ps(ws_tmp[3]); z0 = MNNSSEFMA(s0, w0, z0); z3 = MNNSSEFMA(s0, w1, z3); z6 = MNNSSEFMA(s0, w2, z6); diff --git a/source/backend/cpu/x86_x64/sse/GemmFunction.hpp b/source/backend/cpu/x86_x64/sse/GemmFunction.hpp index b7507abaa..2541b9b2c 100644 --- a/source/backend/cpu/x86_x64/sse/GemmFunction.hpp +++ b/source/backend/cpu/x86_x64/sse/GemmFunction.hpp @@ -213,7 +213,7 @@ static inline __m128 _load_int4x4(const uint8_t* src, __m128 alpha, __m128 bias) int iw2 = iw23 / 16; int iw3 = iw23 % 16; auto ws = _mm_set_ps(iw3, iw2, iw1, iw0); - ws = _mm_sub_ps(ws, _mm_set1_ps(7)); + ws = _mm_sub_ps(ws, _mm_set1_ps(8)); ws = _mm_add_ps(_mm_mul_ps(ws, alpha), bias); return ws; } @@ -226,6 +226,7 @@ static void _SSE_MNNPackedMatMul_12_int4(float* C, const float* A, const float* auto bExtraStride = parameter[5] / sizeof(float); auto bStride = bExtraStride + l * 4; auto hC4 = UP_DIV(h, 4); + float ws_tmp[4]; for (int y = 0; y < hC4; ++y) { auto weight = B + y * bStride / 2; auto dst = C + y * cStride; @@ -235,10 +236,11 @@ static void _SSE_MNNPackedMatMul_12_int4(float* C, const float* A, const float* auto s1 = _mm_loadu_ps(A + 0 * 12 + 4); auto s2 = _mm_loadu_ps(A + 0 * 12 + 8); auto ws = _load_int4x4(weight, alpha, bias); - auto w0 = _mm_set1_ps(ws[0]); - auto w1 = _mm_set1_ps(ws[1]); - auto w2 = _mm_set1_ps(ws[2]); - auto w3 = _mm_set1_ps(ws[3]); + _mm_storeu_ps(ws_tmp, ws); + auto w0 = _mm_set1_ps(ws_tmp[0]); + auto w1 = _mm_set1_ps(ws_tmp[1]); + auto w2 = _mm_set1_ps(ws_tmp[2]); + auto w3 = _mm_set1_ps(ws_tmp[3]); auto z0 = _mm_mul_ps(s0, w0); auto z1 = _mm_mul_ps(s1, w0); auto z2 = _mm_mul_ps(s2, w0); @@ -257,10 +259,11 @@ static void _SSE_MNNPackedMatMul_12_int4(float* C, const float* A, const float* s1 = _mm_loadu_ps(A + sy * 12 + 4); s2 = _mm_loadu_ps(A + sy * 12 + 8); ws = _load_int4x4(weight + sy * 2, alpha, bias); - w0 = _mm_set1_ps(ws[0]); - w1 = _mm_set1_ps(ws[1]); - w2 = _mm_set1_ps(ws[2]); - w3 = _mm_set1_ps(ws[3]); + _mm_storeu_ps(ws_tmp, ws); + w0 = _mm_set1_ps(ws_tmp[0]); + w1 = _mm_set1_ps(ws_tmp[1]); + w2 = _mm_set1_ps(ws_tmp[2]); + w3 = _mm_set1_ps(ws_tmp[3]); z0 = MNNSSEFMA(s0, w0, z0); z1 = MNNSSEFMA(s1, w0, z1); z2 = MNNSSEFMA(s2, w0, z2); @@ -288,6 +291,7 @@ static void _SSE_MNNPackedMatMul_8_int4(float* C, const float* A, const uint8_t* auto bExtraStride = parameter[5] / sizeof(float); auto bStride = bExtraStride + l * 4; auto hC4 = UP_DIV(h, 4); + float ws_tmp[4]; for (int y = 0; y < hC4; ++y) { auto weight = B + y * bStride / 2; auto dst = C + y * cStride; @@ -296,10 +300,11 @@ static void _SSE_MNNPackedMatMul_8_int4(float* C, const float* A, const uint8_t* auto s0 = _mm_loadu_ps(A + 0 * aStride); auto s1 = _mm_loadu_ps(A + 0 * aStride + 4); auto ws = _load_int4x4(weight, alpha, bias); - auto w0 = _mm_set1_ps(ws[0]); - auto w1 = _mm_set1_ps(ws[1]); - auto w2 = _mm_set1_ps(ws[2]); - auto w3 = _mm_set1_ps(ws[3]); + _mm_storeu_ps(ws_tmp, ws); + auto w0 = _mm_set1_ps(ws_tmp[0]); + auto w1 = _mm_set1_ps(ws_tmp[1]); + auto w2 = _mm_set1_ps(ws_tmp[2]); + auto w3 = _mm_set1_ps(ws_tmp[3]); auto z0 = _mm_mul_ps(s0, w0); auto z3 = _mm_mul_ps(s0, w1); auto z6 = _mm_mul_ps(s0, w2); @@ -313,10 +318,11 @@ static void _SSE_MNNPackedMatMul_8_int4(float* C, const float* A, const uint8_t* s0 = _mm_loadu_ps(A + sy * aStride); s1 = _mm_loadu_ps(A + sy * aStride + 4); ws = _load_int4x4(weight + sy * 2, alpha, bias); - w0 = _mm_set1_ps(ws[0]); - w1 = _mm_set1_ps(ws[1]); - w2 = _mm_set1_ps(ws[2]); - w3 = _mm_set1_ps(ws[3]); + _mm_storeu_ps(ws_tmp, ws); + w0 = _mm_set1_ps(ws_tmp[0]); + w1 = _mm_set1_ps(ws_tmp[1]); + w2 = _mm_set1_ps(ws_tmp[2]); + w3 = _mm_set1_ps(ws_tmp[3]); z0 = MNNSSEFMA(s0, w0, z0); z3 = MNNSSEFMA(s0, w1, z3); z6 = MNNSSEFMA(s0, w2, z6); @@ -339,6 +345,7 @@ static void _SSE_MNNPackedMatMul_4_int4(float* C, const float* A, const uint8_t* auto bExtraStride = parameter[5] / sizeof(float); auto bStride = bExtraStride + l * 4; auto hC4 = UP_DIV(h, 4); + float ws_tmp[4]; for (int y = 0; y < hC4; ++y) { auto weight = B + y * bStride / 2; auto dst = C + y * cStride; @@ -346,10 +353,11 @@ static void _SSE_MNNPackedMatMul_4_int4(float* C, const float* A, const uint8_t* auto bias = _mm_loadu_ps(b + y * 4); auto s0 = _mm_loadu_ps(A + 0 * aStride); auto ws = _load_int4x4(weight, alpha, bias); - auto w0 = _mm_set1_ps(ws[0]); - auto w1 = _mm_set1_ps(ws[1]); - auto w2 = _mm_set1_ps(ws[2]); - auto w3 = _mm_set1_ps(ws[3]); + _mm_storeu_ps(ws_tmp, ws); + auto w0 = _mm_set1_ps(ws_tmp[0]); + auto w1 = _mm_set1_ps(ws_tmp[1]); + auto w2 = _mm_set1_ps(ws_tmp[2]); + auto w3 = _mm_set1_ps(ws_tmp[3]); auto z0 = _mm_mul_ps(s0, w0); auto z3 = _mm_mul_ps(s0, w1); auto z6 = _mm_mul_ps(s0, w2); @@ -358,10 +366,11 @@ static void _SSE_MNNPackedMatMul_4_int4(float* C, const float* A, const uint8_t* for (int sy = 1; sy < l; ++sy) { s0 = _mm_loadu_ps(A + sy * aStride); ws = _load_int4x4(weight + sy * 2, alpha, bias); - w0 = _mm_set1_ps(ws[0]); - w1 = _mm_set1_ps(ws[1]); - w2 = _mm_set1_ps(ws[2]); - w3 = _mm_set1_ps(ws[3]); + _mm_storeu_ps(ws_tmp, ws); + w0 = _mm_set1_ps(ws_tmp[0]); + w1 = _mm_set1_ps(ws_tmp[1]); + w2 = _mm_set1_ps(ws_tmp[2]); + w3 = _mm_set1_ps(ws_tmp[3]); z0 = MNNSSEFMA(s0, w0, z0); z3 = MNNSSEFMA(s0, w1, z3); z6 = MNNSSEFMA(s0, w2, z6); @@ -435,6 +444,7 @@ static void _SSE_MNNPackedMatMul_12_int8(float* C, const float* A, const float* auto bExtraStride = parameter[5] / sizeof(float); auto bStride = bExtraStride + l * 4; auto hC4 = UP_DIV(h, 4); + float ws_tmp[4]; for (int y = 0; y < hC4; ++y) { auto weight = B + y * bStride; auto dst = C + y * cStride; @@ -444,10 +454,11 @@ static void _SSE_MNNPackedMatMul_12_int8(float* C, const float* A, const float* auto s1 = _mm_loadu_ps(A + 0 * 12 + 4); auto s2 = _mm_loadu_ps(A + 0 * 12 + 8); auto ws = _load_int8x4(weight, alpha, bias); - auto w0 = _mm_set1_ps(ws[0]); - auto w1 = _mm_set1_ps(ws[1]); - auto w2 = _mm_set1_ps(ws[2]); - auto w3 = _mm_set1_ps(ws[3]); + _mm_storeu_ps(ws_tmp, ws); + auto w0 = _mm_set1_ps(ws_tmp[0]); + auto w1 = _mm_set1_ps(ws_tmp[1]); + auto w2 = _mm_set1_ps(ws_tmp[2]); + auto w3 = _mm_set1_ps(ws_tmp[3]); auto z0 = _mm_mul_ps(s0, w0); auto z1 = _mm_mul_ps(s1, w0); auto z2 = _mm_mul_ps(s2, w0); @@ -466,10 +477,11 @@ static void _SSE_MNNPackedMatMul_12_int8(float* C, const float* A, const float* s1 = _mm_loadu_ps(A + sy * 12 + 4); s2 = _mm_loadu_ps(A + sy * 12 + 8); ws = _load_int8x4(weight + sy * 4, alpha, bias); - w0 = _mm_set1_ps(ws[0]); - w1 = _mm_set1_ps(ws[1]); - w2 = _mm_set1_ps(ws[2]); - w3 = _mm_set1_ps(ws[3]); + _mm_storeu_ps(ws_tmp, ws); + w0 = _mm_set1_ps(ws_tmp[0]); + w1 = _mm_set1_ps(ws_tmp[1]); + w2 = _mm_set1_ps(ws_tmp[2]); + w3 = _mm_set1_ps(ws_tmp[3]); z0 = MNNSSEFMA(s0, w0, z0); z1 = MNNSSEFMA(s1, w0, z1); z2 = MNNSSEFMA(s2, w0, z2); @@ -497,6 +509,7 @@ static void _SSE_MNNPackedMatMul_8_int8(float* C, const float* A, const int8_t* auto bExtraStride = parameter[5] / sizeof(float); auto bStride = bExtraStride + l * 4; auto hC4 = UP_DIV(h, 4); + float ws_tmp[4]; for (int y = 0; y < hC4; ++y) { auto weight = B + y * bStride; auto dst = C + y * cStride; @@ -505,10 +518,11 @@ static void _SSE_MNNPackedMatMul_8_int8(float* C, const float* A, const int8_t* auto s0 = _mm_loadu_ps(A + 0 * aStride); auto s1 = _mm_loadu_ps(A + 0 * aStride + 4); auto ws = _load_int8x4(weight, alpha, bias); - auto w0 = _mm_set1_ps(ws[0]); - auto w1 = _mm_set1_ps(ws[1]); - auto w2 = _mm_set1_ps(ws[2]); - auto w3 = _mm_set1_ps(ws[3]); + _mm_storeu_ps(ws_tmp, ws); + auto w0 = _mm_set1_ps(ws_tmp[0]); + auto w1 = _mm_set1_ps(ws_tmp[1]); + auto w2 = _mm_set1_ps(ws_tmp[2]); + auto w3 = _mm_set1_ps(ws_tmp[3]); auto z0 = _mm_mul_ps(s0, w0); auto z3 = _mm_mul_ps(s0, w1); auto z6 = _mm_mul_ps(s0, w2); @@ -522,10 +536,11 @@ static void _SSE_MNNPackedMatMul_8_int8(float* C, const float* A, const int8_t* s0 = _mm_loadu_ps(A + sy * aStride); s1 = _mm_loadu_ps(A + sy * aStride + 4); ws = _load_int8x4(weight + sy * 4, alpha, bias); - w0 = _mm_set1_ps(ws[0]); - w1 = _mm_set1_ps(ws[1]); - w2 = _mm_set1_ps(ws[2]); - w3 = _mm_set1_ps(ws[3]); + _mm_storeu_ps(ws_tmp, ws); + w0 = _mm_set1_ps(ws_tmp[0]); + w1 = _mm_set1_ps(ws_tmp[1]); + w2 = _mm_set1_ps(ws_tmp[2]); + w3 = _mm_set1_ps(ws_tmp[3]); z0 = MNNSSEFMA(s0, w0, z0); z3 = MNNSSEFMA(s0, w1, z3); z6 = MNNSSEFMA(s0, w2, z6); @@ -548,6 +563,7 @@ static void _SSE_MNNPackedMatMul_4_int8(float* C, const float* A, const int8_t* auto bExtraStride = parameter[5] / sizeof(float); auto bStride = bExtraStride + l * 4; auto hC4 = UP_DIV(h, 4); + float ws_tmp[4]; for (int y = 0; y < hC4; ++y) { auto weight = B + y * bStride; auto dst = C + y * cStride; @@ -555,10 +571,11 @@ static void _SSE_MNNPackedMatMul_4_int8(float* C, const float* A, const int8_t* auto bias = _mm_loadu_ps(b + y * 4); auto s0 = _mm_loadu_ps(A + 0 * aStride); auto ws = _load_int8x4(weight, alpha, bias); - auto w0 = _mm_set1_ps(ws[0]); - auto w1 = _mm_set1_ps(ws[1]); - auto w2 = _mm_set1_ps(ws[2]); - auto w3 = _mm_set1_ps(ws[3]); + _mm_storeu_ps(ws_tmp, ws); + auto w0 = _mm_set1_ps(ws_tmp[0]); + auto w1 = _mm_set1_ps(ws_tmp[1]); + auto w2 = _mm_set1_ps(ws_tmp[2]); + auto w3 = _mm_set1_ps(ws_tmp[3]); auto z0 = _mm_mul_ps(s0, w0); auto z3 = _mm_mul_ps(s0, w1); auto z6 = _mm_mul_ps(s0, w2); @@ -567,10 +584,11 @@ static void _SSE_MNNPackedMatMul_4_int8(float* C, const float* A, const int8_t* for (int sy = 1; sy < l; ++sy) { s0 = _mm_loadu_ps(A + sy * aStride); ws = _load_int8x4(weight + sy * 4, alpha, bias); - w0 = _mm_set1_ps(ws[0]); - w1 = _mm_set1_ps(ws[1]); - w2 = _mm_set1_ps(ws[2]); - w3 = _mm_set1_ps(ws[3]); + _mm_storeu_ps(ws_tmp, ws); + w0 = _mm_set1_ps(ws_tmp[0]); + w1 = _mm_set1_ps(ws_tmp[1]); + w2 = _mm_set1_ps(ws_tmp[2]); + w3 = _mm_set1_ps(ws_tmp[3]); z0 = MNNSSEFMA(s0, w0, z0); z3 = MNNSSEFMA(s0, w1, z3); z6 = MNNSSEFMA(s0, w2, z6); diff --git a/source/backend/cuda/core/CUDABackend.cpp b/source/backend/cuda/core/CUDABackend.cpp index 1ef715a39..a69154125 100644 --- a/source/backend/cuda/core/CUDABackend.cpp +++ b/source/backend/cuda/core/CUDABackend.cpp @@ -301,7 +301,7 @@ Execution* CUDABackend::onCreate(const std::vector& inputs, const std:: void CUDABackend::onResizeBegin() { } -void CUDABackend::onResizeEnd() { +ErrorCode CUDABackend::onResizeEnd() { } void CUDABackend::onExecuteBegin() const { diff --git a/source/backend/cuda/core/CUDABackend.hpp b/source/backend/cuda/core/CUDABackend.hpp index d5011f892..f5db02aa8 100644 --- a/source/backend/cuda/core/CUDABackend.hpp +++ b/source/backend/cuda/core/CUDABackend.hpp @@ -11,6 +11,7 @@ #include #include +#include #include "MNN_generated.h" #include "backend/cuda/core/runtime/CUDARuntime.hpp" #include "core/Backend.hpp" @@ -60,7 +61,7 @@ class CUDABackend : public Backend { virtual Execution *onCreate(const std::vector &inputs, const std::vector &outputs, const MNN::Op *op) override; virtual void onResizeBegin() override; - virtual void onResizeEnd() override; + virtual ErrorCode onResizeEnd() override; virtual void onExecuteBegin() const override; virtual void onExecuteEnd() const override; diff --git a/source/backend/cuda/core/runtime/CUDARuntime.hpp b/source/backend/cuda/core/runtime/CUDARuntime.hpp index 22cdfa581..d82be0ec8 100644 --- a/source/backend/cuda/core/runtime/CUDARuntime.hpp +++ b/source/backend/cuda/core/runtime/CUDARuntime.hpp @@ -107,6 +107,9 @@ class CUDARuntime { size_t threads_num() { return mThreadPerBlock; } + const cudaDeviceProp& prop() const { + return mProp; + } int major_sm() const { return mProp.major; } @@ -114,10 +117,11 @@ class CUDARuntime { return mProp.major * 10 + mProp.minor; } size_t blocks_num(const size_t total_threads); - const cudaDeviceProp& prop() const { - return mProp; + const int smemPerBlock() { + return mProp.sharedMemPerBlock; } + int selectDeviceMaxFreeMemory(); private: diff --git a/source/backend/cuda/execution/ConvCutlassExecution.cu b/source/backend/cuda/execution/ConvCutlassExecution.cu index 7f089ad77..0c267c18a 100644 --- a/source/backend/cuda/execution/ConvCutlassExecution.cu +++ b/source/backend/cuda/execution/ConvCutlassExecution.cu @@ -26,7 +26,7 @@ ConvCutlassExecution::Resource::Resource(Backend* bn, const MNN::Op* op) { const float* filterDataPtr = nullptr; int weightSize = 0; std::shared_ptr quanCommon; - ConvolutionCommon::getConvParameters(&quanCommon, conv, &filterDataPtr, &weightSize); + ConvolutionCommon::getConvParameters(&quanCommon, bn, conv, &filterDataPtr, &weightSize); auto oc = common->outputCount(); int l = weightSize / oc; diff --git a/source/backend/cuda/execution/ConvDepthWiseExecution.cu b/source/backend/cuda/execution/ConvDepthWiseExecution.cu index 079bc2737..f4baac9d5 100755 --- a/source/backend/cuda/execution/ConvDepthWiseExecution.cu +++ b/source/backend/cuda/execution/ConvDepthWiseExecution.cu @@ -655,7 +655,7 @@ static std::shared_ptr _makeResource(const Op* const float* filterDataPtr = nullptr; int weightSize = 0; std::shared_ptr quanCommon; - ConvolutionCommon::getConvParameters(&quanCommon, conv, &filterDataPtr, &weightSize); + ConvolutionCommon::getConvParameters(&quanCommon, bn, conv, &filterDataPtr, &weightSize); auto tempWeightStorage = pool->alloc(depthC * PACK_NUMBER * kernelY * kernelX * sizeof(float)); auto tempWeight = (uint8_t*)tempWeightStorage.first + tempWeightStorage.second; cuda_check(cudaMemset(tempWeight, 0, depthC * PACK_NUMBER * kernelY * kernelX * sizeof(float))); diff --git a/source/backend/cuda/execution/ConvWinogradExecution.cu b/source/backend/cuda/execution/ConvWinogradExecution.cu index 0af83bcc4..8ce9d173d 100644 --- a/source/backend/cuda/execution/ConvWinogradExecution.cu +++ b/source/backend/cuda/execution/ConvWinogradExecution.cu @@ -67,7 +67,7 @@ ConvWinogradExecution::Resource::Resource(Backend* backend, const MNN::Op* op) { const float* filterDataPtr = nullptr; int weightSize = 0; std::shared_ptr quanCommon; - ConvolutionCommon::getConvParameters(&quanCommon, conv, &filterDataPtr, &weightSize); + ConvolutionCommon::getConvParameters(&quanCommon, backend, conv, &filterDataPtr, &weightSize); mKernelInfo.kernelN = common->outputCount(); mKernelInfo.kernelC = weightSize / mKernelInfo.kernelN / mKernelInfo.kernelX / mKernelInfo.kernelY; diff --git a/source/backend/cuda/execution/DeconvSingleInputExecution.cu b/source/backend/cuda/execution/DeconvSingleInputExecution.cu index 12465224c..1e4dc882d 100644 --- a/source/backend/cuda/execution/DeconvSingleInputExecution.cu +++ b/source/backend/cuda/execution/DeconvSingleInputExecution.cu @@ -33,7 +33,7 @@ DeconvSingleInputExecution::Resource::Resource(Backend* bn, const MNN::Op* op) { const float* filterDataPtr = nullptr; int weightSize = 0; std::shared_ptr quanCommon; - ConvolutionCommon::getConvParameters(&quanCommon, conv, &filterDataPtr, &weightSize); + ConvolutionCommon::getConvParameters(&quanCommon, bn, conv, &filterDataPtr, &weightSize); mKernelInfo.kernelN = common->outputCount(); mKernelInfo.kernelC = weightSize / mKernelInfo.kernelN / mKernelInfo.kernelX / mKernelInfo.kernelY; diff --git a/source/backend/cuda/execution/TopKV2Execution.cu b/source/backend/cuda/execution/TopKV2Execution.cu index 46829dda8..30b0ea882 100644 --- a/source/backend/cuda/execution/TopKV2Execution.cu +++ b/source/backend/cuda/execution/TopKV2Execution.cu @@ -1,7 +1,6 @@ #include "TopKV2Execution.hpp" #include - namespace MNN { namespace CUDA { @@ -187,17 +186,22 @@ __global__ void GetResultAllRows(indexT * outputIndicesDevice, valueT * outputVa } -int CalculateNumThreadPerBlock(const int K) { - int numThreadPerBlock; - if (K <= 48) { - numThreadPerBlock = 128; - } else if (K <= 96) { - numThreadPerBlock = 64; - } else { - numThreadPerBlock = 32; - } +// The inequality "numThreadPerBlock * K * (sizeof(indexT) + sizeof(valueT)) <= smemPerBlock" must be guaranteed, which means numThreadPerBlock depends on K. +template +int CalculateNumThreadPerBlock(const int K, const int smemPerBlock) { + int temp = smemPerBlock / (K * (sizeof(indexT) + sizeof(valueT))); + int numCalculate = std::pow(2, (std::floor(std::log2(temp)))); + int numLimit = 1024; + return ALIMIN(numLimit, numCalculate); +} + - return numThreadPerBlock; +// The inequality "numBlockPerRow * K * (sizeof(indexT) + sizeof(valueT)) <= smemPerBlock" must be guaranteed by restricting numElePerThread. +template +int CalcualteNumElePerThread(const int K, const int numElePerRow, const int numThreadPerBlock, const int smemPerBlock) { + int numLimit = K; + int numCalculate = UP_DIV(numElePerRow, (smemPerBlock / (K * (sizeof(indexT) + sizeof(valueT))))-1); + return ALIMAX(numLimit,numCalculate); } @@ -223,8 +227,17 @@ ErrorCode TopKV2Execution::onResize(const std::vector &inputs, const s mParams.mNumElePerRow = mParams.mLengthRow; mParams.mNumK = outputs[0]->buffer().dim[outputs[0]->buffer().dimensions-1].extent; - mParams.mNumElePerThread = mParams.mNumK; - mParams.mNumThreadPerBlock = CalculateNumThreadPerBlock(mParams.mNumK); + auto smemLimit = static_cast(backend())->getCUDARuntime()->smemPerBlock(); + if (inputTensor->getType().code == halide_type_int && inputTensor->getType().bits == 32) { + mParams.mNumThreadPerBlock = CalculateNumThreadPerBlock(mParams.mNumK, smemLimit); + mParams.mNumElePerThread = CalcualteNumElePerThread(mParams.mNumK, mParams.mNumElePerRow, mParams.mNumThreadPerBlock, smemLimit); + } else if (static_cast(backend())->useFp16()) { + mParams.mNumThreadPerBlock = CalculateNumThreadPerBlock(mParams.mNumK, smemLimit); + mParams.mNumElePerThread = CalcualteNumElePerThread(mParams.mNumK, mParams.mNumElePerRow, mParams.mNumThreadPerBlock, smemLimit); + } else { + mParams.mNumThreadPerBlock = CalculateNumThreadPerBlock(mParams.mNumK, smemLimit); + mParams.mNumElePerThread = CalcualteNumElePerThread(mParams.mNumK, mParams.mNumElePerRow, mParams.mNumThreadPerBlock, smemLimit); + } mParams.mNumElePerBlock = mParams.mNumElePerThread * mParams.mNumThreadPerBlock; mParams.mNumBlockPerRow = (mParams.mNumElePerRow - 1 + mParams.mNumElePerBlock) / mParams.mNumElePerBlock; mParams.mNumBlockFinal = mParams.mNumRow; @@ -232,7 +245,7 @@ ErrorCode TopKV2Execution::onResize(const std::vector &inputs, const s mParams.mNumBlockTotal = mParams.mNumBlockPerRow * mParams.mNumRow; // prepare temp buffer - auto pool = static_cast(backend())->getStaticBufferPool(); + auto pool = static_cast(backend())->getBufferPool(); if (inputTensor->getType().code == halide_type_int && inputTensor->getType().bits == 32) { auto bufferIndices = pool->alloc(mParams.mNumBlockTotal * mParams.mNumK * sizeof(int)); @@ -255,6 +268,7 @@ ErrorCode TopKV2Execution::onResize(const std::vector &inputs, const s mParams.mBufferValues = (void*)((uint8_t*)bufferValues.first + bufferValues.second); pool->free(bufferIndices); pool->free(bufferValues); + } return NO_ERROR; @@ -270,25 +284,25 @@ ErrorCode TopKV2Execution::onExecute(const std::vector &inputs, const // configure threads dim3 grid1 = {mParams.mNumBlockPerRow, mParams.mNumRow}; dim3 block1 = {mParams.mNumThreadPerBlock, 1}; - int smemSize_1 = mParams.mNumThreadPerBlock * mParams.mNumK; + int smemSize1 = mParams.mNumThreadPerBlock * mParams.mNumK; dim3 grid2 = {mParams.mNumBlockFinal}; dim3 block2 = {mParams.mNumThreadFinal}; - int smemSize_2 = mParams.mNumBlockPerRow * mParams.mNumK; + int smemSize2 = mParams.mNumBlockPerRow * mParams.mNumK; if (inputs[0]->getType().code == halide_type_int && inputs[0]->getType().bits == 32) { - TopKAllRows<<>>(static_cast(inputDeviceAddr), static_cast(mParams.mBufferIndices), static_cast(mParams.mBufferValues), mParams.mNumK, mParams.mLengthRow, mParams.mMinInt, mParams.mDescendFlag); + TopKAllRows<<>>(static_cast(inputDeviceAddr), static_cast(mParams.mBufferIndices), static_cast(mParams.mBufferValues), mParams.mNumK, mParams.mLengthRow, mParams.mMinInt, mParams.mDescendFlag); checkKernelErrors; - GetResultAllRows<<>>(static_cast(outputIndicesDeviceAddr), static_cast(outputValuesDeviceAddr), static_cast(mParams.mBufferIndices), static_cast(mParams.mBufferValues), mParams.mNumK, mParams.mNumBlockPerRow, mParams.mDescendFlag); + GetResultAllRows<<>>(static_cast(outputIndicesDeviceAddr), static_cast(outputValuesDeviceAddr), static_cast(mParams.mBufferIndices), static_cast(mParams.mBufferValues), mParams.mNumK, mParams.mNumBlockPerRow, mParams.mDescendFlag); checkKernelErrors; } else if (static_cast(backend())->useFp16()) { - TopKAllRows<<>>(static_cast(inputDeviceAddr), static_cast(mParams.mBufferIndices), static_cast(mParams.mBufferValues), mParams.mNumK, mParams.mLengthRow, mParams.mMinHalf, mParams.mDescendFlag); + TopKAllRows<<>>(static_cast(inputDeviceAddr), static_cast(mParams.mBufferIndices), static_cast(mParams.mBufferValues), mParams.mNumK, mParams.mLengthRow, mParams.mMinHalf, mParams.mDescendFlag); checkKernelErrors; - GetResultAllRows<<>>(static_cast(outputIndicesDeviceAddr), static_cast(outputValuesDeviceAddr), static_cast(mParams.mBufferIndices), static_cast(mParams.mBufferValues), mParams.mNumK, mParams.mNumBlockPerRow, mParams.mDescendFlag); + GetResultAllRows<<>>(static_cast(outputIndicesDeviceAddr), static_cast(outputValuesDeviceAddr), static_cast(mParams.mBufferIndices), static_cast(mParams.mBufferValues), mParams.mNumK, mParams.mNumBlockPerRow, mParams.mDescendFlag); checkKernelErrors; } else { - TopKAllRows<<>>(static_cast(inputDeviceAddr), static_cast(mParams.mBufferIndices), static_cast(mParams.mBufferValues), mParams.mNumK, mParams.mLengthRow, mParams.mMinFloat, mParams.mDescendFlag); + TopKAllRows<<>>(static_cast(inputDeviceAddr), static_cast(mParams.mBufferIndices), static_cast(mParams.mBufferValues), mParams.mNumK, mParams.mLengthRow, mParams.mMinFloat, mParams.mDescendFlag); checkKernelErrors; - GetResultAllRows<<>>(static_cast(outputIndicesDeviceAddr), static_cast(outputValuesDeviceAddr), static_cast(mParams.mBufferIndices), static_cast(mParams.mBufferValues), mParams.mNumK, mParams.mNumBlockPerRow, mParams.mDescendFlag); + GetResultAllRows<<>>(static_cast(outputIndicesDeviceAddr), static_cast(outputValuesDeviceAddr), static_cast(mParams.mBufferIndices), static_cast(mParams.mBufferValues), mParams.mNumK, mParams.mNumBlockPerRow, mParams.mDescendFlag); checkKernelErrors; } diff --git a/source/backend/cuda/execution/Transpose.cu b/source/backend/cuda/execution/Transpose.cu index 3faedd437..139deb9fb 100644 --- a/source/backend/cuda/execution/Transpose.cu +++ b/source/backend/cuda/execution/Transpose.cu @@ -329,200 +329,337 @@ void Transpose(uint8_t* output, const uint8_t* input, const TransposeParam* cpuP } } +// for the following transpose kernels: +// maxCount is num of threads i.e., num of elements of output format +// inChannelPack is num of channel pack of input format +// divOutChannelPack is Div for channel pack of output format + +// copy kernel template -__global__ void NCHW_2_NHWC8(const T0* input, - T1* output, - const int maxCount, - const int channel, - const int area, - const int channel_pack, - DivModFast d_ocp, - DivModFast d_area +__global__ void NCHW_2_NCHW(const T0* input, + T1* output, + const int maxCount ) { for(size_t index = blockIdx.x * blockDim.x + threadIdx.x; index < maxCount; index += blockDim.x * gridDim.x) { - int area_idx, temp, chnlp_idx, batch_idx; - d_ocp.divmod(index, temp, chnlp_idx); - d_area.divmod(temp, batch_idx, area_idx); + output[index] = (T1)input[index]; + } +} - if(chnlp_idx >= channel) { - output[index] = (T1)0.0f; - continue; - } - int src_offset = (batch_idx * channel + chnlp_idx) * area + area_idx; +// NHWC NCHW +template +__global__ void NHWC_2_NCHW(const T0* input, + T1* output, + const int maxCount, + const int channel, // redundant parameter + const int area, + const int inChannelPack, + DivModFast divOutChannelPack, + DivModFast divArea +) { + for(size_t index = blockIdx.x * blockDim.x + threadIdx.x; index < maxCount; index += blockDim.x * gridDim.x) { + int area_idx, temp, chnl_idx, batch_idx; + divArea.divmod(index, temp, area_idx); + divOutChannelPack.divmod(temp, batch_idx, chnl_idx); + + int src_offset = (batch_idx * area + area_idx) * inChannelPack+ chnl_idx; + output[index] = (T1)input[src_offset]; + } +} + +// NHWC8_2_NCHW +template +__global__ void NHWC8_2_NCHW(const T0* input, + T1* output, + const int maxCount, + const int channel, // redundant parameter + const int area, + const int inChannelPack, + DivModFast divOutChannelPack, + DivModFast divArea +) { + for(size_t index = blockIdx.x * blockDim.x + threadIdx.x; index < maxCount; index += blockDim.x * gridDim.x) { + int area_idx, temp, chnl_idx, batch_idx; + divArea.divmod(index, temp, area_idx); + divOutChannelPack.divmod(temp, batch_idx, chnl_idx); + + int src_offset = (batch_idx * area + area_idx) * inChannelPack + chnl_idx; output[index] = (T1)input[src_offset]; } } +// C4NHW4_2_NCHW +template +__global__ void C4NHW4_2_NCHW(const T0* input, + T1* output, + const int maxCount, + const int channel, + const int area, + const int inChannelPack, // redundant parameter + DivModFast divOutChannelPack, + DivModFast divArea +) { + const int batch = (maxCount / channel) / area; + for(size_t index = blockIdx.x * blockDim.x + threadIdx.x; index < maxCount; index += blockDim.x * gridDim.x) { + int area_idx, temp, chnl_idx, batch_idx; + divArea.divmod(index, temp, area_idx); + divOutChannelPack.divmod(temp, batch_idx, chnl_idx); + + int c4_idx = chnl_idx >> 2; + int cL_idx = chnl_idx & 3; + int src_offset = ((c4_idx * batch + batch_idx) * area + area_idx) * 4 + cL_idx; + output[index] = (T1)input[src_offset]; + } +} + +// NCHW NHWC template __global__ void NCHW_2_NHWC(const T0* input, - T1* output, - const int maxCount, - const int channel, - const int area, - const int channel_pack, - DivModFast d_oc, - DivModFast d_area + T1* output, + const int maxCount, + const int channel, // redundant parameter + const int area, + const int inChannelPack, + DivModFast divOutChannelPack, + DivModFast divArea ) { for(size_t index = blockIdx.x * blockDim.x + threadIdx.x; index < maxCount; index += blockDim.x * gridDim.x) { int area_idx, temp, chnl_idx, batch_idx; - d_oc.divmod(index, temp, chnl_idx); - d_area.divmod(temp, batch_idx, area_idx); - - int src_offset = (batch_idx * channel + chnl_idx) * area + area_idx; + divOutChannelPack.divmod(index, temp, chnl_idx); + divArea.divmod(temp, batch_idx, area_idx); + + int src_offset = (batch_idx * inChannelPack + chnl_idx) * area + area_idx; + output[index] = (T1)input[src_offset]; + } +} + +// NHWC8 NHWC +template +__global__ void NHWC8_2_NHWC(const T0* input, + T1* output, + const int maxCount, + const int channel, // redundant parameter + const int area, + const int inChannelPack, + DivModFast divOutChannelPack, + DivModFast divArea +) { + for(size_t index = blockIdx.x * blockDim.x + threadIdx.x; index < maxCount; index += blockDim.x * gridDim.x) { + int area_idx, temp, chnl_idx, batch_idx; + divOutChannelPack.divmod(index, temp, chnl_idx); + divArea.divmod(temp, batch_idx, area_idx); + + int src_offset = (batch_idx * area + area_idx) * inChannelPack + chnl_idx; + output[index] = (T1)input[src_offset]; + } +} + +// C4NHW4 NHWC +template +__global__ void C4NHW4_2_NHWC(const T0* input, + T1* output, + const int maxCount, + const int channel, + const int area, + const int inChannelPack, // redundant parameter + DivModFast divOutChannelPack, + DivModFast divArea +) { + const int batch = (maxCount / channel) / area; + for(size_t index = blockIdx.x * blockDim.x + threadIdx.x; index < maxCount; index += blockDim.x * gridDim.x) { + int area_idx, temp, chnl_idx, batch_idx; + divOutChannelPack.divmod(index, temp, chnl_idx); + divArea.divmod(temp, batch_idx, area_idx); + + int c4_idx = chnl_idx >> 2; + int cL_idx = chnl_idx & 3; + int src_offset = ((c4_idx * batch + batch_idx) * area + area_idx) * 4 + cL_idx; output[index] = (T1)input[src_offset]; } } +// NHWC NHWC8 template __global__ void NHWC_2_NHWC8(const T0* input, - T1* output, - const int maxCount, - const int channel, - const int area, - const int channel_pack, - DivModFast d_ocp, - DivModFast d_area + T1* output, + const int maxCount, + const int channel, + const int area, + const int inChannelPack, + DivModFast divOutChannelPack, + DivModFast divArea ) { for(size_t index = blockIdx.x * blockDim.x + threadIdx.x; index < maxCount; index += blockDim.x * gridDim.x) { - int area_idx, temp, chnlp_idx, batch_idx; - d_ocp.divmod(index, temp, chnlp_idx); - d_area.divmod(temp, batch_idx, area_idx); + int area_idx, temp, chnl_idx, batch_idx; + divOutChannelPack.divmod(index, temp, chnl_idx); + divArea.divmod(temp, batch_idx, area_idx); - if(chnlp_idx >= channel) { + if(chnl_idx >= channel) { output[index] = (T1)0.0f; continue; } - int src_offset = (batch_idx * area + area_idx) * channel + chnlp_idx; + + int src_offset = (batch_idx * area + area_idx) * inChannelPack + chnl_idx; output[index] = (T1)input[src_offset]; } } +// NCHW NHWC8 template -__global__ void NHWC8_2_NCHW(const T0* input, - T1* output, - const int maxCount, - const int channel, - const int area, - const int channel_pack, - DivModFast d_oc, - DivModFast d_area +__global__ void NCHW_2_NHWC8(const T0* input, + T1* output, + const int maxCount, + const int channel, + const int area, + const int inChannelPack, + DivModFast divOutChannelPack, + DivModFast divArea ) { for(size_t index = blockIdx.x * blockDim.x + threadIdx.x; index < maxCount; index += blockDim.x * gridDim.x) { + int area_idx, temp, chnl_idx, batch_idx; + divOutChannelPack.divmod(index, temp, chnl_idx); + divArea.divmod(temp, batch_idx, area_idx); - int area_idx, temp, channel_idx, batch_idx; - d_area.divmod(index, temp, area_idx); - d_oc.divmod(temp, batch_idx, channel_idx); + if(chnl_idx >= channel) { + output[index] = (T1)0.0f; + continue; + } - int src_offset = (batch_idx * area + area_idx) * channel_pack + channel_idx; + int src_offset = (batch_idx * inChannelPack + chnl_idx) * area + area_idx; output[index] = (T1)input[src_offset]; } } +// C4NHW4 NHWC8 template -__global__ void NHWC8_2_NHWC(const T0* input, - T1* output, - const int maxCount, - const int channel, - const int area, - const int channel_pack, - DivModFast d_oc, - DivModFast d_area +__global__ void C4NHW4_2_NHWC8(const T0* input, + T1* output, + const int maxCount, + const int channel, + const int area, + const int inChannelPack, // redundant parameter + DivModFast divOutChannelPack, + DivModFast divArea ) { + const int batch = (maxCount / (UP_DIV(channel, 8) * 8)) / area; for(size_t index = blockIdx.x * blockDim.x + threadIdx.x; index < maxCount; index += blockDim.x * gridDim.x) { + int area_idx, temp, chnl_idx, batch_idx; + divOutChannelPack.divmod(index, temp, chnl_idx); + divArea.divmod(temp, batch_idx, area_idx); - int area_idx, temp, channel_idx, batch_idx; - d_oc.divmod(index, temp, channel_idx); - d_area.divmod(temp, batch_idx, area_idx); + if(chnl_idx >= channel) { + output[index] = (T1)0.0f; + continue; + } - int src_offset = (batch_idx * area + area_idx) * channel_pack + channel_idx; + int c4_idx = chnl_idx >> 2; + int cL_idx = chnl_idx & 3; + int src_offset = ((c4_idx * batch + batch_idx) * area + area_idx) * 4 + cL_idx; output[index] = (T1)input[src_offset]; } } +// NHWC_2_C4NHW4 template -__global__ void NCHW_2_NCHW(const T0* input, - T1* output, - const int maxCount +__global__ void NHWC_2_C4NHW4(const T0* input, + T1* output, + const int maxCount, + const int channel, + const int area, + const int inChannelPack, + DivModFast divOutChannelPack, + DivModFast divArea ) { + const int batch = (maxCount / (UP_DIV(channel, 4) * 4)) / area; for(size_t index = blockIdx.x * blockDim.x + threadIdx.x; index < maxCount; index += blockDim.x * gridDim.x) { - output[index] = (T1)input[index]; + // arrange threads arrodring to NHWC4 format + int area_idx, temp, chnl_idx, batch_idx; + divOutChannelPack.divmod(index, temp, chnl_idx); + divArea.divmod(temp, batch_idx, area_idx); + + int c4_idx = chnl_idx >> 2; // chnl_idx / 4 + int cL_idx = chnl_idx & 3; // chnl_idx % 4 + int dst_offset = ((c4_idx * batch + batch_idx) * area + area_idx) * 4 + cL_idx; + int src_offset = (batch_idx * area + area_idx) * inChannelPack + chnl_idx; + + if (chnl_idx >= channel) { + output[dst_offset] = (T1)0.0f;; + continue; + } + + output[dst_offset] = (T1)input[src_offset]; } } +// NCHW C4NHW4 template -__global__ void C4NHW4_2_NHWC8(const T0* input, - T1* output, - const int maxCount, - const int batch, - const int area, - const int channel, - const int channel_pack +__global__ void NCHW_2_C4NHW4(const T0* input, + T1* output, + const int maxCount, + const int channel, + const int area, + const int inChannelPack, + DivModFast divOutChannelPack, + DivModFast divArea ) { + const int batch = (maxCount / (UP_DIV(channel, 4) * 4)) / area; for(size_t index = blockIdx.x * blockDim.x + threadIdx.x; index < maxCount; index += blockDim.x * gridDim.x) { - int c_idx = index % channel_pack; - int temp = index / channel_pack; - int hw_idx = temp % area; - int batch_idx = temp / area; - - if(c_idx >= channel) { - output[index] = (T1)0.0f; - continue; - } - int c4_idx = c_idx >> 2; - int cL_idx = c_idx & 3; - output[index] = (T1)input[((c4_idx * batch + batch_idx) * area + hw_idx) * 4 + cL_idx]; + // arrange threads arrodring to NHWC4 format + int area_idx, temp, chnl_idx, batch_idx; + divOutChannelPack.divmod(index, temp, chnl_idx); + divArea.divmod(temp, batch_idx, area_idx); + + int c4_idx = chnl_idx >> 2; // chnl_idx / 4 + int cL_idx = chnl_idx & 3; // chnl_idx % 4 + int dst_offset = ((c4_idx * batch + batch_idx) * area + area_idx) * 4 + cL_idx; + int src_offset = (batch_idx * inChannelPack + chnl_idx) * area + area_idx; + + if (chnl_idx >= channel) { + output[dst_offset] = (T1)0.0f;; + continue; + } + + output[dst_offset] = (T1)input[src_offset]; } } +// NHWC8 C4NHW4 template __global__ void NHWC8_2_C4NHW4(const T0* input, - T1* output, - const int maxCount, - const int batch, - const int channel, - const int area, - const int channel_pack + T1* output, + const int maxCount, + const int channel, + const int area, + const int inChannelPack, + DivModFast divOutChannelPack, + DivModFast divArea ) { + const int batch = (maxCount / (UP_DIV(channel, 4) * 4)) / area; for(size_t index = blockIdx.x * blockDim.x + threadIdx.x; index < maxCount; index += blockDim.x * gridDim.x) { - int c_idx = index % channel_pack; - int temp = index / channel_pack; - int hw_idx = temp % area; - int batch_idx = temp / area; + // arrange threads arrodring to NHWC4 format + int area_idx, temp, chnl_idx, batch_idx; + divOutChannelPack.divmod(index, temp, chnl_idx); + divArea.divmod(temp, batch_idx, area_idx); + + int c4_idx = chnl_idx >> 2; // chnl_idx / 4 + int cL_idx = chnl_idx & 3; // chnl_idx % 4 + int dst_offset = ((c4_idx * batch + batch_idx) * area + area_idx) * 4 + cL_idx; + int src_offset = (batch_idx * area + area_idx) * inChannelPack + chnl_idx;; - int channel_8 = ((channel + 7) / 8) * 8; - int c4_idx = c_idx >> 2; - int cL_idx = c_idx & 3; - output[((c4_idx * batch + batch_idx) * area + hw_idx) * 4 + cL_idx] = - (T1)input[(batch_idx * area + hw_idx) * channel_8 + c_idx]; + output[dst_offset] = (T1)input[src_offset]; } } template static void insideFormatConvert(T0* input, T1* output, MNN_DATA_FORMAT srcDataFormat, MNN_DATA_FORMAT dstDataFormat, CUDARuntime* runtime, \ - const int area, const int batch, const int channel) { + const int area, const int batch, const int channel, const bool srcDevice, const bool dstDevice) { DivModFast d_oc(channel); - DivModFast d_ocp(UP_DIV(channel, 8) * 8); + DivModFast d_oc4(UP_DIV(channel, 4) * 4); + DivModFast d_oc8(UP_DIV(channel, 8) * 8); DivModFast d_area(area); - if(srcDataFormat == MNN_DATA_FORMAT_NCHW && dstDataFormat == MNN_DATA_FORMAT_NC4HW4) { - const int maxCount = batch * area * UP_DIV(channel, 8) * 8; - const int block_num = runtime->blocks_num(maxCount); - const int block_size = runtime->threads_num(); - NCHW_2_NHWC8<<>>(input, output, maxCount, channel, area, UP_DIV(channel, 8) * 8, - d_ocp, d_area); - checkKernelErrors; - return; - } - if(srcDataFormat == MNN_DATA_FORMAT_NHWC && dstDataFormat == MNN_DATA_FORMAT_NC4HW4) { - const int maxCount = batch * area * UP_DIV(channel, 8) * 8; - const int block_num = runtime->blocks_num(maxCount); - const int block_size = runtime->threads_num(); - NHWC_2_NHWC8<<>>(input, output, maxCount, channel, area, UP_DIV(channel, 8) * 8, - d_ocp, d_area); - checkKernelErrors; - return; - } - if((srcDataFormat == MNN_DATA_FORMAT_NCHW && dstDataFormat == MNN_DATA_FORMAT_NCHW) || \ + // NCHW NCHW + // NHWC NHWC + if ((srcDataFormat == MNN_DATA_FORMAT_NCHW && dstDataFormat == MNN_DATA_FORMAT_NCHW) || \ (srcDataFormat == MNN_DATA_FORMAT_NHWC && dstDataFormat == MNN_DATA_FORMAT_NHWC)) { const int maxCount = batch * area * channel; const int block_num = runtime->blocks_num(maxCount); @@ -531,168 +668,178 @@ static void insideFormatConvert(T0* input, T1* output, MNN_DATA_FORMAT srcDataFo checkKernelErrors; return; } - if(srcDataFormat == MNN_DATA_FORMAT_NC4HW4 && dstDataFormat == MNN_DATA_FORMAT_NCHW) { - const int maxCount = batch * area * channel; - const int block_num = runtime->blocks_num(maxCount); - const int block_size = runtime->threads_num(); - NHWC8_2_NCHW<<>>(input, output, maxCount, channel, area, UP_DIV(channel, 8) * 8, - d_oc, d_area); - checkKernelErrors; + + // NC4HW4 NC4HW4 + if (srcDataFormat == MNN_DATA_FORMAT_NC4HW4 && dstDataFormat == MNN_DATA_FORMAT_NC4HW4) { + if(!srcDevice && dstDevice) { + const int maxCount = batch * area * UP_DIV(channel, 8) * 8; + const int block_num = runtime->blocks_num(maxCount); + const int block_size = runtime->threads_num(); + C4NHW4_2_NHWC8<<>>(input, output, maxCount, channel, area, UP_DIV(channel, 4) * 4, d_oc8, d_area); + checkKernelErrors; + } else if (srcDevice && !dstDevice) { + const int maxCount = batch * area * UP_DIV(channel, 4) * 4; + const int block_num = runtime->blocks_num(maxCount); + const int block_size = runtime->threads_num(); + NHWC8_2_C4NHW4<<>>(input, output, maxCount, channel, area, UP_DIV(channel, 8) * 8, d_oc4, d_area); + checkKernelErrors; + } else { + const int maxCount = batch * area * UP_DIV(channel, 8) * 8; + const int block_num = runtime->blocks_num(maxCount); + const int block_size = runtime->threads_num(); + NCHW_2_NCHW<<>>(input, output, maxCount); + checkKernelErrors; + } return; } - if(srcDataFormat == MNN_DATA_FORMAT_NC4HW4 && dstDataFormat == MNN_DATA_FORMAT_NHWC) { + + // NHWC NCHW + if (srcDataFormat == MNN_DATA_FORMAT_NHWC && dstDataFormat == MNN_DATA_FORMAT_NCHW) { const int maxCount = batch * area * channel; const int block_num = runtime->blocks_num(maxCount); const int block_size = runtime->threads_num(); - NHWC8_2_NHWC<<>>(input, output, maxCount, channel, area, UP_DIV(channel, 8) * 8, - d_oc, d_area); + NHWC_2_NCHW<<>>(input, output, maxCount, channel, area, channel, d_oc, d_area); checkKernelErrors; return; } - if(srcDataFormat == MNN_DATA_FORMAT_NCHW && dstDataFormat == MNN_DATA_FORMAT_NHWC) { + + // NC4HW4 NCHW + if (srcDataFormat == MNN_DATA_FORMAT_NC4HW4 && dstDataFormat == MNN_DATA_FORMAT_NCHW) { + if (!srcDevice) { + const int maxCount = batch * area * channel; + const int block_num = runtime->blocks_num(maxCount); + const int block_size = runtime->threads_num(); + C4NHW4_2_NCHW<<>>(input, output, maxCount, channel, area, UP_DIV(channel, 4) * 4, d_oc, d_area); + checkKernelErrors; + } else { + const int maxCount = batch * area * channel; + const int block_num = runtime->blocks_num(maxCount); + const int block_size = runtime->threads_num(); + NHWC8_2_NCHW<<>>(input, output, maxCount, channel, area, UP_DIV(channel, 8) * 8, d_oc, d_area); + checkKernelErrors; + } + return; + } + + // NCHW NHWC + if (srcDataFormat == MNN_DATA_FORMAT_NCHW && dstDataFormat == MNN_DATA_FORMAT_NHWC) { const int maxCount = batch * area * channel; const int block_num = runtime->blocks_num(maxCount); const int block_size = runtime->threads_num(); - NCHW_2_NHWC<<>>(input, output, maxCount, channel, area, UP_DIV(channel, 8) * 8, - d_oc, d_area); + NCHW_2_NHWC<<>>(input, output, maxCount, channel, area, channel, d_oc, d_area); checkKernelErrors; return; } - MNN_PRINT("insideFormatConvert form %d to %d, not support\n", (int)srcDataFormat, (int)dstDataFormat); - -} - -void FormatConvert(void* output, void* input, MNN_DATA_FORMAT srcDataFormat, MNN_DATA_FORMAT dstDataFormat, CUDARuntime* runtime, \ - const int area, const int batch, const int channel, const Tensor* srcTensor, int precision, bool srcDevice, bool dstDevice) { - - bool isFp16 = (precision == 2); - bool isBf16 = (precision == 3); - if(batch == 0 || area == 0 || channel == 0) { - MNN_PRINT("Error: formatConvert size batch:%d - plane:%d - channel:%d, format:%d->%d, device:%d->%d\n", batch, area, channel, srcDataFormat, dstDataFormat, srcDevice, dstDevice); - return; - } - auto des = TensorUtils::getDescribe(srcTensor); - if ((des->quantAttr.get() != nullptr && des->type == DataType_DT_INT8) || srcTensor->getType().bits == 8) { - if(srcDataFormat == MNN_DATA_FORMAT_NC4HW4 && dstDataFormat == MNN_DATA_FORMAT_NC4HW4) { - if(!srcDevice && dstDevice) { - const int maxCount = batch * area * UP_DIV(channel, 8) * 8; - const int block_num = runtime->blocks_num(maxCount); - const int block_size = runtime->threads_num(); - C4NHW4_2_NHWC8<<>>((int8_t *)input, (int8_t *)output, - maxCount, batch, area, channel, UP_DIV(channel, 8) * 8); - checkKernelErrors; - return; - } - - if(srcDevice && !dstDevice) { - const int maxCount = batch * area * UP_DIV(channel, 4) * 4; - const int block_num = runtime->blocks_num(maxCount); - const int block_size = runtime->threads_num(); - NHWC8_2_C4NHW4<<>>((int8_t *)input, (int8_t *)output, - maxCount, batch, channel, area, UP_DIV(channel, 4) * 4); - checkKernelErrors; - return; - } + // NC4HWC4 NHWC + if (srcDataFormat == MNN_DATA_FORMAT_NC4HW4 && dstDataFormat == MNN_DATA_FORMAT_NHWC) { + if (!srcDevice) { + const int maxCount = batch * area * channel; + const int block_num = runtime->blocks_num(maxCount); + const int block_size = runtime->threads_num(); + C4NHW4_2_NHWC<<>>(input, output, maxCount, channel, area, UP_DIV(channel, 4) * 4, d_oc, d_area); + checkKernelErrors; + } else { + const int maxCount = batch * area * channel; + const int block_num = runtime->blocks_num(maxCount); + const int block_size = runtime->threads_num(); + NHWC8_2_NHWC<<>>(input, output, maxCount, channel, area, UP_DIV(channel, 8) * 8, d_oc, d_area); + checkKernelErrors; } - - insideFormatConvert((int8_t *)input, (int8_t *)output, srcDataFormat, dstDataFormat, runtime, area, batch, channel); return; } - isFp16 = isFp16 & (halide_type_float == srcTensor->getType().code); - isBf16 = isBf16 & (halide_type_float == srcTensor->getType().code); - if(srcDataFormat == MNN_DATA_FORMAT_NC4HW4 && dstDataFormat == MNN_DATA_FORMAT_NC4HW4) { - if(!srcDevice && dstDevice) { + // NCHW NC4HW4 + if(srcDataFormat == MNN_DATA_FORMAT_NCHW && dstDataFormat == MNN_DATA_FORMAT_NC4HW4) { + if (!dstDevice) { + const int maxCount = batch * area * UP_DIV(channel, 4) * 4; + const int block_num = runtime->blocks_num(maxCount); + const int block_size = runtime->threads_num(); + NCHW_2_C4NHW4<<>>(input, output, maxCount, channel, area, channel, d_oc4, d_area); + checkKernelErrors; + } else { const int maxCount = batch * area * UP_DIV(channel, 8) * 8; const int block_num = runtime->blocks_num(maxCount); const int block_size = runtime->threads_num(); - if(isFp16) { - C4NHW4_2_NHWC8<<>>((float *)input, (half *)output, - maxCount, batch, area, channel, UP_DIV(channel, 8) * 8); - checkKernelErrors; - } else if(isBf16) { - #ifdef ENABLE_CUDA_BF16 - C4NHW4_2_NHWC8<<>>((float *)input, (__nv_bfloat16 *)output, - maxCount, batch, area, channel, UP_DIV(channel, 8) * 8); - checkKernelErrors; - #endif - } else { - C4NHW4_2_NHWC8<<>>((float *)input, (float *)output, - maxCount, batch, area, channel, UP_DIV(channel, 8) * 8); - checkKernelErrors; - } - return; + NCHW_2_NHWC8<<>>(input, output, maxCount, channel, area, channel, d_oc8, d_area); + checkKernelErrors; } + return; + } - if(srcDevice && !dstDevice) { + // NHWC NC4HW4 + if(srcDataFormat == MNN_DATA_FORMAT_NHWC && dstDataFormat == MNN_DATA_FORMAT_NC4HW4) { + if (!dstDevice) { const int maxCount = batch * area * UP_DIV(channel, 4) * 4; const int block_num = runtime->blocks_num(maxCount); const int block_size = runtime->threads_num(); - if(isFp16) { - NHWC8_2_C4NHW4<<>>((half *)input, (float *)output, - maxCount, batch, channel, area, UP_DIV(channel, 4) * 4); - checkKernelErrors; - } else if(isBf16) { - #ifdef ENABLE_CUDA_BF16 - NHWC8_2_C4NHW4<<>>((__nv_bfloat16 *)input, (float *)output, - maxCount, batch, channel, area, UP_DIV(channel, 4) * 4); - checkKernelErrors; - #endif - } else { - NHWC8_2_C4NHW4<<>>((float *)input, (float *)output, - maxCount, batch, channel, area, UP_DIV(channel, 4) * 4); - checkKernelErrors; - } - return; - } - - if(srcDevice && dstDevice) { + NHWC_2_C4NHW4<<>>(input, output, maxCount, channel, area, channel, d_oc4, d_area); + checkKernelErrors; + } else { const int maxCount = batch * area * UP_DIV(channel, 8) * 8; const int block_num = runtime->blocks_num(maxCount); const int block_size = runtime->threads_num(); - if(isFp16 || isBf16) { - NCHW_2_NCHW<<>>((half *)input, (half *)output, maxCount); - checkKernelErrors; - } else { - NCHW_2_NCHW<<>>((float *)input, (float *)output, maxCount); - checkKernelErrors; - } - return; + NHWC_2_NHWC8<<>>(input, output, maxCount, channel, area, channel, d_oc8, d_area); + checkKernelErrors; } + return; + } + + MNN_ERROR("CUDA backend doesn't support the format conversion.\n"); + MNN_ASSERT(false); + return; +} + +void FormatConvert(void* output, void* input, MNN_DATA_FORMAT srcDataFormat, MNN_DATA_FORMAT dstDataFormat, CUDARuntime* runtime, \ + const int area, const int batch, const int channel, const Tensor* srcTensor, int precision, bool srcDevice, bool dstDevice) { + if(batch == 0 || area == 0 || channel == 0) { + MNN_PRINT("Error: formatConvert size batch:%d - plane:%d - channel:%d, format:%d->%d, device:%d->%d\n", batch, area, channel, srcDataFormat, dstDataFormat, srcDevice, dstDevice); + return; + } + + bool isFp16 = (precision == 2) && (halide_type_float == srcTensor->getType().code); + bool isBf16 = (precision == 3) && (halide_type_float == srcTensor->getType().code); + + // int8 case + auto des = TensorUtils::getDescribe(srcTensor); + if ((des->quantAttr.get() != nullptr && des->type == DataType_DT_INT8) || srcTensor->getType().bits == 8) { + insideFormatConvert((int8_t *)input, (int8_t *)output, srcDataFormat, dstDataFormat, runtime, area, batch, channel, srcDevice, dstDevice); + return; } + // FP case if(!srcDevice) { if(isFp16) { - insideFormatConvert((float *)input, (half *)output, srcDataFormat, dstDataFormat, runtime, area, batch, channel); + insideFormatConvert((float *)input, (half *)output, srcDataFormat, dstDataFormat, runtime, area, batch, channel, srcDevice, dstDevice); } else if(isBf16) { #ifdef ENABLE_CUDA_BF16 - insideFormatConvert((float *)input, (__nv_bfloat16 *)output, srcDataFormat, dstDataFormat, runtime, area, batch, channel); + insideFormatConvert((float *)input, (__nv_bfloat16 *)output, srcDataFormat, dstDataFormat, runtime, area, batch, channel, srcDevice, dstDevice); #endif } else { - insideFormatConvert((float *)input, (float *)output, srcDataFormat, dstDataFormat, runtime, area, batch, channel); + insideFormatConvert((float *)input, (float *)output, srcDataFormat, dstDataFormat, runtime, area, batch, channel, srcDevice, dstDevice); } } else if(!dstDevice) { if(isFp16) { - insideFormatConvert((half *)input, (float *)output, srcDataFormat, dstDataFormat, runtime, area, batch, channel); + insideFormatConvert((half *)input, (float *)output, srcDataFormat, dstDataFormat, runtime, area, batch, channel, srcDevice, dstDevice); } else if(isBf16) { #ifdef ENABLE_CUDA_BF16 - insideFormatConvert<__nv_bfloat16, float>((__nv_bfloat16 *)input, (float *)output, srcDataFormat, dstDataFormat, runtime, area, batch, channel); + insideFormatConvert<__nv_bfloat16, float>((__nv_bfloat16 *)input, (float *)output, srcDataFormat, dstDataFormat, runtime, area, batch, channel, srcDevice, dstDevice); #endif } else { - insideFormatConvert((float *)input, (float *)output, srcDataFormat, dstDataFormat, runtime, area, batch, channel); + insideFormatConvert((float *)input, (float *)output, srcDataFormat, dstDataFormat, runtime, area, batch, channel, srcDevice, dstDevice); } } else { if(isFp16) { - insideFormatConvert((half *)input, (half *)output, srcDataFormat, dstDataFormat, runtime, area, batch, channel); + insideFormatConvert((half *)input, (half *)output, srcDataFormat, dstDataFormat, runtime, area, batch, channel, srcDevice, dstDevice); } else if(isBf16) { #ifdef ENABLE_CUDA_BF16 - insideFormatConvert<__nv_bfloat16, __nv_bfloat16>((__nv_bfloat16 *)input, (__nv_bfloat16 *)output, srcDataFormat, dstDataFormat, runtime, area, batch, channel); + insideFormatConvert<__nv_bfloat16, __nv_bfloat16>((__nv_bfloat16 *)input, (__nv_bfloat16 *)output, srcDataFormat, dstDataFormat, runtime, area, batch, channel, srcDevice, dstDevice); #endif } else { - insideFormatConvert((float *)input, (float *)output, srcDataFormat, dstDataFormat, runtime, area, batch, channel); + insideFormatConvert((float *)input, (float *)output, srcDataFormat, dstDataFormat, runtime, area, batch, channel, srcDevice, dstDevice); } } + return; } diff --git a/source/backend/cuda/execution/bf16/ConvCutlassBf16Execution.cu b/source/backend/cuda/execution/bf16/ConvCutlassBf16Execution.cu index cf5f678aa..f3741cbe6 100644 --- a/source/backend/cuda/execution/bf16/ConvCutlassBf16Execution.cu +++ b/source/backend/cuda/execution/bf16/ConvCutlassBf16Execution.cu @@ -26,7 +26,7 @@ ConvCutlassBf16Execution::Resource::Resource(Backend* bn, const MNN::Op* op) { const float* filterDataPtr = nullptr; int weightSize = 0; std::shared_ptr quanCommon; - ConvolutionCommon::getConvParameters(&quanCommon, conv, &filterDataPtr, &weightSize); + ConvolutionCommon::getConvParameters(&quanCommon, bn, conv, &filterDataPtr, &weightSize); auto oc = common->outputCount(); int l = weightSize / oc; diff --git a/source/backend/cuda/execution/int8/ConvInt8CutlassExecution.cu b/source/backend/cuda/execution/int8/ConvInt8CutlassExecution.cu index 6eadbe70a..8421f3665 100644 --- a/source/backend/cuda/execution/int8/ConvInt8CutlassExecution.cu +++ b/source/backend/cuda/execution/int8/ConvInt8CutlassExecution.cu @@ -185,7 +185,7 @@ ConvInt8CutlassExecution::Resource::Resource(Backend* bn, const MNN::Op* op) { int weightSize = 0; std::shared_ptr quanCommon; - bool res = ConvolutionCommon::getConvInt8Parameters(conv, quanCommon, filterDataPtr, weightSize, + bool res = ConvolutionCommon::getConvInt8Parameters(conv, quanCommon, bn, filterDataPtr, weightSize, mScaleFloatVec, mBiasInt32Vec); // inputScale, diff --git a/source/backend/hiai/backend/NPUBackend.cpp b/source/backend/hiai/backend/NPUBackend.cpp index baa1a05b8..cd4a0008a 100644 --- a/source/backend/hiai/backend/NPUBackend.cpp +++ b/source/backend/hiai/backend/NPUBackend.cpp @@ -389,11 +389,11 @@ namespace MNN { mSclipMap.clear(); } - void NPUBackend::onResizeEnd() { - bulidIRModelAndLoad(); + ErrorCode NPUBackend::onResizeEnd() { + return bulidIRModelAndLoad(); } - void NPUBackend::bulidIRModelAndLoad() { + ErrorCode NPUBackend::bulidIRModelAndLoad() { std::vector inputs; for (auto input : mInputOps){ inputs.push_back(input.second[0]); @@ -414,7 +414,7 @@ namespace MNN { std::shared_ptr model = std::make_shared("model", graphName); if (model == nullptr) { MNN_ERROR("Create model fail."); - return; + return INVALID_VALUE; } model->SetGraph(graph); @@ -431,7 +431,7 @@ namespace MNN { std::string buffer(size, ' '); if (!file.read(&buffer[0], size)) { MNN_ERROR("Failed to read file.\n"); - return; + return INVALID_VALUE; } file.close(); buildOptions.quantizeConfig = buffer; @@ -440,13 +440,13 @@ namespace MNN { auto ret = modelBuilder.Build(buildOptions, modelName, model, builtModel); if (ret != hiai::SUCCESS || builtModel == nullptr) { MNN_ERROR("model build fail !\n"); - return; + return INVALID_VALUE; } #ifdef HIAI_DEBUG ret = builtModel->SaveToFile("/data/local/tmp/test_quant.om"); if (ret != hiai::SUCCESS) { MNN_ERROR("builtModel SaveToFile failed\n"); - return; + return INVALID_VALUE; } #endif modelManager = hiai::CreateModelManager(); @@ -454,12 +454,12 @@ namespace MNN { ret = modelManager->Init(initOptions, builtModel, nullptr); if (ret != hiai::SUCCESS) { MNN_ERROR("modelManager Init failed"); - return; + return INVALID_VALUE; } ret = modelManager->SetPriority(hiai::ModelPriority::PRIORITY_HIGH); if (ret != hiai::SUCCESS) { MNN_ERROR("modelManager SetPriority failed"); - return; + return INVALID_VALUE; } std::vector inputDesc = builtModel->GetInputTensorDescs(); for (size_t i = 0; i < inputDesc.size(); i++) { @@ -478,7 +478,7 @@ namespace MNN { index++; } } - return; + return NO_ERROR; } int NPUBackend::process() const { diff --git a/source/backend/hiai/backend/NPUBackend.hpp b/source/backend/hiai/backend/NPUBackend.hpp index 8dd21662d..3c8df1db7 100644 --- a/source/backend/hiai/backend/NPUBackend.hpp +++ b/source/backend/hiai/backend/NPUBackend.hpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include "HiAiModelManagerService.h" @@ -267,11 +268,11 @@ namespace MNN { virtual void onCopyBuffer(const Tensor* srcTensor, const Tensor* dstTensor) const override; virtual void onResizeBegin() override; - virtual void onResizeEnd() override; + virtual ErrorCode onResizeEnd() override; public: - void bulidIRModelAndLoad(); + ErrorCode bulidIRModelAndLoad(); int process() const ; shared_ptr getInputOps(const Op *op, int index = 0); diff --git a/source/backend/hiai/execution/NPUConvolution.cpp b/source/backend/hiai/execution/NPUConvolution.cpp index 6459ff2a0..dbafa6870 100644 --- a/source/backend/hiai/execution/NPUConvolution.cpp +++ b/source/backend/hiai/execution/NPUConvolution.cpp @@ -36,7 +36,7 @@ ErrorCode NPUConvolution::onResize(const std::vector &inputs, const st std::shared_ptr quanCommon; if (nullptr != conv2D->quanParameter()) { - quanCommon = ConvolutionCommon::load(conv2D->quanParameter(), true); + quanCommon = ConvolutionCommon::load(conv2D, backend(), true); if (nullptr == quanCommon) { MNN_ERROR("Memory not Enough, can't extract IDST Convolution: %s \n", mOp->name()->c_str()); } diff --git a/source/backend/hiai/execution/NPUConvolutionDepthwise.cpp b/source/backend/hiai/execution/NPUConvolutionDepthwise.cpp index c7907ea22..b7adde852 100644 --- a/source/backend/hiai/execution/NPUConvolutionDepthwise.cpp +++ b/source/backend/hiai/execution/NPUConvolutionDepthwise.cpp @@ -36,7 +36,7 @@ ErrorCode NPUConvolutionDepthwise::onResize(const std::vector &inputs, std::shared_ptr quanCommon; if (nullptr != conv2D->quanParameter()) { - quanCommon = ConvolutionCommon::load(conv2D->quanParameter(), true); + quanCommon = ConvolutionCommon::load(conv2D, backend(), true); if (nullptr == quanCommon) { MNN_ERROR("Memory not Enough, can't extract IDST Convolution: %s \n", mOp->name()->c_str()); } diff --git a/source/backend/metal/MetalBackend.hpp b/source/backend/metal/MetalBackend.hpp index 71b56c81d..8eeb74bca 100644 --- a/source/backend/metal/MetalBackend.hpp +++ b/source/backend/metal/MetalBackend.hpp @@ -14,6 +14,7 @@ #include "core/TensorUtils.hpp" #include "MNN_generated.h" #include "MetalDefine.h" +#include #include //#include "MNNMetalContext.h" #include "MetalCache_generated.h" @@ -141,7 +142,7 @@ class MetalBackend : public Backend { const MNN::Op *op) override; virtual void onResizeBegin() override; - virtual void onResizeEnd() override; + virtual ErrorCode onResizeEnd() override; virtual void onExecuteBegin() const override; virtual void onExecuteEnd() const override; virtual int onSync(Tensor::MapType mtype, bool toCpu, const Tensor* dstTensor) override; diff --git a/source/backend/metal/MetalBackend.mm b/source/backend/metal/MetalBackend.mm index 89c4079cb..57962cbb4 100644 --- a/source/backend/metal/MetalBackend.mm +++ b/source/backend/metal/MetalBackend.mm @@ -355,9 +355,10 @@ MTLSize getTensorShape(id shape, const Tensor *tensor) { [ctx wait]; } -void MetalBackend::onResizeEnd() { +ErrorCode MetalBackend::onResizeEnd() { auto ctx = (__bridge MNNMetalContext *)context(); mFrameEncodeCache = (!ctx.isCommitEachShader && mOpFullSupport); + return NO_ERROR; } void MetalBackend::onCopyHostToDevice(const Tensor *src, const Tensor *dst) const { diff --git a/source/backend/metal/MetalConvolutionCommon.mm b/source/backend/metal/MetalConvolutionCommon.mm index a59fc8882..cfcaf3093 100644 --- a/source/backend/metal/MetalConvolutionCommon.mm +++ b/source/backend/metal/MetalConvolutionCommon.mm @@ -94,7 +94,7 @@ void MetalConvolutionCommon::loadWeight(const MNN::Convolution2D *conv) { std::shared_ptr qnt = NULL; if (conv->quanParameter()) { - qnt = ConvolutionCommon::load(conv->quanParameter(), true); + qnt = ConvolutionCommon::load(conv, backend(), true); } mWeight = weightForConv(conv, qnt.get(), mDepthwise); } diff --git a/source/backend/metal/MetalDeconvolution.mm b/source/backend/metal/MetalDeconvolution.mm index d4d691d95..52ef54cf5 100755 --- a/source/backend/metal/MetalDeconvolution.mm +++ b/source/backend/metal/MetalDeconvolution.mm @@ -139,7 +139,7 @@ static int leastCommonMultiple(int m, int n) { // forcy downgrade to float like what CPU does std::shared_ptr qnt = NULL; if (deconv->quanParameter()) { - qnt = ConvolutionCommon::load(deconv->quanParameter(), true); + qnt = ConvolutionCommon::load(deconv, backend, true); } mWeight = weightForDeconv(context, mDepthwise, deconv, qnt.get()); mBias = biasForDeconv(context, deconv); diff --git a/source/backend/nnapi/backend/NNAPIBackend.cpp b/source/backend/nnapi/backend/NNAPIBackend.cpp index 9d2f1ee10..bc4755dc3 100644 --- a/source/backend/nnapi/backend/NNAPIBackend.cpp +++ b/source/backend/nnapi/backend/NNAPIBackend.cpp @@ -252,7 +252,7 @@ namespace MNN { mQuantCacheMap.clear(); } - void NNAPIBackend::onResizeEnd() { + ErrorCode NNAPIBackend::onResizeEnd() { buildModel(); mHalfBuffer.clear(); mQuantCacheMap.clear(); @@ -453,7 +453,7 @@ namespace MNN { return NO_ERROR; } - void NNAPIBackend::buildModel() { + ErrorCode NNAPIBackend::buildModel() { // set input and output of model std::vector inputOperands(mInputTensors.size()), outputOperands(mOutputTensors.size()); for (int i = 0; i < mInputTensors.size(); i++) { @@ -503,6 +503,7 @@ namespace MNN { CHECK(ANeuralNetworksCompilation_setPreference_27, mNNAPICompilation, ANEURALNETWORKS_PREFER_SUSTAINED_SPEED); CHECK(ANeuralNetworksCompilation_finish_27, mNNAPICompilation); CHECK(ANeuralNetworksBurst_create_29, mNNAPICompilation, &mNNAPIBurst); + return NO_ERROR; } void NNAPIBackend::invokeModel() const { diff --git a/source/backend/nnapi/backend/NNAPIBackend.hpp b/source/backend/nnapi/backend/NNAPIBackend.hpp index 8525f7ea6..17e947973 100644 --- a/source/backend/nnapi/backend/NNAPIBackend.hpp +++ b/source/backend/nnapi/backend/NNAPIBackend.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -80,7 +81,7 @@ namespace MNN { virtual void onCopyBuffer(const Tensor* srcTensor, const Tensor* dstTensor) const override; virtual void onResizeBegin() override; - virtual void onResizeEnd() override; + virtual ErrorCode onResizeEnd() override; public: class Creator { @@ -118,7 +119,7 @@ namespace MNN { ErrorCode buildQuantOperation(const Tensor* src, const Tensor* dst); ErrorCode replaceTensorWith(const Tensor* src, const Tensor* replace); uint32_t buildDequantOperand(const Tensor* t); - void buildModel(); + ErrorCode buildModel(); void invokeModel() const; private: bool mNCHW = false; diff --git a/source/backend/nnapi/execution/NNAPIConvolution.cpp b/source/backend/nnapi/execution/NNAPIConvolution.cpp index 120097a12..30a34c012 100644 --- a/source/backend/nnapi/execution/NNAPIConvolution.cpp +++ b/source/backend/nnapi/execution/NNAPIConvolution.cpp @@ -81,7 +81,7 @@ ErrorCode NNAPIConvolution::onResize(const std::vector &inputs, const weightPtr = conv2D->quanParameter()->buffer()->data(); weightSize = conv2D->quanParameter()->buffer()->size(); } else if (nullptr != conv2D->quanParameter()) { - quanCommon = ConvolutionCommon::load(conv2D->quanParameter(), true); + quanCommon = ConvolutionCommon::load(conv2D, backend(), true); if (nullptr == quanCommon) { MNN_ERROR("Memory not Enough, can't extract IDST Convolution: %s \n", mOp->name()->c_str()); } diff --git a/source/backend/opencl/core/OpenCLBackend.cpp b/source/backend/opencl/core/OpenCLBackend.cpp index 333677ec4..cc2200e33 100644 --- a/source/backend/opencl/core/OpenCLBackend.cpp +++ b/source/backend/opencl/core/OpenCLBackend.cpp @@ -505,11 +505,12 @@ void OpenCLBackend::onResizeBegin() { mOpenCLRuntime->releaseRecord(); } -void OpenCLBackend::onResizeEnd() { +ErrorCode OpenCLBackend::onResizeEnd() { #ifndef ENABLE_OPENCL_TIME_PROFILER mOpenCLRuntime->setCommandQueueProfileDisable(); #endif mOpenCLRuntime->endRecord(); + return NO_ERROR; } void OpenCLBackend::onExecuteBegin() const { diff --git a/source/backend/opencl/core/OpenCLBackend.hpp b/source/backend/opencl/core/OpenCLBackend.hpp index 9e90e1bce..a22c5f2a5 100644 --- a/source/backend/opencl/core/OpenCLBackend.hpp +++ b/source/backend/opencl/core/OpenCLBackend.hpp @@ -11,6 +11,7 @@ #include "core/Backend.hpp" #include "MNN_generated.h" +#include #include #include @@ -102,7 +103,7 @@ class OpenCLBackend : public Backend { const MNN::Op *op) override; virtual void onResizeBegin() override; - virtual void onResizeEnd() override; + virtual ErrorCode onResizeEnd() override; virtual void onExecuteBegin() const override; virtual void onExecuteEnd() const override; diff --git a/source/backend/opencl/execution/buffer/BinaryBufExecution.cpp b/source/backend/opencl/execution/buffer/BinaryBufExecution.cpp index 4a5272095..61cdce622 100644 --- a/source/backend/opencl/execution/buffer/BinaryBufExecution.cpp +++ b/source/backend/opencl/execution/buffer/BinaryBufExecution.cpp @@ -315,7 +315,7 @@ class BinaryBufCreator : public OpenCLBackend::Creator { case BinaryOpOperation_SquaredDifference: return new BinaryBufExecution(inputs, "(in0-in1)*(in0-in1)", op, backend); case BinaryOpOperation_ATAN2: - return new BinaryBufExecution(inputs, "atan(sign(in1)*in0/(fabs(in1)>(FLOAT4)((FLOAT)0.0000001)?fabs(in1):(FLOAT4)((FLOAT)0.0000001)))", op, backend); + return new BinaryBufExecution(inputs, "(in1==(FLOAT4)0?(sign(in0)*(FLOAT4)(PI/2)):(atan(in0/in1)+(in1>(FLOAT4)0?(FLOAT4)0:sign(in0)*(FLOAT4)PI)))", op, backend); case BinaryOpOperation_NOTEQUAL: return new BinaryBufExecution(inputs, "convert_float4(-isnotequal(in0,in1))", op, backend); case BinaryOpOperation_MOD: diff --git a/source/backend/opencl/execution/buffer/ConvBufExecution.cpp b/source/backend/opencl/execution/buffer/ConvBufExecution.cpp index 6ae253bc9..e771bca16 100644 --- a/source/backend/opencl/execution/buffer/ConvBufExecution.cpp +++ b/source/backend/opencl/execution/buffer/ConvBufExecution.cpp @@ -325,7 +325,7 @@ ConvBufExecution::ConvBufExecution(const std::vector &inputs, const st mRasterExe.reset(new RasterBufExecution({mFilter.get()}, op, mOpenCLBackend)); } else { int weightSize = 0; - ConvolutionCommon::getConvParameters(&quanCommon, conv2dParams, &mFilterDataPtr, &weightSize); + ConvolutionCommon::getConvParameters(&quanCommon, backend, conv2dParams, &mFilterDataPtr, &weightSize); //select opt conv method mConv1x1Opt = (mKernelHeight == mKernelWidth && mKernelHeight == 1 && mPaddings[0] == 0 && mPaddings[1] == 0 && mStrides[0] == 1 && mStrides[1] == 1 && inputs[0]->width() >= 4); @@ -517,7 +517,7 @@ ErrorCode ConvBufExecution::onResize(const std::vector &inputs, const int min_index = min_cost.second; if(min_index >= c8_index_start) {//if best kernel is "conv_2d_1x1_c8h1w4", set weight packCout to 8 int weightSize = 0; - ConvolutionCommon::getConvParameters(&quanCommon, mConv2dParams, &mFilterDataPtr, &weightSize); + ConvolutionCommon::getConvParameters(&quanCommon, backend(), mConv2dParams, &mFilterDataPtr, &weightSize); setConv1x1WeightBuffer(8, 4, mFilterDataPtr); } mGlobalWorkSize = {globalWorkSize[min_index][0], globalWorkSize[min_index][1]}; diff --git a/source/backend/opencl/execution/buffer/ConvBufWinograd.cpp b/source/backend/opencl/execution/buffer/ConvBufWinograd.cpp index 55948f724..57b6b6623 100644 --- a/source/backend/opencl/execution/buffer/ConvBufWinograd.cpp +++ b/source/backend/opencl/execution/buffer/ConvBufWinograd.cpp @@ -54,7 +54,7 @@ ConvBufWinograd::ConvBufWinograd(const MNN::Convolution2D* op, Backend* backend) int weightSize = 0; const float* filterDataPtr = nullptr; std::shared_ptr quanCommon; - ConvolutionCommon::getConvParameters(&quanCommon, op, &filterDataPtr, &weightSize); + ConvolutionCommon::getConvParameters(&quanCommon, backend, op, &filterDataPtr, &weightSize); int oc = mCommon->outputCount(); int ic = weightSize / oc / mCommon->kernelX() / mCommon->kernelY(); diff --git a/source/backend/opencl/execution/buffer/ConvSubgroupBufExecution.cpp b/source/backend/opencl/execution/buffer/ConvSubgroupBufExecution.cpp index b3336be60..396d1d750 100644 --- a/source/backend/opencl/execution/buffer/ConvSubgroupBufExecution.cpp +++ b/source/backend/opencl/execution/buffer/ConvSubgroupBufExecution.cpp @@ -112,7 +112,7 @@ ConvSubgroupBuf::ConvSubgroupBuf(const std::vector &inputs, const std: const float *FilterDataPtr = NULL; int weightSize = 0; std::shared_ptr quanCommon; - ConvolutionCommon::getConvParameters(&quanCommon, conv2dParams, &FilterDataPtr, &weightSize); + ConvolutionCommon::getConvParameters(&quanCommon, backend, conv2dParams, &FilterDataPtr, &weightSize); if (FilterDataPtr != nullptr) { std::shared_ptr sourceWeight( Tensor::create(std::vector{mOutputChannel, mInputChannel, mKernelWidth, mKernelHeight}, diff --git a/source/backend/opencl/execution/buffer/DeconvBufExecution.cpp b/source/backend/opencl/execution/buffer/DeconvBufExecution.cpp index 68bd691b3..2f1bddeb4 100644 --- a/source/backend/opencl/execution/buffer/DeconvBufExecution.cpp +++ b/source/backend/opencl/execution/buffer/DeconvBufExecution.cpp @@ -35,7 +35,7 @@ DeconvBufExecution::DeconvBufExecution(const std::vector &inputs, cons const float* filterDataPtr = nullptr; int weightSize = 0; std::shared_ptr quanCommon; - ConvolutionCommon::getConvParameters(&quanCommon, conv2dParams, &filterDataPtr, &weightSize); + ConvolutionCommon::getConvParameters(&quanCommon, backend, conv2dParams, &filterDataPtr, &weightSize); int inputChannel = weightSize / (kernelWidth * kernelHeight * outputChannel); std::vector filterShape{outputChannel, inputChannel, kernelHeight, kernelWidth}; diff --git a/source/backend/opencl/execution/buffer/DepthwiseConvBufExecution.cpp b/source/backend/opencl/execution/buffer/DepthwiseConvBufExecution.cpp index 8fdb986c3..0ac37171e 100644 --- a/source/backend/opencl/execution/buffer/DepthwiseConvBufExecution.cpp +++ b/source/backend/opencl/execution/buffer/DepthwiseConvBufExecution.cpp @@ -35,7 +35,7 @@ DepthwiseConvBufExecution::DepthwiseConvBufExecution(const std::vector const float* filterDataPtr = nullptr; int filterDataSize = 0; std::shared_ptr quanCommon; - ConvolutionCommon::getConvParameters(&quanCommon, mCon2dParams, &filterDataPtr, &filterDataSize); + ConvolutionCommon::getConvParameters(&quanCommon, backend, mCon2dParams, &filterDataPtr, &filterDataSize); mFilter.reset(Tensor::createDevice({1, ROUND_UP(filterImageShape[1], 2)/*for kernel C8 read*/, 1, 4 * filterImageShape[0]})); std::shared_ptr filterBuffer(Tensor::createDevice(filterShape)); diff --git a/source/backend/opencl/execution/buffer/DepthwiseConvSubgroupBufExecution.cpp b/source/backend/opencl/execution/buffer/DepthwiseConvSubgroupBufExecution.cpp index efdce0e0d..ffe4b3d50 100644 --- a/source/backend/opencl/execution/buffer/DepthwiseConvSubgroupBufExecution.cpp +++ b/source/backend/opencl/execution/buffer/DepthwiseConvSubgroupBufExecution.cpp @@ -40,7 +40,7 @@ DepthwiseConvSubgroupBufExecution::DepthwiseConvSubgroupBufExecution(const std:: const float *filterDataPtr = nullptr; int filterDataSize = 0; std::shared_ptr quanCommon; - ConvolutionCommon::getConvParameters(&quanCommon, mCon2dParams, &filterDataPtr, &filterDataSize); + ConvolutionCommon::getConvParameters(&quanCommon, backend, mCon2dParams, &filterDataPtr, &filterDataSize); if (filterDataPtr != nullptr) { std::shared_ptr sourceWeight(Tensor::create( std::vector{1, outputChannel, kernelWidth, kernelHeight}, diff --git a/source/backend/opencl/execution/buffer/LoopBufExecution.cpp b/source/backend/opencl/execution/buffer/LoopBufExecution.cpp index 96d372571..574a1426e 100644 --- a/source/backend/opencl/execution/buffer/LoopBufExecution.cpp +++ b/source/backend/opencl/execution/buffer/LoopBufExecution.cpp @@ -17,7 +17,10 @@ namespace OpenCL { static void _TileOrPackTensor(Tensor *input, Tensor *output, cl::Kernel& kernel, cl::NDRange &globalWorkSize, cl::NDRange &localWorkSize, const int Width, const int Height, const int Channel, - const int Batch, OpenCLRuntime *runTime, const std::string &KernelName, const std::set &buildOptions) { + const int Batch, OpenCLRuntime *runTime, const std::string &KernelName, std::set buildOptions) { + if (TensorUtils::getDescribe(output)->dimensionFormat == MNN::MNN_DATA_FORMAT_NHWC || TensorUtils::getDescribe(input)->dimensionFormat == MNN::MNN_DATA_FORMAT_NHWC){ + buildOptions.emplace("-DMNN_NHWC"); + } kernel = runTime->buildKernel("loop_buf", KernelName, buildOptions); uint32_t mMaxWorkGroupSize = static_cast(runTime->getMaxWorkGroupSize(kernel)); std::vector mGlobalWorkSize = {(uint32_t)(Width * Height), (uint32_t)(UP_DIV(Channel, 4)), (uint32_t)(Batch)}; @@ -92,7 +95,7 @@ static void _setTensorStack(std::vector &result, const std::vector(Tensor::createDevice(std::vector{Batch, Channel, Height, Width})); + mTmpTensors[1] = std::make_shared(Tensor::createDevice(std::vector{Batch, Channel, Height, Width}, Tensor::CAFFE)); mOpenCLBackend->onAcquireBuffer(mTmpTensors[1].get(), Backend::DYNAMIC); Unit unit; @@ -108,7 +111,7 @@ static void _setTensorStack(std::vector &result, const std::vector(Tensor::createDevice(std::vector{Batch, Channel, Height, Width}))); + mOffsetTensors.emplace_back(std::make_shared(Tensor::createDevice(std::vector{Batch, Channel, Height, Width}, Tensor::CAFFE))); mOpenCLBackend->onAcquireBuffer(mOffsetTensors.back().get(), Backend::DYNAMIC); Unit unit; @@ -119,13 +122,13 @@ static void _setTensorStack(std::vector &result, const std::vector(Tensor::createDevice(std::vector{n, z, y, x})); + mTmpTensors[0] = std::make_shared(Tensor::createDevice(std::vector{n, z, y, x}, Tensor::CAFFE)); mOpenCLBackend->onAcquireBuffer(mTmpTensors[0].get(), Backend::DYNAMIC); int offset_index = 0; Unit unit; - std::string KernelName = "batch_gather_buf"; - unit.kernel = runTime->buildKernel("loop_buf", KernelName, mBuildOptions); + std::string KernelName = "batch_gather"; + unit.kernel = runTime->buildKernel("loop", KernelName, mBuildOptions); uint32_t mMaxWorkGroupSize = static_cast(runTime->getMaxWorkGroupSize(unit.kernel)); std::vector mGlobalWorkSize = {(uint32_t)(x * y), (uint32_t)(z), (uint32_t)(n)}; @@ -222,7 +225,7 @@ ErrorCode LoopBatchMatMulBufExecution::onResize(const std::vector &inp const int Width = Shape.at(2); const int Height = Shape.at(1); const int Batch = Shape.at(0); - mTmpTensors[i] = std::make_shared(Tensor::createDevice(std::vector{Batch, Channel, Height, Width})); + mTmpTensors[i] = std::make_shared(Tensor::createDevice(std::vector{Batch, Channel, Height, Width}, Tensor::CAFFE)); mOpenCLBackend->onAcquireBuffer(mTmpTensors[i].get(), Backend::DYNAMIC); Unit unit; @@ -238,7 +241,7 @@ ErrorCode LoopBatchMatMulBufExecution::onResize(const std::vector &inp const int Width = Shape.at(2); const int Height = Shape.at(1); const int Batch = Shape.at(0); - mOffsetTensors.emplace_back(std::make_shared(Tensor::createDevice(std::vector{Batch, Channel, Height, Width}))); + mOffsetTensors.emplace_back(std::make_shared(Tensor::createDevice(std::vector{Batch, Channel, Height, Width}, Tensor::CAFFE))); mOpenCLBackend->onAcquireBuffer(mOffsetTensors.back().get(), Backend::DYNAMIC); Unit unit; @@ -249,12 +252,12 @@ ErrorCode LoopBatchMatMulBufExecution::onResize(const std::vector &inp // matmul { - mTmpTensors[0] = std::make_shared(Tensor::createDevice(std::vector{1, n, e, h})); + mTmpTensors[0] = std::make_shared(Tensor::createDevice(std::vector{1, n, e, h}, Tensor::CAFFE)); mOpenCLBackend->onAcquireBuffer(mTmpTensors[0].get(), Backend::DYNAMIC); int offset_index = 0; Unit unit; - std::string KernelName = "batch_matmul_buf"; + std::string KernelName = "batch_matmul"; if (mHasBias) { mBuildOptions.emplace("-DBIAS"); } @@ -264,7 +267,7 @@ ErrorCode LoopBatchMatMulBufExecution::onResize(const std::vector &inp if (mTransposeB) { mBuildOptions.emplace("-DTRANSPOSE_B"); } - unit.kernel = runTime->buildKernel("loop_buf", KernelName, mBuildOptions); + unit.kernel = runTime->buildKernel("loop", KernelName, mBuildOptions); uint32_t mMaxWorkGroupSize = static_cast(runTime->getMaxWorkGroupSize(unit.kernel)); std::vector mGlobalWorkSize = {(uint32_t)(h), (uint32_t)(e),(uint32_t)(n)}; @@ -324,6 +327,70 @@ ErrorCode LoopBatchMatMulBufExecution::onResize(const std::vector &inp return NO_ERROR; } +LoopBinaryBufExecution::LoopBinaryBufExecution(const LoopParam *loop, const std::string &compute, const MNN::Op *op, Backend *bn) + : CommonExecution(bn, op) { + mLoop = loop; + mTensors.resize(mLoop->tensorNumber()); + auto cmd = loop->commands()->GetAs(0); + mBuildOptions.emplace("-DLOOP_BINARY_OPERATOR=" + compute); +} + +ErrorCode LoopBinaryBufExecution::onResize(const std::vector &inputs, const std::vector &outputs) { + auto cmd = mLoop->commands()->GetAs(0); + OpenCLBackend *mOpenCLBackend = (OpenCLBackend *)backend(); + auto runTime = mOpenCLBackend->getOpenCLRuntime(); + _setTensorStack(mTensors, inputs, outputs, mLoop); + mUnits.clear(); + + Unit unit; + auto input0 = mTensors[cmd->indexes()->data()[1]]; + std::vector Input0Shape = tensorShapeFormat(input0); + int Input0Size[4] = {Input0Shape.at(2), Input0Shape.at(1),Input0Shape.at(3),Input0Shape.at(0)}; + + auto input1 = mTensors[cmd->indexes()->data()[2]]; + std::vector Input1Shape = tensorShapeFormat(input1); + int Input1Size[4] = {Input1Shape.at(2), Input1Shape.at(1),Input1Shape.at(3),Input1Shape.at(0)}; + + auto output = mTensors[cmd->indexes()->data()[0]]; + std::vector Shape = tensorShapeFormat(output); + const int Channel = Shape.at(3); + const int Width = Shape.at(2); + const int Height = Shape.at(1); + const int Batch = Shape.at(0); + const int ChannelBlock = UP_DIV(Channel, 4); + auto BuildOptions = mBuildOptions; + if(Input0Size[2] != Input1Size[2]){ + BuildOptions.emplace("-DBROADCAST_CHANNEL"); + } + std::string KernelName = "broadcast_binary_buf"; + unit.kernel = runTime->buildKernel("loop_buf", KernelName, BuildOptions); + uint32_t mMaxWorkGroupSize = static_cast(runTime->getMaxWorkGroupSize(unit.kernel)); + + std::vector mGlobalWorkSize = {(uint32_t)(Width), (uint32_t)(Height), (uint32_t)(Batch * ChannelBlock)}; + + uint32_t index = 0; + cl_int ret = CL_SUCCESS; + ret |= unit.kernel.setArg(index++, mGlobalWorkSize[0]); + ret |= unit.kernel.setArg(index++, mGlobalWorkSize[1]); + ret |= unit.kernel.setArg(index++, mGlobalWorkSize[2]); + ret |= unit.kernel.setArg(index++, openCLBuffer(output)); + ret |= unit.kernel.setArg(index++, openCLBuffer(input0)); + ret |= unit.kernel.setArg(index++, openCLBuffer(input1)); + ret |= unit.kernel.setArg(index++, sizeof(Input0Size), Input0Size); + ret |= unit.kernel.setArg(index++, sizeof(Input1Size), Input1Size); + ret |= unit.kernel.setArg(index++, Width); + ret |= unit.kernel.setArg(index++, Height); + ret |= unit.kernel.setArg(index++, ChannelBlock); + MNN_CHECK_CL_SUCCESS(ret, "setArg LoopBinaryBufExecution"); + + std::vector mLocalWorkSize = localWS3DDefault(mGlobalWorkSize, mMaxWorkGroupSize, runTime, KernelName, unit.kernel).first; + + unit.globalWorkSize = {mGlobalWorkSize[0], mGlobalWorkSize[1], mGlobalWorkSize[2]}; + unit.localWorkSize = {mLocalWorkSize[0], mLocalWorkSize[1], mLocalWorkSize[2]}; + mUnits.emplace_back(unit); + return NO_ERROR; +} + class LoopBufCreator : public OpenCLBackend::Creator { public: virtual Execution *onCreate(const std::vector &inputs, const std::vector &outputs, @@ -351,6 +418,49 @@ class LoopBufCreator : public OpenCLBackend::Creator { if (OpType_MatMul == subop->type() && loop->parallel()) { return new LoopBatchMatMulBufExecution(loop, op, backend); } + if (OpType_BinaryOp == subop->type() && loop->parallel()) { + switch (subop->main_as_BinaryOp()->opType()) { + case BinaryOpOperation_MUL: + return new LoopBinaryBufExecution(loop, "in0*in1", op, backend); + case BinaryOpOperation_ADD: + return new LoopBinaryBufExecution(loop, "in0+in1", op, backend); + case BinaryOpOperation_SUB: + return new LoopBinaryBufExecution(loop, "in0-in1", op, backend); + case BinaryOpOperation_REALDIV: + return new LoopBinaryBufExecution(loop, "sign(in1)*in0/(fabs(in1)>(FLOAT4)((FLOAT)0.0000001)?fabs(in1):(FLOAT4)((FLOAT)0.0000001))", op, backend); + case BinaryOpOperation_MINIMUM: + return new LoopBinaryBufExecution(loop, "in0>in1?in1:in0", op, backend); + case BinaryOpOperation_MAXIMUM: + return new LoopBinaryBufExecution(loop, "in0>in1?in0:in1", op, backend); + case BinaryOpOperation_GREATER: + return new LoopBinaryBufExecution(loop, "convert_float4(-isgreater(in0,in1))", op, backend); + case BinaryOpOperation_LESS: + return new LoopBinaryBufExecution(loop, "convert_float4(-isless(in0,in1))", op, backend); + case BinaryOpOperation_LESS_EQUAL: + return new LoopBinaryBufExecution(loop, "convert_float4(-islessequal(in0,in1))", op, backend); + case BinaryOpOperation_GREATER_EQUAL: + return new LoopBinaryBufExecution(loop, "convert_float4(-isgreaterequal(in0,in1))", op, backend); + case BinaryOpOperation_EQUAL: + return new LoopBinaryBufExecution(loop, "convert_float4(-isequal(in0,in1))", op, backend); + case BinaryOpOperation_FLOORDIV: + return new LoopBinaryBufExecution(loop, "floor(sign(in1)*in0/(fabs(in1)>(FLOAT4)((FLOAT)0.0000001)?fabs(in1):(FLOAT4)((FLOAT)0.0000001)))", op, backend); + case BinaryOpOperation_FLOORMOD: + return new LoopBinaryBufExecution(loop, "in0-floor(sign(in1)*in0/(fabs(in1)>(FLOAT4)((FLOAT)0.0000001)?fabs(in1):(FLOAT4)((FLOAT)0.0000001)))*in1", op, backend); + case BinaryOpOperation_POW: + return new LoopBinaryBufExecution(loop, "pow(in0,in1)", op, backend); + case BinaryOpOperation_SquaredDifference: + return new LoopBinaryBufExecution(loop, "(in0-in1)*(in0-in1)", op, backend); + case BinaryOpOperation_ATAN2: + return new LoopBinaryBufExecution(loop, "atan(sign(in1)*in0/(fabs(in1)>(FLOAT4)((FLOAT)0.0000001)?fabs(in1):(FLOAT4)((FLOAT)0.0000001)))", op, backend); + case BinaryOpOperation_NOTEQUAL: + return new LoopBinaryBufExecution(loop, "convert_float4(-isnotequal(in0,in1))", op, backend); + case BinaryOpOperation_MOD: + return new LoopBinaryBufExecution(loop, "in0-floor(sign(in1)*in0/(fabs(in1)>(FLOAT4)((FLOAT)0.0000001)?fabs(in1):(FLOAT4)((FLOAT)0.0000001)))*in1", op, backend); + default: + break; + } + return nullptr; + } } return nullptr; } diff --git a/source/backend/opencl/execution/buffer/LoopBufExecution.hpp b/source/backend/opencl/execution/buffer/LoopBufExecution.hpp index abda4f412..7a5270181 100644 --- a/source/backend/opencl/execution/buffer/LoopBufExecution.hpp +++ b/source/backend/opencl/execution/buffer/LoopBufExecution.hpp @@ -54,6 +54,19 @@ class LoopBatchMatMulBufExecution : public CommonExecution { std::set mBuildOptions; }; + +class LoopBinaryBufExecution : public CommonExecution { +public: + LoopBinaryBufExecution(const LoopParam *loop, const std::string &compute, const MNN::Op *op, Backend *bn); + virtual ~LoopBinaryBufExecution() = default; + virtual ErrorCode onResize(const std::vector &inputs, const std::vector &outputs) override; + +private: + const LoopParam *mLoop; + std::vector mTensors; + std::set mBuildOptions; +}; + } // namespace OpenCL } // namespace MNN #endif /* LoopBufExecution_hpp */ diff --git a/source/backend/opencl/execution/buffer/SoftmaxBufExecution.cpp b/source/backend/opencl/execution/buffer/SoftmaxBufExecution.cpp index 48dd8a9be..1906850a2 100644 --- a/source/backend/opencl/execution/buffer/SoftmaxBufExecution.cpp +++ b/source/backend/opencl/execution/buffer/SoftmaxBufExecution.cpp @@ -21,10 +21,11 @@ SoftmaxBufExecution::SoftmaxBufExecution(const std::vector &inputs, in mOpenCLBackend = static_cast(backend); } -bool SoftmaxBufExecution::buildSoftmaxKernel() { +bool SoftmaxBufExecution::buildSoftmaxKernel(int localSize) { auto runtime = mOpenCLBackend->getOpenCLRuntime(); if (mKernel.get() == nullptr) { std::set buildOptions; + buildOptions.emplace("-DSOFTMAX_LOCAL_SIZE=" + std::to_string(localSize)); std::string kernelName; if (mAxis == 1) { mKernel = runtime->buildKernel("softmax_buf", "softmax_channel", buildOptions); @@ -39,6 +40,14 @@ bool SoftmaxBufExecution::buildSoftmaxKernel() { return true; } +int SoftmaxBufExecution::getLocalSize(int size, int maxGroupSize){ + int local_size = 1; + while(local_size * 2 <= maxGroupSize && local_size * 2 <= size){ + local_size *= 2; + } + return local_size; +} + ErrorCode SoftmaxBufExecution::onResize(const std::vector &inputs, const std::vector &outputs) { Tensor *input = inputs[0]; Tensor *output = outputs[0]; @@ -70,63 +79,47 @@ ErrorCode SoftmaxBufExecution::onResize(const std::vector &inputs, con const int channelBlocks = UP_DIV(outputChannels, 4); const int remainChannels = channelBlocks * 4 - outputChannels; + auto MaxWorkItems = mOpenCLBackend->getOpenCLRuntime()->getMaxWorkItemSizes(); + int localSize = getLocalSize(channel, MaxWorkItems[0]); + if(localSize < 4){ + localSize = 1; + } if(inputBatch == outside && channel == inputChannels && inside == inputWidth * inputHeight){ mAxis = 1; - }else if(inputBatch * inputChannels == outside && channel == inputHeight && inside == inputHeight){ + localSize = getLocalSize(channelBlocks, MaxWorkItems[0]); + }else if(inputBatch * inputChannels == outside && channel == inputHeight && inside == inputWidth){ mAxis = 2; }else if(inputBatch * inputChannels * inputHeight == outside && channel == inputWidth && inside == 1){ mAxis = 3; } - buildSoftmaxKernel(); + buildSoftmaxKernel(localSize); + cl_int ret = CL_SUCCESS; + int shape[] = {outputBatch, channelBlocks, outputHeight, outputWidth}; if (mAxis == 1) { - mGlobalWorkSize = {static_cast(outputWidth), - static_cast(outputHeight * outputBatch), 1}; - int shape[] = {outputBatch, channelBlocks, outputHeight, outputWidth}; - - uint32_t idx = 0; - cl_int ret = CL_SUCCESS; - ret |= mKernel.setArg(idx++, mGlobalWorkSize[0]); - ret |= mKernel.setArg(idx++, mGlobalWorkSize[1]); - ret |= mKernel.setArg(idx++, mGlobalWorkSize[2]); - - ret |= mKernel.setArg(idx++, openCLBuffer(input)); - ret |= mKernel.setArg(idx++, openCLBuffer(output)); - ret |= mKernel.setArg(idx++, static_cast(outputChannels)); - ret |= mKernel.setArg(idx++, remainChannels); - ret |= mKernel.setArg(idx++, shape); - MNN_CHECK_CL_SUCCESS(ret, "setArg SoftmaxBufExecution axis_1"); - - std::string kernelName = "softmax_buf_channel"; - mLocalWorkSize = - localWS3DDefault(mGlobalWorkSize, mMaxWorkGroupSize, mOpenCLBackend->getOpenCLRuntime(), kernelName, mKernel).first; + mGlobalWorkSize = {(uint32_t)(localSize), (uint32_t)outputWidth, (uint32_t)outputHeight * outputBatch}; + } else if (mAxis == 2){ - mGlobalWorkSize = {(uint32_t)channelBlocks*outputWidth, (uint32_t)outputBatch, 1}; - int shape[] = {outputBatch, channelBlocks, outputHeight, outputWidth}; - cl_int ret = CL_SUCCESS; - ret |= mKernel.setArg(0, openCLBuffer(input)); - ret |= mKernel.setArg(1, openCLBuffer(output)); - ret |= mKernel.setArg(2, shape); - MNN_CHECK_CL_SUCCESS(ret, "setArg SoftmaxBufExecution axis_2"); - - std::string kernelName = "softmax_buf_height"; - mLocalWorkSize = - localWS3DDefault(mGlobalWorkSize, mMaxWorkGroupSize, mOpenCLBackend->getOpenCLRuntime(), kernelName, mKernel).first; + mGlobalWorkSize = {(uint32_t)(localSize), (uint32_t)channelBlocks*outputWidth, (uint32_t)outputBatch}; } else { MNN_ASSERT(mAxis == 3); - mGlobalWorkSize = {(uint32_t)channelBlocks, (uint32_t)outputBatch*outputHeight, 1}; - int shape[] = {outputBatch, channelBlocks, outputHeight, outputWidth}; - cl_int ret = CL_SUCCESS; - ret |= mKernel.setArg(0, openCLBuffer(input)); - ret |= mKernel.setArg(1, openCLBuffer(output)); - ret |= mKernel.setArg(2, shape); - MNN_CHECK_CL_SUCCESS(ret, "setArg SoftmaxBufExecution axis_3"); - - std::string kernelName = "softmax_buf_width"; - mLocalWorkSize = - localWS3DDefault(mGlobalWorkSize, mMaxWorkGroupSize, mOpenCLBackend->getOpenCLRuntime(), kernelName, mKernel).first; + mGlobalWorkSize = {(uint32_t)(localSize), (uint32_t)channelBlocks, (uint32_t)outputBatch*outputHeight}; + } + mLocalWorkSize = {(uint32_t)(localSize), 1, 1}; + + uint32_t idx = 0; + ret |= mKernel.setArg(idx++, mGlobalWorkSize[0]); + ret |= mKernel.setArg(idx++, mGlobalWorkSize[1]); + ret |= mKernel.setArg(idx++, mGlobalWorkSize[2]); + + ret |= mKernel.setArg(idx++, openCLImage(input)); + ret |= mKernel.setArg(idx++, openCLImage(output)); + ret |= mKernel.setArg(idx++, remainChannels); + ret |= mKernel.setArg(idx++, shape); + MNN_CHECK_CL_SUCCESS(ret, "setArg SoftmaxBufExecution"); + if(localSize == 1){ + mLocalWorkSize = localWS3DDefault(mGlobalWorkSize, mMaxWorkGroupSize, mOpenCLBackend->getOpenCLRuntime(), "softmax_buf", mKernel).first; } - return NO_ERROR; } diff --git a/source/backend/opencl/execution/buffer/SoftmaxBufExecution.hpp b/source/backend/opencl/execution/buffer/SoftmaxBufExecution.hpp index 31b9773f3..9a9044bbc 100644 --- a/source/backend/opencl/execution/buffer/SoftmaxBufExecution.hpp +++ b/source/backend/opencl/execution/buffer/SoftmaxBufExecution.hpp @@ -26,8 +26,9 @@ class SoftmaxBufExecution : public Execution { virtual ErrorCode onResize(const std::vector &inputs, const std::vector &outputs) override; virtual ErrorCode onExecute(const std::vector &inputs, const std::vector &outputs) override; - bool buildSoftmaxKernel(); + bool buildSoftmaxKernel(int localSize); private: + int getLocalSize(int size, int maxGroupSize); cl::Kernel mKernel; uint32_t mMaxWorkGroupSize; OpenCLBackend *mOpenCLBackend; diff --git a/source/backend/opencl/execution/cl/binary.cl b/source/backend/opencl/execution/cl/binary.cl index 2a62b4ca4..79a6d119f 100644 --- a/source/backend/opencl/execution/cl/binary.cl +++ b/source/backend/opencl/execution/cl/binary.cl @@ -1,6 +1,7 @@ #ifdef MNN_SUPPORT_FP16 #pragma OPENCL EXTENSION cl_khr_fp16 : enable #endif +#define PI 3.141592653589f __constant sampler_t SAMPLER = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST; __kernel void binary(__private int global_dim0, __private int global_dim1, diff --git a/source/backend/opencl/execution/cl/binary_buf.cl b/source/backend/opencl/execution/cl/binary_buf.cl index f3fcb2cc2..033bd4ca3 100644 --- a/source/backend/opencl/execution/cl/binary_buf.cl +++ b/source/backend/opencl/execution/cl/binary_buf.cl @@ -1,6 +1,7 @@ #ifdef MNN_SUPPORT_FP16 #pragma OPENCL EXTENSION cl_khr_fp16 : enable #endif +#define PI 3.141592653589f __kernel void binary_buf(__private int global_dim0, __private int global_dim1, __global FLOAT* input0, __global FLOAT* input1, __global FLOAT* output, diff --git a/source/backend/opencl/execution/cl/loop.cl b/source/backend/opencl/execution/cl/loop.cl index 9c1b782a8..80891a504 100644 --- a/source/backend/opencl/execution/cl/loop.cl +++ b/source/backend/opencl/execution/cl/loop.cl @@ -89,10 +89,17 @@ __kernel void tile(__private int global_dim0, __private int global_dim1, __priva const int h = pos.x / width; const int c = pos.y << 2; +#ifdef MNN_NHWC + const int c_dst_pitch = 1; + const int x_dst_pitch = c_dst_pitch * channel; + const int y_dst_pitch = x_dst_pitch * width; + const int b_dst_pitch = y_dst_pitch * height; +#else const int x_dst_pitch = 1; const int y_dst_pitch = x_dst_pitch * width; const int c_dst_pitch = y_dst_pitch * height; const int b_dst_pitch = c_dst_pitch * channel; +#endif __global FLOAT* dst_ptr = output + pos.z * b_dst_pitch + c * c_dst_pitch + h * y_dst_pitch + w * x_dst_pitch; FLOAT4 value = RI_F(input, SAMPLER, (int2)(pos.y * width + w, pos.z * height + h)); @@ -118,10 +125,17 @@ __kernel void pack(__private int global_dim0, __private int global_dim1, __priva const int h = pos.x / width; const int c = pos.y << 2; +#ifdef MNN_NHWC + const int c_src_pitch = 1; + const int x_src_pitch = c_src_pitch * channel; + const int y_src_pitch = x_src_pitch * width; + const int b_src_pitch = y_src_pitch * height; +#else const int x_src_pitch = 1; const int y_src_pitch = x_src_pitch * width; const int c_src_pitch = y_src_pitch * height; const int b_src_pitch = c_src_pitch * channel; +#endif __global FLOAT* src_ptr = input + pos.z * b_src_pitch + c * c_src_pitch + h * y_src_pitch + w * x_src_pitch; FLOAT4 value = (FLOAT4)0; FLOAT *value_ptr = (FLOAT*)&value; @@ -157,4 +171,53 @@ __kernel void batch_gather(__private int global_dim0, __private int global_dim1, int2 offset = index * steps; output[offset.x + stride_dst.w + x * stride_dst.x + y * stride_dst.y + pos.y * stride_dst.z] = input[offset.y + stride_src.w + x * stride_src.x + y * stride_src.y + pos.y * stride_src.z]; } -} \ No newline at end of file +} + +#ifdef LOOP_BINARY_OPERATOR +__kernel void broadcast_binary(__private int global_dim0, __private int global_dim1, __private int global_dim2, + __write_only image2d_t output, __read_only image2d_t input0, __read_only image2d_t input1, + __private const int4 src0_size, //(width, height, channel, batch) + __private const int4 src1_size, + __private const int dst_width, __private const int dst_height, + __private const int channel_block) { + int3 pos = (int3)(get_global_id(0), get_global_id(1), get_global_id(2)); + + if (pos.x < global_dim0 && pos.y < global_dim1 && pos.z < global_dim2) { + + const int w = pos.x; + const int h = pos.y; + const int c = pos.z % channel_block; + const int n = pos.z / channel_block; + + FLOAT4 in0 = RI_F(input0, SAMPLER, (int2)(c * src0_size.x + w, n * src0_size.y + h)); +#ifdef BROADCAST_CHANNEL + const int w1 = w % src1_size.x; + const int h1 = h % src1_size.y; + const int n1 = n % src1_size.w; + const int c1 = c << 2; + int4 c1_vec = (int4)(c1, c1 + 1, c1 + 2, c1 + 3); + c1_vec = c1_vec % (int4)(src1_size.z); + int4 c4_vec = (c1_vec + 3) / 4; + FLOAT4 in1; + FLOAT* in1_ptr = (FLOAT*)&in1; + int* c1_vec_prt = (int*)&c1_vec; + int* c4_vec_prt = (int*)&c4_vec; + for(int i = 0; i < 4; ++i){ + int remain = (c4_vec_prt[i] << 2) - c1_vec_prt[i]; + FLOAT4 tmp = RI_F(input1, SAMPLER, (int2)(c4_vec_prt[i] * src1_size.x + w1, n1 * src1_size.y + h1)); + FLOAT* tmp_ptr = (FLOAT*)&tmp; + in1_ptr[i] = tmp_ptr[remain]; + } +#else + const int w1 = w % src1_size.x; + const int h1 = h % src1_size.y; + const int c1 = c; + const int n1 = n % src1_size.w; + FLOAT4 in1 = RI_F(input1, SAMPLER, (int2)(c1 * src1_size.x + w1, n1 * src1_size.y + h1)); +#endif + FLOAT4 out = CONVERT_FLOAT4(LOOP_BINARY_OPERATOR); + WI_F(output, (int2)(c * dst_width + w, n * dst_height + h), out); + } +} +#endif + diff --git a/source/backend/opencl/execution/cl/loop_buf.cl b/source/backend/opencl/execution/cl/loop_buf.cl index a3217996e..f7bf28512 100644 --- a/source/backend/opencl/execution/cl/loop_buf.cl +++ b/source/backend/opencl/execution/cl/loop_buf.cl @@ -1,80 +1,6 @@ #ifdef MNN_SUPPORT_FP16 #pragma OPENCL EXTENSION cl_khr_fp16 : enable #endif - -__kernel void batch_matmul_buf(__private int global_dim0, __private int global_dim1, __private int global_dim2, - __global FLOAT* output, __global FLOAT* input_A, __global FLOAT* input_B, -#ifdef BIAS - __global FLOAT* input_C, -#endif - __global FLOAT* offset_O, __global FLOAT* offset_A, __global FLOAT* offset_B, -#ifdef BIAS - __global FLOAT* offset_C, -#endif - __private const int e, - __private const int l, - __private const int h, - __private const int4 offsets, - __private const int4 iters, - __private const int4 steps) { - int3 pos = (int3)(get_global_id(0), get_global_id(1), get_global_id(2)); - - if (pos.x < global_dim0 && pos.y < global_dim1 && pos.z < global_dim2) { - int4 index = (int4)(pos.z); - if (iters.x >= 0) { - index.x = (int)(offset_O[pos.z]); - } - if (iters.y >= 0) { - index.y = (int)(offset_A[pos.z]); - } - if (iters.z >= 0) { - index.z = (int)(offset_B[pos.z]); - } -#ifdef BIAS - if (iters.w >= 0) { - index.w = (int)(offset_C[pos.z]); - } -#endif - int4 offset = index * steps + offsets; - -#if TRANSPOSE_A - __global FLOAT* A_ptr = input_A + offset.y + pos.y; -#else - __global FLOAT* A_ptr = input_A + offset.y + pos.y * l; -#endif - -#if TRANSPOSE_B - __global FLOAT* B_ptr = input_B + offset.z + pos.x * l; -#else - __global FLOAT* B_ptr = input_B + offset.z + pos.x; -#endif - -#ifdef BIAS - FLOAT value = input_C[offset.w + pos.x]; -#else - FLOAT value = 0; -#endif - - for(int i = 0; i < l; ++i){ -#if TRANSPOSE_A - FLOAT value_a = A_ptr[i * e]; -#else - FLOAT value_a = A_ptr[i]; -#endif - -#if TRANSPOSE_B - FLOAT value_b = B_ptr[i]; -#else - FLOAT value_b = B_ptr[i * h]; -#endif - - value = mad(value_a, value_b, value); - } - - output[offset.x + pos.y * h + pos.x] = value; - } -} - __kernel void tile_buf(__private int global_dim0, __private int global_dim1, __private int global_dim2, __global FLOAT* input, __global FLOAT* output, __private const int width, @@ -89,11 +15,17 @@ __kernel void tile_buf(__private int global_dim0, __private int global_dim1, __p const int y_src_pitch = x_src_pitch * width; const int c_src_pitch = y_src_pitch * height; const int b_src_pitch = c_src_pitch * ((channel + 3) / 4); - +#ifdef MNN_NHWC + const int c_dst_pitch = 1; + const int x_dst_pitch = c_dst_pitch * channel; + const int y_dst_pitch = x_dst_pitch * width; + const int b_dst_pitch = y_dst_pitch * height; +#else const int x_dst_pitch = 1; const int y_dst_pitch = x_dst_pitch * width; const int c_dst_pitch = y_dst_pitch * height; const int b_dst_pitch = c_dst_pitch * channel; +#endif __global FLOAT* dst_ptr = output + pos.z * b_dst_pitch + c * c_dst_pitch + h * y_dst_pitch + w * x_dst_pitch; FLOAT4 value = vload4(0, input + pos.z * b_src_pitch + pos.y * c_src_pitch + h * y_src_pitch + w * x_src_pitch); @@ -121,11 +53,17 @@ __kernel void pack_buf(__private int global_dim0, __private int global_dim1, __p const int y_dst_pitch = x_dst_pitch * width; const int c_dst_pitch = y_dst_pitch * height; const int b_dst_pitch = c_dst_pitch * ((channel + 3) / 4); - +#ifdef MNN_NHWC + const int c_src_pitch = 1; + const int x_src_pitch = c_src_pitch * channel; + const int y_src_pitch = x_src_pitch * width; + const int b_src_pitch = y_src_pitch * height; +#else const int x_src_pitch = 1; const int y_src_pitch = x_src_pitch * width; const int c_src_pitch = y_src_pitch * height; const int b_src_pitch = c_src_pitch * channel; +#endif __global FLOAT* src_ptr = input + pos.z * b_src_pitch + c * c_src_pitch + h * y_src_pitch + w * x_src_pitch; FLOAT4 value = (FLOAT4)0; FLOAT *value_ptr = (FLOAT*)&value; @@ -136,29 +74,52 @@ __kernel void pack_buf(__private int global_dim0, __private int global_dim1, __p } } -__kernel void batch_gather_buf(__private int global_dim0, __private int global_dim1, __private int global_dim2, - __global FLOAT* output, __global FLOAT* input, - __global FLOAT* offset_dst, __global FLOAT* offset_src, - __private const int x_size, - __private const int4 stride_src, - __private const int4 stride_dst, - __private const int2 steps, - __private const int2 iters) { +#ifdef LOOP_BINARY_OPERATOR +__kernel void broadcast_binary_buf(__private int global_dim0, __private int global_dim1, __private int global_dim2, + __global FLOAT* output, __global FLOAT* input0, __global FLOAT* input1, + __private const int4 src0_size, //(width, height, channel, batch) + __private const int4 src1_size, + __private const int dst_width, __private const int dst_height, + __private const int channel_block) { int3 pos = (int3)(get_global_id(0), get_global_id(1), get_global_id(2)); if (pos.x < global_dim0 && pos.y < global_dim1 && pos.z < global_dim2) { - int x = pos.x % x_size; - int y = pos.x / x_size; - - int2 index = (int2)(pos.z, pos.z); - if (iters.x >= 0) { - index.x = (int)(offset_dst[pos.z]); - } - if (iters.y >= 0) { - index.y = (int)(offset_src[pos.z]); + const int w = pos.x; + const int h = pos.y; + const int c = pos.z % channel_block; + const int n = pos.z / channel_block; + const int src0_channel_block = (src0_size.z + 3) / 4; + const int src1_channel_block = (src1_size.z + 3) / 4; + + FLOAT4 in0 = vload4(0, input0 + ((((n * src0_channel_block) + c) * src0_size.y + h) * src0_size.x + w) * 4); +#ifdef BROADCAST_CHANNEL + const int w1 = w % src1_size.x; + const int h1 = h % src1_size.y; + const int n1 = n % src1_size.w; + const int c1 = c << 2; + int4 c1_vec = (int4)(c1, c1 + 1, c1 + 2, c1 + 3); + c1_vec = c1_vec % (int4)(src1_size.z); + int4 c4_vec = (c1_vec + 3) / 4; + FLOAT4 in1; + FLOAT* in1_ptr = (FLOAT*)&in1; + int* c1_vec_prt = (int*)&c1_vec; + int* c4_vec_prt = (int*)&c4_vec; + for(int i = 0; i < 4; ++i){ + int remain = (c4_vec_prt[i] << 2) - c1_vec_prt[i]; + FLOAT4 tmp = vload4(0, input1 + ((((n1 * src1_channel_block) + c4_vec_prt[i]) * src1_size.y + h1) * src1_size.x + w1) * 4); + FLOAT* tmp_ptr = (FLOAT*)&tmp; + in1_ptr[i] = tmp_ptr[remain]; } - int2 offset = index * steps; - output[offset.x + stride_dst.w + x * stride_dst.x + y * stride_dst.y + pos.y * stride_dst.z] = input[offset.y + stride_src.w + x * stride_src.x + y * stride_src.y + pos.y * stride_src.z]; +#else + const int w1 = w % src1_size.x; + const int h1 = h % src1_size.y; + const int c1 = c; + const int n1 = n % src1_size.w; + FLOAT4 in1 = vload4(0, input1 + ((((n1 * src1_channel_block) + c1) * src1_size.y + h1) * src1_size.x + w1) * 4); +#endif + FLOAT4 out = CONVERT_FLOAT4(LOOP_BINARY_OPERATOR); + vstore4(out, 0, output + ((((n * channel_block) + c) * dst_height + h) * dst_width + w) * 4); } } +#endif diff --git a/source/backend/opencl/execution/cl/matmul_buf.cl b/source/backend/opencl/execution/cl/matmul_buf.cl index 6fe1ee97c..46d0fe1e5 100644 --- a/source/backend/opencl/execution/cl/matmul_buf.cl +++ b/source/backend/opencl/execution/cl/matmul_buf.cl @@ -171,10 +171,11 @@ __kernel void matmul_transA_buf(GLOBAL_SIZE_2_DIMS __global const FLOAT* input_a for (short pos = 0; pos < channel_blocks; pos += 1) { const int inpa_offset = (4*pos) * height_blocks + height_blocks_idx; + short remain = (pos + 1) * 4 - channels; FLOAT4 a0 = vload4(inpa_offset, input_a); - FLOAT4 a1 = vload4(inpa_offset + height_blocks, input_a); - FLOAT4 a2 = vload4(inpa_offset + height_blocks*2, input_a); - FLOAT4 a3 = vload4(inpa_offset + height_blocks*3, input_a); + FLOAT4 a1 = ((remain >= 3) ? v_zero : vload4(inpa_offset + height_blocks, input_a)); + FLOAT4 a2 = ((remain >= 2) ? v_zero : vload4(inpa_offset + height_blocks*2, input_a)); + FLOAT4 a3 = ((remain >= 1) ? v_zero : vload4(inpa_offset + height_blocks*3, input_a)); const int inpb_offset = (4*pos) * width_blocks + width_blocks_idx; FLOAT4 b0 = vload4(inpb_offset, input_b); @@ -182,11 +183,6 @@ __kernel void matmul_transA_buf(GLOBAL_SIZE_2_DIMS __global const FLOAT* input_a FLOAT4 b2 = vload4(inpb_offset + width_blocks*2, input_b); FLOAT4 b3 = vload4(inpb_offset + width_blocks*3, input_b); - short remain = (pos + 1) * 4 - channels; - a3 = ((remain >= 1) ? v_zero : a3); - a2 = ((remain >= 2) ? v_zero : a2); - a1 = ((remain >= 3) ? v_zero : a1); - FLOAT4 a0_trans = (FLOAT4)(a0.x, a1.x, a2.x, a3.x); FLOAT4 a1_trans = (FLOAT4)(a0.y, a1.y, a2.y, a3.y); FLOAT4 a2_trans = (FLOAT4)(a0.z, a1.z, a2.z, a3.z); @@ -261,10 +257,11 @@ __kernel void matmul_transA_transB_buf(GLOBAL_SIZE_2_DIMS __global const FLOAT* for (short pos = 0; pos < channel_blocks; pos += 1) { const int inpa_offset = (4*pos) * height_blocks + height_blocks_idx; + short remain = (pos + 1) * 4 - channels; FLOAT4 a0 = vload4(inpa_offset, input_a); - FLOAT4 a1 = vload4(inpa_offset + height_blocks, input_a); - FLOAT4 a2 = vload4(inpa_offset + height_blocks*2, input_a); - FLOAT4 a3 = vload4(inpa_offset + height_blocks*3, input_a); + FLOAT4 a1 = ((remain >= 3) ? v_zero : vload4(inpa_offset + height_blocks, input_a)); + FLOAT4 a2 = ((remain >= 2) ? v_zero : vload4(inpa_offset + height_blocks*2, input_a)); + FLOAT4 a3 = ((remain >= 1) ? v_zero : vload4(inpa_offset + height_blocks*3, input_a)); const int inpb_offset = (4*width_blocks_idx) * channel_blocks + pos; FLOAT4 b0 = vload4(inpb_offset, input_b); @@ -272,11 +269,6 @@ __kernel void matmul_transA_transB_buf(GLOBAL_SIZE_2_DIMS __global const FLOAT* FLOAT4 b2 = vload4(inpb_offset + channel_blocks*2, input_b); FLOAT4 b3 = vload4(inpb_offset + channel_blocks*3, input_b); - short remain = (pos + 1) * 4 - channels; - a3 = ((remain >= 1) ? v_zero : a3); - a2 = ((remain >= 2) ? v_zero : a2); - a1 = ((remain >= 3) ? v_zero : a1); - FLOAT4 a0_trans = (FLOAT4)(a0.x, a1.x, a2.x, a3.x); FLOAT4 a1_trans = (FLOAT4)(a0.y, a1.y, a2.y, a3.y); FLOAT4 a2_trans = (FLOAT4)(a0.z, a1.z, a2.z, a3.z); diff --git a/source/backend/opencl/execution/cl/opencl_program.cc b/source/backend/opencl/execution/cl/opencl_program.cc index c24a8e52a..4d0e0a698 100644 --- a/source/backend/opencl/execution/cl/opencl_program.cc +++ b/source/backend/opencl/execution/cl/opencl_program.cc @@ -66,12 +66,12 @@ extern const std::map> OpenCLProgramMap }, { "softmax", - { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,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,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x45,0x58,0x50,0x20,0x65,0x78,0x70,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x5f,0x74,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x20,0x3d,0x20,0x43,0x4c,0x4b,0x5f,0x4e,0x4f,0x52,0x4d,0x41,0x4c,0x49,0x5a,0x45,0x44,0x5f,0x43,0x4f,0x4f,0x52,0x44,0x53,0x5f,0x46,0x41,0x4c,0x53,0x45,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x41,0x44,0x44,0x52,0x45,0x53,0x53,0x5f,0x43,0x4c,0x41,0x4d,0x50,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x4e,0x45,0x41,0x52,0x45,0x53,0x54,0x3b,0xa,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x73,0x6f,0x66,0x74,0x6d,0x61,0x78,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x20,0x2f,0x2f,0x20,0x4e,0x43,0x48,0x57,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x20,0x7b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x20,0x26,0x26,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x29,0x20,0x7b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x73,0x68,0x6f,0x72,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2d,0x20,0x31,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x77,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2d,0x20,0x31,0x29,0x20,0x2a,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x20,0x2c,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x77,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x33,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x73,0x68,0x6f,0x72,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2d,0x20,0x31,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x20,0x3d,0x20,0x45,0x58,0x50,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x20,0x2d,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x20,0x3d,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x20,0x2b,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x79,0x20,0x2b,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x7a,0x20,0x2b,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x77,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x2b,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2d,0x20,0x31,0x29,0x20,0x2a,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x20,0x2d,0x3d,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x45,0x58,0x50,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x77,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x45,0x58,0x50,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x45,0x58,0x50,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x45,0x58,0x50,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x45,0x58,0x50,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x45,0x58,0x50,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x45,0x58,0x50,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x45,0x58,0x50,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x45,0x58,0x50,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x33,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x45,0x58,0x50,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x63,0x75,0x72,0x5f,0x6f,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x70,0x6f,0x73,0x20,0x20,0x3d,0x20,0x6d,0x61,0x64,0x32,0x34,0x28,0x69,0x2c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x63,0x75,0x72,0x5f,0x6f,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x70,0x6f,0x73,0x2c,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x29,0x20,0x2d,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x20,0x3d,0x20,0x45,0x58,0x50,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x29,0x20,0x2f,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x63,0x75,0x72,0x5f,0x6f,0x75,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x5f,0x70,0x6f,0x73,0x2c,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x73,0x6f,0x66,0x74,0x6d,0x61,0x78,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x28,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x20,0x2f,0x2f,0x20,0x4e,0x43,0x48,0x57,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x63,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x62,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x77,0x63,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x20,0x26,0x26,0x20,0x62,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x4d,0x61,0x78,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x63,0x2c,0x20,0x62,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x31,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2c,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x63,0x2c,0x20,0x62,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x69,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x45,0x78,0x70,0x20,0x53,0x75,0x6d,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x63,0x2c,0x20,0x62,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x69,0x29,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x52,0x65,0x73,0x75,0x6c,0x74,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x65,0x78,0x70,0x28,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x63,0x2c,0x20,0x62,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x69,0x29,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x29,0x20,0x2f,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x63,0x2c,0x20,0x62,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x69,0x29,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x73,0x6f,0x66,0x74,0x6d,0x61,0x78,0x5f,0x77,0x69,0x64,0x74,0x68,0x28,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x20,0x2f,0x2f,0x20,0x4e,0x43,0x48,0x57,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x63,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x62,0x68,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x63,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x26,0x26,0x20,0x62,0x68,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x4d,0x61,0x78,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x63,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x62,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x31,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2c,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x63,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2b,0x69,0x2c,0x20,0x62,0x68,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x45,0x78,0x70,0x20,0x53,0x75,0x6d,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x63,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2b,0x69,0x2c,0x20,0x62,0x68,0x29,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x52,0x65,0x73,0x75,0x6c,0x74,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x65,0x78,0x70,0x28,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x63,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2b,0x69,0x2c,0x20,0x62,0x68,0x29,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x29,0x20,0x2f,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x63,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2b,0x69,0x2c,0x20,0x62,0x68,0x29,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa, } + { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,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,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x45,0x58,0x50,0x20,0x65,0x78,0x70,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x5f,0x74,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x20,0x3d,0x20,0x43,0x4c,0x4b,0x5f,0x4e,0x4f,0x52,0x4d,0x41,0x4c,0x49,0x5a,0x45,0x44,0x5f,0x43,0x4f,0x4f,0x52,0x44,0x53,0x5f,0x46,0x41,0x4c,0x53,0x45,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x41,0x44,0x44,0x52,0x45,0x53,0x53,0x5f,0x43,0x4c,0x41,0x4d,0x50,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x4e,0x45,0x41,0x52,0x45,0x53,0x54,0x3b,0xa,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x73,0x6f,0x66,0x74,0x6d,0x61,0x78,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x20,0x2f,0x2f,0x20,0x4e,0x43,0x48,0x57,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x20,0x7b,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x68,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x78,0x2c,0x20,0x77,0x2c,0x20,0x62,0x68,0x29,0x3b,0xa,0x23,0x69,0x66,0x20,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x3d,0x20,0x34,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6c,0x69,0x64,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x73,0x75,0x6d,0x5b,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5d,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x6c,0x69,0x64,0x3b,0x20,0x69,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2d,0x20,0x31,0x3b,0x20,0x69,0x2b,0x3d,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2c,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x62,0x68,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,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,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x32,0x3b,0x20,0x69,0x20,0x3e,0x20,0x30,0x3b,0x20,0x69,0x20,0x2f,0x3d,0x20,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x6c,0x69,0x64,0x20,0x3c,0x20,0x69,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x2c,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x20,0x2b,0x20,0x69,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,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,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x73,0x75,0x6d,0x5b,0x30,0x5d,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x77,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x20,0x2b,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2d,0x20,0x31,0x29,0x20,0x2a,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x20,0x2c,0x20,0x62,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x77,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x33,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x6c,0x69,0x64,0x3b,0x20,0x69,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2d,0x20,0x31,0x3b,0x20,0x69,0x2b,0x3d,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x62,0x68,0x29,0x29,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,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,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x32,0x3b,0x20,0x69,0x20,0x3e,0x20,0x30,0x3b,0x20,0x69,0x20,0x2f,0x3d,0x20,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x6c,0x69,0x64,0x20,0x3c,0x20,0x69,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x2b,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x20,0x2b,0x20,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,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,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x73,0x75,0x6d,0x5b,0x30,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x79,0x20,0x2b,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x77,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x20,0x2d,0x3d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x77,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x33,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x6c,0x69,0x64,0x3b,0x20,0x69,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x3b,0x20,0x69,0x2b,0x3d,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x65,0x78,0x70,0x28,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x62,0x68,0x29,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x29,0x20,0x2f,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x62,0x68,0x29,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2d,0x20,0x31,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2c,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x62,0x68,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x77,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x20,0x2b,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2d,0x20,0x31,0x29,0x20,0x2a,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x20,0x2c,0x20,0x62,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x77,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x33,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2d,0x20,0x31,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x62,0x68,0x29,0x29,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x79,0x20,0x2b,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x77,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x20,0x2d,0x3d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x77,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x33,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x65,0x78,0x70,0x28,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x62,0x68,0x29,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x29,0x20,0x2f,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x20,0x2b,0x20,0x69,0x20,0x2a,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x62,0x68,0x29,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x73,0x6f,0x66,0x74,0x6d,0x61,0x78,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x20,0x2f,0x2f,0x20,0x4e,0x43,0x48,0x57,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x63,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x78,0x2c,0x20,0x77,0x63,0x2c,0x20,0x62,0x29,0x3b,0xa,0x23,0x69,0x66,0x20,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x3d,0x20,0x34,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6c,0x69,0x64,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x73,0x75,0x6d,0x5b,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x4d,0x61,0x78,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x6c,0x69,0x64,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0x20,0x69,0x2b,0x3d,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2c,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x63,0x2c,0x20,0x62,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x69,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,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,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x32,0x3b,0x20,0x69,0x20,0x3e,0x20,0x30,0x3b,0x20,0x69,0x20,0x2f,0x3d,0x20,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x6c,0x69,0x64,0x20,0x3c,0x20,0x69,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x2c,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x20,0x2b,0x20,0x69,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,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,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x73,0x75,0x6d,0x5b,0x30,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x45,0x78,0x70,0x20,0x53,0x75,0x6d,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x6c,0x69,0x64,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0x20,0x69,0x2b,0x3d,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x63,0x2c,0x20,0x62,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x69,0x29,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,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,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x32,0x3b,0x20,0x69,0x20,0x3e,0x20,0x30,0x3b,0x20,0x69,0x20,0x2f,0x3d,0x20,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x6c,0x69,0x64,0x20,0x3c,0x20,0x69,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x2b,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x20,0x2b,0x20,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,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,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x73,0x75,0x6d,0x5b,0x30,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x52,0x65,0x73,0x75,0x6c,0x74,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x6c,0x69,0x64,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0x20,0x69,0x2b,0x3d,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x65,0x78,0x70,0x28,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x63,0x2c,0x20,0x62,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x69,0x29,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x29,0x20,0x2f,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x63,0x2c,0x20,0x62,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x69,0x29,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x4d,0x61,0x78,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2c,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x63,0x2c,0x20,0x62,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x69,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x45,0x78,0x70,0x20,0x53,0x75,0x6d,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x63,0x2c,0x20,0x62,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x69,0x29,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x52,0x65,0x73,0x75,0x6c,0x74,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x65,0x78,0x70,0x28,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x63,0x2c,0x20,0x62,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x69,0x29,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x29,0x20,0x2f,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x77,0x63,0x2c,0x20,0x62,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x69,0x29,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x7d,0xa,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x73,0x6f,0x66,0x74,0x6d,0x61,0x78,0x5f,0x77,0x69,0x64,0x74,0x68,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x20,0x2f,0x2f,0x20,0x4e,0x43,0x48,0x57,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x68,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x78,0x2c,0x20,0x63,0x2c,0x20,0x62,0x68,0x29,0x3b,0xa,0x23,0x69,0x66,0x20,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x3d,0x20,0x34,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6c,0x69,0x64,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x73,0x75,0x6d,0x5b,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x4d,0x61,0x78,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x6c,0x69,0x64,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x3b,0x20,0x69,0x2b,0x3d,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2c,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x63,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2b,0x69,0x2c,0x20,0x62,0x68,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,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,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x32,0x3b,0x20,0x69,0x20,0x3e,0x20,0x30,0x3b,0x20,0x69,0x20,0x2f,0x3d,0x20,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x6c,0x69,0x64,0x20,0x3c,0x20,0x69,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x2c,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x20,0x2b,0x20,0x69,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,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,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x73,0x75,0x6d,0x5b,0x30,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x45,0x78,0x70,0x20,0x53,0x75,0x6d,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x6c,0x69,0x64,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0x20,0x69,0x2b,0x3d,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x63,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2b,0x69,0x2c,0x20,0x62,0x68,0x29,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,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,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x32,0x3b,0x20,0x69,0x20,0x3e,0x20,0x30,0x3b,0x20,0x69,0x20,0x2f,0x3d,0x20,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x6c,0x69,0x64,0x20,0x3c,0x20,0x69,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x2b,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x20,0x2b,0x20,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,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,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x73,0x75,0x6d,0x5b,0x30,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x52,0x65,0x73,0x75,0x6c,0x74,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x6c,0x69,0x64,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x3b,0x20,0x69,0x2b,0x3d,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x65,0x78,0x70,0x28,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x63,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2b,0x69,0x2c,0x20,0x62,0x68,0x29,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x29,0x20,0x2f,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x63,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2b,0x69,0x2c,0x20,0x62,0x68,0x29,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x4d,0x61,0x78,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2c,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x63,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2b,0x69,0x2c,0x20,0x62,0x68,0x29,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x45,0x78,0x70,0x20,0x53,0x75,0x6d,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x63,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2b,0x69,0x2c,0x20,0x62,0x68,0x29,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x52,0x65,0x73,0x75,0x6c,0x74,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x65,0x78,0x70,0x28,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x63,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2b,0x69,0x2c,0x20,0x62,0x68,0x29,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x29,0x20,0x2f,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x63,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2b,0x69,0x2c,0x20,0x62,0x68,0x29,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x7d,0xa, } }, #ifndef MNN_OPENCL_BUFFER_CLOSED { "binary_buf", - { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,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,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62,0x69,0x6e,0x61,0x72,0x79,0x5f,0x62,0x75,0x66,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x2c,0x2f,0x2f,0x5b,0x4e,0x2c,0x48,0x2c,0x57,0x2c,0x43,0x34,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x63,0x74,0x69,0x76,0x61,0x74,0x69,0x6f,0x6e,0x54,0x79,0x70,0x65,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x29,0x3b,0x2f,0x2f,0x4e,0x43,0x34,0x2c,0x20,0x48,0x57,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x2a,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x29,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x79,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x78,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x69,0x6e,0x30,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x30,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x30,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x30,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x79,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x69,0x6e,0x31,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x31,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x31,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x31,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x4f,0x50,0x45,0x52,0x41,0x54,0x4f,0x52,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x61,0x63,0x74,0x69,0x76,0x61,0x74,0x69,0x6f,0x6e,0x54,0x79,0x70,0x65,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x6f,0x75,0x74,0x2c,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x70,0x72,0x65,0x6c,0x75,0x5f,0x62,0x75,0x66,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x2f,0x2f,0x5b,0x4e,0x2c,0x48,0x2c,0x57,0x2c,0x43,0x34,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x29,0x3b,0x2f,0x2f,0x4e,0x43,0x34,0x2c,0x20,0x48,0x57,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x2a,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x29,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x25,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x4f,0x50,0x45,0x52,0x41,0x54,0x4f,0x52,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x6f,0x75,0x74,0x2c,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa, } + { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,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,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x50,0x49,0x20,0x33,0x2e,0x31,0x34,0x31,0x35,0x39,0x32,0x36,0x35,0x33,0x35,0x38,0x39,0x66,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62,0x69,0x6e,0x61,0x72,0x79,0x5f,0x62,0x75,0x66,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x2c,0x2f,0x2f,0x5b,0x4e,0x2c,0x48,0x2c,0x57,0x2c,0x43,0x34,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x63,0x74,0x69,0x76,0x61,0x74,0x69,0x6f,0x6e,0x54,0x79,0x70,0x65,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x29,0x3b,0x2f,0x2f,0x4e,0x43,0x34,0x2c,0x20,0x48,0x57,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x2a,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x29,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x79,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x78,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x69,0x6e,0x30,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x30,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x30,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x30,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x79,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x69,0x6e,0x31,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x31,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x31,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x31,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x4f,0x50,0x45,0x52,0x41,0x54,0x4f,0x52,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x61,0x63,0x74,0x69,0x76,0x61,0x74,0x69,0x6f,0x6e,0x54,0x79,0x70,0x65,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x6f,0x75,0x74,0x2c,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x70,0x72,0x65,0x6c,0x75,0x5f,0x62,0x75,0x66,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x2f,0x2f,0x5b,0x4e,0x2c,0x48,0x2c,0x57,0x2c,0x43,0x34,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x29,0x3b,0x2f,0x2f,0x4e,0x43,0x34,0x2c,0x20,0x48,0x57,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x2a,0x20,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x29,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x25,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x4f,0x50,0x45,0x52,0x41,0x54,0x4f,0x52,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x6f,0x75,0x74,0x2c,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa, } }, #endif #ifndef MNN_OPENCL_BUFFER_CLOSED @@ -166,7 +166,7 @@ extern const std::map> OpenCLProgramMap }, { "loop", - { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,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,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x5f,0x74,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x20,0x3d,0x20,0x43,0x4c,0x4b,0x5f,0x4e,0x4f,0x52,0x4d,0x41,0x4c,0x49,0x5a,0x45,0x44,0x5f,0x43,0x4f,0x4f,0x52,0x44,0x53,0x5f,0x46,0x41,0x4c,0x53,0x45,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x41,0x44,0x44,0x52,0x45,0x53,0x53,0x5f,0x43,0x4c,0x41,0x4d,0x50,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x4e,0x45,0x41,0x52,0x45,0x53,0x54,0x3b,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x6d,0x61,0x74,0x6d,0x75,0x6c,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x41,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x42,0x2c,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x43,0x2c,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x4f,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x41,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x42,0x2c,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x43,0x2c,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x69,0x74,0x65,0x72,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x74,0x65,0x70,0x73,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x33,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x33,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x69,0x6e,0x64,0x65,0x78,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x34,0x29,0x28,0x70,0x6f,0x73,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x74,0x65,0x72,0x73,0x2e,0x78,0x20,0x3e,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x64,0x65,0x78,0x2e,0x78,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x29,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x4f,0x5b,0x70,0x6f,0x73,0x2e,0x7a,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x74,0x65,0x72,0x73,0x2e,0x79,0x20,0x3e,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x64,0x65,0x78,0x2e,0x79,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x29,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x41,0x5b,0x70,0x6f,0x73,0x2e,0x7a,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x74,0x65,0x72,0x73,0x2e,0x7a,0x20,0x3e,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x64,0x65,0x78,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x29,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x42,0x5b,0x70,0x6f,0x73,0x2e,0x7a,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x74,0x65,0x72,0x73,0x2e,0x77,0x20,0x3e,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x64,0x65,0x78,0x2e,0x77,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x29,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x43,0x5b,0x70,0x6f,0x73,0x2e,0x7a,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x69,0x6e,0x64,0x65,0x78,0x20,0x2a,0x20,0x73,0x74,0x65,0x70,0x73,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x23,0x69,0x66,0x20,0x54,0x52,0x41,0x4e,0x53,0x50,0x4f,0x53,0x45,0x5f,0x41,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x41,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x41,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x79,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x41,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x41,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x79,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x6c,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x20,0x54,0x52,0x41,0x4e,0x53,0x50,0x4f,0x53,0x45,0x5f,0x42,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x42,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x42,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x7a,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x2a,0x20,0x6c,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x42,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x42,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x7a,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x78,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x43,0x5b,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x77,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x78,0x5d,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x30,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6c,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x23,0x69,0x66,0x20,0x54,0x52,0x41,0x4e,0x53,0x50,0x4f,0x53,0x45,0x5f,0x41,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x20,0x3d,0x20,0x41,0x5f,0x70,0x74,0x72,0x5b,0x69,0x20,0x2a,0x20,0x65,0x5d,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x20,0x3d,0x20,0x41,0x5f,0x70,0x74,0x72,0x5b,0x69,0x5d,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x20,0x54,0x52,0x41,0x4e,0x53,0x50,0x4f,0x53,0x45,0x5f,0x42,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x20,0x3d,0x20,0x42,0x5f,0x70,0x74,0x72,0x5b,0x69,0x5d,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x20,0x3d,0x20,0x42,0x5f,0x70,0x74,0x72,0x5b,0x69,0x20,0x2a,0x20,0x68,0x5d,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x68,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x78,0x5d,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x74,0x69,0x6c,0x65,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x33,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x33,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x25,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x2f,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x78,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x79,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x64,0x73,0x74,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x2a,0x20,0x62,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x63,0x20,0x2a,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x68,0x20,0x2a,0x20,0x79,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x77,0x20,0x2a,0x20,0x78,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x77,0x2c,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x5f,0x70,0x74,0x72,0x5b,0x30,0x5d,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x63,0x20,0x2b,0x20,0x31,0x20,0x3e,0x3d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x5f,0x70,0x74,0x72,0x5b,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x5d,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x63,0x20,0x2b,0x20,0x32,0x20,0x3e,0x3d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x5f,0x70,0x74,0x72,0x5b,0x32,0x20,0x2a,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x5d,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x63,0x20,0x2b,0x20,0x33,0x20,0x3e,0x3d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x5f,0x70,0x74,0x72,0x5b,0x33,0x20,0x2a,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x5d,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x2e,0x77,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x70,0x61,0x63,0x6b,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x33,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x33,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x25,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x2f,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x78,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x79,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x63,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x73,0x72,0x63,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x2a,0x20,0x62,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x63,0x20,0x2a,0x20,0x63,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x68,0x20,0x2a,0x20,0x79,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x77,0x20,0x2a,0x20,0x78,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x76,0x61,0x6c,0x75,0x65,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x29,0x26,0x76,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x34,0x20,0x26,0x26,0x20,0x28,0x69,0x20,0x2b,0x20,0x63,0x20,0x3c,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x70,0x74,0x72,0x5b,0x69,0x5d,0x20,0x3d,0x20,0x73,0x72,0x63,0x5f,0x70,0x74,0x72,0x5b,0x69,0x20,0x2a,0x20,0x63,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x77,0x2c,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x68,0x29,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x67,0x61,0x74,0x68,0x65,0x72,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x64,0x73,0x74,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x73,0x72,0x63,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x5f,0x73,0x69,0x7a,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x72,0x63,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x64,0x73,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x73,0x74,0x65,0x70,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x74,0x65,0x72,0x73,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x33,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x33,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x78,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x25,0x20,0x78,0x5f,0x73,0x69,0x7a,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x79,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x2f,0x20,0x78,0x5f,0x73,0x69,0x7a,0x65,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x64,0x65,0x78,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x70,0x6f,0x73,0x2e,0x7a,0x2c,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x74,0x65,0x72,0x73,0x2e,0x78,0x20,0x3e,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x64,0x65,0x78,0x2e,0x78,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x29,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x64,0x73,0x74,0x5b,0x70,0x6f,0x73,0x2e,0x7a,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x74,0x65,0x72,0x73,0x2e,0x79,0x20,0x3e,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x64,0x65,0x78,0x2e,0x79,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x29,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x73,0x72,0x63,0x5b,0x70,0x6f,0x73,0x2e,0x7a,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x32,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x69,0x6e,0x64,0x65,0x78,0x20,0x2a,0x20,0x73,0x74,0x65,0x70,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x78,0x20,0x2b,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x64,0x73,0x74,0x2e,0x77,0x20,0x2b,0x20,0x78,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x64,0x73,0x74,0x2e,0x78,0x20,0x2b,0x20,0x79,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x64,0x73,0x74,0x2e,0x79,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x64,0x73,0x74,0x2e,0x7a,0x5d,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5b,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x79,0x20,0x2b,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x72,0x63,0x2e,0x77,0x20,0x2b,0x20,0x78,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x72,0x63,0x2e,0x78,0x20,0x2b,0x20,0x79,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x72,0x63,0x2e,0x79,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x72,0x63,0x2e,0x7a,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d, } + { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,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,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x5f,0x74,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x20,0x3d,0x20,0x43,0x4c,0x4b,0x5f,0x4e,0x4f,0x52,0x4d,0x41,0x4c,0x49,0x5a,0x45,0x44,0x5f,0x43,0x4f,0x4f,0x52,0x44,0x53,0x5f,0x46,0x41,0x4c,0x53,0x45,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x41,0x44,0x44,0x52,0x45,0x53,0x53,0x5f,0x43,0x4c,0x41,0x4d,0x50,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x4e,0x45,0x41,0x52,0x45,0x53,0x54,0x3b,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x6d,0x61,0x74,0x6d,0x75,0x6c,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x41,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x42,0x2c,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x43,0x2c,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x4f,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x41,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x42,0x2c,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x43,0x2c,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x69,0x74,0x65,0x72,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x74,0x65,0x70,0x73,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x33,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x33,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x69,0x6e,0x64,0x65,0x78,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x34,0x29,0x28,0x70,0x6f,0x73,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x74,0x65,0x72,0x73,0x2e,0x78,0x20,0x3e,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x64,0x65,0x78,0x2e,0x78,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x29,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x4f,0x5b,0x70,0x6f,0x73,0x2e,0x7a,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x74,0x65,0x72,0x73,0x2e,0x79,0x20,0x3e,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x64,0x65,0x78,0x2e,0x79,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x29,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x41,0x5b,0x70,0x6f,0x73,0x2e,0x7a,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x74,0x65,0x72,0x73,0x2e,0x7a,0x20,0x3e,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x64,0x65,0x78,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x29,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x42,0x5b,0x70,0x6f,0x73,0x2e,0x7a,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x74,0x65,0x72,0x73,0x2e,0x77,0x20,0x3e,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x64,0x65,0x78,0x2e,0x77,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x29,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x43,0x5b,0x70,0x6f,0x73,0x2e,0x7a,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x69,0x6e,0x64,0x65,0x78,0x20,0x2a,0x20,0x73,0x74,0x65,0x70,0x73,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x23,0x69,0x66,0x20,0x54,0x52,0x41,0x4e,0x53,0x50,0x4f,0x53,0x45,0x5f,0x41,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x41,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x41,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x79,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x41,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x41,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x79,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x6c,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x20,0x54,0x52,0x41,0x4e,0x53,0x50,0x4f,0x53,0x45,0x5f,0x42,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x42,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x42,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x7a,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x2a,0x20,0x6c,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x42,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x42,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x7a,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x78,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x43,0x5b,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x77,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x78,0x5d,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x30,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6c,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x23,0x69,0x66,0x20,0x54,0x52,0x41,0x4e,0x53,0x50,0x4f,0x53,0x45,0x5f,0x41,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x20,0x3d,0x20,0x41,0x5f,0x70,0x74,0x72,0x5b,0x69,0x20,0x2a,0x20,0x65,0x5d,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x20,0x3d,0x20,0x41,0x5f,0x70,0x74,0x72,0x5b,0x69,0x5d,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x20,0x54,0x52,0x41,0x4e,0x53,0x50,0x4f,0x53,0x45,0x5f,0x42,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x20,0x3d,0x20,0x42,0x5f,0x70,0x74,0x72,0x5b,0x69,0x5d,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x20,0x3d,0x20,0x42,0x5f,0x70,0x74,0x72,0x5b,0x69,0x20,0x2a,0x20,0x68,0x5d,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x68,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x78,0x5d,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x74,0x69,0x6c,0x65,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x33,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x33,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x25,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x2f,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x4e,0x48,0x57,0x43,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x78,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x79,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x78,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x79,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x64,0x73,0x74,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x2a,0x20,0x62,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x63,0x20,0x2a,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x68,0x20,0x2a,0x20,0x79,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x77,0x20,0x2a,0x20,0x78,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x77,0x2c,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x68,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x5f,0x70,0x74,0x72,0x5b,0x30,0x5d,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x63,0x20,0x2b,0x20,0x31,0x20,0x3e,0x3d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x5f,0x70,0x74,0x72,0x5b,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x5d,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x63,0x20,0x2b,0x20,0x32,0x20,0x3e,0x3d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x5f,0x70,0x74,0x72,0x5b,0x32,0x20,0x2a,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x5d,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x63,0x20,0x2b,0x20,0x33,0x20,0x3e,0x3d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x5f,0x70,0x74,0x72,0x5b,0x33,0x20,0x2a,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x5d,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x2e,0x77,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x70,0x61,0x63,0x6b,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x33,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x33,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x25,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x2f,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x4e,0x48,0x57,0x43,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x63,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x78,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x79,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x78,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x79,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x63,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x73,0x72,0x63,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x2a,0x20,0x62,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x63,0x20,0x2a,0x20,0x63,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x68,0x20,0x2a,0x20,0x79,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x77,0x20,0x2a,0x20,0x78,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x76,0x61,0x6c,0x75,0x65,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x29,0x26,0x76,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x34,0x20,0x26,0x26,0x20,0x28,0x69,0x20,0x2b,0x20,0x63,0x20,0x3c,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x70,0x74,0x72,0x5b,0x69,0x5d,0x20,0x3d,0x20,0x73,0x72,0x63,0x5f,0x70,0x74,0x72,0x5b,0x69,0x20,0x2a,0x20,0x63,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x77,0x2c,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x68,0x29,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x67,0x61,0x74,0x68,0x65,0x72,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x64,0x73,0x74,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x73,0x72,0x63,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x5f,0x73,0x69,0x7a,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x72,0x63,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x64,0x73,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x73,0x74,0x65,0x70,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x74,0x65,0x72,0x73,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x33,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x33,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x78,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x25,0x20,0x78,0x5f,0x73,0x69,0x7a,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x79,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x2f,0x20,0x78,0x5f,0x73,0x69,0x7a,0x65,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x64,0x65,0x78,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x70,0x6f,0x73,0x2e,0x7a,0x2c,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x74,0x65,0x72,0x73,0x2e,0x78,0x20,0x3e,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x64,0x65,0x78,0x2e,0x78,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x29,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x64,0x73,0x74,0x5b,0x70,0x6f,0x73,0x2e,0x7a,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x74,0x65,0x72,0x73,0x2e,0x79,0x20,0x3e,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x64,0x65,0x78,0x2e,0x79,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x29,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x73,0x72,0x63,0x5b,0x70,0x6f,0x73,0x2e,0x7a,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x32,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x69,0x6e,0x64,0x65,0x78,0x20,0x2a,0x20,0x73,0x74,0x65,0x70,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x78,0x20,0x2b,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x64,0x73,0x74,0x2e,0x77,0x20,0x2b,0x20,0x78,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x64,0x73,0x74,0x2e,0x78,0x20,0x2b,0x20,0x79,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x64,0x73,0x74,0x2e,0x79,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x64,0x73,0x74,0x2e,0x7a,0x5d,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5b,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x79,0x20,0x2b,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x72,0x63,0x2e,0x77,0x20,0x2b,0x20,0x78,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x72,0x63,0x2e,0x78,0x20,0x2b,0x20,0x79,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x72,0x63,0x2e,0x79,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x72,0x63,0x2e,0x7a,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4c,0x4f,0x4f,0x50,0x5f,0x42,0x49,0x4e,0x41,0x52,0x59,0x5f,0x4f,0x50,0x45,0x52,0x41,0x54,0x4f,0x52,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62,0x72,0x6f,0x61,0x64,0x63,0x61,0x73,0x74,0x5f,0x62,0x69,0x6e,0x61,0x72,0x79,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x72,0x63,0x30,0x5f,0x73,0x69,0x7a,0x65,0x2c,0x20,0x2f,0x2f,0x28,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2c,0x20,0x62,0x61,0x74,0x63,0x68,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x33,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x33,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x25,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6e,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x2f,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x63,0x20,0x2a,0x20,0x73,0x72,0x63,0x30,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x78,0x20,0x2b,0x20,0x77,0x2c,0x20,0x6e,0x20,0x2a,0x20,0x73,0x72,0x63,0x30,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x79,0x20,0x2b,0x20,0x68,0x29,0x29,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x52,0x4f,0x41,0x44,0x43,0x41,0x53,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x31,0x20,0x3d,0x20,0x77,0x20,0x25,0x20,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x31,0x20,0x3d,0x20,0x68,0x20,0x25,0x20,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6e,0x31,0x20,0x3d,0x20,0x6e,0x20,0x25,0x20,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x77,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x31,0x20,0x3d,0x20,0x63,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x63,0x31,0x5f,0x76,0x65,0x63,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x34,0x29,0x28,0x63,0x31,0x2c,0x20,0x63,0x31,0x20,0x2b,0x20,0x31,0x2c,0x20,0x63,0x31,0x20,0x2b,0x20,0x32,0x2c,0x20,0x63,0x31,0x20,0x2b,0x20,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x31,0x5f,0x76,0x65,0x63,0x20,0x3d,0x20,0x63,0x31,0x5f,0x76,0x65,0x63,0x20,0x25,0x20,0x28,0x69,0x6e,0x74,0x34,0x29,0x28,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x63,0x34,0x5f,0x76,0x65,0x63,0x20,0x3d,0x20,0x28,0x63,0x31,0x5f,0x76,0x65,0x63,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x31,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x29,0x26,0x69,0x6e,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x2a,0x20,0x63,0x31,0x5f,0x76,0x65,0x63,0x5f,0x70,0x72,0x74,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x2a,0x29,0x26,0x63,0x31,0x5f,0x76,0x65,0x63,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x2a,0x20,0x63,0x34,0x5f,0x76,0x65,0x63,0x5f,0x70,0x72,0x74,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x2a,0x29,0x26,0x63,0x34,0x5f,0x76,0x65,0x63,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x34,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x20,0x28,0x63,0x34,0x5f,0x76,0x65,0x63,0x5f,0x70,0x72,0x74,0x5b,0x69,0x5d,0x20,0x3c,0x3c,0x20,0x32,0x29,0x20,0x2d,0x20,0x63,0x31,0x5f,0x76,0x65,0x63,0x5f,0x70,0x72,0x74,0x5b,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x74,0x6d,0x70,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x63,0x34,0x5f,0x76,0x65,0x63,0x5f,0x70,0x72,0x74,0x5b,0x69,0x5d,0x20,0x2a,0x20,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x78,0x20,0x2b,0x20,0x77,0x31,0x2c,0x20,0x6e,0x31,0x20,0x2a,0x20,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x79,0x20,0x2b,0x20,0x68,0x31,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x74,0x6d,0x70,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x29,0x26,0x74,0x6d,0x70,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x5f,0x70,0x74,0x72,0x5b,0x69,0x5d,0x20,0x3d,0x20,0x74,0x6d,0x70,0x5f,0x70,0x74,0x72,0x5b,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x31,0x20,0x3d,0x20,0x77,0x20,0x25,0x20,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x31,0x20,0x3d,0x20,0x68,0x20,0x25,0x20,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x31,0x20,0x3d,0x20,0x63,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6e,0x31,0x20,0x3d,0x20,0x6e,0x20,0x25,0x20,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x77,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x63,0x31,0x20,0x2a,0x20,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x78,0x20,0x2b,0x20,0x77,0x31,0x2c,0x20,0x6e,0x31,0x20,0x2a,0x20,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x79,0x20,0x2b,0x20,0x68,0x31,0x29,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x4c,0x4f,0x4f,0x50,0x5f,0x42,0x49,0x4e,0x41,0x52,0x59,0x5f,0x4f,0x50,0x45,0x52,0x41,0x54,0x4f,0x52,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x63,0x20,0x2a,0x20,0x64,0x73,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x77,0x2c,0x20,0x6e,0x20,0x2a,0x20,0x64,0x73,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x68,0x29,0x2c,0x20,0x6f,0x75,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa, } }, #ifndef MNN_OPENCL_BUFFER_CLOSED { @@ -207,7 +207,7 @@ extern const std::map> OpenCLProgramMap #ifndef MNN_OPENCL_BUFFER_CLOSED { "matmul_buf", - { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,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,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x32,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5c,0xa,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x2c,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x32,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x69,0x66,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x29,0x20,0x7b,0x20,0x5c,0xa,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x6d,0x61,0x74,0x6d,0x75,0x6c,0x5f,0x62,0x75,0x66,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x32,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x61,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x63,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x2c,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x2f,0x2f,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x57,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0x2f,0x2f,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x48,0xa,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x32,0x28,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2c,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x30,0x20,0x3d,0x20,0x30,0x2c,0x20,0x62,0x31,0x20,0x3d,0x20,0x30,0x2c,0x20,0x62,0x32,0x20,0x3d,0x20,0x30,0x2c,0x20,0x62,0x33,0x20,0x3d,0x20,0x30,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x74,0x65,0x6d,0x70,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x63,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x20,0x3d,0x20,0x74,0x65,0x6d,0x70,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x20,0x3d,0x20,0x74,0x65,0x6d,0x70,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x20,0x3d,0x20,0x74,0x65,0x6d,0x70,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x20,0x3d,0x20,0x74,0x65,0x6d,0x70,0x2e,0x77,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x73,0x68,0x6f,0x72,0x74,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x30,0x3b,0x20,0x70,0x6f,0x73,0x20,0x3c,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0x20,0x70,0x6f,0x73,0x20,0x2b,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x70,0x6f,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x61,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x68,0x6f,0x72,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x20,0x28,0x70,0x6f,0x73,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x34,0x20,0x2d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x70,0x6f,0x73,0x2a,0x34,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x33,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x33,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x31,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x32,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x33,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x32,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x33,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x33,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x74,0x6d,0x70,0x30,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x62,0x30,0x2e,0x73,0x30,0x2c,0x20,0x62,0x31,0x2e,0x73,0x30,0x2c,0x20,0x62,0x32,0x2e,0x73,0x30,0x2c,0x20,0x62,0x33,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x74,0x6d,0x70,0x31,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x62,0x30,0x2e,0x73,0x31,0x2c,0x20,0x62,0x31,0x2e,0x73,0x31,0x2c,0x20,0x62,0x32,0x2e,0x73,0x31,0x2c,0x20,0x62,0x33,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x74,0x6d,0x70,0x32,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x62,0x30,0x2e,0x73,0x32,0x2c,0x20,0x62,0x31,0x2e,0x73,0x32,0x2c,0x20,0x62,0x32,0x2e,0x73,0x32,0x2c,0x20,0x62,0x33,0x2e,0x73,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x74,0x6d,0x70,0x33,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x62,0x30,0x2e,0x73,0x33,0x2c,0x20,0x62,0x31,0x2e,0x73,0x33,0x2c,0x20,0x62,0x32,0x2e,0x73,0x33,0x2c,0x20,0x62,0x33,0x2e,0x73,0x33,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x2c,0x20,0x62,0x74,0x6d,0x70,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x2c,0x20,0x62,0x74,0x6d,0x70,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x2c,0x20,0x62,0x74,0x6d,0x70,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x2c,0x20,0x62,0x74,0x6d,0x70,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x2c,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x2c,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x2c,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x29,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x29,0x3b,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x6d,0x61,0x74,0x6d,0x75,0x6c,0x5f,0x74,0x72,0x61,0x6e,0x73,0x42,0x5f,0x62,0x75,0x66,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x32,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x61,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x63,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x2c,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x32,0x28,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2c,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x30,0x20,0x3d,0x20,0x30,0x2c,0x20,0x62,0x31,0x20,0x3d,0x20,0x30,0x2c,0x20,0x62,0x32,0x20,0x3d,0x20,0x30,0x2c,0x20,0x62,0x33,0x20,0x3d,0x20,0x30,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x74,0x65,0x6d,0x70,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x63,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x20,0x3d,0x20,0x74,0x65,0x6d,0x70,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x20,0x3d,0x20,0x74,0x65,0x6d,0x70,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x20,0x3d,0x20,0x74,0x65,0x6d,0x70,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x20,0x3d,0x20,0x74,0x65,0x6d,0x70,0x2e,0x77,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x73,0x68,0x6f,0x72,0x74,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x30,0x3b,0x20,0x70,0x6f,0x73,0x20,0x3c,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0x20,0x70,0x6f,0x73,0x20,0x2b,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x70,0x6f,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x61,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x68,0x6f,0x72,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x20,0x28,0x70,0x6f,0x73,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x34,0x20,0x2d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2a,0x34,0x29,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x70,0x6f,0x73,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x33,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x33,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x2e,0x79,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x2e,0x7a,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x2e,0x77,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x2e,0x7a,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x2e,0x77,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x2e,0x77,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x2c,0x20,0x62,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x2c,0x20,0x62,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x2c,0x20,0x62,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x2c,0x20,0x62,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x2c,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x2c,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x2c,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x29,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x29,0x3b,0xa,0x7d,0xa,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x6d,0x61,0x74,0x6d,0x75,0x6c,0x5f,0x74,0x72,0x61,0x6e,0x73,0x41,0x5f,0x62,0x75,0x66,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x32,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x61,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x63,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x32,0x28,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2c,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x5f,0x7a,0x65,0x72,0x6f,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x63,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x20,0x3d,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x20,0x3d,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x20,0x3d,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x73,0x68,0x6f,0x72,0x74,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x30,0x3b,0x20,0x70,0x6f,0x73,0x20,0x3c,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0x20,0x70,0x6f,0x73,0x20,0x2b,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x34,0x2a,0x70,0x6f,0x73,0x29,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x61,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x61,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x61,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x33,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x61,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x34,0x2a,0x70,0x6f,0x73,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x33,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x68,0x6f,0x72,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x20,0x28,0x70,0x6f,0x73,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x34,0x20,0x2d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x33,0x20,0x3d,0x20,0x28,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3e,0x3d,0x20,0x31,0x29,0x20,0x3f,0x20,0x76,0x5f,0x7a,0x65,0x72,0x6f,0x20,0x3a,0x20,0x61,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x32,0x20,0x3d,0x20,0x28,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3e,0x3d,0x20,0x32,0x29,0x20,0x3f,0x20,0x76,0x5f,0x7a,0x65,0x72,0x6f,0x20,0x3a,0x20,0x61,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x31,0x20,0x3d,0x20,0x28,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3e,0x3d,0x20,0x33,0x29,0x20,0x3f,0x20,0x76,0x5f,0x7a,0x65,0x72,0x6f,0x20,0x3a,0x20,0x61,0x31,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x30,0x5f,0x74,0x72,0x61,0x6e,0x73,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x61,0x30,0x2e,0x78,0x2c,0x20,0x61,0x31,0x2e,0x78,0x2c,0x20,0x61,0x32,0x2e,0x78,0x2c,0x20,0x61,0x33,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x31,0x5f,0x74,0x72,0x61,0x6e,0x73,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x61,0x30,0x2e,0x79,0x2c,0x20,0x61,0x31,0x2e,0x79,0x2c,0x20,0x61,0x32,0x2e,0x79,0x2c,0x20,0x61,0x33,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x32,0x5f,0x74,0x72,0x61,0x6e,0x73,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x61,0x30,0x2e,0x7a,0x2c,0x20,0x61,0x31,0x2e,0x7a,0x2c,0x20,0x61,0x32,0x2e,0x7a,0x2c,0x20,0x61,0x33,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x33,0x5f,0x74,0x72,0x61,0x6e,0x73,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x61,0x30,0x2e,0x77,0x2c,0x20,0x61,0x31,0x2e,0x77,0x2c,0x20,0x61,0x32,0x2e,0x77,0x2c,0x20,0x61,0x33,0x2e,0x77,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x30,0x5f,0x74,0x72,0x61,0x6e,0x73,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x62,0x30,0x2e,0x78,0x2c,0x20,0x62,0x31,0x2e,0x78,0x2c,0x20,0x62,0x32,0x2e,0x78,0x2c,0x20,0x62,0x33,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x31,0x5f,0x74,0x72,0x61,0x6e,0x73,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x62,0x30,0x2e,0x79,0x2c,0x20,0x62,0x31,0x2e,0x79,0x2c,0x20,0x62,0x32,0x2e,0x79,0x2c,0x20,0x62,0x33,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x32,0x5f,0x74,0x72,0x61,0x6e,0x73,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x62,0x30,0x2e,0x7a,0x2c,0x20,0x62,0x31,0x2e,0x7a,0x2c,0x20,0x62,0x32,0x2e,0x7a,0x2c,0x20,0x62,0x33,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x33,0x5f,0x74,0x72,0x61,0x6e,0x73,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x62,0x30,0x2e,0x77,0x2c,0x20,0x62,0x31,0x2e,0x77,0x2c,0x20,0x62,0x32,0x2e,0x77,0x2c,0x20,0x62,0x33,0x2e,0x77,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x6d,0x61,0x74,0x6d,0x75,0x6c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x30,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x30,0x5f,0x74,0x72,0x61,0x6e,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x2e,0x79,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x30,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x31,0x5f,0x74,0x72,0x61,0x6e,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x2e,0x7a,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x30,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x32,0x5f,0x74,0x72,0x61,0x6e,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x2e,0x77,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x30,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x33,0x5f,0x74,0x72,0x61,0x6e,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x31,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x30,0x5f,0x74,0x72,0x61,0x6e,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x2e,0x79,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x31,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x31,0x5f,0x74,0x72,0x61,0x6e,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x2e,0x7a,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x31,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x32,0x5f,0x74,0x72,0x61,0x6e,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x2e,0x77,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x31,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x33,0x5f,0x74,0x72,0x61,0x6e,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x32,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x30,0x5f,0x74,0x72,0x61,0x6e,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x2e,0x79,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x32,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x31,0x5f,0x74,0x72,0x61,0x6e,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x2e,0x7a,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x32,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x32,0x5f,0x74,0x72,0x61,0x6e,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x2e,0x77,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x32,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x33,0x5f,0x74,0x72,0x61,0x6e,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x33,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x30,0x5f,0x74,0x72,0x61,0x6e,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x2e,0x79,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x33,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x31,0x5f,0x74,0x72,0x61,0x6e,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x2e,0x7a,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x33,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x32,0x5f,0x74,0x72,0x61,0x6e,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x2e,0x77,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x33,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x33,0x5f,0x74,0x72,0x61,0x6e,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x34,0x2a,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x34,0x2a,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2b,0x31,0x20,0x3e,0x3d,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x34,0x2a,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2b,0x32,0x20,0x3e,0x3d,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x32,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x34,0x2a,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2b,0x33,0x20,0x3e,0x3d,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x33,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x29,0x3b,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x6d,0x61,0x74,0x6d,0x75,0x6c,0x5f,0x74,0x72,0x61,0x6e,0x73,0x41,0x5f,0x74,0x72,0x61,0x6e,0x73,0x42,0x5f,0x62,0x75,0x66,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x32,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x61,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x63,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x32,0x28,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2c,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x5f,0x7a,0x65,0x72,0x6f,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x63,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x20,0x3d,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x20,0x3d,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x20,0x3d,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x73,0x68,0x6f,0x72,0x74,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x30,0x3b,0x20,0x70,0x6f,0x73,0x20,0x3c,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0x20,0x70,0x6f,0x73,0x20,0x2b,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x34,0x2a,0x70,0x6f,0x73,0x29,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x61,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x61,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x61,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x33,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x61,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x34,0x2a,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x70,0x6f,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x33,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x68,0x6f,0x72,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x20,0x28,0x70,0x6f,0x73,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x34,0x20,0x2d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x33,0x20,0x3d,0x20,0x28,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3e,0x3d,0x20,0x31,0x29,0x20,0x3f,0x20,0x76,0x5f,0x7a,0x65,0x72,0x6f,0x20,0x3a,0x20,0x61,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x32,0x20,0x3d,0x20,0x28,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3e,0x3d,0x20,0x32,0x29,0x20,0x3f,0x20,0x76,0x5f,0x7a,0x65,0x72,0x6f,0x20,0x3a,0x20,0x61,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x31,0x20,0x3d,0x20,0x28,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3e,0x3d,0x20,0x33,0x29,0x20,0x3f,0x20,0x76,0x5f,0x7a,0x65,0x72,0x6f,0x20,0x3a,0x20,0x61,0x31,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x30,0x5f,0x74,0x72,0x61,0x6e,0x73,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x61,0x30,0x2e,0x78,0x2c,0x20,0x61,0x31,0x2e,0x78,0x2c,0x20,0x61,0x32,0x2e,0x78,0x2c,0x20,0x61,0x33,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x31,0x5f,0x74,0x72,0x61,0x6e,0x73,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x61,0x30,0x2e,0x79,0x2c,0x20,0x61,0x31,0x2e,0x79,0x2c,0x20,0x61,0x32,0x2e,0x79,0x2c,0x20,0x61,0x33,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x32,0x5f,0x74,0x72,0x61,0x6e,0x73,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x61,0x30,0x2e,0x7a,0x2c,0x20,0x61,0x31,0x2e,0x7a,0x2c,0x20,0x61,0x32,0x2e,0x7a,0x2c,0x20,0x61,0x33,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x33,0x5f,0x74,0x72,0x61,0x6e,0x73,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x61,0x30,0x2e,0x77,0x2c,0x20,0x61,0x31,0x2e,0x77,0x2c,0x20,0x61,0x32,0x2e,0x77,0x2c,0x20,0x61,0x33,0x2e,0x77,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x6d,0x61,0x74,0x6d,0x75,0x6c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x30,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x2e,0x79,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x30,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x2e,0x7a,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x30,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x2e,0x77,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x30,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x31,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x2e,0x79,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x31,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x2e,0x7a,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x31,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x2e,0x77,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x31,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x32,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x2e,0x79,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x32,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x2e,0x7a,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x32,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x2e,0x77,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x32,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x33,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x2e,0x79,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x33,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x2e,0x7a,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x33,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x2e,0x77,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x33,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x34,0x2a,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x34,0x2a,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2b,0x31,0x20,0x3e,0x3d,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x34,0x2a,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2b,0x32,0x20,0x3e,0x3d,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x32,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x34,0x2a,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2b,0x33,0x20,0x3e,0x3d,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x33,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x29,0x3b,0xa,0x7d,0xa, } + { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,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,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x32,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5c,0xa,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x2c,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x32,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x69,0x66,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x29,0x20,0x7b,0x20,0x5c,0xa,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x6d,0x61,0x74,0x6d,0x75,0x6c,0x5f,0x62,0x75,0x66,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x32,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x61,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x63,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x2c,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x2f,0x2f,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x57,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0x2f,0x2f,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x48,0xa,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x32,0x28,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2c,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x30,0x20,0x3d,0x20,0x30,0x2c,0x20,0x62,0x31,0x20,0x3d,0x20,0x30,0x2c,0x20,0x62,0x32,0x20,0x3d,0x20,0x30,0x2c,0x20,0x62,0x33,0x20,0x3d,0x20,0x30,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x74,0x65,0x6d,0x70,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x63,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x20,0x3d,0x20,0x74,0x65,0x6d,0x70,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x20,0x3d,0x20,0x74,0x65,0x6d,0x70,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x20,0x3d,0x20,0x74,0x65,0x6d,0x70,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x20,0x3d,0x20,0x74,0x65,0x6d,0x70,0x2e,0x77,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x73,0x68,0x6f,0x72,0x74,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x30,0x3b,0x20,0x70,0x6f,0x73,0x20,0x3c,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0x20,0x70,0x6f,0x73,0x20,0x2b,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x70,0x6f,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x61,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x68,0x6f,0x72,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x20,0x28,0x70,0x6f,0x73,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x34,0x20,0x2d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x70,0x6f,0x73,0x2a,0x34,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x33,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x33,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x31,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x32,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x33,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x32,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x33,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x33,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x74,0x6d,0x70,0x30,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x62,0x30,0x2e,0x73,0x30,0x2c,0x20,0x62,0x31,0x2e,0x73,0x30,0x2c,0x20,0x62,0x32,0x2e,0x73,0x30,0x2c,0x20,0x62,0x33,0x2e,0x73,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x74,0x6d,0x70,0x31,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x62,0x30,0x2e,0x73,0x31,0x2c,0x20,0x62,0x31,0x2e,0x73,0x31,0x2c,0x20,0x62,0x32,0x2e,0x73,0x31,0x2c,0x20,0x62,0x33,0x2e,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x74,0x6d,0x70,0x32,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x62,0x30,0x2e,0x73,0x32,0x2c,0x20,0x62,0x31,0x2e,0x73,0x32,0x2c,0x20,0x62,0x32,0x2e,0x73,0x32,0x2c,0x20,0x62,0x33,0x2e,0x73,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x74,0x6d,0x70,0x33,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x62,0x30,0x2e,0x73,0x33,0x2c,0x20,0x62,0x31,0x2e,0x73,0x33,0x2c,0x20,0x62,0x32,0x2e,0x73,0x33,0x2c,0x20,0x62,0x33,0x2e,0x73,0x33,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x2c,0x20,0x62,0x74,0x6d,0x70,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x2c,0x20,0x62,0x74,0x6d,0x70,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x2c,0x20,0x62,0x74,0x6d,0x70,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x2c,0x20,0x62,0x74,0x6d,0x70,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x2c,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x2c,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x2c,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x29,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x29,0x3b,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x6d,0x61,0x74,0x6d,0x75,0x6c,0x5f,0x74,0x72,0x61,0x6e,0x73,0x42,0x5f,0x62,0x75,0x66,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x32,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x61,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x63,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x2c,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x32,0x28,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2c,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x30,0x20,0x3d,0x20,0x30,0x2c,0x20,0x62,0x31,0x20,0x3d,0x20,0x30,0x2c,0x20,0x62,0x32,0x20,0x3d,0x20,0x30,0x2c,0x20,0x62,0x33,0x20,0x3d,0x20,0x30,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x74,0x65,0x6d,0x70,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x63,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x20,0x3d,0x20,0x74,0x65,0x6d,0x70,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x20,0x3d,0x20,0x74,0x65,0x6d,0x70,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x20,0x3d,0x20,0x74,0x65,0x6d,0x70,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x20,0x3d,0x20,0x74,0x65,0x6d,0x70,0x2e,0x77,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x73,0x68,0x6f,0x72,0x74,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x30,0x3b,0x20,0x70,0x6f,0x73,0x20,0x3c,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0x20,0x70,0x6f,0x73,0x20,0x2b,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x70,0x6f,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x61,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x68,0x6f,0x72,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x20,0x28,0x70,0x6f,0x73,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x34,0x20,0x2d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2a,0x34,0x29,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x70,0x6f,0x73,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x33,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x33,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x2e,0x79,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x2e,0x7a,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x2e,0x77,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x2e,0x7a,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x2e,0x77,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x2e,0x77,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x2c,0x20,0x62,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x2c,0x20,0x62,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x2c,0x20,0x62,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x2c,0x20,0x62,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x2c,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x2c,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x2c,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x29,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x29,0x3b,0xa,0x7d,0xa,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x6d,0x61,0x74,0x6d,0x75,0x6c,0x5f,0x74,0x72,0x61,0x6e,0x73,0x41,0x5f,0x62,0x75,0x66,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x32,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x61,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x63,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x32,0x28,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2c,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x5f,0x7a,0x65,0x72,0x6f,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x63,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x20,0x3d,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x20,0x3d,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x20,0x3d,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x73,0x68,0x6f,0x72,0x74,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x30,0x3b,0x20,0x70,0x6f,0x73,0x20,0x3c,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0x20,0x70,0x6f,0x73,0x20,0x2b,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x34,0x2a,0x70,0x6f,0x73,0x29,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x68,0x6f,0x72,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x20,0x28,0x70,0x6f,0x73,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x34,0x20,0x2d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x61,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x31,0x20,0x3d,0x20,0x28,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3e,0x3d,0x20,0x33,0x29,0x20,0x3f,0x20,0x76,0x5f,0x7a,0x65,0x72,0x6f,0x20,0x3a,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x61,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x32,0x20,0x3d,0x20,0x28,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3e,0x3d,0x20,0x32,0x29,0x20,0x3f,0x20,0x76,0x5f,0x7a,0x65,0x72,0x6f,0x20,0x3a,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x61,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x33,0x20,0x3d,0x20,0x28,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3e,0x3d,0x20,0x31,0x29,0x20,0x3f,0x20,0x76,0x5f,0x7a,0x65,0x72,0x6f,0x20,0x3a,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x33,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x61,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x34,0x2a,0x70,0x6f,0x73,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x33,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x30,0x5f,0x74,0x72,0x61,0x6e,0x73,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x61,0x30,0x2e,0x78,0x2c,0x20,0x61,0x31,0x2e,0x78,0x2c,0x20,0x61,0x32,0x2e,0x78,0x2c,0x20,0x61,0x33,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x31,0x5f,0x74,0x72,0x61,0x6e,0x73,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x61,0x30,0x2e,0x79,0x2c,0x20,0x61,0x31,0x2e,0x79,0x2c,0x20,0x61,0x32,0x2e,0x79,0x2c,0x20,0x61,0x33,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x32,0x5f,0x74,0x72,0x61,0x6e,0x73,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x61,0x30,0x2e,0x7a,0x2c,0x20,0x61,0x31,0x2e,0x7a,0x2c,0x20,0x61,0x32,0x2e,0x7a,0x2c,0x20,0x61,0x33,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x33,0x5f,0x74,0x72,0x61,0x6e,0x73,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x61,0x30,0x2e,0x77,0x2c,0x20,0x61,0x31,0x2e,0x77,0x2c,0x20,0x61,0x32,0x2e,0x77,0x2c,0x20,0x61,0x33,0x2e,0x77,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x30,0x5f,0x74,0x72,0x61,0x6e,0x73,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x62,0x30,0x2e,0x78,0x2c,0x20,0x62,0x31,0x2e,0x78,0x2c,0x20,0x62,0x32,0x2e,0x78,0x2c,0x20,0x62,0x33,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x31,0x5f,0x74,0x72,0x61,0x6e,0x73,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x62,0x30,0x2e,0x79,0x2c,0x20,0x62,0x31,0x2e,0x79,0x2c,0x20,0x62,0x32,0x2e,0x79,0x2c,0x20,0x62,0x33,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x32,0x5f,0x74,0x72,0x61,0x6e,0x73,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x62,0x30,0x2e,0x7a,0x2c,0x20,0x62,0x31,0x2e,0x7a,0x2c,0x20,0x62,0x32,0x2e,0x7a,0x2c,0x20,0x62,0x33,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x33,0x5f,0x74,0x72,0x61,0x6e,0x73,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x62,0x30,0x2e,0x77,0x2c,0x20,0x62,0x31,0x2e,0x77,0x2c,0x20,0x62,0x32,0x2e,0x77,0x2c,0x20,0x62,0x33,0x2e,0x77,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x6d,0x61,0x74,0x6d,0x75,0x6c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x30,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x30,0x5f,0x74,0x72,0x61,0x6e,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x2e,0x79,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x30,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x31,0x5f,0x74,0x72,0x61,0x6e,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x2e,0x7a,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x30,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x32,0x5f,0x74,0x72,0x61,0x6e,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x2e,0x77,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x30,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x33,0x5f,0x74,0x72,0x61,0x6e,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x31,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x30,0x5f,0x74,0x72,0x61,0x6e,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x2e,0x79,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x31,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x31,0x5f,0x74,0x72,0x61,0x6e,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x2e,0x7a,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x31,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x32,0x5f,0x74,0x72,0x61,0x6e,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x2e,0x77,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x31,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x33,0x5f,0x74,0x72,0x61,0x6e,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x32,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x30,0x5f,0x74,0x72,0x61,0x6e,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x2e,0x79,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x32,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x31,0x5f,0x74,0x72,0x61,0x6e,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x2e,0x7a,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x32,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x32,0x5f,0x74,0x72,0x61,0x6e,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x2e,0x77,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x32,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x33,0x5f,0x74,0x72,0x61,0x6e,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x33,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x30,0x5f,0x74,0x72,0x61,0x6e,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x2e,0x79,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x33,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x31,0x5f,0x74,0x72,0x61,0x6e,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x2e,0x7a,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x33,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x32,0x5f,0x74,0x72,0x61,0x6e,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x2e,0x77,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x33,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x33,0x5f,0x74,0x72,0x61,0x6e,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x34,0x2a,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x34,0x2a,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2b,0x31,0x20,0x3e,0x3d,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x34,0x2a,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2b,0x32,0x20,0x3e,0x3d,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x32,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x34,0x2a,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2b,0x33,0x20,0x3e,0x3d,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x33,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x29,0x3b,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x6d,0x61,0x74,0x6d,0x75,0x6c,0x5f,0x74,0x72,0x61,0x6e,0x73,0x41,0x5f,0x74,0x72,0x61,0x6e,0x73,0x42,0x5f,0x62,0x75,0x66,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x32,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x61,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x63,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x32,0x28,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2c,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x5f,0x7a,0x65,0x72,0x6f,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x28,0x46,0x4c,0x4f,0x41,0x54,0x29,0x30,0x2e,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x63,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x20,0x3d,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x20,0x3d,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x20,0x3d,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x73,0x68,0x6f,0x72,0x74,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x30,0x3b,0x20,0x70,0x6f,0x73,0x20,0x3c,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x3b,0x20,0x70,0x6f,0x73,0x20,0x2b,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x34,0x2a,0x70,0x6f,0x73,0x29,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x68,0x6f,0x72,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x20,0x28,0x70,0x6f,0x73,0x20,0x2b,0x20,0x31,0x29,0x20,0x2a,0x20,0x34,0x20,0x2d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x61,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x31,0x20,0x3d,0x20,0x28,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3e,0x3d,0x20,0x33,0x29,0x20,0x3f,0x20,0x76,0x5f,0x7a,0x65,0x72,0x6f,0x20,0x3a,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x61,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x32,0x20,0x3d,0x20,0x28,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3e,0x3d,0x20,0x32,0x29,0x20,0x3f,0x20,0x76,0x5f,0x7a,0x65,0x72,0x6f,0x20,0x3a,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x61,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x33,0x20,0x3d,0x20,0x28,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3e,0x3d,0x20,0x31,0x29,0x20,0x3f,0x20,0x76,0x5f,0x7a,0x65,0x72,0x6f,0x20,0x3a,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x33,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x61,0x29,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x34,0x2a,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x70,0x6f,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x32,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x62,0x33,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x6e,0x70,0x62,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x33,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x62,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x30,0x5f,0x74,0x72,0x61,0x6e,0x73,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x61,0x30,0x2e,0x78,0x2c,0x20,0x61,0x31,0x2e,0x78,0x2c,0x20,0x61,0x32,0x2e,0x78,0x2c,0x20,0x61,0x33,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x31,0x5f,0x74,0x72,0x61,0x6e,0x73,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x61,0x30,0x2e,0x79,0x2c,0x20,0x61,0x31,0x2e,0x79,0x2c,0x20,0x61,0x32,0x2e,0x79,0x2c,0x20,0x61,0x33,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x32,0x5f,0x74,0x72,0x61,0x6e,0x73,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x61,0x30,0x2e,0x7a,0x2c,0x20,0x61,0x31,0x2e,0x7a,0x2c,0x20,0x61,0x32,0x2e,0x7a,0x2c,0x20,0x61,0x33,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x33,0x5f,0x74,0x72,0x61,0x6e,0x73,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x61,0x30,0x2e,0x77,0x2c,0x20,0x61,0x31,0x2e,0x77,0x2c,0x20,0x61,0x32,0x2e,0x77,0x2c,0x20,0x61,0x33,0x2e,0x77,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2f,0x6d,0x61,0x74,0x6d,0x75,0x6c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x30,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x2e,0x79,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x30,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x2e,0x7a,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x30,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x2e,0x77,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x30,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x31,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x2e,0x79,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x31,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x2e,0x7a,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x31,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x2e,0x77,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x31,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x32,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x2e,0x79,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x32,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x2e,0x7a,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x32,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x2e,0x77,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x32,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x33,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x2e,0x79,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x33,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x2e,0x7a,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x33,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x2e,0x77,0x20,0x2b,0x3d,0x20,0x64,0x6f,0x74,0x28,0x61,0x33,0x5f,0x74,0x72,0x61,0x6e,0x73,0x2c,0x20,0x62,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x34,0x2a,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x29,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x30,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x34,0x2a,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2b,0x31,0x20,0x3e,0x3d,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x31,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x34,0x2a,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2b,0x32,0x20,0x3e,0x3d,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x32,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x32,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x34,0x2a,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x5f,0x69,0x64,0x78,0x2b,0x33,0x20,0x3e,0x3d,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x33,0x2c,0x20,0x6f,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x2b,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x73,0x2a,0x33,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x29,0x3b,0xa,0x7d,0xa, } }, #endif { @@ -237,7 +237,7 @@ extern const std::map> OpenCLProgramMap #ifndef MNN_OPENCL_BUFFER_CLOSED { "softmax_buf", - { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,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,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x45,0x58,0x50,0x20,0x65,0x78,0x70,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x73,0x6f,0x66,0x74,0x6d,0x61,0x78,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x29,0x20,0x7b,0x2f,0x2f,0x4e,0x43,0x48,0x57,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x20,0x26,0x26,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x2f,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x25,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x30,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2b,0x77,0x69,0x64,0x74,0x68,0x5f,0x69,0x64,0x78,0x29,0x2a,0x34,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x73,0x68,0x6f,0x72,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2d,0x20,0x31,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x77,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2d,0x20,0x31,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x77,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x33,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x73,0x68,0x6f,0x72,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2d,0x20,0x31,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x20,0x3d,0x20,0x45,0x58,0x50,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x20,0x2d,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x2b,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x20,0x3d,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x20,0x2b,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x79,0x20,0x2b,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x7a,0x20,0x2b,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x77,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2d,0x20,0x31,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x20,0x2d,0x3d,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x45,0x58,0x50,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x77,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x45,0x58,0x50,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x45,0x58,0x50,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x45,0x58,0x50,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x45,0x58,0x50,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x45,0x58,0x50,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x45,0x58,0x50,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x45,0x58,0x50,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x45,0x58,0x50,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x33,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x45,0x58,0x50,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x20,0x2d,0x20,0x66,0x6c,0x6f,0x61,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x20,0x3d,0x20,0x45,0x58,0x50,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x29,0x20,0x2f,0x20,0x61,0x63,0x63,0x75,0x6d,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2c,0x20,0x69,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x73,0x6f,0x66,0x74,0x6d,0x61,0x78,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x20,0x2f,0x2f,0x20,0x4e,0x43,0x48,0x57,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x77,0x63,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x62,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x20,0x3d,0x20,0x77,0x63,0x20,0x2f,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x20,0x3d,0x20,0x77,0x63,0x20,0x25,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x63,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x30,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2b,0x77,0x29,0x2a,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x77,0x63,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x20,0x26,0x26,0x20,0x62,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x4d,0x61,0x78,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x31,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x45,0x78,0x70,0x20,0x53,0x75,0x6d,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x52,0x65,0x73,0x75,0x6c,0x74,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x65,0x78,0x70,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x29,0x20,0x2f,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x76,0x61,0x6c,0x75,0x65,0x2c,0x20,0x69,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x20,0x20,0x20,0xa,0x7d,0xa,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x73,0x6f,0x66,0x74,0x6d,0x61,0x78,0x5f,0x77,0x69,0x64,0x74,0x68,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x20,0x2f,0x2f,0x20,0x4e,0x43,0x48,0x57,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x63,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x62,0x68,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x20,0x3d,0x20,0x62,0x68,0x20,0x2f,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x20,0x3d,0x20,0x62,0x68,0x20,0x25,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x63,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x68,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2b,0x30,0x29,0x2a,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x63,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x26,0x26,0x20,0x62,0x68,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x4d,0x61,0x78,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x31,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x45,0x78,0x70,0x20,0x53,0x75,0x6d,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x52,0x65,0x73,0x75,0x6c,0x74,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x65,0x78,0x70,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x29,0x20,0x2f,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x76,0x61,0x6c,0x75,0x65,0x2c,0x20,0x69,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa, } + { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,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,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x45,0x58,0x50,0x20,0x65,0x78,0x70,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x29,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x30,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x32,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x31,0x20,0x7c,0x7c,0x20,0x69,0x6e,0x70,0x75,0x74,0x33,0x20,0x3e,0x3d,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5c,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x73,0x6f,0x66,0x74,0x6d,0x61,0x78,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x29,0x20,0x7b,0x2f,0x2f,0x4e,0x43,0x48,0x57,0xa,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x68,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x78,0x2c,0x20,0x77,0x2c,0x20,0x62,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x62,0x68,0x20,0x2f,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x20,0x3d,0x20,0x62,0x68,0x20,0x25,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x61,0x74,0x63,0x68,0x5f,0x69,0x64,0x78,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x30,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x68,0x65,0x69,0x67,0x68,0x74,0x5f,0x69,0x64,0x78,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2b,0x77,0x29,0x2a,0x34,0x3b,0xa,0x23,0x69,0x66,0x20,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x3d,0x20,0x34,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6c,0x69,0x64,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x73,0x75,0x6d,0x5b,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5d,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x6c,0x69,0x64,0x3b,0x20,0x69,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2d,0x20,0x31,0x3b,0x20,0x69,0x2b,0x3d,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,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,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x32,0x3b,0x20,0x69,0x20,0x3e,0x20,0x30,0x3b,0x20,0x69,0x20,0x2f,0x3d,0x20,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x6c,0x69,0x64,0x20,0x3c,0x20,0x69,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x2c,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x20,0x2b,0x20,0x69,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,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,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x73,0x75,0x6d,0x5b,0x30,0x5d,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x77,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2d,0x20,0x31,0x29,0x20,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x77,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x33,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x6c,0x69,0x64,0x3b,0x20,0x69,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2d,0x20,0x31,0x3b,0x20,0x69,0x2b,0x3d,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,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,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x32,0x3b,0x20,0x69,0x20,0x3e,0x20,0x30,0x3b,0x20,0x69,0x20,0x2f,0x3d,0x20,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x6c,0x69,0x64,0x20,0x3c,0x20,0x69,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x2b,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x20,0x2b,0x20,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,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,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x73,0x75,0x6d,0x5b,0x30,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x79,0x20,0x2b,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x77,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x20,0x2d,0x3d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x77,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x33,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x6c,0x69,0x64,0x3b,0x20,0x69,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x3b,0x20,0x69,0x2b,0x3d,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x65,0x78,0x70,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x29,0x20,0x2f,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x76,0x61,0x6c,0x75,0x65,0x2c,0x20,0x69,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2d,0x20,0x31,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x77,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x28,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2d,0x20,0x31,0x29,0x20,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x77,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x33,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x20,0x2d,0x20,0x31,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x20,0x2d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x3d,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x79,0x20,0x2b,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x77,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x20,0x2d,0x3d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x77,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x20,0x3d,0x3d,0x20,0x33,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x65,0x78,0x70,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x29,0x20,0x2f,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x76,0x61,0x6c,0x75,0x65,0x2c,0x20,0x69,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x7d,0xa,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x73,0x6f,0x66,0x74,0x6d,0x61,0x78,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x20,0x2f,0x2f,0x20,0x4e,0x43,0x48,0x57,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x63,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x78,0x2c,0x20,0x77,0x63,0x2c,0x20,0x62,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x20,0x3d,0x20,0x77,0x63,0x20,0x2f,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x20,0x3d,0x20,0x77,0x63,0x20,0x25,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x63,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x30,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2b,0x77,0x29,0x2a,0x34,0x3b,0xa,0x23,0x69,0x66,0x20,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x3d,0x20,0x34,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6c,0x69,0x64,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x73,0x75,0x6d,0x5b,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x4d,0x61,0x78,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x6c,0x69,0x64,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0x20,0x69,0x2b,0x3d,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,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,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x32,0x3b,0x20,0x69,0x20,0x3e,0x20,0x30,0x3b,0x20,0x69,0x20,0x2f,0x3d,0x20,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x6c,0x69,0x64,0x20,0x3c,0x20,0x69,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x2c,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x20,0x2b,0x20,0x69,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,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,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x73,0x75,0x6d,0x5b,0x30,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x45,0x78,0x70,0x20,0x53,0x75,0x6d,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x6c,0x69,0x64,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0x20,0x69,0x2b,0x3d,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,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,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x32,0x3b,0x20,0x69,0x20,0x3e,0x20,0x30,0x3b,0x20,0x69,0x20,0x2f,0x3d,0x20,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x6c,0x69,0x64,0x20,0x3c,0x20,0x69,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x2b,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x20,0x2b,0x20,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,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,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x73,0x75,0x6d,0x5b,0x30,0x5d,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x52,0x65,0x73,0x75,0x6c,0x74,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x6c,0x69,0x64,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0x20,0x69,0x2b,0x3d,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x65,0x78,0x70,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x29,0x20,0x2f,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x76,0x61,0x6c,0x75,0x65,0x2c,0x20,0x69,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x4d,0x61,0x78,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x45,0x78,0x70,0x20,0x53,0x75,0x6d,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x52,0x65,0x73,0x75,0x6c,0x74,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x65,0x78,0x70,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x29,0x20,0x2f,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x76,0x61,0x6c,0x75,0x65,0x2c,0x20,0x69,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x7d,0xa,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x73,0x6f,0x66,0x74,0x6d,0x61,0x78,0x5f,0x77,0x69,0x64,0x74,0x68,0x28,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5f,0x33,0x5f,0x44,0x49,0x4d,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x20,0x2f,0x2f,0x20,0x4e,0x43,0x48,0x57,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x68,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x44,0x45,0x41,0x4c,0x5f,0x4e,0x4f,0x4e,0x5f,0x55,0x4e,0x49,0x46,0x4f,0x52,0x4d,0x5f,0x44,0x49,0x4d,0x33,0x28,0x78,0x2c,0x20,0x63,0x2c,0x20,0x62,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x20,0x3d,0x20,0x62,0x68,0x20,0x2f,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x20,0x3d,0x20,0x62,0x68,0x20,0x25,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x28,0x28,0x28,0x62,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2b,0x63,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2b,0x68,0x29,0x2a,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x2b,0x30,0x29,0x2a,0x34,0x3b,0xa,0x23,0x69,0x66,0x20,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x3d,0x20,0x34,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x6c,0x69,0x64,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x73,0x75,0x6d,0x5b,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x4d,0x61,0x78,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x6c,0x69,0x64,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x3b,0x20,0x69,0x2b,0x3d,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,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,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x32,0x3b,0x20,0x69,0x20,0x3e,0x20,0x30,0x3b,0x20,0x69,0x20,0x2f,0x3d,0x20,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x6c,0x69,0x64,0x20,0x3c,0x20,0x69,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x2c,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x20,0x2b,0x20,0x69,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,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,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x73,0x75,0x6d,0x5b,0x30,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x45,0x78,0x70,0x20,0x53,0x75,0x6d,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x6c,0x69,0x64,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0x20,0x69,0x2b,0x3d,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,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,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x32,0x3b,0x20,0x69,0x20,0x3e,0x20,0x30,0x3b,0x20,0x69,0x20,0x2f,0x3d,0x20,0x32,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x6c,0x69,0x64,0x20,0x3c,0x20,0x69,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x3d,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x5d,0x20,0x2b,0x20,0x73,0x75,0x6d,0x5b,0x6c,0x69,0x64,0x20,0x2b,0x20,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,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,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x73,0x75,0x6d,0x5b,0x30,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x52,0x65,0x73,0x75,0x6c,0x74,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x6c,0x69,0x64,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x3b,0x20,0x69,0x2b,0x3d,0x53,0x4f,0x46,0x54,0x4d,0x41,0x58,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x65,0x78,0x70,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x29,0x20,0x2f,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x76,0x61,0x6c,0x75,0x65,0x2c,0x20,0x69,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x4d,0x61,0x78,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x2d,0x46,0x4c,0x54,0x5f,0x4d,0x41,0x58,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x2c,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x45,0x78,0x70,0x20,0x53,0x75,0x6d,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x20,0x2b,0x3d,0x20,0x65,0x78,0x70,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x2f,0x2a,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x20,0x52,0x65,0x73,0x75,0x6c,0x74,0x20,0x2a,0x2f,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x65,0x78,0x70,0x28,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x69,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x20,0x2d,0x20,0x6d,0x61,0x78,0x56,0x61,0x6c,0x75,0x65,0x29,0x20,0x2f,0x20,0x73,0x75,0x6d,0x56,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x76,0x61,0x6c,0x75,0x65,0x2c,0x20,0x69,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x7d,0xa, } }, #endif #ifndef MNN_OPENCL_BUFFER_CLOSED @@ -272,12 +272,12 @@ extern const std::map> OpenCLProgramMap }, { "binary", - { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,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,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x5f,0x74,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x20,0x3d,0x20,0x43,0x4c,0x4b,0x5f,0x4e,0x4f,0x52,0x4d,0x41,0x4c,0x49,0x5a,0x45,0x44,0x5f,0x43,0x4f,0x4f,0x52,0x44,0x53,0x5f,0x46,0x41,0x4c,0x53,0x45,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x41,0x44,0x44,0x52,0x45,0x53,0x53,0x5f,0x43,0x4c,0x41,0x4d,0x50,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x4e,0x45,0x41,0x52,0x45,0x53,0x54,0x3b,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62,0x69,0x6e,0x61,0x72,0x79,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x2c,0x2f,0x2f,0x5b,0x4e,0x2c,0x48,0x2c,0x57,0x2c,0x43,0x34,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x63,0x74,0x69,0x76,0x61,0x74,0x69,0x6f,0x6e,0x54,0x79,0x70,0x65,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x29,0x3b,0x2f,0x2f,0x57,0x43,0x34,0x2c,0x20,0x4e,0x48,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x30,0x2c,0x20,0x69,0x6e,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x29,0x20,0x7b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x78,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x2c,0x20,0x30,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x69,0x6e,0x30,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x30,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x30,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x30,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x70,0x6f,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x79,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x2c,0x20,0x30,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x69,0x6e,0x31,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x31,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x31,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x31,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x70,0x6f,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x4f,0x50,0x45,0x52,0x41,0x54,0x4f,0x52,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x61,0x63,0x74,0x69,0x76,0x61,0x74,0x69,0x6f,0x6e,0x54,0x79,0x70,0x65,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x70,0x6f,0x73,0x2c,0x20,0x6f,0x75,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62,0x69,0x6e,0x61,0x72,0x79,0x5f,0x70,0x72,0x65,0x6c,0x75,0x28,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x2c,0x20,0x69,0x6e,0x74,0x32,0x20,0x77,0x68,0x49,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x69,0x6e,0x74,0x34,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x4e,0x48,0x57,0x43,0x53,0x74,0x65,0x70,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x6e,0x68,0x77,0x63,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x34,0x29,0x28,0x70,0x6f,0x73,0x2e,0x79,0x2f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2c,0x20,0x70,0x6f,0x73,0x2e,0x79,0x25,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2c,0x20,0x70,0x6f,0x73,0x2e,0x78,0x25,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2c,0x20,0x70,0x6f,0x73,0x2e,0x78,0x2f,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x6e,0x68,0x77,0x63,0x2e,0x78,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x26,0x26,0x20,0x6e,0x68,0x77,0x63,0x2e,0x77,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x6e,0x68,0x77,0x63,0x31,0x20,0x3d,0x20,0x6e,0x68,0x77,0x63,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x4e,0x48,0x57,0x43,0x53,0x74,0x65,0x70,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x6f,0x73,0x31,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6e,0x68,0x77,0x63,0x31,0x2e,0x77,0x2a,0x77,0x68,0x49,0x6e,0x70,0x75,0x74,0x31,0x2e,0x78,0x2b,0x6e,0x68,0x77,0x63,0x31,0x2e,0x7a,0x2c,0x20,0x6e,0x68,0x77,0x63,0x31,0x2e,0x78,0x2a,0x77,0x68,0x49,0x6e,0x70,0x75,0x74,0x31,0x2e,0x79,0x2b,0x6e,0x68,0x77,0x63,0x31,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x70,0x6f,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x70,0x6f,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x4f,0x50,0x45,0x52,0x41,0x54,0x4f,0x52,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x70,0x6f,0x73,0x2c,0x20,0x6f,0x75,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x69,0x6d,0x61,0x67,0x65,0x43,0x6f,0x70,0x79,0x28,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x64,0x69,0x6d,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x69,0x6d,0x61,0x67,0x65,0x5f,0x64,0x69,0x6d,0x28,0x69,0x6e,0x70,0x75,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x3e,0x3d,0x20,0x64,0x69,0x6d,0x2e,0x78,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3e,0x3d,0x20,0x64,0x69,0x6d,0x2e,0x79,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x70,0x6f,0x73,0x2c,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x70,0x6f,0x73,0x29,0x29,0x3b,0xa,0x7d,0xa, } + { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,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,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x50,0x49,0x20,0x33,0x2e,0x31,0x34,0x31,0x35,0x39,0x32,0x36,0x35,0x33,0x35,0x38,0x39,0x66,0xa,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x5f,0x74,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x20,0x3d,0x20,0x43,0x4c,0x4b,0x5f,0x4e,0x4f,0x52,0x4d,0x41,0x4c,0x49,0x5a,0x45,0x44,0x5f,0x43,0x4f,0x4f,0x52,0x44,0x53,0x5f,0x46,0x41,0x4c,0x53,0x45,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x41,0x44,0x44,0x52,0x45,0x53,0x53,0x5f,0x43,0x4c,0x41,0x4d,0x50,0x20,0x7c,0x20,0x43,0x4c,0x4b,0x5f,0x46,0x49,0x4c,0x54,0x45,0x52,0x5f,0x4e,0x45,0x41,0x52,0x45,0x53,0x54,0x3b,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62,0x69,0x6e,0x61,0x72,0x79,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x2c,0x2f,0x2f,0x5b,0x4e,0x2c,0x48,0x2c,0x57,0x2c,0x43,0x34,0x5d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x63,0x74,0x69,0x76,0x61,0x74,0x69,0x6f,0x6e,0x54,0x79,0x70,0x65,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x29,0x3b,0x2f,0x2f,0x57,0x43,0x34,0x2c,0x20,0x4e,0x48,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x30,0x2c,0x20,0x69,0x6e,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x29,0x20,0x7b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x78,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x2c,0x20,0x30,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x69,0x6e,0x30,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x30,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x30,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x30,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x70,0x6f,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x69,0x73,0x46,0x75,0x6c,0x6c,0x2e,0x79,0x20,0x3d,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x30,0x2c,0x20,0x30,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x28,0x69,0x6e,0x31,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x31,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x31,0x2e,0x78,0x2c,0x20,0x69,0x6e,0x31,0x2e,0x78,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x70,0x6f,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x4f,0x50,0x45,0x52,0x41,0x54,0x4f,0x52,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x61,0x63,0x74,0x69,0x76,0x61,0x74,0x69,0x6f,0x6e,0x54,0x79,0x70,0x65,0x20,0x3d,0x3d,0x20,0x31,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x66,0x6d,0x61,0x78,0x28,0x6f,0x75,0x74,0x2c,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x70,0x6f,0x73,0x2c,0x20,0x6f,0x75,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62,0x69,0x6e,0x61,0x72,0x79,0x5f,0x70,0x72,0x65,0x6c,0x75,0x28,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x68,0x61,0x70,0x65,0x2c,0x20,0x69,0x6e,0x74,0x32,0x20,0x77,0x68,0x49,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x69,0x6e,0x74,0x34,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x4e,0x48,0x57,0x43,0x53,0x74,0x65,0x70,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x6e,0x68,0x77,0x63,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x34,0x29,0x28,0x70,0x6f,0x73,0x2e,0x79,0x2f,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2c,0x20,0x70,0x6f,0x73,0x2e,0x79,0x25,0x73,0x68,0x61,0x70,0x65,0x2e,0x79,0x2c,0x20,0x70,0x6f,0x73,0x2e,0x78,0x25,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x2c,0x20,0x70,0x6f,0x73,0x2e,0x78,0x2f,0x73,0x68,0x61,0x70,0x65,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x6e,0x68,0x77,0x63,0x2e,0x78,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x78,0x20,0x26,0x26,0x20,0x6e,0x68,0x77,0x63,0x2e,0x77,0x20,0x3c,0x20,0x73,0x68,0x61,0x70,0x65,0x2e,0x77,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x6e,0x68,0x77,0x63,0x31,0x20,0x3d,0x20,0x6e,0x68,0x77,0x63,0x20,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x4e,0x48,0x57,0x43,0x53,0x74,0x65,0x70,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x6f,0x73,0x31,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x6e,0x68,0x77,0x63,0x31,0x2e,0x77,0x2a,0x77,0x68,0x49,0x6e,0x70,0x75,0x74,0x31,0x2e,0x78,0x2b,0x6e,0x68,0x77,0x63,0x31,0x2e,0x7a,0x2c,0x20,0x6e,0x68,0x77,0x63,0x31,0x2e,0x78,0x2a,0x77,0x68,0x49,0x6e,0x70,0x75,0x74,0x31,0x2e,0x79,0x2b,0x6e,0x68,0x77,0x63,0x31,0x2e,0x79,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x70,0x6f,0x73,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x70,0x6f,0x73,0x31,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x4f,0x50,0x45,0x52,0x41,0x54,0x4f,0x52,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x70,0x6f,0x73,0x2c,0x20,0x6f,0x75,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x69,0x6d,0x61,0x67,0x65,0x43,0x6f,0x70,0x79,0x28,0x5f,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x77,0x72,0x69,0x74,0x65,0x5f,0x6f,0x6e,0x6c,0x79,0x20,0x69,0x6d,0x61,0x67,0x65,0x32,0x64,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x64,0x69,0x6d,0x20,0x3d,0x20,0x67,0x65,0x74,0x5f,0x69,0x6d,0x61,0x67,0x65,0x5f,0x64,0x69,0x6d,0x28,0x69,0x6e,0x70,0x75,0x74,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x3e,0x3d,0x20,0x64,0x69,0x6d,0x2e,0x78,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3e,0x3d,0x20,0x64,0x69,0x6d,0x2e,0x79,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x57,0x49,0x5f,0x46,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x70,0x6f,0x73,0x2c,0x20,0x52,0x49,0x5f,0x46,0x28,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x53,0x41,0x4d,0x50,0x4c,0x45,0x52,0x2c,0x20,0x70,0x6f,0x73,0x29,0x29,0x3b,0xa,0x7d,0xa, } }, #ifndef MNN_OPENCL_BUFFER_CLOSED { "loop_buf", - { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,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,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x6d,0x61,0x74,0x6d,0x75,0x6c,0x5f,0x62,0x75,0x66,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x41,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x42,0x2c,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x43,0x2c,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x4f,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x41,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x42,0x2c,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x43,0x2c,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6c,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x69,0x74,0x65,0x72,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x74,0x65,0x70,0x73,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x33,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x33,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x69,0x6e,0x64,0x65,0x78,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x34,0x29,0x28,0x70,0x6f,0x73,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x74,0x65,0x72,0x73,0x2e,0x78,0x20,0x3e,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x64,0x65,0x78,0x2e,0x78,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x29,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x4f,0x5b,0x70,0x6f,0x73,0x2e,0x7a,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x74,0x65,0x72,0x73,0x2e,0x79,0x20,0x3e,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x64,0x65,0x78,0x2e,0x79,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x29,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x41,0x5b,0x70,0x6f,0x73,0x2e,0x7a,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x74,0x65,0x72,0x73,0x2e,0x7a,0x20,0x3e,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x64,0x65,0x78,0x2e,0x7a,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x29,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x42,0x5b,0x70,0x6f,0x73,0x2e,0x7a,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x74,0x65,0x72,0x73,0x2e,0x77,0x20,0x3e,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x64,0x65,0x78,0x2e,0x77,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x29,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x43,0x5b,0x70,0x6f,0x73,0x2e,0x7a,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x69,0x6e,0x64,0x65,0x78,0x20,0x2a,0x20,0x73,0x74,0x65,0x70,0x73,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x23,0x69,0x66,0x20,0x54,0x52,0x41,0x4e,0x53,0x50,0x4f,0x53,0x45,0x5f,0x41,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x41,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x41,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x79,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x41,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x41,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x79,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x6c,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x20,0x54,0x52,0x41,0x4e,0x53,0x50,0x4f,0x53,0x45,0x5f,0x42,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x42,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x42,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x7a,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x2a,0x20,0x6c,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x42,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x42,0x20,0x2b,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x7a,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x78,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x49,0x41,0x53,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x43,0x5b,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x77,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x78,0x5d,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x30,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x6c,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x23,0x69,0x66,0x20,0x54,0x52,0x41,0x4e,0x53,0x50,0x4f,0x53,0x45,0x5f,0x41,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x20,0x3d,0x20,0x41,0x5f,0x70,0x74,0x72,0x5b,0x69,0x20,0x2a,0x20,0x65,0x5d,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x20,0x3d,0x20,0x41,0x5f,0x70,0x74,0x72,0x5b,0x69,0x5d,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x23,0x69,0x66,0x20,0x54,0x52,0x41,0x4e,0x53,0x50,0x4f,0x53,0x45,0x5f,0x42,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x20,0x3d,0x20,0x42,0x5f,0x70,0x74,0x72,0x5b,0x69,0x5d,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x20,0x3d,0x20,0x42,0x5f,0x70,0x74,0x72,0x5b,0x69,0x20,0x2a,0x20,0x68,0x5d,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x6d,0x61,0x64,0x28,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x78,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x68,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x78,0x5d,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x74,0x69,0x6c,0x65,0x5f,0x62,0x75,0x66,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x33,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x33,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x25,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x2f,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x78,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x79,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x63,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x28,0x28,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x78,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x79,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x64,0x73,0x74,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x2a,0x20,0x62,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x63,0x20,0x2a,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x68,0x20,0x2a,0x20,0x79,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x77,0x20,0x2a,0x20,0x78,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x2a,0x20,0x62,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x63,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x68,0x20,0x2a,0x20,0x79,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x77,0x20,0x2a,0x20,0x78,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x5f,0x70,0x74,0x72,0x5b,0x30,0x5d,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x63,0x20,0x2b,0x20,0x31,0x20,0x3e,0x3d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x5f,0x70,0x74,0x72,0x5b,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x5d,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x63,0x20,0x2b,0x20,0x32,0x20,0x3e,0x3d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x5f,0x70,0x74,0x72,0x5b,0x32,0x20,0x2a,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x5d,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x63,0x20,0x2b,0x20,0x33,0x20,0x3e,0x3d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x5f,0x70,0x74,0x72,0x5b,0x33,0x20,0x2a,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x5d,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x2e,0x77,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x70,0x61,0x63,0x6b,0x5f,0x62,0x75,0x66,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x33,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x33,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x25,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x2f,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x78,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x79,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x28,0x28,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x29,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x78,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x79,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x63,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x73,0x72,0x63,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x2a,0x20,0x62,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x63,0x20,0x2a,0x20,0x63,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x68,0x20,0x2a,0x20,0x79,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x77,0x20,0x2a,0x20,0x78,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x76,0x61,0x6c,0x75,0x65,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x29,0x26,0x76,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x34,0x20,0x26,0x26,0x20,0x28,0x69,0x20,0x2b,0x20,0x63,0x20,0x3c,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x70,0x74,0x72,0x5b,0x69,0x5d,0x20,0x3d,0x20,0x73,0x72,0x63,0x5f,0x70,0x74,0x72,0x5b,0x69,0x20,0x2a,0x20,0x63,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x76,0x61,0x6c,0x75,0x65,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x2a,0x20,0x62,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x68,0x20,0x2a,0x20,0x79,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x77,0x20,0x2a,0x20,0x78,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x67,0x61,0x74,0x68,0x65,0x72,0x5f,0x62,0x75,0x66,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x64,0x73,0x74,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x73,0x72,0x63,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x5f,0x73,0x69,0x7a,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x72,0x63,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x64,0x73,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x73,0x74,0x65,0x70,0x73,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x74,0x65,0x72,0x73,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x33,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x33,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x78,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x25,0x20,0x78,0x5f,0x73,0x69,0x7a,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x79,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x2f,0x20,0x78,0x5f,0x73,0x69,0x7a,0x65,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x64,0x65,0x78,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x32,0x29,0x28,0x70,0x6f,0x73,0x2e,0x7a,0x2c,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x74,0x65,0x72,0x73,0x2e,0x78,0x20,0x3e,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x64,0x65,0x78,0x2e,0x78,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x29,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x64,0x73,0x74,0x5b,0x70,0x6f,0x73,0x2e,0x7a,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x69,0x74,0x65,0x72,0x73,0x2e,0x79,0x20,0x3e,0x3d,0x20,0x30,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x64,0x65,0x78,0x2e,0x79,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x29,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x5f,0x73,0x72,0x63,0x5b,0x70,0x6f,0x73,0x2e,0x7a,0x5d,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x32,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x3d,0x20,0x69,0x6e,0x64,0x65,0x78,0x20,0x2a,0x20,0x73,0x74,0x65,0x70,0x73,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x78,0x20,0x2b,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x64,0x73,0x74,0x2e,0x77,0x20,0x2b,0x20,0x78,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x64,0x73,0x74,0x2e,0x78,0x20,0x2b,0x20,0x79,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x64,0x73,0x74,0x2e,0x79,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x64,0x73,0x74,0x2e,0x7a,0x5d,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5b,0x6f,0x66,0x66,0x73,0x65,0x74,0x2e,0x79,0x20,0x2b,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x72,0x63,0x2e,0x77,0x20,0x2b,0x20,0x78,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x72,0x63,0x2e,0x78,0x20,0x2b,0x20,0x79,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x72,0x63,0x2e,0x79,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x73,0x74,0x72,0x69,0x64,0x65,0x5f,0x73,0x72,0x63,0x2e,0x7a,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa, } + { 0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x53,0x55,0x50,0x50,0x4f,0x52,0x54,0x5f,0x46,0x50,0x31,0x36,0xa,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,0x6b,0x68,0x72,0x5f,0x66,0x70,0x31,0x36,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x74,0x69,0x6c,0x65,0x5f,0x62,0x75,0x66,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x33,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x33,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x25,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x2f,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x78,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x79,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x63,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x28,0x28,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x29,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x4e,0x48,0x57,0x43,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x78,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x79,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x78,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x79,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x64,0x73,0x74,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x2a,0x20,0x62,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x63,0x20,0x2a,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x68,0x20,0x2a,0x20,0x79,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x77,0x20,0x2a,0x20,0x78,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x2a,0x20,0x62,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x63,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x68,0x20,0x2a,0x20,0x79,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x77,0x20,0x2a,0x20,0x78,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x5f,0x70,0x74,0x72,0x5b,0x30,0x5d,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x63,0x20,0x2b,0x20,0x31,0x20,0x3e,0x3d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x5f,0x70,0x74,0x72,0x5b,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x5d,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x63,0x20,0x2b,0x20,0x32,0x20,0x3e,0x3d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x5f,0x70,0x74,0x72,0x5b,0x32,0x20,0x2a,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x5d,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x2e,0x7a,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x28,0x63,0x20,0x2b,0x20,0x33,0x20,0x3e,0x3d,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x73,0x74,0x5f,0x70,0x74,0x72,0x5b,0x33,0x20,0x2a,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x5d,0x20,0x3d,0x20,0x76,0x61,0x6c,0x75,0x65,0x2e,0x77,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x70,0x61,0x63,0x6b,0x5f,0x62,0x75,0x66,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x33,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x33,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x25,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x20,0x2f,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x78,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x79,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x28,0x28,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x29,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4d,0x4e,0x4e,0x5f,0x4e,0x48,0x57,0x43,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x63,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x78,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x79,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x78,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x79,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x78,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x77,0x69,0x64,0x74,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x79,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x3d,0x20,0x63,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x73,0x72,0x63,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x2a,0x20,0x62,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x63,0x20,0x2a,0x20,0x63,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x68,0x20,0x2a,0x20,0x79,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x77,0x20,0x2a,0x20,0x78,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x76,0x61,0x6c,0x75,0x65,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x34,0x29,0x30,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x20,0x2a,0x76,0x61,0x6c,0x75,0x65,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x29,0x26,0x76,0x61,0x6c,0x75,0x65,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x34,0x20,0x26,0x26,0x20,0x28,0x69,0x20,0x2b,0x20,0x63,0x20,0x3c,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x29,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x70,0x74,0x72,0x5b,0x69,0x5d,0x20,0x3d,0x20,0x73,0x72,0x63,0x5f,0x70,0x74,0x72,0x5b,0x69,0x20,0x2a,0x20,0x63,0x5f,0x73,0x72,0x63,0x5f,0x70,0x69,0x74,0x63,0x68,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x76,0x61,0x6c,0x75,0x65,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x2a,0x20,0x62,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x2a,0x20,0x63,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x68,0x20,0x2a,0x20,0x79,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x20,0x2b,0x20,0x77,0x20,0x2a,0x20,0x78,0x5f,0x64,0x73,0x74,0x5f,0x70,0x69,0x74,0x63,0x68,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x4c,0x4f,0x4f,0x50,0x5f,0x42,0x49,0x4e,0x41,0x52,0x59,0x5f,0x4f,0x50,0x45,0x52,0x41,0x54,0x4f,0x52,0xa,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62,0x72,0x6f,0x61,0x64,0x63,0x61,0x73,0x74,0x5f,0x62,0x69,0x6e,0x61,0x72,0x79,0x5f,0x62,0x75,0x66,0x28,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x2c,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x72,0x63,0x30,0x5f,0x73,0x69,0x7a,0x65,0x2c,0x20,0x2f,0x2f,0x28,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x2c,0x20,0x62,0x61,0x74,0x63,0x68,0x29,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x5f,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x33,0x20,0x70,0x6f,0x73,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x33,0x29,0x28,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x2c,0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x32,0x29,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x70,0x6f,0x73,0x2e,0x78,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x30,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x79,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x31,0x20,0x26,0x26,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x3c,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x64,0x69,0x6d,0x32,0x29,0x20,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x25,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6e,0x20,0x3d,0x20,0x70,0x6f,0x73,0x2e,0x7a,0x20,0x2f,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x30,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x3d,0x20,0x28,0x73,0x72,0x63,0x30,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x31,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x20,0x3d,0x20,0x28,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x7a,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x30,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x30,0x20,0x2b,0x20,0x28,0x28,0x28,0x28,0x6e,0x20,0x2a,0x20,0x73,0x72,0x63,0x30,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x29,0x20,0x2b,0x20,0x63,0x29,0x20,0x2a,0x20,0x73,0x72,0x63,0x30,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x79,0x20,0x2b,0x20,0x68,0x29,0x20,0x2a,0x20,0x73,0x72,0x63,0x30,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x78,0x20,0x2b,0x20,0x77,0x29,0x20,0x2a,0x20,0x34,0x29,0x3b,0xa,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x42,0x52,0x4f,0x41,0x44,0x43,0x41,0x53,0x54,0x5f,0x43,0x48,0x41,0x4e,0x4e,0x45,0x4c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x31,0x20,0x3d,0x20,0x77,0x20,0x25,0x20,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x31,0x20,0x3d,0x20,0x68,0x20,0x25,0x20,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6e,0x31,0x20,0x3d,0x20,0x6e,0x20,0x25,0x20,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x77,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x31,0x20,0x3d,0x20,0x63,0x20,0x3c,0x3c,0x20,0x32,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x63,0x31,0x5f,0x76,0x65,0x63,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x34,0x29,0x28,0x63,0x31,0x2c,0x20,0x63,0x31,0x20,0x2b,0x20,0x31,0x2c,0x20,0x63,0x31,0x20,0x2b,0x20,0x32,0x2c,0x20,0x63,0x31,0x20,0x2b,0x20,0x33,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x31,0x5f,0x76,0x65,0x63,0x20,0x3d,0x20,0x63,0x31,0x5f,0x76,0x65,0x63,0x20,0x25,0x20,0x28,0x69,0x6e,0x74,0x34,0x29,0x28,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x7a,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x34,0x20,0x63,0x34,0x5f,0x76,0x65,0x63,0x20,0x3d,0x20,0x28,0x63,0x31,0x5f,0x76,0x65,0x63,0x20,0x2b,0x20,0x33,0x29,0x20,0x2f,0x20,0x34,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x69,0x6e,0x31,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x29,0x26,0x69,0x6e,0x31,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x2a,0x20,0x63,0x31,0x5f,0x76,0x65,0x63,0x5f,0x70,0x72,0x74,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x2a,0x29,0x26,0x63,0x31,0x5f,0x76,0x65,0x63,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x2a,0x20,0x63,0x34,0x5f,0x76,0x65,0x63,0x5f,0x70,0x72,0x74,0x20,0x3d,0x20,0x28,0x69,0x6e,0x74,0x2a,0x29,0x26,0x63,0x34,0x5f,0x76,0x65,0x63,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x69,0x20,0x3c,0x20,0x34,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x7b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x20,0x3d,0x20,0x28,0x63,0x34,0x5f,0x76,0x65,0x63,0x5f,0x70,0x72,0x74,0x5b,0x69,0x5d,0x20,0x3c,0x3c,0x20,0x32,0x29,0x20,0x2d,0x20,0x63,0x31,0x5f,0x76,0x65,0x63,0x5f,0x70,0x72,0x74,0x5b,0x69,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x74,0x6d,0x70,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x2b,0x20,0x28,0x28,0x28,0x28,0x6e,0x31,0x20,0x2a,0x20,0x73,0x72,0x63,0x31,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x29,0x20,0x2b,0x20,0x63,0x34,0x5f,0x76,0x65,0x63,0x5f,0x70,0x72,0x74,0x5b,0x69,0x5d,0x29,0x20,0x2a,0x20,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x79,0x20,0x2b,0x20,0x68,0x31,0x29,0x20,0x2a,0x20,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x78,0x20,0x2b,0x20,0x77,0x31,0x29,0x20,0x2a,0x20,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x20,0x74,0x6d,0x70,0x5f,0x70,0x74,0x72,0x20,0x3d,0x20,0x28,0x46,0x4c,0x4f,0x41,0x54,0x2a,0x29,0x26,0x74,0x6d,0x70,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x31,0x5f,0x70,0x74,0x72,0x5b,0x69,0x5d,0x20,0x3d,0x20,0x74,0x6d,0x70,0x5f,0x70,0x74,0x72,0x5b,0x72,0x65,0x6d,0x61,0x69,0x6e,0x5d,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0xa,0x23,0x65,0x6c,0x73,0x65,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x77,0x31,0x20,0x3d,0x20,0x77,0x20,0x25,0x20,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x78,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x68,0x31,0x20,0x3d,0x20,0x68,0x20,0x25,0x20,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x79,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x31,0x20,0x3d,0x20,0x63,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6e,0x31,0x20,0x3d,0x20,0x6e,0x20,0x25,0x20,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x77,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x69,0x6e,0x31,0x20,0x3d,0x20,0x76,0x6c,0x6f,0x61,0x64,0x34,0x28,0x30,0x2c,0x20,0x69,0x6e,0x70,0x75,0x74,0x31,0x20,0x2b,0x20,0x28,0x28,0x28,0x28,0x6e,0x31,0x20,0x2a,0x20,0x73,0x72,0x63,0x31,0x5f,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x29,0x20,0x2b,0x20,0x63,0x31,0x29,0x20,0x2a,0x20,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x79,0x20,0x2b,0x20,0x68,0x31,0x29,0x20,0x2a,0x20,0x73,0x72,0x63,0x31,0x5f,0x73,0x69,0x7a,0x65,0x2e,0x78,0x20,0x2b,0x20,0x77,0x31,0x29,0x20,0x2a,0x20,0x34,0x29,0x3b,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x46,0x4c,0x4f,0x41,0x54,0x34,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x43,0x4f,0x4e,0x56,0x45,0x52,0x54,0x5f,0x46,0x4c,0x4f,0x41,0x54,0x34,0x28,0x4c,0x4f,0x4f,0x50,0x5f,0x42,0x49,0x4e,0x41,0x52,0x59,0x5f,0x4f,0x50,0x45,0x52,0x41,0x54,0x4f,0x52,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x73,0x74,0x6f,0x72,0x65,0x34,0x28,0x6f,0x75,0x74,0x2c,0x20,0x30,0x2c,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x20,0x2b,0x20,0x28,0x28,0x28,0x28,0x6e,0x20,0x2a,0x20,0x63,0x68,0x61,0x6e,0x6e,0x65,0x6c,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x29,0x20,0x2b,0x20,0x63,0x29,0x20,0x2a,0x20,0x64,0x73,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x20,0x2b,0x20,0x68,0x29,0x20,0x2a,0x20,0x64,0x73,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x20,0x2b,0x20,0x77,0x29,0x20,0x2a,0x20,0x34,0x29,0x3b,0xa,0x20,0x20,0x20,0x20,0x7d,0xa,0x7d,0xa,0x23,0x65,0x6e,0x64,0x69,0x66,0xa, } }, #endif { diff --git a/source/backend/opencl/execution/cl/softmax.cl b/source/backend/opencl/execution/cl/softmax.cl index fb0698cba..23133d7de 100644 --- a/source/backend/opencl/execution/cl/softmax.cl +++ b/source/backend/opencl/execution/cl/softmax.cl @@ -14,124 +14,268 @@ __constant sampler_t SAMPLER = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST; -__kernel void softmax_channel(GLOBAL_SIZE_3_DIMS __read_only image2d_t input, __write_only image2d_t output, __private const int output_channels, +__kernel void softmax_channel(GLOBAL_SIZE_3_DIMS __read_only image2d_t input, __write_only image2d_t output, __private const int remain_channels, __private const int4 shape // NCHW ) { - const int width_idx = get_global_id(0); - const int batch_height_idx = get_global_id(1); + const int x = get_global_id(0); + const int w = get_global_id(1); + const int bh = get_global_id(2); + DEAL_NON_UNIFORM_DIM3(x, w, bh); +#if SOFTMAX_LOCAL_SIZE >= 4 + int lid = get_local_id(0); + FLOAT4 local sum[SOFTMAX_LOCAL_SIZE]; + FLOAT4 maxValue = (FLOAT4)-FLT_MAX; + for (int i = lid; i < shape.y - 1; i+=SOFTMAX_LOCAL_SIZE) { + maxValue = fmax(maxValue, RI_F(input, SAMPLER, (int2)(w + i * shape.w, bh))); + } + + sum[lid] = maxValue; + barrier(CLK_LOCAL_MEM_FENCE); + for(int i = SOFTMAX_LOCAL_SIZE/2; i > 0; i /= 2){ + if (lid < i) + sum[lid] = fmax(sum[lid], sum[lid + i]); + barrier(CLK_LOCAL_MEM_FENCE); + } + maxValue = sum[0]; + + maxValue.x = fmax(maxValue.x, maxValue.y); + maxValue.x = fmax(maxValue.x, maxValue.z); + maxValue.x = fmax(maxValue.x, maxValue.w); + + FLOAT4 input_data = RI_F(input, SAMPLER, (int2)(w + (shape.y - 1) * shape.w , bh)); + if (remain_channels == 0) { + maxValue.x = fmax(maxValue.x, input_data.x); + maxValue.x = fmax(maxValue.x, input_data.y); + maxValue.x = fmax(maxValue.x, input_data.z); + maxValue.x = fmax(maxValue.x, input_data.w); + } else if (remain_channels == 1) { + maxValue.x = fmax(maxValue.x, input_data.z); + maxValue.x = fmax(maxValue.x, input_data.y); + maxValue.x = fmax(maxValue.x, input_data.x); + } else if (remain_channels == 2) { + maxValue.x = fmax(maxValue.x, input_data.y); + maxValue.x = fmax(maxValue.x, input_data.x); + } else if (remain_channels == 3) { + maxValue.x = fmax(maxValue.x, input_data.x); + } + + FLOAT4 sumValue = (FLOAT4)0; + for (int i = lid; i < shape.y - 1; i+=SOFTMAX_LOCAL_SIZE) { + sumValue += exp(RI_F(input, SAMPLER, (int2)(w + i * shape.w, bh)) - (FLOAT4)maxValue.x); + } + sum[lid] = sumValue; + barrier(CLK_LOCAL_MEM_FENCE); + for(int i = SOFTMAX_LOCAL_SIZE/2; i > 0; i /= 2){ + if (lid < i) + sum[lid] = sum[lid] + sum[lid + i]; + barrier(CLK_LOCAL_MEM_FENCE); + } + sumValue = sum[0]; + sumValue.x = sumValue.x + sumValue.y + sumValue.z + sumValue.w; + + + input_data -= maxValue.x; + if (remain_channels == 0) { + sumValue.x += exp(input_data.w); + sumValue.x += exp(input_data.z); + sumValue.x += exp(input_data.y); + sumValue.x += exp(input_data.x); + } else if (remain_channels == 1) { + sumValue.x += exp(input_data.z); + sumValue.x += exp(input_data.y); + sumValue.x += exp(input_data.x); + } else if (remain_channels == 2) { + sumValue.x += exp(input_data.y); + sumValue.x += exp(input_data.x); + } else if (remain_channels == 3) { + sumValue.x += exp(input_data.x); + } + for(int i = lid; i < shape.y; i+=SOFTMAX_LOCAL_SIZE){ + FLOAT4 value = exp(RI_F(input, SAMPLER, (int2)(w + i * shape.w, bh)) - maxValue.x) / sumValue.x; + WI_F(output, (int2)(w + i * shape.w, bh), value); + } +#else + FLOAT4 maxValue = (FLOAT4)-FLT_MAX; + for (int i = 0; i < shape.y - 1; i++) { + maxValue = fmax(maxValue, RI_F(input, SAMPLER, (int2)(w + i * shape.w, bh))); + } - if (width_idx < shape.w && batch_height_idx < shape.x*shape.z) { - - FLOAT4 float_max_value = (FLOAT4)-FLT_MAX; - FLOAT4 input_data; - for (short i = 0; i < shape.y - 1; ++i) { - input_data = RI_F(input, SAMPLER, (int2)(width_idx + i * shape.w, batch_height_idx)); - float_max_value = max(float_max_value, input_data); - } - float_max_value.x = max(float_max_value.x, float_max_value.y); - float_max_value.x = max(float_max_value.x, float_max_value.z); - float_max_value.x = max(float_max_value.x, float_max_value.w); - - input_data = RI_F(input, SAMPLER, (int2)(width_idx + (shape.y - 1) * shape.w , batch_height_idx)); - if (remain_channels == 0) { - float_max_value.x = max(float_max_value.x, input_data.x); - float_max_value.x = max(float_max_value.x, input_data.y); - float_max_value.x = max(float_max_value.x, input_data.z); - float_max_value.x = max(float_max_value.x, input_data.w); - } else if (remain_channels == 1) { - float_max_value.x = max(float_max_value.x, input_data.z); - float_max_value.x = max(float_max_value.x, input_data.y); - float_max_value.x = max(float_max_value.x, input_data.x); - } else if (remain_channels == 2) { - float_max_value.x = max(float_max_value.x, input_data.y); - float_max_value.x = max(float_max_value.x, input_data.x); - } else if (remain_channels == 3) { - float_max_value.x = max(float_max_value.x, input_data.x); - } - - - FLOAT4 accum_result = 0; - for (short i = 0; i < shape.y - 1; ++i) { - input_data = RI_F(input, SAMPLER, (int2)(width_idx + i * shape.w, batch_height_idx)); - input_data = EXP(input_data - float_max_value.x); - accum_result += input_data; - } - accum_result.x = accum_result.x + accum_result.y + accum_result.z + accum_result.w; - - input_data = RI_F(input, SAMPLER, (int2)(width_idx + (shape.y - 1) * shape.w, batch_height_idx)); - input_data -= float_max_value.x; - if (remain_channels == 0) { - accum_result.x += EXP(input_data.w); - accum_result.x += EXP(input_data.z); - accum_result.x += EXP(input_data.y); - accum_result.x += EXP(input_data.x); - } else if (remain_channels == 1) { - accum_result.x += EXP(input_data.z); - accum_result.x += EXP(input_data.y); - accum_result.x += EXP(input_data.x); - } else if (remain_channels == 2) { - accum_result.x += EXP(input_data.y); - accum_result.x += EXP(input_data.x); - } else if (remain_channels == 3) { - accum_result.x += EXP(input_data.x); - } - - for(int i = 0; i < shape.y; ++i){ - int cur_out_width_pos = mad24(i, shape.w, width_idx); - input_data = RI_F(input, SAMPLER, (int2)(cur_out_width_pos, batch_height_idx)) - float_max_value.x; - input_data = EXP(input_data) / accum_result.x; - WI_F(output, (int2)(cur_out_width_pos, batch_height_idx), input_data); - } + maxValue.x = fmax(maxValue.x, maxValue.y); + maxValue.x = fmax(maxValue.x, maxValue.z); + maxValue.x = fmax(maxValue.x, maxValue.w); + + FLOAT4 input_data = RI_F(input, SAMPLER, (int2)(w + (shape.y - 1) * shape.w , bh)); + if (remain_channels == 0) { + maxValue.x = fmax(maxValue.x, input_data.x); + maxValue.x = fmax(maxValue.x, input_data.y); + maxValue.x = fmax(maxValue.x, input_data.z); + maxValue.x = fmax(maxValue.x, input_data.w); + } else if (remain_channels == 1) { + maxValue.x = fmax(maxValue.x, input_data.z); + maxValue.x = fmax(maxValue.x, input_data.y); + maxValue.x = fmax(maxValue.x, input_data.x); + } else if (remain_channels == 2) { + maxValue.x = fmax(maxValue.x, input_data.y); + maxValue.x = fmax(maxValue.x, input_data.x); + } else if (remain_channels == 3) { + maxValue.x = fmax(maxValue.x, input_data.x); + } + + FLOAT4 sumValue = (FLOAT4)0; + for (int i = 0; i < shape.y - 1; i++) { + sumValue += exp(RI_F(input, SAMPLER, (int2)(w + i * shape.w, bh)) - (FLOAT4)maxValue.x); } + sumValue.x = sumValue.x + sumValue.y + sumValue.z + sumValue.w; + input_data -= maxValue.x; + if (remain_channels == 0) { + sumValue.x += exp(input_data.w); + sumValue.x += exp(input_data.z); + sumValue.x += exp(input_data.y); + sumValue.x += exp(input_data.x); + } else if (remain_channels == 1) { + sumValue.x += exp(input_data.z); + sumValue.x += exp(input_data.y); + sumValue.x += exp(input_data.x); + } else if (remain_channels == 2) { + sumValue.x += exp(input_data.y); + sumValue.x += exp(input_data.x); + } else if (remain_channels == 3) { + sumValue.x += exp(input_data.x); + } + for(int i = 0; i < shape.y; i++){ + FLOAT4 value = exp(RI_F(input, SAMPLER, (int2)(w + i * shape.w, bh)) - maxValue.x) / sumValue.x; + WI_F(output, (int2)(w + i * shape.w, bh), value); + } +#endif } -__kernel void softmax_height(__read_only image2d_t input, __write_only image2d_t output, - __private const int4 shape // NCHW +__kernel void softmax_height(GLOBAL_SIZE_3_DIMS __read_only image2d_t input, __write_only image2d_t output, + __private const int remain_channels, __private const int4 shape // NCHW ) { - int wc = get_global_id(0); - int b = get_global_id(1); - if (wc < shape.y*shape.w && b < shape.x) { - /*Compute Max */ - FLOAT4 maxValue = RI_F(input, SAMPLER, (int2)(wc, b*shape.z)); - for (int i=1; i= 4 + int lid = get_local_id(0); + FLOAT4 local sum[SOFTMAX_LOCAL_SIZE]; + /*Compute Max */ + FLOAT4 maxValue = (FLOAT4)(-FLT_MAX); + for (int i=lid; i 0; i /= 2){ + if (lid < i) + sum[lid] = fmax(sum[lid], sum[lid + i]); + barrier(CLK_LOCAL_MEM_FENCE); + } + maxValue = sum[0]; + + /*Compute Exp Sum*/ + FLOAT4 sumValue = (FLOAT4)0; + for (int i=lid; i 0; i /= 2){ + if (lid < i) + sum[lid] = sum[lid] + sum[lid + i]; + barrier(CLK_LOCAL_MEM_FENCE); + } + sumValue = sum[0]; + + /*Compute Result */ + for (int i=lid; i= 4 + int lid = get_local_id(0); + FLOAT4 local sum[SOFTMAX_LOCAL_SIZE]; + + /*Compute Max */ + FLOAT4 maxValue = (FLOAT4)(-FLT_MAX); + for (int i=lid; i 0; i /= 2){ + if (lid < i) + sum[lid] = fmax(sum[lid], sum[lid + i]); + barrier(CLK_LOCAL_MEM_FENCE); + } + maxValue = sum[0]; + + /*Compute Exp Sum*/ + FLOAT4 sumValue = (FLOAT4)0; + for (int i=lid; i 0; i /= 2){ + if (lid < i) + sum[lid] = sum[lid] + sum[lid + i]; + barrier(CLK_LOCAL_MEM_FENCE); + } + sumValue = sum[0]; + + /*Compute Result */ + for (int i=lid; i= 4 + int lid = get_local_id(0); + FLOAT4 local sum[SOFTMAX_LOCAL_SIZE]; + + FLOAT4 maxValue = (FLOAT4)-FLT_MAX; + for (int i = lid; i < shape.y - 1; i+=SOFTMAX_LOCAL_SIZE) { + maxValue = fmax(maxValue, vload4(i*shape.z*shape.w, input+offset)); + } + + sum[lid] = maxValue; + barrier(CLK_LOCAL_MEM_FENCE); + for(int i = SOFTMAX_LOCAL_SIZE/2; i > 0; i /= 2){ + if (lid < i) + sum[lid] = fmax(sum[lid], sum[lid + i]); + barrier(CLK_LOCAL_MEM_FENCE); + } + maxValue = sum[0]; + + maxValue.x = fmax(maxValue.x, maxValue.y); + maxValue.x = fmax(maxValue.x, maxValue.z); + maxValue.x = fmax(maxValue.x, maxValue.w); + + FLOAT4 input_data = vload4((shape.y - 1) *shape.z*shape.w, input+offset); + if (remain_channels == 0) { + maxValue.x = fmax(maxValue.x, input_data.x); + maxValue.x = fmax(maxValue.x, input_data.y); + maxValue.x = fmax(maxValue.x, input_data.z); + maxValue.x = fmax(maxValue.x, input_data.w); + } else if (remain_channels == 1) { + maxValue.x = fmax(maxValue.x, input_data.z); + maxValue.x = fmax(maxValue.x, input_data.y); + maxValue.x = fmax(maxValue.x, input_data.x); + } else if (remain_channels == 2) { + maxValue.x = fmax(maxValue.x, input_data.y); + maxValue.x = fmax(maxValue.x, input_data.x); + } else if (remain_channels == 3) { + maxValue.x = fmax(maxValue.x, input_data.x); + } + + FLOAT4 sumValue = (FLOAT4)0; + for (int i = lid; i < shape.y - 1; i+=SOFTMAX_LOCAL_SIZE) { + sumValue += exp(vload4(i*shape.z*shape.w, input+offset) - (FLOAT4)maxValue.x); + } + sum[lid] = sumValue; + barrier(CLK_LOCAL_MEM_FENCE); + for(int i = SOFTMAX_LOCAL_SIZE/2; i > 0; i /= 2){ + if (lid < i) + sum[lid] = sum[lid] + sum[lid + i]; + barrier(CLK_LOCAL_MEM_FENCE); + } + sumValue = sum[0]; + sumValue.x = sumValue.x + sumValue.y + sumValue.z + sumValue.w; + + + input_data -= maxValue.x; + if (remain_channels == 0) { + sumValue.x += exp(input_data.w); + sumValue.x += exp(input_data.z); + sumValue.x += exp(input_data.y); + sumValue.x += exp(input_data.x); + } else if (remain_channels == 1) { + sumValue.x += exp(input_data.z); + sumValue.x += exp(input_data.y); + sumValue.x += exp(input_data.x); + } else if (remain_channels == 2) { + sumValue.x += exp(input_data.y); + sumValue.x += exp(input_data.x); + } else if (remain_channels == 3) { + sumValue.x += exp(input_data.x); + } + for(int i = lid; i < shape.y; i+=SOFTMAX_LOCAL_SIZE){ + FLOAT4 value = exp(vload4(i*shape.z*shape.w, input+offset) - maxValue.x) / sumValue.x; + vstore4(value, i*shape.z*shape.w, output+offset); + } +#else + FLOAT4 maxValue = (FLOAT4)-FLT_MAX; + for (int i = 0; i < shape.y - 1; i++) { + maxValue = fmax(maxValue, vload4(i*shape.z*shape.w, input+offset)); + } + + maxValue.x = fmax(maxValue.x, maxValue.y); + maxValue.x = fmax(maxValue.x, maxValue.z); + maxValue.x = fmax(maxValue.x, maxValue.w); + + FLOAT4 input_data = vload4((shape.y - 1) *shape.z*shape.w, input+offset); + if (remain_channels == 0) { + maxValue.x = fmax(maxValue.x, input_data.x); + maxValue.x = fmax(maxValue.x, input_data.y); + maxValue.x = fmax(maxValue.x, input_data.z); + maxValue.x = fmax(maxValue.x, input_data.w); + } else if (remain_channels == 1) { + maxValue.x = fmax(maxValue.x, input_data.z); + maxValue.x = fmax(maxValue.x, input_data.y); + maxValue.x = fmax(maxValue.x, input_data.x); + } else if (remain_channels == 2) { + maxValue.x = fmax(maxValue.x, input_data.y); + maxValue.x = fmax(maxValue.x, input_data.x); + } else if (remain_channels == 3) { + maxValue.x = fmax(maxValue.x, input_data.x); } + + FLOAT4 sumValue = (FLOAT4)0; + for (int i = 0; i < shape.y - 1; i++) { + sumValue += exp(vload4(i*shape.z*shape.w, input+offset) - (FLOAT4)maxValue.x); + } + sumValue.x = sumValue.x + sumValue.y + sumValue.z + sumValue.w; + input_data -= maxValue.x; + if (remain_channels == 0) { + sumValue.x += exp(input_data.w); + sumValue.x += exp(input_data.z); + sumValue.x += exp(input_data.y); + sumValue.x += exp(input_data.x); + } else if (remain_channels == 1) { + sumValue.x += exp(input_data.z); + sumValue.x += exp(input_data.y); + sumValue.x += exp(input_data.x); + } else if (remain_channels == 2) { + sumValue.x += exp(input_data.y); + sumValue.x += exp(input_data.x); + } else if (remain_channels == 3) { + sumValue.x += exp(input_data.x); + } + for(int i = 0; i < shape.y; i++){ + FLOAT4 value = exp(vload4(i*shape.z*shape.w, input+offset) - maxValue.x) / sumValue.x; + vstore4(value, i*shape.z*shape.w, output+offset); + } +#endif } -__kernel void softmax_height(__global const FLOAT *input, +__kernel void softmax_height(GLOBAL_SIZE_3_DIMS + __global const FLOAT *input, __global FLOAT *output, + __private const int remain_channels, __private const int4 shape // NCHW ) { - int wc = get_global_id(0); - int b = get_global_id(1); + const int x = get_global_id(0); + const int wc = get_global_id(1); + const int b = get_global_id(2); + DEAL_NON_UNIFORM_DIM3(x, wc, b); const int c = wc / shape.w; const int w = wc % shape.w; const int offset = (((b*shape.y+c)*shape.z+0)*shape.w+w)*4; +#if SOFTMAX_LOCAL_SIZE >= 4 + int lid = get_local_id(0); + FLOAT4 local sum[SOFTMAX_LOCAL_SIZE]; + + /*Compute Max */ + FLOAT4 maxValue = (FLOAT4)(-FLT_MAX); + for (int i=lid; i 0; i /= 2){ + if (lid < i) + sum[lid] = fmax(sum[lid], sum[lid + i]); + barrier(CLK_LOCAL_MEM_FENCE); + } + maxValue = sum[0]; + + /*Compute Exp Sum*/ + FLOAT4 sumValue = (FLOAT4)0; + for (int i=lid; i 0; i /= 2){ + if (lid < i) + sum[lid] = sum[lid] + sum[lid + i]; + barrier(CLK_LOCAL_MEM_FENCE); + } + sumValue = sum[0]; + + /*Compute Result */ + for (int i=lid; i= 4 + int lid = get_local_id(0); + FLOAT4 local sum[SOFTMAX_LOCAL_SIZE]; + + /*Compute Max */ + FLOAT4 maxValue = (FLOAT4)(-FLT_MAX); + for (int i=lid; i 0; i /= 2){ + if (lid < i) + sum[lid] = fmax(sum[lid], sum[lid + i]); + barrier(CLK_LOCAL_MEM_FENCE); + } + maxValue = sum[0]; + + /*Compute Exp Sum*/ + FLOAT4 sumValue = (FLOAT4)0; + for (int i=lid; i 0; i /= 2){ + if (lid < i) + sum[lid] = sum[lid] + sum[lid + i]; + barrier(CLK_LOCAL_MEM_FENCE); + } + sumValue = sum[0]; + + /*Compute Result */ + for (int i=lid; i &inputs, const std::vec std::shared_ptr quanCommon; if (nullptr != conv2dParams->quanParameter()) { - quanCommon = ConvolutionCommon::load(conv2dParams->quanParameter(), true); + quanCommon = ConvolutionCommon::load(conv2dParams, backend, true); if (nullptr == quanCommon) { MNN_ERROR("Memory not Enough, can't extract IDST Convolution: %s \n", op->name()->c_str()); } diff --git a/source/backend/opencl/execution/image/ConvWinograd.cpp b/source/backend/opencl/execution/image/ConvWinograd.cpp index f04e66732..9304636ba 100644 --- a/source/backend/opencl/execution/image/ConvWinograd.cpp +++ b/source/backend/opencl/execution/image/ConvWinograd.cpp @@ -69,7 +69,7 @@ ConvWinograd::ConvWinograd(const MNN::Convolution2D* op, Backend* backend) : Exe std::shared_ptr quanCommon; if (nullptr != op->quanParameter()) { - quanCommon = ConvolutionCommon::load(op->quanParameter(), true); + quanCommon = ConvolutionCommon::load(op, backend, true); if (nullptr == quanCommon) { MNN_ERROR("Memory not Enough, can't extract IDST Convolution \n"); } diff --git a/source/backend/opencl/execution/image/DeconvExecution.cpp b/source/backend/opencl/execution/image/DeconvExecution.cpp index 691c594f7..3f5f8b104 100644 --- a/source/backend/opencl/execution/image/DeconvExecution.cpp +++ b/source/backend/opencl/execution/image/DeconvExecution.cpp @@ -33,7 +33,7 @@ DeconvExecution::DeconvExecution(const std::vector &inputs, const MNN: const float* filterDataPtr = nullptr; int weightSize = 0; std::shared_ptr quanCommon; - ConvolutionCommon::getConvParameters(&quanCommon, conv2dParams, &filterDataPtr, &weightSize); + ConvolutionCommon::getConvParameters(&quanCommon, backend, conv2dParams, &filterDataPtr, &weightSize); int inputChannel = weightSize / (kernelWidth * kernelHeight * outputChannel); std::vector filterShape{outputChannel, inputChannel, kernelHeight, kernelWidth}; diff --git a/source/backend/opencl/execution/image/DepthwiseConvExecution.cpp b/source/backend/opencl/execution/image/DepthwiseConvExecution.cpp index b125aeb99..116cb1feb 100644 --- a/source/backend/opencl/execution/image/DepthwiseConvExecution.cpp +++ b/source/backend/opencl/execution/image/DepthwiseConvExecution.cpp @@ -37,7 +37,7 @@ DepthwiseConvExecution::DepthwiseConvExecution(const std::vector &inpu const float* filterDataPtr = nullptr; int filterDataSize = 0; std::shared_ptr quanCommon; - ConvolutionCommon::getConvParameters(&quanCommon, mCon2dParams, &filterDataPtr, &filterDataSize); + ConvolutionCommon::getConvParameters(&quanCommon, backend, mCon2dParams, &filterDataPtr, &filterDataSize); mFilter.reset(Tensor::createDevice({1, filterImageShape[1], 1, 4 * filterImageShape[0]})); std::shared_ptr filterBuffer(Tensor::createDevice(filterShape)); diff --git a/source/backend/opencl/execution/image/DepthwiseDeconvExecution.cpp b/source/backend/opencl/execution/image/DepthwiseDeconvExecution.cpp index 0c08759ba..393a8edc0 100644 --- a/source/backend/opencl/execution/image/DepthwiseDeconvExecution.cpp +++ b/source/backend/opencl/execution/image/DepthwiseDeconvExecution.cpp @@ -36,7 +36,7 @@ DepthwiseDeconvExecution::DepthwiseDeconvExecution(const std::vector & const float* filterDataPtr = nullptr; int tempWeightSize = 0; std::shared_ptr quanCommon; - ConvolutionCommon::getConvParameters(&quanCommon, mCon2dParams, &filterDataPtr, &tempWeightSize); + ConvolutionCommon::getConvParameters(&quanCommon, backend, mCon2dParams, &filterDataPtr, &tempWeightSize); mFilter.reset(Tensor::createDevice({1, filterImageShape[1], 1, 4 * filterImageShape[0]})); std::shared_ptr filterBuffer(Tensor::createDevice(filterShape)); diff --git a/source/backend/opencl/execution/image/EltwiseExecution.cpp b/source/backend/opencl/execution/image/EltwiseExecution.cpp index 02e29a706..61b651d53 100644 --- a/source/backend/opencl/execution/image/EltwiseExecution.cpp +++ b/source/backend/opencl/execution/image/EltwiseExecution.cpp @@ -207,7 +207,7 @@ class EltwiseCreator : public OpenCLBackend::Creator { case BinaryOpOperation_SquaredDifference: return new EltwiseExecution(inputs, "(in0-in1)*(in0-in1)", op, backend); case BinaryOpOperation_ATAN2: - return new EltwiseExecution(inputs, "atan(sign(in1)*in0/(fabs(in1)>(FLOAT4)((FLOAT)0.0000001)?fabs(in1):(FLOAT4)((FLOAT)0.0000001)))", op, backend); + return new EltwiseExecution(inputs, "(in1==(FLOAT4)0?(sign(in0)*(FLOAT4)(PI/2)):(atan(in0/in1)+(in1>(FLOAT4)0?(FLOAT4)0:sign(in0)*(FLOAT4)PI)))", op, backend); case BinaryOpOperation_NOTEQUAL: return new EltwiseExecution(inputs, "convert_float4(-isnotequal(in0,in1))", op, backend); case BinaryOpOperation_MOD: diff --git a/source/backend/opencl/execution/image/LoopExecution.cpp b/source/backend/opencl/execution/image/LoopExecution.cpp index d5af7770f..c4180fe2f 100644 --- a/source/backend/opencl/execution/image/LoopExecution.cpp +++ b/source/backend/opencl/execution/image/LoopExecution.cpp @@ -15,7 +15,11 @@ namespace OpenCL { static void _TileTensor(Tensor *input, cl::Buffer *output, cl::Kernel& kernel, cl::NDRange &globalWorkSize, cl::NDRange &localWorkSize, const int Width, const int Height, const int Channel, - const int Batch, OpenCLRuntime *runTime, const std::set &buildOptions) { + const int Batch, OpenCLRuntime *runTime, std::set buildOptions) { + + if (TensorUtils::getDescribe(input)->dimensionFormat == MNN::MNN_DATA_FORMAT_NHWC){ + buildOptions.emplace("-DMNN_NHWC"); + } kernel = runTime->buildKernel("loop", "tile", buildOptions); uint32_t mMaxWorkGroupSize = static_cast(runTime->getMaxWorkGroupSize(kernel)); std::vector mGlobalWorkSize = {(uint32_t)(Width * Height), (uint32_t)(UP_DIV(Channel, 4)), (uint32_t)(Batch)}; @@ -42,7 +46,10 @@ static void _TileTensor(Tensor *input, cl::Buffer *output, cl::Kernel& kernel, c static void _PackTensor(cl::Buffer *input, Tensor *output, cl::Kernel& kernel, cl::NDRange &globalWorkSize, cl::NDRange &localWorkSize, const int Width, const int Height, const int Channel, - const int Batch, OpenCLRuntime *runTime, const std::set &buildOptions) { + const int Batch, OpenCLRuntime *runTime, std::set buildOptions) { + if (TensorUtils::getDescribe(output)->dimensionFormat == MNN::MNN_DATA_FORMAT_NHWC){ + buildOptions.emplace("-DMNN_NHWC"); + } kernel = runTime->buildKernel("loop", "pack", buildOptions); uint32_t mMaxWorkGroupSize = static_cast(runTime->getMaxWorkGroupSize(kernel)); std::vector mGlobalWorkSize = {(uint32_t)(Width * Height), (uint32_t)(UP_DIV(Channel, 4)), (uint32_t)(Batch)}; @@ -353,6 +360,75 @@ ErrorCode LoopBatchMatMulExecution::onResize(const std::vector &inputs return NO_ERROR; } +LoopBinaryExecution::LoopBinaryExecution(const LoopParam *loop, const std::string &compute, const MNN::Op *op, Backend *bn) + : CommonExecution(bn, op) { + mLoop = loop; + mTensors.resize(mLoop->tensorNumber()); + auto cmd = loop->commands()->GetAs(0); + mBuildOptions.emplace("-DLOOP_BINARY_OPERATOR=" + compute); +} +ErrorCode LoopBinaryExecution::onResize(const std::vector &inputs, const std::vector &outputs) { + auto cmd = mLoop->commands()->GetAs(0); + OpenCLBackend *mOpenCLBackend = (OpenCLBackend *)backend(); + auto runTime = mOpenCLBackend->getOpenCLRuntime(); + startRecord(runTime, mRecording); + _setTensorStack(mTensors, inputs, outputs, mLoop); + mUnits.clear(); + Unit unit; + auto input0 = mTensors[cmd->indexes()->data()[1]]; + std::vector Input0Shape = tensorShapeFormat(input0); + int Input0Size[4] = {Input0Shape.at(2), Input0Shape.at(1),Input0Shape.at(3),Input0Shape.at(0)}; + + auto input1 = mTensors[cmd->indexes()->data()[2]]; + std::vector Input1Shape = tensorShapeFormat(input1); + int Input1Size[4] = {Input1Shape.at(2), Input1Shape.at(1),Input1Shape.at(3),Input1Shape.at(0)}; + + auto output = mTensors[cmd->indexes()->data()[0]]; + std::vector Shape = tensorShapeFormat(output); + const int Channel = Shape.at(3); + const int Width = Shape.at(2); + const int Height = Shape.at(1); + const int Batch = Shape.at(0); + const int ChannelBlock = UP_DIV(Channel, 4); + auto BuildOptions = mBuildOptions; + if(Input0Size[2] != Input1Size[2]){ + BuildOptions.emplace("-DBROADCAST_CHANNEL"); + } + std::string KernelName = "broadcast_binary"; + unit.kernel = runTime->buildKernel("loop", KernelName, BuildOptions); + uint32_t mMaxWorkGroupSize = static_cast(runTime->getMaxWorkGroupSize(unit.kernel)); + + + std::vector mGlobalWorkSize = {(uint32_t)(Width), (uint32_t)(Height), (uint32_t)(Batch * ChannelBlock)}; + + uint32_t index = 0; + cl_int ret = CL_SUCCESS; + ret |= unit.kernel.setArg(index++, mGlobalWorkSize[0]); + ret |= unit.kernel.setArg(index++, mGlobalWorkSize[1]); + ret |= unit.kernel.setArg(index++, mGlobalWorkSize[2]); + ret |= unit.kernel.setArg(index++, openCLImage(output)); + ret |= unit.kernel.setArg(index++, openCLImage(input0)); + ret |= unit.kernel.setArg(index++, openCLImage(input1)); + ret |= unit.kernel.setArg(index++, sizeof(Input0Size), Input0Size); + ret |= unit.kernel.setArg(index++, sizeof(Input1Size), Input1Size); + ret |= unit.kernel.setArg(index++, Width); + ret |= unit.kernel.setArg(index++, Height); + ret |= unit.kernel.setArg(index++, ChannelBlock); + MNN_CHECK_CL_SUCCESS(ret, "setArg LoopBinaryExecution"); + + std::vector mLocalWorkSize = localWS3DDefault(mGlobalWorkSize, mMaxWorkGroupSize, runTime, KernelName, unit.kernel).first; + + unit.globalWorkSize = {mGlobalWorkSize[0], mGlobalWorkSize[1], mGlobalWorkSize[2]}; + unit.localWorkSize = {mLocalWorkSize[0], mLocalWorkSize[1], mLocalWorkSize[2]}; + recordKernel3d(unit.kernel, mGlobalWorkSize, mLocalWorkSize, runTime); + mUnits.emplace_back(unit); + + endRecord(runTime, mRecording); + + return NO_ERROR; +} + + class LoopCreator : public OpenCLBackend::Creator { public: virtual Execution *onCreate(const std::vector &inputs, const std::vector &outputs, @@ -374,6 +450,49 @@ class LoopCreator : public OpenCLBackend::Creator { if (OpType_MatMul == subop->type() && loop->parallel()) { return new LoopBatchMatMulExecution(loop, op, backend); } + if (OpType_BinaryOp == subop->type() && loop->parallel()) { + switch (subop->main_as_BinaryOp()->opType()) { + case BinaryOpOperation_MUL: + return new LoopBinaryExecution(loop, "in0*in1", op, backend); + case BinaryOpOperation_ADD: + return new LoopBinaryExecution(loop, "in0+in1", op, backend); + case BinaryOpOperation_SUB: + return new LoopBinaryExecution(loop, "in0-in1", op, backend); + case BinaryOpOperation_REALDIV: + return new LoopBinaryExecution(loop, "sign(in1)*in0/(fabs(in1)>(FLOAT4)((FLOAT)0.0000001)?fabs(in1):(FLOAT4)((FLOAT)0.0000001))", op, backend); + case BinaryOpOperation_MINIMUM: + return new LoopBinaryExecution(loop, "in0>in1?in1:in0", op, backend); + case BinaryOpOperation_MAXIMUM: + return new LoopBinaryExecution(loop, "in0>in1?in0:in1", op, backend); + case BinaryOpOperation_GREATER: + return new LoopBinaryExecution(loop, "convert_float4(-isgreater(in0,in1))", op, backend); + case BinaryOpOperation_LESS: + return new LoopBinaryExecution(loop, "convert_float4(-isless(in0,in1))", op, backend); + case BinaryOpOperation_LESS_EQUAL: + return new LoopBinaryExecution(loop, "convert_float4(-islessequal(in0,in1))", op, backend); + case BinaryOpOperation_GREATER_EQUAL: + return new LoopBinaryExecution(loop, "convert_float4(-isgreaterequal(in0,in1))", op, backend); + case BinaryOpOperation_EQUAL: + return new LoopBinaryExecution(loop, "convert_float4(-isequal(in0,in1))", op, backend); + case BinaryOpOperation_FLOORDIV: + return new LoopBinaryExecution(loop, "floor(sign(in1)*in0/(fabs(in1)>(FLOAT4)((FLOAT)0.0000001)?fabs(in1):(FLOAT4)((FLOAT)0.0000001)))", op, backend); + case BinaryOpOperation_FLOORMOD: + return new LoopBinaryExecution(loop, "in0-floor(sign(in1)*in0/(fabs(in1)>(FLOAT4)((FLOAT)0.0000001)?fabs(in1):(FLOAT4)((FLOAT)0.0000001)))*in1", op, backend); + case BinaryOpOperation_POW: + return new LoopBinaryExecution(loop, "pow(in0,in1)", op, backend); + case BinaryOpOperation_SquaredDifference: + return new LoopBinaryExecution(loop, "(in0-in1)*(in0-in1)", op, backend); + case BinaryOpOperation_ATAN2: + return new LoopBinaryExecution(loop, "atan(sign(in1)*in0/(fabs(in1)>(FLOAT4)((FLOAT)0.0000001)?fabs(in1):(FLOAT4)((FLOAT)0.0000001)))", op, backend); + case BinaryOpOperation_NOTEQUAL: + return new LoopBinaryExecution(loop, "convert_float4(-isnotequal(in0,in1))", op, backend); + case BinaryOpOperation_MOD: + return new LoopBinaryExecution(loop, "in0-floor(sign(in1)*in0/(fabs(in1)>(FLOAT4)((FLOAT)0.0000001)?fabs(in1):(FLOAT4)((FLOAT)0.0000001)))*in1", op, backend); + default: + break; + } + return nullptr; + } } return nullptr; } diff --git a/source/backend/opencl/execution/image/LoopExecution.hpp b/source/backend/opencl/execution/image/LoopExecution.hpp index 45a163a32..ae2476143 100644 --- a/source/backend/opencl/execution/image/LoopExecution.hpp +++ b/source/backend/opencl/execution/image/LoopExecution.hpp @@ -53,6 +53,18 @@ class LoopBatchMatMulExecution : public CommonExecution { std::set mBuildOptions; }; +class LoopBinaryExecution : public CommonExecution { +public: + LoopBinaryExecution(const LoopParam *loop, const std::string &compute, const MNN::Op *op, Backend *bn); + virtual ~LoopBinaryExecution() = default; + virtual ErrorCode onResize(const std::vector &inputs, const std::vector &outputs) override; + +private: + const LoopParam *mLoop; + std::vector mTensors; + std::set mBuildOptions; +}; + } // namespace OpenCL } // namespace MNN #endif /* LoopExecution_hpp */ diff --git a/source/backend/opencl/execution/image/SoftmaxExecution.cpp b/source/backend/opencl/execution/image/SoftmaxExecution.cpp index 5ddc63791..74c78a62f 100644 --- a/source/backend/opencl/execution/image/SoftmaxExecution.cpp +++ b/source/backend/opencl/execution/image/SoftmaxExecution.cpp @@ -19,10 +19,11 @@ SoftmaxExecution::SoftmaxExecution(const std::vector &inputs, int axis mOpenCLBackend = static_cast(backend); } -bool SoftmaxExecution::buildSoftmaxKernel() { +bool SoftmaxExecution::buildSoftmaxKernel(int localSize) { auto runtime = mOpenCLBackend->getOpenCLRuntime(); if (mKernel.get() == nullptr) { std::set buildOptions; + buildOptions.emplace("-DSOFTMAX_LOCAL_SIZE=" + std::to_string(localSize)); std::string kernelName; if (mAxis == 1) { mKernel = runtime->buildKernel("softmax", "softmax_channel", buildOptions); @@ -37,6 +38,14 @@ bool SoftmaxExecution::buildSoftmaxKernel() { return true; } +int SoftmaxExecution::getLocalSize(int size, int maxGroupSize){ + int local_size = 1; + while(local_size * 2 <= maxGroupSize && local_size * 2 <= size){ + local_size *= 2; + } + return local_size; +} + ErrorCode SoftmaxExecution::onResize(const std::vector &inputs, const std::vector &outputs) { startRecord(mOpenCLBackend->getOpenCLRuntime(), mRecording); Tensor *input = inputs[0]; @@ -68,61 +77,46 @@ ErrorCode SoftmaxExecution::onResize(const std::vector &inputs, const const int channelBlocks = UP_DIV(outputChannels, 4); const int remainChannels = channelBlocks * 4 - outputChannels; + auto MaxWorkItems = mOpenCLBackend->getOpenCLRuntime()->getMaxWorkItemSizes(); + int localSize = getLocalSize(channel, MaxWorkItems[0]); + if(localSize < 4){ + localSize = 1; + } if(inputBatch == outside && channel == inputChannels && inside == inputWidth * inputHeight){ mAxis = 1; - }else if(inputBatch * inputChannels == outside && channel == inputHeight && inside == inputHeight){ + localSize = getLocalSize(channelBlocks, MaxWorkItems[0]); + }else if(inputBatch * inputChannels == outside && channel == inputHeight && inside == inputWidth){ mAxis = 2; }else if(inputBatch * inputChannels * inputHeight == outside && channel == inputWidth && inside == 1){ mAxis = 3; } - buildSoftmaxKernel(); + buildSoftmaxKernel(localSize); cl_int ret = CL_SUCCESS; + int shape[] = {outputBatch, channelBlocks, outputHeight, outputWidth}; if (mAxis == 1) { - mGlobalWorkSize = {static_cast(outputWidth), - static_cast(outputHeight * outputBatch), 1}; - int shape[] = {outputBatch, channelBlocks, outputHeight, outputWidth}; - - uint32_t idx = 0; - ret |= mKernel.setArg(idx++, mGlobalWorkSize[0]); - ret |= mKernel.setArg(idx++, mGlobalWorkSize[1]); - ret |= mKernel.setArg(idx++, mGlobalWorkSize[2]); - - ret |= mKernel.setArg(idx++, openCLImage(input)); - ret |= mKernel.setArg(idx++, openCLImage(output)); - ret |= mKernel.setArg(idx++, static_cast(outputChannels)); - ret |= mKernel.setArg(idx++, remainChannels); - ret |= mKernel.setArg(idx++, shape); - MNN_CHECK_CL_SUCCESS(ret, "setArg SoftmaxExecution Axis_1"); - - std::string kernelName = "softmax_channel"; - mLocalWorkSize = localWS3DDefault(mGlobalWorkSize, mMaxWorkGroupSize, mOpenCLBackend->getOpenCLRuntime(), kernelName, mKernel).first; + mGlobalWorkSize = {(uint32_t)(localSize), (uint32_t)outputWidth, (uint32_t)outputHeight * outputBatch}; } else if (mAxis == 2){ - if (mMaxWorkGroupSize > 256) { - mLocalWorkSize = {16, 16, 1}; - } else { - mLocalWorkSize = {8, 8, 1}; - } - mGlobalWorkSize = {(uint32_t)channelBlocks*outputWidth, (uint32_t)outputBatch, 1}; - int shape[] = {outputBatch, channelBlocks, outputHeight, outputWidth}; - ret |= mKernel.setArg(0, openCLImage(input)); - ret |= mKernel.setArg(1, openCLImage(output)); - ret |= mKernel.setArg(2, shape); - MNN_CHECK_CL_SUCCESS(ret, "setArg SoftmaxExecution Axis_2"); + mGlobalWorkSize = {(uint32_t)(localSize), (uint32_t)channelBlocks*outputWidth, (uint32_t)outputBatch}; } else { MNN_ASSERT(mAxis == 3); - if (mMaxWorkGroupSize > 256) { - mLocalWorkSize = {16, 16, 1}; - } else { - mLocalWorkSize = {8, 8, 1}; - } - mGlobalWorkSize = {(uint32_t)channelBlocks, (uint32_t)outputBatch*outputHeight, 1}; - int shape[] = {outputBatch, channelBlocks, outputHeight, outputWidth}; - ret |= mKernel.setArg(0, openCLImage(input)); - ret |= mKernel.setArg(1, openCLImage(output)); - ret |= mKernel.setArg(2, shape); - MNN_CHECK_CL_SUCCESS(ret, "setArg SoftmaxExecution Axis_3"); + mGlobalWorkSize = {(uint32_t)(localSize), (uint32_t)channelBlocks, (uint32_t)outputBatch*outputHeight}; + } + mLocalWorkSize = {(uint32_t)(localSize), 1, 1}; + + uint32_t idx = 0; + ret |= mKernel.setArg(idx++, mGlobalWorkSize[0]); + ret |= mKernel.setArg(idx++, mGlobalWorkSize[1]); + ret |= mKernel.setArg(idx++, mGlobalWorkSize[2]); + + ret |= mKernel.setArg(idx++, openCLImage(input)); + ret |= mKernel.setArg(idx++, openCLImage(output)); + ret |= mKernel.setArg(idx++, remainChannels); + ret |= mKernel.setArg(idx++, shape); + MNN_CHECK_CL_SUCCESS(ret, "setArg SoftmaxExecution"); + if(localSize == 1){ + mLocalWorkSize = localWS3DDefault(mGlobalWorkSize, mMaxWorkGroupSize, mOpenCLBackend->getOpenCLRuntime(), "softmax", mKernel).first; } recordKernel3d(mKernel, mGlobalWorkSize, mLocalWorkSize, mOpenCLBackend->getOpenCLRuntime()); endRecord(mOpenCLBackend->getOpenCLRuntime(), mRecording); diff --git a/source/backend/opencl/execution/image/SoftmaxExecution.hpp b/source/backend/opencl/execution/image/SoftmaxExecution.hpp index 4d167211f..3fc64f9a7 100644 --- a/source/backend/opencl/execution/image/SoftmaxExecution.hpp +++ b/source/backend/opencl/execution/image/SoftmaxExecution.hpp @@ -26,8 +26,9 @@ class SoftmaxExecution : public Execution, public CommonExtension { virtual ErrorCode onResize(const std::vector &inputs, const std::vector &outputs) override; virtual ErrorCode onExecute(const std::vector &inputs, const std::vector &outputs) override; - bool buildSoftmaxKernel(); + bool buildSoftmaxKernel(int localSize); private: + int getLocalSize(int size, int maxGroupSize); cl::Kernel mKernel; uint32_t mMaxWorkGroupSize; OpenCLBackend *mOpenCLBackend; diff --git a/source/backend/tensorrt/backend/TRTBackend.cpp b/source/backend/tensorrt/backend/TRTBackend.cpp index eb3dfb2c3..49d954b10 100755 --- a/source/backend/tensorrt/backend/TRTBackend.cpp +++ b/source/backend/tensorrt/backend/TRTBackend.cpp @@ -356,7 +356,7 @@ void TRTBackend::onResizeBegin() { init(); } -void TRTBackend::onResizeEnd() { +ErrorCode TRTBackend::onResizeEnd() { #ifdef TRT_LOG printf("\n\nTRTBackend onResizeEnd in\n"); #endif @@ -434,6 +434,7 @@ void TRTBackend::onResizeEnd() { delete l; } mEraseLayers.clear(); + return NO_ERROR; } INetworkDefinition* TRTBackend::getNetwork() { diff --git a/source/backend/tensorrt/backend/TRTBackend.hpp b/source/backend/tensorrt/backend/TRTBackend.hpp index c8eb7742a..c7e14fa6c 100644 --- a/source/backend/tensorrt/backend/TRTBackend.hpp +++ b/source/backend/tensorrt/backend/TRTBackend.hpp @@ -9,6 +9,7 @@ #ifndef MNN_TRTBackend_H #define MNN_TRTBackend_H +#include #include #include @@ -88,7 +89,7 @@ class TRTBackend : public Backend { virtual void onCopyBuffer(const Tensor* srcTensor, const Tensor* dstTensor) const override; virtual void onResizeBegin() override; - virtual void onResizeEnd() override; + virtual ErrorCode onResizeEnd() override; class Creator { public: diff --git a/source/backend/tensorrt/execution/TRTConvolution.cpp b/source/backend/tensorrt/execution/TRTConvolution.cpp index af9a01be8..109b24cb1 100644 --- a/source/backend/tensorrt/execution/TRTConvolution.cpp +++ b/source/backend/tensorrt/execution/TRTConvolution.cpp @@ -34,7 +34,7 @@ std::vector TRTConvolution::onEncode(const std::vector &xO int weightSize = 0; std::shared_ptr quanWeight; if (nullptr != mOp->main_as_Convolution2D()->quanParameter()) { - quanWeight = ConvolutionCommon::load(mOp->main_as_Convolution2D()->quanParameter(), true); + quanWeight = ConvolutionCommon::load(mOp->main_as_Convolution2D(), backend(), true); srcCount = quanWeight->weightFloat.size() / (outputCount * kernelX * kernelY); source = quanWeight->weightFloat.get(); weightSize = quanWeight->weightFloat.size(); diff --git a/source/backend/tensorrt/execution/TRTDeconvolution.cpp b/source/backend/tensorrt/execution/TRTDeconvolution.cpp index 8ec7bd872..835a17b86 100755 --- a/source/backend/tensorrt/execution/TRTDeconvolution.cpp +++ b/source/backend/tensorrt/execution/TRTDeconvolution.cpp @@ -35,7 +35,7 @@ std::vector TRTDeconvolution::onEncode(const std::vector & int weightSize = 0; std::shared_ptr quanCommon; - ConvolutionCommon::getConvParameters(&quanCommon, conv2D, &source, &weightSize); + ConvolutionCommon::getConvParameters(&quanCommon, backend(), conv2D, &source, &weightSize); nvinfer1::DimsHW NVKSize(kernelY, kernelX); nvinfer1::DimsHW NVKSSize(conv2DCommon->strideY(), conv2DCommon->strideX()); diff --git a/source/backend/tensorrt/execution/TRTDepthwiseConvolution.cpp b/source/backend/tensorrt/execution/TRTDepthwiseConvolution.cpp index 990bee757..e2beeb066 100644 --- a/source/backend/tensorrt/execution/TRTDepthwiseConvolution.cpp +++ b/source/backend/tensorrt/execution/TRTDepthwiseConvolution.cpp @@ -36,7 +36,7 @@ std::vector TRTDepthwiseConvolution::onEncode(const std::vector quanWeight; if (nullptr != mOp->main_as_Convolution2D()->quanParameter()) { - quanWeight = ConvolutionCommon::load(mOp->main_as_Convolution2D()->quanParameter(), true); + quanWeight = ConvolutionCommon::load(mOp->main_as_Convolution2D(), backend(), true); source = quanWeight->weightFloat.get(); weightSize = quanWeight->weightFloat.size(); } else { diff --git a/source/backend/tensorrt/execution/TRTDepthwiseDeconvolution.cpp b/source/backend/tensorrt/execution/TRTDepthwiseDeconvolution.cpp index 0e54957c1..fe620a824 100755 --- a/source/backend/tensorrt/execution/TRTDepthwiseDeconvolution.cpp +++ b/source/backend/tensorrt/execution/TRTDepthwiseDeconvolution.cpp @@ -35,7 +35,7 @@ std::vector TRTDepthwiseDeconvolution::onEncode(const std::vector quanCommon; - ConvolutionCommon::getConvParameters(&quanCommon, conv2D, &source, &weightSize); + ConvolutionCommon::getConvParameters(&quanCommon, backend(), conv2D, &source, &weightSize); nvinfer1::DimsHW NVKSize(kernelY, kernelX); nvinfer1::DimsHW NVKSSize(conv2DCommon->strideY(), conv2DCommon->strideX()); diff --git a/source/backend/vulkan/buffer/backend/VulkanBackend.cpp b/source/backend/vulkan/buffer/backend/VulkanBackend.cpp index a7b8e99cb..ed3d44152 100644 --- a/source/backend/vulkan/buffer/backend/VulkanBackend.cpp +++ b/source/backend/vulkan/buffer/backend/VulkanBackend.cpp @@ -131,10 +131,11 @@ void VulkanBackend::onResizeBegin() { mCmdBuffer->begin(0); } } -void VulkanBackend::onResizeEnd() { +ErrorCode VulkanBackend::onResizeEnd() { if (!mDirect) { mCmdBuffer->end(); } + return NO_ERROR; } class VulkanMemRelease : public Backend::MemObj { public: diff --git a/source/backend/vulkan/buffer/backend/VulkanBackend.hpp b/source/backend/vulkan/buffer/backend/VulkanBackend.hpp index 887cf3076..107d01a0f 100644 --- a/source/backend/vulkan/buffer/backend/VulkanBackend.hpp +++ b/source/backend/vulkan/buffer/backend/VulkanBackend.hpp @@ -10,6 +10,7 @@ #define VulkanBackend_hpp #include +#include #include "MNN_generated.h" #include "VulkanRuntime.hpp" namespace MNN { @@ -27,7 +28,7 @@ class VulkanBackend : public Backend { virtual void onExecuteBegin() const override; virtual void onExecuteEnd() const override; virtual void onResizeBegin() override; - virtual void onResizeEnd() override; + virtual ErrorCode onResizeEnd() override; virtual void onCopyBuffer(const Tensor* srcTensor, const Tensor* dstTensor) const override; virtual const Runtime* getRuntime() override { return mRuntime; diff --git a/source/backend/vulkan/buffer/execution/VulkanConvolution.cpp b/source/backend/vulkan/buffer/execution/VulkanConvolution.cpp index 6b224fe8a..67da4f59f 100644 --- a/source/backend/vulkan/buffer/execution/VulkanConvolution.cpp +++ b/source/backend/vulkan/buffer/execution/VulkanConvolution.cpp @@ -289,7 +289,7 @@ class VulkanConvolutionCreator : public VulkanBackend::Creator { return nullptr; } } - quanWeight = ConvolutionCommon::load(op->main_as_Convolution2D()->quanParameter(), true); + quanWeight = ConvolutionCommon::load(op->main_as_Convolution2D(), backend, true); srcCount = quanWeight->weightFloat.size() / (outputCount * fh * fw); source = quanWeight->weightFloat.get(); weightSize = quanWeight->weightFloat.size(); diff --git a/source/backend/vulkan/buffer/execution/VulkanDeconvolution.cpp b/source/backend/vulkan/buffer/execution/VulkanDeconvolution.cpp index 3a4125dc7..24546054e 100644 --- a/source/backend/vulkan/buffer/execution/VulkanDeconvolution.cpp +++ b/source/backend/vulkan/buffer/execution/VulkanDeconvolution.cpp @@ -45,7 +45,7 @@ VulkanDeconvolution* VulkanDeconvolution::create(Backend* bn, const Convolution2 int tempWeightSize = 0; std::shared_ptr quanCommon; if (!multiInputs) { - ConvolutionCommon::getConvParameters(&quanCommon, conv, &tempWeight, &tempWeightSize); + ConvolutionCommon::getConvParameters(&quanCommon, bn, conv, &tempWeight, &tempWeightSize); MNN_ASSERT(nullptr != tempWeight); if (0 >= ci) { ci = tempWeightSize / co / kw / kh; diff --git a/source/backend/vulkan/image/backend/VulkanBackend.cpp b/source/backend/vulkan/image/backend/VulkanBackend.cpp index 67cefb716..a033f4e3c 100644 --- a/source/backend/vulkan/image/backend/VulkanBackend.cpp +++ b/source/backend/vulkan/image/backend/VulkanBackend.cpp @@ -114,13 +114,14 @@ void VulkanBackend::onResizeBegin() { mCmdBuffer->begin(0); } } -void VulkanBackend::onResizeEnd() { +ErrorCode VulkanBackend::onResizeEnd() { if (!mDirect) { mCmdBuffer->end(); } mInitBuffer->end(); mCmdBuffers.emplace_back(mInitBuffer->get()); _finish(); + return NO_ERROR; } class VulkanMemRelease : public Backend::MemObj { public: diff --git a/source/backend/vulkan/image/backend/VulkanBackend.hpp b/source/backend/vulkan/image/backend/VulkanBackend.hpp index 7784593bb..ef07c4c32 100644 --- a/source/backend/vulkan/image/backend/VulkanBackend.hpp +++ b/source/backend/vulkan/image/backend/VulkanBackend.hpp @@ -10,6 +10,7 @@ #define VulkanBackend_hpp #include +#include #include "MNN_generated.h" #include "VulkanRuntime.hpp" #include "VulkanTensor.hpp" @@ -31,7 +32,7 @@ class VulkanBackend : public Backend { virtual void onExecuteBegin() const override; virtual void onExecuteEnd() const override; virtual void onResizeBegin() override; - virtual void onResizeEnd() override; + virtual ErrorCode onResizeEnd() override; virtual void onCopyBuffer(const Tensor* srcTensor, const Tensor* dstTensor) const override; const VulkanPipeline* getPipeline(const std::string& key, const std::vector& types, diff --git a/source/backend/vulkan/image/execution/VulkanConvolution.cpp b/source/backend/vulkan/image/execution/VulkanConvolution.cpp index a3f99e191..6f3857895 100644 --- a/source/backend/vulkan/image/execution/VulkanConvolution.cpp +++ b/source/backend/vulkan/image/execution/VulkanConvolution.cpp @@ -255,7 +255,7 @@ class VulkanConvolutionCreator : public VulkanBackend::Creator { return nullptr; } } - quanWeight = ConvolutionCommon::load(op->main_as_Convolution2D()->quanParameter(), true); + quanWeight = ConvolutionCommon::load(op->main_as_Convolution2D(), backend, true); srcCount = quanWeight->weightFloat.size() / (outputCount * fh * fw); source = quanWeight->weightFloat.get(); weightSize = quanWeight->weightFloat.size(); diff --git a/source/backend/vulkan/image/execution/VulkanDeconvolution.cpp b/source/backend/vulkan/image/execution/VulkanDeconvolution.cpp index 543665ea5..22b906356 100644 --- a/source/backend/vulkan/image/execution/VulkanDeconvolution.cpp +++ b/source/backend/vulkan/image/execution/VulkanDeconvolution.cpp @@ -34,7 +34,7 @@ VulkanDeconvolution::VulkanDeconvolution(Backend* bn, const std::vector const float* filterDataPtr = nullptr; int tempWeightSize = 0; std::shared_ptr quanCommon; - ConvolutionCommon::getConvParameters(&quanCommon, conv, &filterDataPtr, &tempWeightSize); + ConvolutionCommon::getConvParameters(&quanCommon, bn, conv, &filterDataPtr, &tempWeightSize); if (nullptr != filterDataPtr) { MNN_ASSERT(inputs.size() == 1); diff --git a/source/backend/vulkan/image/execution/VulkanDeconvolutionDepthwise.cpp b/source/backend/vulkan/image/execution/VulkanDeconvolutionDepthwise.cpp index e68604f89..5f9855cc5 100644 --- a/source/backend/vulkan/image/execution/VulkanDeconvolutionDepthwise.cpp +++ b/source/backend/vulkan/image/execution/VulkanDeconvolutionDepthwise.cpp @@ -41,7 +41,7 @@ VulkanDeconvolutionDepthwise::VulkanDeconvolutionDepthwise(Backend* bn, const Co const float* tempWeight = nullptr; int tempWeightSize = 0; std::shared_ptr quanCommon; - ConvolutionCommon::getConvParameters(&quanCommon, conv, &tempWeight, &tempWeightSize); + ConvolutionCommon::getConvParameters(&quanCommon, bn, conv, &tempWeight, &tempWeightSize); for (int b = 0; b < co; ++b) { int b_4 = b / 4; diff --git a/source/core/Backend.hpp b/source/core/Backend.hpp index a833a9ed0..06ed11b8b 100644 --- a/source/core/Backend.hpp +++ b/source/core/Backend.hpp @@ -115,8 +115,9 @@ class Backend : public NonCopyable { /** * @brief callback after resize ops. */ - virtual void onResizeEnd() { + virtual ErrorCode onResizeEnd() { // nothing to do + return NO_ERROR; } /** diff --git a/source/core/BufferAllocator.cpp b/source/core/BufferAllocator.cpp index 911fb2182..e82d3033b 100644 --- a/source/core/BufferAllocator.cpp +++ b/source/core/BufferAllocator.cpp @@ -383,16 +383,20 @@ void DeferBufferAllocator::reset() { mBarrrierFreeChunks.clear(); } -size_t DeferBufferAllocator::compute() { +ErrorCode DeferBufferAllocator::compute() { if (mPtr.ptr()) { - return mTotalSize; + return NO_ERROR; } mTotalSize = 0; if (mFreeList.empty()) { - return mTotalSize; + return NO_ERROR; } MNN_ASSERT(mFreeList.size() == 1); MNN_ASSERT(mHead == mTail); + if (mFreeList.size() != 1 || mHead != mTail) { + // Defer allocator compute error + return INVALID_VALUE; + } auto chunk = mHead; while (chunk) { chunk->offset = mTotalSize; @@ -401,6 +405,9 @@ size_t DeferBufferAllocator::compute() { chunk = chunk->right; } mPtr = mAllocator->onAlloc(mTotalSize, mAlign); + if (mPtr.ptr() == nullptr) { + return OUT_OF_MEMORY; + } // mPtr.reset(static_cast(malloc(mTotalSize))); for (auto& chunk : mChunks) { chunk->base = mPtr.ptr(); @@ -408,7 +415,7 @@ size_t DeferBufferAllocator::compute() { t->buffer().host = mPtr.ptr() + chunk->offset; } } - return mTotalSize; + return NO_ERROR; } // some utils functions of DeferBufferAllocator diff --git a/source/core/BufferAllocator.hpp b/source/core/BufferAllocator.hpp index 33c9593b6..07ab0ea19 100644 --- a/source/core/BufferAllocator.hpp +++ b/source/core/BufferAllocator.hpp @@ -17,6 +17,7 @@ #include "NonCopyable.hpp" #include "AutoStorage.h" #include +#include namespace MNN { @@ -97,7 +98,7 @@ class MNN_PUBLIC BufferAllocator : public NonCopyable { virtual void beginGroup() {} virtual void endGroup() {} virtual void reset() {} - virtual size_t compute() { return 0; } + virtual ErrorCode compute() { return NO_ERROR; } }; @@ -207,7 +208,7 @@ class MNN_PUBLIC DeferBufferAllocator : public BufferAllocator { void beginGroup() override; void endGroup() override; void reset() override; - size_t compute() override; + ErrorCode compute() override; private: std::vector> mChunks; MemNode *mHead = nullptr, *mTail = nullptr; diff --git a/source/core/ConvolutionCommon.cpp b/source/core/ConvolutionCommon.cpp index 2f1223f6d..5b986b460 100644 --- a/source/core/ConvolutionCommon.cpp +++ b/source/core/ConvolutionCommon.cpp @@ -10,6 +10,7 @@ #include #include "backend/cpu/compute/CommonOptFunction.h" #include "half.hpp" +#include "core/OpCommonUtils.hpp" namespace MNN { static inline void *MNNMemoryAllocAlignZeroAlign(size_t size) { @@ -186,15 +187,14 @@ static void StreamSizeRead(void *dst, int unit, size_t count, unsigned char *&fi file += (unit * count); } -static bool isFastSample(const std::vector& sample, int bit) { - if (bit != 4) { - return false; - } - if (sample.size() != (1 << bit) - 1) { +static bool isLinearSample(const std::vector& sample, int bit) { + const int offset = 1 << (bit - 1); + const int size = 1 << bit; + if (sample.size() != size) { return false; } for (int i = 0; i < sample.size(); i++) { - if (static_cast(sample[i]) != i - 7) { + if (static_cast(sample[i]) != i - offset) { return false; } } @@ -219,7 +219,7 @@ static int8_t *ReadQuanData_c(unsigned char *&s, size_t* len, ConvolutionCommon: // sample uint32_t sampleCnt = 0; StreamSizeRead(&sampleCnt, 1, 1, s); - if (0 == sampleCnt) { + if (sampleCnt == 0) { sampleCnt = 256; } result->weightMap.resize(sampleCnt); @@ -228,9 +228,9 @@ static int8_t *ReadQuanData_c(unsigned char *&s, size_t* len, ConvolutionCommon: break; StreamSizeRead(samples, 1, sampleCnt, s); SimpleRank(samples, sampleCnt, 1); - // index uint32_t idxBitsCnt = atLestBitsCnt(sampleCnt); idxBitsCnt = idxBitsCnt < 1 ? 1 : idxBitsCnt; + // index size_t idxBufSize = ceil(idxBitsCnt * dataCnt * 0.125); idxBuf = (uint8_t *)MNNMemoryAllocAlignZeroAlign(idxBufSize); if (nullptr == idxBuf) { @@ -242,13 +242,23 @@ static int8_t *ReadQuanData_c(unsigned char *&s, size_t* len, ConvolutionCommon: if (nullptr == blob) { break; } - if (isFastSample(result->weightMap, idxBitsCnt)) { - for (int i = 0; i < idxBufSize; i++) { - int val = idxBuf[i]; - int x1 = val / 16; - int x2 = val % 16; - blob[2 * i] = x1 - 7; - blob[2 * i + 1] = x2 - 7; + + if (isLinearSample(result->weightMap, idxBitsCnt) && (idxBitsCnt == 4 || idxBitsCnt == 8)) { + // fast sample for bit = 4 or 8 + if (idxBitsCnt == 4) { + for (int i = 0; i < idxBufSize; i++) { + int val = idxBuf[i]; + int x1 = val / 16; + int x2 = val % 16; + blob[2 * i] = x1 - 8; + blob[2 * i + 1] = x2 - 8; + } + } + if (idxBitsCnt == 8) { + for (int i = 0; i < idxBufSize; i++) { + int val = idxBuf[i]; + blob[i] = val - 64; + } } } else { // split index value into bytes @@ -265,6 +275,7 @@ static int8_t *ReadQuanData_c(unsigned char *&s, size_t* len, ConvolutionCommon: } blob[i] = samples[idxBytes[i]]; } + if (i < dataCnt) { MNNMemoryFreeAlign(blob); blob = nullptr; @@ -284,8 +295,7 @@ static int8_t *ReadQuanData_c(unsigned char *&s, size_t* len, ConvolutionCommon: return blob; } -static int8_t *ReadSparseQuanData_c(unsigned char *&myfile, size_t* len, const flatbuffers::Vector *alpha, ConvolutionCommon::Int8Common* result, bool useInt32) { - // MNN_ERROR("sparse:%d\n", 1); +static int8_t *ReadSparseQuanData_c(unsigned char *&myfile, size_t* len, const float* alpha_ptr, size_t alpha_size, ConvolutionCommon::Int8Common* result, bool useInt32) { // MNN_ERROR("sparse:%d\n", 1); unsigned int shape[32]; uint32_t ucMapSize = 0; PSIMPLE_SET setWeight = CreateSimpleSet(256); @@ -356,9 +366,9 @@ static int8_t *ReadSparseQuanData_c(unsigned char *&myfile, size_t* len, const f if (nullptr == arrWeightIdx) { return nullptr; } + int iDataNeedBits = (int)ceil(_log2(ucMapSize)); + iDataNeedBits = iDataNeedBits < 1 ? 1 : iDataNeedBits; { - int iDataNeedBits = (int)ceil(_log2(ucMapSize)); - iDataNeedBits = iDataNeedBits < 1 ? 1 : iDataNeedBits; size_t bufLen = (size_t)(ceil(0.125 * iDataNeedBits * nnz)); char *buf = (char *)MNNMemoryAllocAlignZeroAlign(bufLen * sizeof(char)); if (nullptr == buf) { @@ -371,15 +381,16 @@ static int8_t *ReadSparseQuanData_c(unsigned char *&myfile, size_t* len, const f } // set blob data with idx and weight idx { - if (alpha->size() == 2 * shape[0]) { - auto alphaPtr = alpha->data(); + if (alpha_size == 2 * shape[0]) { + const int min_value = -(1 << (iDataNeedBits - 1)); + auto alphaPtr = alpha_ptr; int area = Size / shape[0]; for (int i = 0; i < shape[0]; i++) { float min = alphaPtr[2*i]; float scale = alphaPtr[2*i+1]; - int zeroQuant = -128; + int zeroQuant = min_value; if (scale > 1e-6) { - zeroQuant = round((0.0f - min) / scale) + (-128); + zeroQuant = round((0.0f - min) / scale) + min_value; } memset(blob+area*i, zeroQuant, area * sizeof(signed char)); } @@ -402,9 +413,36 @@ static int8_t *ReadSparseQuanData_c(unsigned char *&myfile, size_t* len, const f *len = Size; return blob; } -std::shared_ptr ConvolutionCommon::load(const IDSTQuan *quan, bool forceFloat, bool forceInt8) { - auto result = std::make_shared(); +std::shared_ptr ConvolutionCommon::load(const Convolution2D *conv, Backend* backend, bool forceFloat, bool forceInt8) { + auto quan = conv->quanParameter(); + auto result = std::make_shared(); result->quan = quan; + size_t buffer_size = 0, alpha_size = 0; + const int8_t* buffer_ptr = nullptr; + const float* alpha_ptr = nullptr; + std::unique_ptr external_buffer; + std::unique_ptr external_alpha; + if (USE_EXTERNAL_DATA(conv) && quan->buffer() == nullptr) { + // external data + buffer_size = conv->external()->Get(1); + alpha_size = conv->external()->Get(2) / sizeof(float); + external_buffer.reset(new int8_t[buffer_size]); + external_alpha.reset(new float[alpha_size]); + buffer_ptr = external_buffer.get(); + alpha_ptr = external_alpha.get(); + auto char_buffer_ptr = reinterpret_cast(external_buffer.get()); + auto char_alpha_ptr = reinterpret_cast(external_alpha.get()); + OpCommonUtils::loadExternalDatas(backend, {char_buffer_ptr, char_alpha_ptr}, conv->external()->data()); + } else { + if (quan->buffer()) { + buffer_size = quan->buffer()->size(); + buffer_ptr = quan->buffer()->data(); + } + if (quan->alpha()) { + alpha_size = quan->alpha()->size(); + alpha_ptr = quan->alpha()->data(); + } + } if (quan->index() != nullptr) { if (forceFloat) { // Expand sparse to dense @@ -415,25 +453,24 @@ std::shared_ptr ConvolutionCommon::load(const IDS ::memset(result->weightFloat.get(), 0, quan->weightSize() * sizeof(float)); auto index = quan->index()->data(); auto indexSize = quan->index()->size(); - if (nullptr == quan->alpha() || quan->alpha()->size() != indexSize) { + if (nullptr == alpha_ptr || alpha_size != indexSize) { MNN_ERROR("The model is error, don't has alpha but has index\n"); return nullptr; } - auto weightRaw = quan->alpha()->data(); for (uint32_t i=0; iweightFloat.get()[index[i]] = weightRaw[i]; + result->weightFloat.get()[index[i]] = alpha_ptr[i]; } } // Otherwise needn't treat, just return result with quan info return result; } size_t weightLength = 0; int8_t *buffer = nullptr; - auto originBuffer = (unsigned char *)quan->buffer()->data(); + auto originBuffer = (unsigned char *)buffer_ptr; if (1 == quan->type()) { buffer = ReadQuanData_c(originBuffer, &weightLength, result.get(), quan->shapeInt32()); } if (2 == quan->type()) { - buffer = ReadSparseQuanData_c(originBuffer, &weightLength, quan->alpha(), result.get(), quan->shapeInt32()); + buffer = ReadSparseQuanData_c(originBuffer, &weightLength, alpha_ptr, alpha_size, result.get(), quan->shapeInt32()); } if (result->weightMap.size() > 0 && result->weightMap.size() <= 16) { // Compute Remap for int4 @@ -462,9 +499,9 @@ std::shared_ptr ConvolutionCommon::load(const IDS } // read fp16 data if (3 == quan->type()) { - weightLength = quan->buffer()->size() / sizeof(half_float::half); - std::vector tempHalfWeight(quan->buffer()->size()); - ::memcpy(tempHalfWeight.data(), quan->buffer()->data(), quan->buffer()->size()); + weightLength = buffer_size / sizeof(half_float::half); + std::vector tempHalfWeight(buffer_size); + ::memcpy(tempHalfWeight.data(), buffer_ptr, buffer_size); auto halfWeight = reinterpret_cast(tempHalfWeight.data()); result->weightFloat.reset(weightLength); if (nullptr == result->weightFloat.get()) { @@ -478,9 +515,9 @@ std::shared_ptr ConvolutionCommon::load(const IDS // weight int8 only if (4 == quan->type()) { - weightLength = quan->buffer()->size(); + weightLength = buffer_size; result->weight.reset(weightLength); - ::memcpy(result->weight.get(), quan->buffer()->data(), weightLength); + ::memcpy(result->weight.get(), buffer_ptr, weightLength); } if (result->weight.get() == nullptr) { @@ -490,12 +527,12 @@ std::shared_ptr ConvolutionCommon::load(const IDS } result->weight.set(buffer, weightLength); } - result->alpha.reset(quan->alpha()->size()); + result->alpha.reset(alpha_size); if (nullptr == result->alpha.get()) { MNN_PRINT("Alloc memory error for extract idst int8\n"); return nullptr; } - ::memcpy(result->alpha.get(), quan->alpha()->data(), quan->alpha()->size() * sizeof(float)); + ::memcpy(result->alpha.get(), alpha_ptr, alpha_size * sizeof(float)); { int outputCount = 0; bool oldType4 = (quan->type() == 4 && quan->aMin() == 0 && std::abs(quan->quantScale()) < 1e-6); @@ -563,12 +600,12 @@ std::shared_ptr ConvolutionCommon::load(const IDS return result; } -void ConvolutionCommon::getConvParameters(std::shared_ptr *quanCommon, const MNN::Convolution2D *conv2d, const float** originWeight, int* originWeightSize) { +void ConvolutionCommon::getConvParameters(std::shared_ptr *quanCommon, Backend* backend, const MNN::Convolution2D *conv2d, const float** originWeight, int* originWeightSize) { *originWeight = nullptr; *originWeightSize = 0; if (nullptr != conv2d->quanParameter()) { bool forceFloat = conv2d->quanParameter()->index() != nullptr; - *quanCommon = load(conv2d->quanParameter(), forceFloat); + *quanCommon = load(conv2d, backend, forceFloat); *originWeight = (*quanCommon)->weightFloat.get(); *originWeightSize = (*quanCommon)->weightFloat.size(); } @@ -578,7 +615,7 @@ void ConvolutionCommon::getConvParameters(std::shared_ptr *quanCommo } } -bool ConvolutionCommon::getConvInt8Parameters(const MNN::Convolution2D* conv2d, std::shared_ptr& quanCommon, +bool ConvolutionCommon::getConvInt8Parameters(const MNN::Convolution2D* conv2d, std::shared_ptr& quanCommon, Backend* backend, const int8_t*& weight, int& weightSize, float*& scale, int32_t*& bias) { int outputCount = conv2d->common()->outputCount(); weightSize = 0; @@ -588,7 +625,7 @@ bool ConvolutionCommon::getConvInt8Parameters(const MNN::Convolution2D* conv2d, weightSize = conv2d->symmetricQuan()->weight()->size(); } if (conv2d->quanParameter() && conv2d->quanParameter()->buffer()) { - quanCommon = ConvolutionCommon::load(conv2d->quanParameter(), false, true); + quanCommon = ConvolutionCommon::load(conv2d, backend, false, true); weight = quanCommon->weight.get(); weightSize = quanCommon->weight.size(); } diff --git a/source/core/ConvolutionCommon.hpp b/source/core/ConvolutionCommon.hpp index 912b11e55..f41c88a2b 100644 --- a/source/core/ConvolutionCommon.hpp +++ b/source/core/ConvolutionCommon.hpp @@ -23,10 +23,11 @@ class MNN_PUBLIC ConvolutionCommon : public Execution { std::vector weightMap; std::vector weightReverseMap; bool canUseInt4 = false; + Backend* backend = nullptr; }; - static std::shared_ptr load(const IDSTQuan* quan, bool forceFloat = false, bool forceInt8 = false); - static void getConvParameters(std::shared_ptr *quanCommon, const MNN::Convolution2D *conv2d, const float** originWeight, int* originWeightSize); - static bool getConvInt8Parameters(const MNN::Convolution2D* conv2d, std::shared_ptr& quanCommon, + static std::shared_ptr load(const Convolution2D* conv, Backend* backend = nullptr, bool forceFloat = false, bool forceInt8 = false); + static void getConvParameters(std::shared_ptr *quanCommon, Backend* backend, const MNN::Convolution2D *conv2d, const float** originWeight, int* originWeightSize); + static bool getConvInt8Parameters(const MNN::Convolution2D* conv2d, std::shared_ptr& quanCommon, Backend* backend, const int8_t*& weight, int& weightSize, float*& scale, int32_t*& bias); // Return padX, padY diff --git a/source/core/OpCommonUtils.cpp b/source/core/OpCommonUtils.cpp index 15cca8aa7..4e8fd9677 100644 --- a/source/core/OpCommonUtils.cpp +++ b/source/core/OpCommonUtils.cpp @@ -28,6 +28,9 @@ void OpCommonUtils::loadBlobData(Backend* backend, const Op* op, char* ptr, int case DataType_DT_FLOAT: result = (void*)b->float32s()->Data(); break; + case DataType_DT_BFLOAT16: + result = (void*)b->uint8s()->Data(); + break; case DataType_DT_INT32: result = (void*)b->int32s()->Data(); break; diff --git a/source/core/Pipeline.cpp b/source/core/Pipeline.cpp index 554752353..e83db1a96 100644 --- a/source/core/Pipeline.cpp +++ b/source/core/Pipeline.cpp @@ -967,9 +967,12 @@ ErrorCode Pipeline::allocMemory(bool firstMalloc, bool forbidReplace) { _recycleDynamicMemory(c.get()); } } - mBackend->onResizeEnd(); - mBackupBackend->onResizeEnd(); - return NO_ERROR; + auto code = mBackend->onResizeEnd(); + if (code != NO_ERROR) { + return code; + } + code = mBackupBackend->onResizeEnd(); + return code; } void Pipeline::_copyInputs() { @@ -1004,26 +1007,32 @@ ErrorCode Pipeline::execute() { for (auto& cmdP : buffer.command) { auto& cmd = *cmdP; auto code = cmd.execution->onExecute(cmd.workInputs, cmd.workOutputs); +// #define LOG_VERPOSE #ifdef LOG_VERPOSE - MNN_PRINT("%s Input begin:\n", EnumNameOpType(cmd.op->type())); - for (auto t : cmd.workInputs) { - auto ptr = (float*)t->map(Tensor::MAP_TENSOR_READ, t->getDimensionType()); + auto dumpT = [](Tensor* t) { auto size = TensorUtils::getRawSize(t); - for (int i=0; i 10 ? 10 : size; + if (t->getType() == halide_type_of()) { + for (int i=0; ihost()[i]); + } + } else { + for (int i=0; ihost()[i]); + } } MNN_PRINT("\n"); - t->unmap(Tensor::MAP_TENSOR_READ, Tensor::CAFFE, ptr); - } - MNN_PRINT("%s Output begin:\n", EnumNameOpType(cmd.op->type())); - for (auto t : cmd.workOutputs) { - auto ptr = (float*)t->map(Tensor::MAP_TENSOR_READ, t->getDimensionType()); - auto size = TensorUtils::getRawSize(t); - for (int i=0; iname() && cmd.op->name()->str() == "/embed/embed_/Gather_output_0"*/ + cmd.op->type() == OpType_Convolution) { + MNN_PRINT("%s Input begin:\n", EnumNameOpType(cmd.op->type())); + for (auto t : cmd.workInputs) { + dumpT(t); + } + MNN_PRINT("%s Output begin:\n", EnumNameOpType(cmd.op->type())); + for (auto t : cmd.workOutputs) { + dumpT(t); } - MNN_PRINT("\n"); - t->unmap(Tensor::MAP_TENSOR_READ, Tensor::CAFFE, ptr); } #endif if (NO_ERROR != code) { diff --git a/source/core/Tensor.cpp b/source/core/Tensor.cpp index d799f6898..2f5991f7f 100644 --- a/source/core/Tensor.cpp +++ b/source/core/Tensor.cpp @@ -391,8 +391,8 @@ void Tensor::printShape() const { MNN_PRINT("\n"); } -int Tensor::size() const { - auto dataSize = mBuffer.type.bytes(); +size_t Tensor::usize() const { + size_t dataSize = mBuffer.type.bytes(); MNN_ASSERT(dataSize >= 1); auto nativeDescribe = mDescribe->mContent.get(); for (int i = 0; i < this->buffer().dimensions; i++) { @@ -405,6 +405,10 @@ int Tensor::size() const { return dataSize; } +int Tensor::size() const { + return static_cast(usize()); +} + void* Tensor::map(MapType mtype, DimensionType dtype) { auto nativeDescribe = mDescribe->mContent.get(); auto bn = nativeDescribe->getBackend(); diff --git a/source/geometry/GeometryComputerUtils.cpp b/source/geometry/GeometryComputerUtils.cpp index f7de5cc31..fddffa9f5 100644 --- a/source/geometry/GeometryComputerUtils.cpp +++ b/source/geometry/GeometryComputerUtils.cpp @@ -236,7 +236,10 @@ ErrorCode GeometryComputerUtils::shapeComputeAndGeometryTransform( } backupBackend->onResizeBegin(); auto code = exe->onResize(c.inputs, c.outputs); - backupBackend->onResizeEnd(); + if (NO_ERROR != code) { + return NOT_SUPPORT; + } + code = backupBackend->onResizeEnd(); if (NO_ERROR != code) { return NOT_SUPPORT; } diff --git a/test.ps1 b/test.ps1 index 3799f5ed3..9fe70a299 100644 --- a/test.ps1 +++ b/test.ps1 @@ -57,18 +57,20 @@ function run_remote([String]$cmd) { } function log($case, $title, $blocked, $failed, $passed, $skipped) { - Write-Output "TEST_NAME_${case}: $title\nTEST_CASE_AMOUNT_${case}: {`"blocked`":$blocked,`"failed`":$failed,`"passed`":$passed,`"skipped`":$skipped}\n" + Write-Output "TEST_NAME_${case}: $title" + Write-Output "TEST_CASE_AMOUNT_${case}: {`"blocked`":$blocked,`"failed`":$failed,`"passed`":$passed,`"skipped`":$skipped}" } function failed() { Write-Output "TEST_NAME_EXCEPTION: Exception" Write-Output 'TEST_CASE_AMOUNT_EXCEPTION: {"blocked":0,"failed":1,"passed":0,"skipped":0}' - exit 1 + exit } function build_lib_test() { - Invoke-Expression "./package_scripts/win/build_lib.ps1 -path $outdir $(If ($gpu) {"-backends 'opencl,vulkan'"}) $(If ($x86) {'-x86'})" - $WrongNum = $($LastExitCode -ne 0) + # build_lib_release.ps1 just build release for speed + Invoke-Expression "./package_scripts/win/build_lib_release.ps1 -path $outdir -cibuild $(If ($gpu) {"-backends 'opencl,vulkan'"}) $(If ($x86) {'-x86'})" + $WrongNum = [int]$($LastExitCode -ne 0) log "WINDOWS_LIB" "Windows主库编译测试" 0 $WrongNum $(1 - $WrongNum) 0 if ($WrongNum -ne 0) { Write-Output "### Windows主库编译测试失败,测试终止" @@ -221,13 +223,14 @@ function pymnn_whl_test() { } build_lib_test -build_tool_test -build_whl_test -build_bridge_test - -if ($test_avx512) { - sync_remote -} -unit_test -model_test -pymnn_whl_test +# TODO: open other test +# build_tool_test +# build_whl_test +# build_bridge_test + +# if ($test_avx512) { +# sync_remote +# } +# unit_test +# model_test +# pymnn_whl_test \ No newline at end of file diff --git a/test/core/IDSTTest.cpp b/test/core/IDSTTest.cpp index 7dd973159..e2e042c5e 100644 --- a/test/core/IDSTTest.cpp +++ b/test/core/IDSTTest.cpp @@ -23,12 +23,14 @@ class IDSTTest : public MNNTestCase { std::vector quantWeight(kernelNum * kernelSize, 0); // IDST encode std::unique_ptr idstQuantT = IDSTEncoder::encode(weight.data(), scale, kernelSize, kernelNum, false, quantWeight.data(), -127); + std::unique_ptr conv2dT(new Convolution2DT); + conv2dT->quanParameter = std::move(idstQuantT); flatbuffers::FlatBufferBuilder builder; - auto lastOffset = IDSTQuan::Pack(builder, idstQuantT.get()); + auto lastOffset = Convolution2D::Pack(builder, conv2dT.get()); builder.Finish(lastOffset); - auto idstQuant = flatbuffers::GetRoot(builder.GetBufferPointer()); + auto conv2d = flatbuffers::GetRoot(builder.GetBufferPointer()); // IDST decode - std::shared_ptr common = ConvolutionCommon::load(idstQuant); + std::shared_ptr common = ConvolutionCommon::load(conv2d); // is input == output ? bool res = (0 == memcmp(common->weightFloat.get(), weight.data(), weight.size())); return res; diff --git a/tools/converter/forward.json b/tools/converter/forward.json new file mode 100644 index 000000000..3fb140782 --- /dev/null +++ b/tools/converter/forward.json @@ -0,0 +1,7 @@ +{ + "backend":0, + "mode":1, + "precision":1, + "memory":1, + "power":1 +} diff --git a/tools/converter/include/cli.hpp b/tools/converter/include/cli.hpp index 11ea60203..6f9456818 100644 --- a/tools/converter/include/cli.hpp +++ b/tools/converter/include/cli.hpp @@ -16,7 +16,7 @@ class MNN_PUBLIC Cli { public: static bool initializeMNNConvertArgs(modelConfig &modelPath, int argc, char **argv); static bool convertModel(modelConfig& modelPath); - static int testconvert(const std::string& defaultCacheFile, const std::string& directName, float maxErrorRate); + static int testconvert(const std::string& defaultCacheFile, const std::string& directName, float maxErrorRate, const std::string& configJson); static bool mnn2json(const char* modelFile, const char* jsonFile, int flag = 3); static bool json2mnn(const char* jsonFile, const char* modelFile); }; diff --git a/tools/converter/include/config.hpp b/tools/converter/include/config.hpp index 13c590d86..991ad1217 100644 --- a/tools/converter/include/config.hpp +++ b/tools/converter/include/config.hpp @@ -55,11 +55,16 @@ class MNN_PUBLIC modelConfig { std::string customOpLibs = ""; std::string authCode = ""; std::string testDir = ""; + std::string testConfig; float testThredhold = 0.01; bool mnn2json = false; bool dumpInfo = false; bool saveExternalData = false; bool inSubGraph = false; + // using external data when convert + int64_t externalTreshold = 1024 * 64; + std::ofstream* externalFile = nullptr; + int64_t externalOffset = 0; }; #endif // CONFIG_HPP diff --git a/tools/converter/source/TestConvertResult.cpp b/tools/converter/source/TestConvertResult.cpp index deae1ec45..707c0d5bb 100644 --- a/tools/converter/source/TestConvertResult.cpp +++ b/tools/converter/source/TestConvertResult.cpp @@ -10,11 +10,15 @@ #include "cli.hpp" int main(int argc, char *argv[]) { if (argc < 3) { - MNN_ERROR("Usage: ./TestConvertResult [Onnx, Tf, Tflite, Torch] ${Dir}\n"); + MNN_ERROR("Usage: ./TestConvertResult [Onnx, Tf, Tflite, Torch] ${Dir} [config.json]\n"); return 0; } std::string inputType = argv[1]; std::string directName = argv[2]; + std::string configFile; + if (argc >= 4) { + configFile = argv[3]; + } auto inputModel = modelConfig::ONNX; auto suffix = ".onnx"; if (inputType == "Tf") { @@ -39,5 +43,5 @@ int main(int argc, char *argv[]) { modelPath.keepInputFormat = true; MNN::Cli::convertModel(modelPath); } - return MNN::Cli::testconvert(defaultCacheFile, directName, 0.01f); + return MNN::Cli::testconvert(defaultCacheFile, directName, 0.01f, configFile); } diff --git a/tools/converter/source/common/CommonUtils.hpp b/tools/converter/source/common/CommonUtils.hpp index 356e409bf..79178c0fb 100644 --- a/tools/converter/source/common/CommonUtils.hpp +++ b/tools/converter/source/common/CommonUtils.hpp @@ -17,7 +17,9 @@ void converToStaticModel(const MNN::Net* net, std::map>& inputConfig, std::string mnnFile); void removeParams(std::unique_ptr& netT); +void RemoveAndStoreParam(std::unique_ptr& op, std::ofstream* fs, int64_t& offset); bool saveExternalData(std::unique_ptr& netT, const std::string& extraFileName); +bool loadExternalData(std::unique_ptr& netT, const char* extraFileName); void castParamsToHalf(std::unique_ptr& netT); void AlignDenormalizedValue(std::unique_ptr& netT); void addSparseInfo(std::unique_ptr& netT, MNN::Compression::Pipeline proto); diff --git a/tools/converter/source/common/RemoveParams.cpp b/tools/converter/source/common/RemoveParams.cpp index 2bcfc6ede..e441e4a6a 100644 --- a/tools/converter/source/common/RemoveParams.cpp +++ b/tools/converter/source/common/RemoveParams.cpp @@ -7,6 +7,7 @@ // #include "CommonUtils.hpp" +#include "../source/core/FileLoader.hpp" #include auto RemoveParams = [](std::unique_ptr& op) { @@ -59,18 +60,18 @@ auto RemoveParams = [](std::unique_ptr& op) { }; template -static void storeWeight(std::ofstream& fs, std::vector& weight, std::vector& external, int64_t& offset) { +static void storeWeight(std::ofstream* fs, std::vector& weight, std::vector& external, int64_t& offset) { if (external.empty()) { external.push_back(offset); } int64_t size = weight.size() * sizeof(T); - fs.write(reinterpret_cast(weight.data()), size); + fs->write(reinterpret_cast(weight.data()), size); weight.clear(); external.push_back(size); offset += size; } -static void RemoveAndStoreParam(std::unique_ptr& op, std::ofstream& fs, int64_t& offset) { +void RemoveAndStoreParam(std::unique_ptr& op, std::ofstream* fs, int64_t& offset) { const auto opType = op->type; switch (opType) { case MNN::OpType_Convolution: @@ -78,8 +79,13 @@ static void RemoveAndStoreParam(std::unique_ptr& op, std::ofstream& fs case MNN::OpType_ConvolutionDepthwise: { auto param = op->main.AsConvolution2D(); - storeWeight(fs, param->weight, param->external, offset); - storeWeight(fs, param->bias, param->external, offset); + if (param->quanParameter) { + storeWeight(fs, param->quanParameter->buffer, param->external, offset); + storeWeight(fs, param->quanParameter->alpha, param->external, offset); + } else { + storeWeight(fs, param->weight, param->external, offset); + storeWeight(fs, param->bias, param->external, offset); + } break; } case MNN::OpType_Scale: { @@ -101,10 +107,20 @@ static void RemoveAndStoreParam(std::unique_ptr& op, std::ofstream& fs case MNN::OpType_TrainableParam: case MNN::OpType_Const: { auto param = op->main.AsBlob(); + size_t totalSize = 1; + for (auto dim : param->dims) { + totalSize *= dim; + } + if (totalSize <= 1024) { + break; + } switch (param->dataType) { case MNN::DataType_DT_FLOAT: storeWeight(fs, param->float32s, param->external, offset); break; + case MNN::DataType_DT_BFLOAT16: + storeWeight(fs, param->uint8s, param->external, offset); + break; case MNN::DataType_DT_INT32: storeWeight(fs, param->int32s, param->external, offset); break; @@ -142,13 +158,97 @@ bool saveExternalData(std::unique_ptr& netT, const std::string& extra } int64_t offset = 0; for (auto& op : netT->oplists) { - RemoveAndStoreParam(op, extraFile, offset); + RemoveAndStoreParam(op, &extraFile, offset); } for (auto& subgraph : netT->subgraphs) { for (auto& op : subgraph->nodes) { - RemoveAndStoreParam(op, extraFile, offset); + RemoveAndStoreParam(op, &extraFile, offset); } } extraFile.close(); return true; } + +template +static void loadExternalData(MNN::FileLoader& fl, std::vector& data, int64_t size) { + data.resize(size / sizeof(T)); + fl.read(reinterpret_cast(data.data()), size); +} + +void loadExternalParam(std::unique_ptr& op, MNN::FileLoader& fl) { + const auto opType = op->type; + switch (opType) { + case MNN::OpType_Convolution: + case MNN::OpType_Deconvolution: + case MNN::OpType_ConvolutionDepthwise: + { + auto param = op->main.AsConvolution2D(); + if (param->external.size() != 3) { + return; + } + fl.offset(param->external[0]); + if (param->quanParameter) { + loadExternalData(fl, param->quanParameter->buffer, param->external[1]); + loadExternalData(fl, param->quanParameter->alpha, param->external[2]); + } else { + loadExternalData(fl, param->weight, param->external[1]); + loadExternalData(fl, param->bias, param->external[2]); + } + param->external.clear(); + break; + } + case MNN::OpType_Scale: { + auto param = op->main.AsScale(); + break; + } + case MNN::OpType_LayerNorm: { + auto param = op->main.AsLayerNorm(); + break; + } + case MNN::OpType_TrainableParam: + case MNN::OpType_Const: { + auto param = op->main.AsBlob(); + if (param->external.size() != 2) { + return; + } + size_t totalSize = 1; + for (auto dim : param->dims) { + totalSize *= dim; + } + fl.offset(param->external[0]); + switch (param->dataType) { + case MNN::DataType_DT_FLOAT: + loadExternalData(fl, param->float32s, param->external[1]); + break; + case MNN::DataType_DT_INT32: + loadExternalData(fl, param->int32s, param->external[1]); + break; + case MNN::DataType_DT_UINT8: + loadExternalData(fl, param->uint8s, param->external[1]); + break; + case MNN::DataType_DT_INT8: + loadExternalData(fl, param->int8s, param->external[1]); + break; + default: + break; + } + param->external.clear(); + break; + } + default: + break; + } +} + +bool loadExternalData(std::unique_ptr& netT, const char* extraFileName) { + MNN::FileLoader fileloader(extraFileName); + for (auto& op : netT->oplists) { + loadExternalParam(op, fileloader); + } + for (auto& subgraph : netT->subgraphs) { + for (auto& op : subgraph->nodes) { + loadExternalParam(op, fileloader); + } + } + return true; +} \ No newline at end of file diff --git a/tools/converter/source/common/WeightQuantAndCoding.cpp b/tools/converter/source/common/WeightQuantAndCoding.cpp index f92782246..d61c331ae 100644 --- a/tools/converter/source/common/WeightQuantAndCoding.cpp +++ b/tools/converter/source/common/WeightQuantAndCoding.cpp @@ -151,11 +151,11 @@ void WeightQuantAndCoding(std::unique_ptr& op, const modelConfig& conf } if (opType == MNN::OpType_ConvInt8 || opType == MNN::OpType_DepthwiseConvInt8) { - param->quanParameter = IDSTEncoder::encode(weightData.data(), scales, kernelSize, kernelNum, false, param->symmetricQuan->weight.data(), int(clampMin)); + param->quanParameter = IDSTEncoder::encode(weightData.data(), scales, kernelSize, kernelNum, false, param->symmetricQuan->weight.data(), int(clampMin), bits); param->symmetricQuan->weight.clear(); param->quanParameter->alpha = {1.0f}; // fake scales } else { - param->quanParameter = IDSTEncoder::encode(weightData.data(), scales, kernelSize, kernelNum, asymmetricQuantFlag, quantWeights.data(), int(clampMin)); + param->quanParameter = IDSTEncoder::encode(weightData.data(), scales, kernelSize, kernelNum, asymmetricQuantFlag, quantWeights.data(), int(clampMin), bits); param->weight.clear(); } }; diff --git a/tools/converter/source/common/cli.cpp b/tools/converter/source/common/cli.cpp index f4165e00c..0e58b0d45 100644 --- a/tools/converter/source/common/cli.cpp +++ b/tools/converter/source/common/cli.cpp @@ -249,6 +249,11 @@ bool Cli::initializeMNNConvertArgs(modelConfig &modelPath, int argc, char **argv "set test dir, mnn will convert model and then check the result", cxxopts::value() ) + ( + "testconfig", + "set test config json, example: tools/converter/forward.json", + cxxopts::value() + ) ( "thredhold", "if set test dir, thredhold mean the max rate permit for run MNN model and origin error", @@ -455,6 +460,9 @@ bool Cli::initializeMNNConvertArgs(modelConfig &modelPath, int argc, char **argv if (result.count("testdir")) { modelPath.testDir = result["testdir"].as(); } + if (result.count("testconfig")) { + modelPath.testConfig = result["testconfig"].as(); + } if (result.count("thredhold")) { modelPath.testThredhold = result["thredhold"].as(); } @@ -538,7 +546,7 @@ bool Cli::convertModel(modelConfig& modelPath) { } if (modelPath.testDir.size() > 0) { std::cout << "Check convert result by " << modelPath.testDir << ", thredhold is " << modelPath.testThredhold << std::endl; - Cli::testconvert(modelPath.MNNModel, modelPath.testDir, modelPath.testThredhold); + Cli::testconvert(modelPath.MNNModel, modelPath.testDir, modelPath.testThredhold, modelPath.testConfig); } return true; } @@ -607,13 +615,13 @@ static bool compareOutput(MNN::Express::VARP output, const std::string& directNa return true; } -int Cli::testconvert(const std::string& defaultCacheFile, const std::string& directName, float maxErrorRate) { - rapidjson::Document document; +int Cli::testconvert(const std::string& defaultCacheFile, const std::string& directName, float maxErrorRate, const std::string& backendConfigJson) { std::map inputInfo; std::map> inputShape; std::vector inputNames; std::vector outputNames; { + rapidjson::Document document; std::ostringstream jsonNameOs; jsonNameOs << directName << "/input.json"; std::ifstream fileNames(jsonNameOs.str().c_str()); @@ -664,15 +672,46 @@ int Cli::testconvert(const std::string& defaultCacheFile, const std::string& dir // If type not fount, let it failed config.backupType = MNN_FORWARD_CPU; BackendConfig backendConfig; - // config.path.outputs.push_back("ResizeBilinear_2"); - // backendConfig.power = BackendConfig::Power_High; backendConfig.precision = static_cast(1); - // backendConfig.memory = BackendConfig::Memory_High; config.backendConfig = &backendConfig; + if (!backendConfigJson.empty()) { + do { + rapidjson::Document configDoc; + std::ifstream configOs(backendConfigJson.c_str()); + if (configOs.fail()) { + break; + } + std::ostringstream outputConfigOs; + outputConfigOs << configOs.rdbuf(); + auto outputStr = outputConfigOs.str(); + configDoc.Parse(outputStr.c_str()); + if (configDoc.HasParseError()) { + MNN_ERROR("Invalid json for backend config\n"); + break; + } + if (configDoc.HasMember("backend")) { + config.type = (MNNForwardType)configDoc["backend"].GetInt(); + } + if (configDoc.HasMember("mode")) { + config.mode = configDoc["mode"].GetInt(); + } + if (configDoc.HasMember("precision")) { + config.backendConfig->precision = (MNN::BackendConfig::PrecisionMode)configDoc["precision"].GetInt(); + } + if (configDoc.HasMember("memory")) { + config.backendConfig->memory = (MNN::BackendConfig::MemoryMode)configDoc["memory"].GetInt(); + } + if (configDoc.HasMember("power")) { + config.backendConfig->power = (MNN::BackendConfig::PowerMode)configDoc["power"].GetInt(); + } + } while (false); + } + MNN::Express::Module::Config mConfig; mConfig.shapeMutable = true; std::shared_ptr rtmgr(MNN::Express::Executor::RuntimeManager::createRuntimeManager(config)); + rtmgr->setExternalFile("./convert_cache.mnn.weight"); std::shared_ptr net(MNN::Express::Module::load(inputNames, outputNames, defaultCacheFile.c_str(), rtmgr, &mConfig)); auto mInfo = net->getInfo(); std::vector inputs(mInfo->inputs.size()); diff --git a/tools/converter/source/common/writeFb.cpp b/tools/converter/source/common/writeFb.cpp index cb274dedb..178ed1122 100644 --- a/tools/converter/source/common/writeFb.cpp +++ b/tools/converter/source/common/writeFb.cpp @@ -45,6 +45,11 @@ int writeFb(std::unique_ptr& netT, const std::string& MNNModelFile, c netT->extraInfo->name = config.authCode; } + if (1) { + // load external data for some change + loadExternalData(netT, ".__convert_external_data.bin"); + } + if (config.benchmarkModel) { removeParams(netT); } diff --git a/tools/converter/source/onnx/onnxOpConverter.cpp b/tools/converter/source/onnx/onnxOpConverter.cpp index 767f8867b..d253ab4f1 100644 --- a/tools/converter/source/onnx/onnxOpConverter.cpp +++ b/tools/converter/source/onnx/onnxOpConverter.cpp @@ -170,6 +170,7 @@ MNN::DataType onnxOpConverter::convertDataType(int32_t itype) { static std::map<::onnx::TensorProto_DataType, MNN::DataType> dataTypeMap{ {onnx::TensorProto_DataType_FLOAT, MNN::DataType_DT_FLOAT}, {onnx::TensorProto_DataType_FLOAT16, MNN::DataType_DT_HALF}, + {onnx::TensorProto_DataType_BFLOAT16, MNN::DataType_DT_BFLOAT16}, {onnx::TensorProto_DataType_INT8, MNN::DataType_DT_INT8}, {onnx::TensorProto_DataType_INT32, MNN::DataType_DT_INT32}, {onnx::TensorProto_DataType_INT64, MNN::DataType_DT_INT32}, // For compability, use int32 instead of int64 @@ -346,6 +347,11 @@ MNN::BlobT* onnxOpConverter::convertTensorToBlob(const onnx::TensorProto* consta ::memcpy(constantParam->uint8s.data(), tensor_content, dataSize * sizeof(int16_t)); break; } + case onnx::TensorProto_DataType_BFLOAT16: { + constantParam->uint8s.resize(dataSize * sizeof(int16_t)); + ::memcpy(constantParam->uint8s.data(), tensor_content, dataSize * sizeof(int16_t)); + break; + } case onnx::TensorProto_DataType_FLOAT: { float* tempFloatData = (float*)tensor_content; constantParam->float32s.resize(dataSize); diff --git a/tools/converter/source/optimizer/PostConverter.cpp b/tools/converter/source/optimizer/PostConverter.cpp index 271ff835e..ea1e16eda 100644 --- a/tools/converter/source/optimizer/PostConverter.cpp +++ b/tools/converter/source/optimizer/PostConverter.cpp @@ -567,6 +567,17 @@ using namespace MNN; using namespace MNN::Express; std::unique_ptr optimizeNet(std::unique_ptr& originNet, bool forTraining, modelConfig& config) { Global::Reset(&config); + std::unique_ptr externalFile( + new std::ofstream(".__convert_external_data.bin", std::ios::binary), + [](std::ofstream* fs){ + fs->close(); + delete fs; + }); + if (externalFile.get() && externalFile->is_open() && externalFile->good()) { + config.externalFile = externalFile.get(); + } else { + config.externalFile = nullptr; + } if (originNet->sourceType == NetSource_TENSORFLOW) { GenerateSubGraph(originNet); } diff --git a/tools/converter/source/optimizer/merge/ConvertMatMulToConv2D.cpp b/tools/converter/source/optimizer/merge/ConvertMatMulToConv2D.cpp index 96da4f1d9..3d959a5eb 100644 --- a/tools/converter/source/optimizer/merge/ConvertMatMulToConv2D.cpp +++ b/tools/converter/source/optimizer/merge/ConvertMatMulToConv2D.cpp @@ -14,6 +14,7 @@ #include "MergeHelpers.hpp" #include "Utils.hpp" #include "cli.hpp" +#include "../../common/CommonUtils.hpp" namespace MNN { namespace Express { @@ -102,6 +103,10 @@ ConvertMatMulToConv2D::ConvertMatMulToConv2D() { if (biasInfo->size != numberOutput) { return false; } + // input shape may be change, don't fuse + if (bias->expr().first->inputType() == VARP::InputType::INPUT) { + return false; + } auto matmulInput = input->expr().first->inputs().at(0); auto newExpr = Expr::create(input->expr().first->extra(), {matmulInput, weight, bias}); newExpr->setName(expr->name()); @@ -253,6 +258,9 @@ ConvertMatMulToConv2D::ConvertMatMulToConv2D() { input = _ReshapeF(input, _Concat({_Unsqueeze(_Scalar(-1), {0}), inputL, _Unsqueeze(_Scalar(1), {0}), _Unsqueeze(_Scalar(1), {0})}, 0), format); } } + if (config->externalFile && info->size >= config->externalTreshold) { + RemoveAndStoreParam(dense_op, config->externalFile, config->externalOffset); + } EXPRP dense_expr = Expr::create(dense_op.get(), {input}, 1); VARP output = Variable::create(dense_expr); output->setName(expr->outputName(0) + "__matmul_converted"); diff --git a/tools/converter/source/optimizer/postconvert/FuseDupOp.cpp b/tools/converter/source/optimizer/postconvert/FuseDupOp.cpp index 6fa179035..adc9ca42e 100644 --- a/tools/converter/source/optimizer/postconvert/FuseDupOp.cpp +++ b/tools/converter/source/optimizer/postconvert/FuseDupOp.cpp @@ -6,23 +6,27 @@ // Copyright © 2018, Alibaba Group Holding Limited // +#include #include "../PostTreatUtils.hpp" #include #include using namespace MNN; class FuseDupOp : public PostConverter { public: - static bool isSameOp(const MNN::OpT* op0, const MNN::OpT* op1) { - if (op0->type != op1->type) { + static bool isSameIndexes(const MNN::OpT* op0, const MNN::OpT* op1) { + if (op0->inputIndexes != op1->inputIndexes) { return false; } - if (op0->main.type != op1->main.type) { + if (op0->outputIndexes.size() != op1->outputIndexes.size()) { return false; } - if (op0->inputIndexes != op1->inputIndexes) { + return true; + } + static bool isSameOp(const MNN::OpT* op0, const MNN::OpT* op1) { + if (op0->type != op1->type) { return false; } - if (op0->outputIndexes.size() != op1->outputIndexes.size()) { + if (op0->main.type != op1->main.type) { return false; } if (op0->main.type == OpParameter_NONE) { @@ -97,30 +101,90 @@ class FuseDupOp : public PostConverter { } } } + std::map> sameOps; for (int i=0; ioplists.size(); ++i) { auto originOp = net->oplists[i].get(); if (nullptr == originOp || updateNames.find(originOp->name) != updateNames.end()) { continue; } + std::vector sameOpIndexes; for (int j=i+1; j < net->oplists.size(); ++j) { auto judgeOp = net->oplists[j].get(); if (nullptr == judgeOp || updateNames.find(judgeOp->name) != updateNames.end()) { continue; } if (isSameOp(originOp, judgeOp)) { - auto keepOp = originOp, removeOp = judgeOp; - // outputs must keep - if (outputNames.find(removeOp->name) != outputNames.end()) { - keepOp = removeOp; - removeOp = originOp; + sameOpIndexes.emplace_back(j); + } + } + sameOps.insert(std::make_pair(i, sameOpIndexes)); + } + + bool change = false; + int step = 0; + do { + change = false; + for (int i=0; ioplists.size(); ++i) { + auto originOp = net->oplists[i].get(); + if (nullptr == originOp) { + continue; + } + auto iter = sameOps.find(i); + if (iter == sameOps.end()) { + continue; + } + for (auto j : iter->second) { + auto judgeOp = net->oplists[j].get(); + if (nullptr == judgeOp || updateNames.find(judgeOp->name) != updateNames.end()) { + continue; } - for (int v=0; voutputIndexes.size(); ++v) { - replaceIndexes.insert(std::make_pair(removeOp->outputIndexes[v], keepOp->outputIndexes[v])); + if (isSameIndexes(judgeOp, originOp)) { + auto keepOp = originOp, removeOp = judgeOp; + // outputs must keep + if (outputNames.find(removeOp->name) != outputNames.end()) { + keepOp = removeOp; + removeOp = originOp; + } + for (int v=0; voutputIndexes.size(); ++v) { + auto originIndex = removeOp->outputIndexes[v]; + auto newIndex = keepOp->outputIndexes[v]; + if (originIndex != newIndex) { + auto replaceIter = replaceIndexes.find(newIndex); + if (replaceIter != replaceIndexes.end()) { + newIndex = replaceIter->second; + } + replaceIndexes.insert(std::make_pair(originIndex, newIndex)); + } + } + net->oplists[j].reset(); + change = true; } - net->oplists[j].reset(); } } - } + auto findFinalIndex = [&](int index) -> int { + auto iter = replaceIndexes.find(index); + if (iter == replaceIndexes.end()) { + return index; + } + return iter->second; + }; + // Replace index + for (auto& op : net->oplists) { + if (nullptr == op.get()) { + continue; + } + for (int i=0; iinputIndexes.size(); ++i) { + op->inputIndexes[i] = findFinalIndex(op->inputIndexes[i]); + } + for (int i=0; ioutputIndexes.size(); ++i) { + op->outputIndexes[i] = findFinalIndex(op->outputIndexes[i]); + } + } + step++; + } while (change); +#ifdef DEBUG + MNN_PRINT("FuseDup run for %d step\n", step); +#endif // Remove nullptr op auto tempOpList = std::move(net->oplists); net->oplists.clear(); @@ -129,25 +193,6 @@ class FuseDupOp : public PostConverter { net->oplists.emplace_back(std::move(tempOpList[i])); } } - - auto findFinalIndex = [&](int index) -> int { - while (true) { - auto iter = replaceIndexes.find(index); - if (iter == replaceIndexes.end()) { - return index; - } - index = iter->second; - } - }; - // Replace index - for (auto& op : net->oplists) { - for (int i=0; iinputIndexes.size(); ++i) { - op->inputIndexes[i] = findFinalIndex(op->inputIndexes[i]); - } - for (int i=0; ioutputIndexes.size(); ++i) { - op->outputIndexes[i] = findFinalIndex(op->outputIndexes[i]); - } - } return true; } }; diff --git a/tools/cpp/IDSTEncoder.hpp b/tools/cpp/IDSTEncoder.hpp index afef60404..13c33b678 100644 --- a/tools/cpp/IDSTEncoder.hpp +++ b/tools/cpp/IDSTEncoder.hpp @@ -72,9 +72,20 @@ static void FillBuffer(char *buf, unsigned int buf_len, const char *arr, unsigne } } -static void GetWeightSet(std::set &setWeight, const float* weightData, const float* alphaData, int area, int channel, bool asymmetricQuantFlag) +static void GetWeightSet(std::set &setWeight, const float* weightData, const float* alphaData, int area, int channel, bool asymmetricQuantFlag, const int bits) { + const int offset = 1 << (bits - 1); + int min_value = -offset; + int max_value = offset - 1; setWeight.clear(); +#define LINEAR_WEIGHT_SET +#ifdef LINEAR_WEIGHT_SET + // using linear weight map + for (int i = min_value; i <= max_value; i++) { + setWeight.insert(i); + } + return; +#endif if (asymmetricQuantFlag) { for (int i = 0; i < channel; i++) { @@ -82,13 +93,13 @@ static void GetWeightSet(std::set &setWeight, const float* weightData, cons float alpha = alphaData[2*i+1]; if (alpha <= 1e-6f) { - setWeight.insert(-128); + setWeight.insert(min_value); continue; } for (int j = 0; j < area; j++) { float weight = weightData[i * area + j]; - setWeight.insert(fmax(fmin(round((weight - min) / alpha) + (-128), 127), -128)); + setWeight.insert(fmax(fmin(round((weight - min) / alpha) + min_value, max_value), min_value)); } } } else { @@ -103,14 +114,17 @@ static void GetWeightSet(std::set &setWeight, const float* weightData, cons for (int j = 0; j < area; j++) { float weight = weightData[i * area + j]; - setWeight.insert(fmax(fmin(round(weight / alpha), 127), -128)); + setWeight.insert(fmax(fmin(round(weight / alpha), max_value), min_value)); } } } } -static float GetSparsity(const float* weightData, int weightSize, unsigned int& nnz, const float* alphaData, int area, int channel, bool asymmetricQuantFlag, int iMaxStep = -1) +static float GetSparsity(const float* weightData, int weightSize, unsigned int& nnz, const float* alphaData, int area, int channel, bool asymmetricQuantFlag, const int bits, int iMaxStep = -1) { + const int offset = 1 << (bits - 1); + int min_value = -offset; + int max_value = offset - 1; nnz = 0; int iPreIdx = 0; float sparsity; @@ -119,16 +133,16 @@ static float GetSparsity(const float* weightData, int weightSize, unsigned int& { float min = alphaData[2*(i/area)]; float alpha = alphaData[2*(i/area)+1]; - int zeroQuant = -128; + int zeroQuant = min_value; if (alpha > 1e-6) { - zeroQuant = round((0.0f - min) / alpha) + (-128); + zeroQuant = round((0.0f - min) / alpha) + min_value; } float weight = weightData[i]; - int value = -128; + int value = min_value; if (alpha > 1e-6) { - value = round((weight - min) / alpha) + (-128); + value = round((weight - min) / alpha) + min_value; } if (value != zeroQuant) @@ -176,7 +190,7 @@ static unsigned int GetBestMaxStep(const float* weightData, int weightSize, unsi for (int i = 2; i < 9; i++) { unsigned int nnz = 0; - GetSparsity(weightData, weightSize, nnz, alphaData, area, channel, asymmetricQuantFlag, pow(2, i) - 1); + GetSparsity(weightData, weightSize, nnz, alphaData, area, channel, asymmetricQuantFlag, BlobDataSize, pow(2, i) - 1); size_t tmp = ceil(0.125 * nnz * i) + ceil(0.125 * nnz * BlobDataSize); if (tmp < szBestSize) { @@ -188,12 +202,12 @@ static unsigned int GetBestMaxStep(const float* weightData, int weightSize, unsi return best_nnz; } -static void WriteCQBlobs(std::ostream &out, const float* weightData, const float* alphaData, int area, int channel, bool asymmetricQuantFlag, bool& shapeUseInt32) +static void WriteCQBlobs(std::ostream &out, const float* weightData, const float* alphaData, int area, int channel, bool asymmetricQuantFlag, bool& shapeUseInt32, const int bits) { //push values into buffer //Find int values in all blobs and check; std::set setWeight; - GetWeightSet(setWeight, weightData, alphaData, area, channel, asymmetricQuantFlag); + GetWeightSet(setWeight, weightData, alphaData, area, channel, asymmetricQuantFlag, bits); int iCount = setWeight.size(); int iNeedBits = ceil(log2(iCount)); iNeedBits = iNeedBits < 1 ? 1 : iNeedBits; @@ -207,6 +221,9 @@ static void WriteCQBlobs(std::ostream &out, const float* weightData, const float { mapWeight[*it] = iIdx++; } + const int offset = 1 << (bits - 1); + int min_value = -offset; + int max_value = offset - 1; size_t buf_len = size_t(ceil(0.125 * iNeedBits * area * channel)); char *buf = new char[buf_len]; { @@ -220,10 +237,10 @@ static void WriteCQBlobs(std::ostream &out, const float* weightData, const float for (int j = 0; j < area; j++) { float weight = weightData[i * area + j]; - int value = -128; + int value = min_value; if (alpha > 1e-6f) { - value = fmax(fmin(round((weight - min) / alpha) + (-128), 127), -128); + value = fmax(fmin(round((weight - min) / alpha) + min_value, max_value), min_value); } *tmp = mapWeight[value]; tmp++; @@ -239,7 +256,7 @@ static void WriteCQBlobs(std::ostream &out, const float* weightData, const float int value = 0; if (alpha > 1e-6f) { - value = fmax(fmin(round(weight / alpha), 127), -128); + value = fmax(fmin(round(weight / alpha), max_value), min_value); } *tmp = mapWeight[value]; tmp++; @@ -270,14 +287,12 @@ static void WriteCQBlobs(std::ostream &out, const float* weightData, const float delete[] buf; } -static void WriteSparseQuanBlobs(std::ostream &out, const float* weightData, const float* alphaData, int area, int channel, bool asymmetricQuantFlag, bool& shapeUseInt32) +static void WriteSparseQuanBlobs(std::ostream &out, const float* weightData, const float* alphaData, int area, int channel, bool asymmetricQuantFlag, bool& shapeUseInt32, const int bits) { std::set setWeight; - GetWeightSet(setWeight, weightData, alphaData, area, channel, asymmetricQuantFlag); + GetWeightSet(setWeight, weightData, alphaData, area, channel, asymmetricQuantFlag, bits); int iDataNeedBits = ceil(log2(setWeight.size())); iDataNeedBits = iDataNeedBits < 1 ? 1 : iDataNeedBits; - unsigned int nnz = 0; - int weightSize = area * channel; std::map mapWeight; { int iIdx = 0; @@ -286,12 +301,17 @@ static void WriteSparseQuanBlobs(std::ostream &out, const float* weightData, con mapWeight[*it] = iIdx++; } } + unsigned int nnz = 0; + int weightSize = area * channel; unsigned char iNeedBits; nnz = GetBestMaxStep(weightData, weightSize, iNeedBits, iDataNeedBits, alphaData, area, channel, asymmetricQuantFlag); //weight buf size_t data_buf_len = size_t(ceil(0.125 * iDataNeedBits * nnz)); char* data_buf = new char[data_buf_len]; //sparse COO buf + const int offset = 1 << (bits - 1); + int min_value = -offset; + int max_value = offset - 1; size_t buf_len = size_t(ceil(0.125 * iNeedBits * nnz)); char* buf = new char[buf_len]; { //fill buf with step values; @@ -306,16 +326,16 @@ static void WriteSparseQuanBlobs(std::ostream &out, const float* weightData, con { float min = alphaData[2*(i/area)]; float alpha = alphaData[2*(i/area)+1]; - int zeroQuant = -128; + int zeroQuant = min_value; if (alpha > 1e-6) { - zeroQuant = round((0.0f - min) / alpha) + (-128); + zeroQuant = round((0.0f - min) / alpha) + min_value; } float weight = weightData[i]; - int value = -128; + int value = min_value; if (alpha > 1e-6) { - value = round((weight - min) / alpha) + (-128); + value = round((weight - min) / alpha) + min_value; } if (value != zeroQuant) @@ -396,11 +416,11 @@ static void WriteSparseQuanBlobs(std::ostream &out, const float* weightData, con } static std::unique_ptr encode(const float* weight, const std::vector& scale, int kernelSize, int kernelNum, - bool asymmetricQuantFlag, const int8_t* quantWeightPtr, const int clampMin) { + bool asymmetricQuantFlag, const int8_t* quantWeightPtr, const int clampMin, const int bits = 8) { std::ostringstream outputStringStreamCQ, outputStringStreamSQ; bool shapeUseInt32 = false; - WriteCQBlobs(outputStringStreamCQ, weight, scale.data(), kernelSize, kernelNum, asymmetricQuantFlag, shapeUseInt32); - WriteSparseQuanBlobs(outputStringStreamSQ, weight, scale.data(), kernelSize, kernelNum, asymmetricQuantFlag, shapeUseInt32); + WriteCQBlobs(outputStringStreamCQ, weight, scale.data(), kernelSize, kernelNum, asymmetricQuantFlag, shapeUseInt32, bits); + WriteSparseQuanBlobs(outputStringStreamSQ, weight, scale.data(), kernelSize, kernelNum, asymmetricQuantFlag, shapeUseInt32, bits); std::unique_ptr idst(new IDSTQuanT); auto cqStr = outputStringStreamCQ.str(); auto sqStr = outputStringStreamSQ.str(); diff --git a/tools/quantization/calibration.cpp b/tools/quantization/calibration.cpp index c7d5c1b7f..45624c377 100644 --- a/tools/quantization/calibration.cpp +++ b/tools/quantization/calibration.cpp @@ -711,9 +711,10 @@ void Calibration::_insertScale() { if (nullptr != conv2d->quanParameter.get()) { flatbuffers::FlatBufferBuilder tempBuilder; tempBuilder.Finish(IDSTQuan::Pack(tempBuilder, conv2d->quanParameter.get())); - auto quanP = flatbuffers::GetRoot( tempBuilder.GetBufferPointer()); + tempBuilder.Finish(Convolution2D::Pack(tempBuilder, conv2d)); + auto conv2d = flatbuffers::GetRoot(tempBuilder.GetBufferPointer()); bool forceFloat = true; - quanCommon = ConvolutionCommon::load(quanP, true, true); + quanCommon = ConvolutionCommon::load(conv2d, nullptr, true, true); // Back to float originWeight = quanCommon->weightFloat.get(); originWeightSize = quanCommon->weightFloat.size(); diff --git a/tools/script/convertOnnxTest.py b/tools/script/convertOnnxTest.py index 4533eb769..c409a8ebc 100755 --- a/tools/script/convertOnnxTest.py +++ b/tools/script/convertOnnxTest.py @@ -2,7 +2,10 @@ #-- coding:utf8 -- import sys +config_file = "" model_root_dir = sys.argv[1] +if len(sys.argv) > 2: + config_file = sys.argv[2] total_num = 0 import os def run_cmd(args): @@ -23,7 +26,7 @@ def run_cmd(args): if name == '.DS_Store' or name == 'ops': continue print(name) - message = run_cmd(['./TestConvertResult', 'Onnx', root_dir + '/' + name]) + message = run_cmd(['./TestConvertResult', 'Onnx', root_dir + '/' + name, config_file]) if (message.find('TEST_SUCCESS') == -1): gWrong.append(name) print(message)