diff --git a/onnxruntime/contrib_ops/webgpu/quantization/subgroup_matrix_matmul_nbits.cc b/onnxruntime/contrib_ops/webgpu/quantization/subgroup_matrix_matmul_nbits.cc index 956b369d6b34d..df417cd6ec563 100644 --- a/onnxruntime/contrib_ops/webgpu/quantization/subgroup_matrix_matmul_nbits.cc +++ b/onnxruntime/contrib_ops/webgpu/quantization/subgroup_matrix_matmul_nbits.cc @@ -5,6 +5,7 @@ #include "contrib_ops/webgpu/quantization/subgroup_matrix_matmul_nbits.h" #include "contrib_ops/webgpu/quantization/matmul_nbits_common.h" +#include "core/providers/webgpu/vendor/intel/intel_device_info.h" namespace onnxruntime { namespace contrib { @@ -299,13 +300,8 @@ Status ApplySubgroupMatrixMatMulNBits(const Tensor* a, const Tensor* b, const Te // For large M on Intel Xe, cap dispatch_y so each workgroup processes multiple // M-tiles sequentially, reducing scheduling overhead. if (M > 2048 && context.AdapterInfo().vendor == std::string_view{"intel"}) { - // Each XeCore has 4 XVE x 8 SIMD-32 hardware threads = 32 subgroups. - uint32_t hw_subgroups = 0; - if (context.AdapterInfo().architecture == std::string_view{"xe-3lpg"}) { - hw_subgroups = 384; // 12 XeCore x 32 - } else if (context.AdapterInfo().architecture == std::string_view{"xe-2lpg"}) { - hw_subgroups = 256; // 8 XeCore x 32 - } + const uint32_t hw_subgroups = + ::onnxruntime::webgpu::intel::HwSubgroups(std::string_view{context.AdapterInfo().architecture}); if (hw_subgroups > 0) { constexpr uint32_t kOccupancyFactor = 16; // empirically tuned on Xe2/Xe3 devices uint32_t target_wgs = hw_subgroups * kOccupancyFactor / (work_group_size / 32); diff --git a/onnxruntime/core/providers/webgpu/math/matmul.cc b/onnxruntime/core/providers/webgpu/math/matmul.cc index 8e769186e56fc..1e4d9b761fa68 100644 --- a/onnxruntime/core/providers/webgpu/math/matmul.cc +++ b/onnxruntime/core/providers/webgpu/math/matmul.cc @@ -13,6 +13,9 @@ #include "core/providers/webgpu/data_transfer.h" #include "core/providers/webgpu/vendor/intel/math/matmul.h" #include "core/providers/webgpu/webgpu_utils.h" +#if !defined(__wasm__) +#include "core/providers/webgpu/vendor/intel/math/subgroup_matrix_matmul.h" +#endif namespace onnxruntime { namespace webgpu { @@ -120,6 +123,17 @@ Status MatMul::ComputeInternal(ComputeContext& context) const { } bool has_bias = context.InputCount() > 2; +#if !defined(__wasm__) + // Try a vendor-optimized implementation (e.g. Intel subgroup-matrix) first. + if (impl_) { + bool handled = false; + ORT_RETURN_IF_ERROR(impl_->Compute(context, handled)); + if (handled) { + return Status::OK(); + } + } +#endif + if (helper.N() < 8 && helper.K() < 8) { // call MatMulNaiveProgram const uint32_t m = narrow(helper.M()); // left matrix first dimension @@ -174,6 +188,26 @@ Status MatMul::ComputeInternal(ComputeContext& context) const { return ComputeMatMul(&context, Activation(), inputs, output_tensor); } +Status MatMul::PrePackInternal(ComputeContextBase& context, + const Tensor& tensor, + int input_idx, + AllocatorPtr alloc, + /*out*/ bool& is_packed) { + is_packed = false; +#if !defined(__wasm__) + // Create the vendor-optimized implementation once based on device capabilities. + if (!impl_) { + impl_ = intel::CreateSubgroupMatrixMatMulImpl(context, *this); + } +#else + ORT_UNUSED_PARAMETER(context); +#endif + ORT_UNUSED_PARAMETER(tensor); + ORT_UNUSED_PARAMETER(input_idx); + ORT_UNUSED_PARAMETER(alloc); + return Status::OK(); +} + Status ComputeMatMul(ComputeContext* context, const Activation& activation, std::vector& inputs, Tensor* output_tensor, bool is_channels_last, const TensorShape& input_a_reshape, diff --git a/onnxruntime/core/providers/webgpu/math/matmul.h b/onnxruntime/core/providers/webgpu/math/matmul.h index 89101c60a1b6c..bcc6aadb01a69 100644 --- a/onnxruntime/core/providers/webgpu/math/matmul.h +++ b/onnxruntime/core/providers/webgpu/math/matmul.h @@ -3,6 +3,8 @@ #pragma once +#include + #include "core/providers/webgpu/webgpu_kernel.h" #include "core/providers/webgpu/program.h" #include "core/providers/cpu/math/matmul_helper.h" @@ -29,12 +31,41 @@ MatMulFillBiasOrZeroBeforeSplitKProgram CreateMatMulFillBiasOrZeroBeforeSplitKPr class MatMul final : public WebGpuKernel { public: + // Abstract base class for alternative optimized MatMul implementations. + // Implementations can provide optimized computation paths by deriving from this class. + class MatMulOptImpl { + public: + explicit MatMulOptImpl(const MatMul& parent) : parent_(parent) {} + virtual ~MatMulOptImpl() = default; + + // Called during Compute phase to execute implementation-specific computation. + // @param context The WebGPU compute context. + // @param handled Output parameter. Set to true if this implementation handled the computation. + // @return Status::OK() on success, or an error status on failure. + virtual Status Compute(ComputeContext& context, + /*out*/ bool& handled) = 0; + + protected: + const MatMul& parent_; + }; + MatMul(const OpKernelInfo& info) : WebGpuKernel{info} {} Status ComputeInternal(ComputeContext& context) const override; + + Status PrePackInternal(ComputeContextBase& context, + const Tensor& tensor, + int input_idx, + AllocatorPtr alloc, + /*out*/ bool& is_packed) override; + constexpr static uint32_t MATMUL_PACKED_WORKGROUP_SIZE_X = 8; constexpr static uint32_t MATMUL_PACKED_WORKGROUP_SIZE_Y = 8; constexpr static uint32_t MATMUL_PACKED_WORKGROUP_SIZE_Z = 1; + + private: + // Alternative optimized implementation (created during PrePack if applicable) + mutable std::unique_ptr impl_; }; class MatMulNaiveProgram final : public Program { diff --git a/onnxruntime/core/providers/webgpu/vendor/intel/intel_device_info.cc b/onnxruntime/core/providers/webgpu/vendor/intel/intel_device_info.cc new file mode 100644 index 0000000000000..43b58eae8613b --- /dev/null +++ b/onnxruntime/core/providers/webgpu/vendor/intel/intel_device_info.cc @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#if !defined(__wasm__) + +#include "core/providers/webgpu/vendor/intel/intel_device_info.h" + +#include + +namespace onnxruntime { +namespace webgpu { +namespace intel { + +uint32_t HwSubgroups(std::string_view arch) { + if (arch == std::string_view{"xe-3lpg"}) { + return 384; // 12 Xe cores x 32 + } + if (arch == std::string_view{"xe-2lpg"}) { + return 256; // 8 Xe cores x 32 + } + return 0; // unknown architecture; caller decides the fallback +} + +bool IsSubgroupMatrixConfigSupported(const ComputeContextBase& context, uint32_t m, uint32_t n, uint32_t k) { + if (!context.HasFeature(wgpu::FeatureName::ChromiumExperimentalSubgroupMatrix)) { + return false; + } + const wgpu::AdapterInfo& adapter_info = context.AdapterInfo(); + if (adapter_info.subgroupMinSize != 16 || adapter_info.subgroupMaxSize != 32) { + return false; + } + const wgpu::AdapterPropertiesSubgroupMatrixConfigs& configs = context.SubgroupMatrixConfigs(); + return std::any_of(configs.configs, configs.configs + configs.configCount, + [m, n, k](const auto& c) { + return c.componentType == wgpu::SubgroupMatrixComponentType::F16 && + c.resultComponentType == wgpu::SubgroupMatrixComponentType::F16 && + c.M == m && c.N == n && c.K == k; + }); +} + +} // namespace intel +} // namespace webgpu +} // namespace onnxruntime + +#endif // !defined(__wasm__) diff --git a/onnxruntime/core/providers/webgpu/vendor/intel/intel_device_info.h b/onnxruntime/core/providers/webgpu/vendor/intel/intel_device_info.h new file mode 100644 index 0000000000000..ad66935bd7dc8 --- /dev/null +++ b/onnxruntime/core/providers/webgpu/vendor/intel/intel_device_info.h @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +#if !defined(__wasm__) + +#include +#include + +#include "core/providers/webgpu/compute_context.h" + +namespace onnxruntime { +namespace webgpu { +namespace intel { + +// Approximate number of subgroups an Intel Xe GPU keeps resident at once. Each Xe +// core runs 4 XVE x 8 SIMD32 hardware threads = 32 subgroups, so the count is +// (number of Xe cores) x 32. Returns 0 for an unrecognized architecture so each +// caller can apply its own fallback policy. +uint32_t HwSubgroups(std::string_view arch); + +// Returns true if the device exposes an m x n x k F16/F16 subgroup matrix config +// within the Intel Xe subgroup size range (min 16, max 32). +bool IsSubgroupMatrixConfigSupported(const ComputeContextBase& context, uint32_t m, uint32_t n, uint32_t k); + +} // namespace intel +} // namespace webgpu +} // namespace onnxruntime + +#endif // !defined(__wasm__) diff --git a/onnxruntime/core/providers/webgpu/vendor/intel/math/subgroup_matrix_matmul.cc b/onnxruntime/core/providers/webgpu/vendor/intel/math/subgroup_matrix_matmul.cc new file mode 100644 index 0000000000000..8ee14442b5fb7 --- /dev/null +++ b/onnxruntime/core/providers/webgpu/vendor/intel/math/subgroup_matrix_matmul.cc @@ -0,0 +1,281 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#if !defined(__wasm__) + +#include "core/providers/webgpu/vendor/intel/math/subgroup_matrix_matmul.h" + +#include +#include +#include +#include +#include + +#include "core/common/narrow.h" +#include "core/providers/webgpu/compute_context.h" +#include "core/providers/webgpu/shader_helper.h" +#include "core/providers/webgpu/vendor/intel/intel_device_info.h" + +// Pretuned tile + split-K table baked into the build; consulted before the +// heuristic in SelectConfig. +#include "core/providers/webgpu/vendor/intel/math/subgroup_matrix_matmul_tuned.inc" + +namespace onnxruntime { +namespace webgpu { +namespace intel { + +namespace { + +// Tile + split-K configuration chosen for one MatMul problem. +struct SgMatMulConfig { + uint32_t tile_m; // output rows per workgroup (multiple of kSubgroupMatrixM) + uint32_t tile_n; // output cols per workgroup (multiple of kSubgroupMatrixN) + uint32_t split_k; // subgroups cooperating along K (1 = no split) +}; + +bool IsFloat16(const Tensor& tensor) { + return tensor.GetElementType() == ONNX_NAMESPACE::TensorProto_DataType_FLOAT16; +} + +constexpr uint32_t kTileMCandidates[] = {8, 16, 32, 64}; +constexpr uint32_t kTileNCandidates[] = {16, 32, 64}; +constexpr uint32_t kSplitKCandidates[] = {1, 2, 4, 8}; +// Scratch holds split_k partial f16 tiles; cap keeps it within the SLM budget. +constexpr uint32_t kMaxScratchElems = 16384; // 32 KB + +// Hard constraints a config must satisfy to run correctly for this problem. +// Used to reject a pretuned entry whose bucket does not fit the actual K. +bool IsConfigValid(const SgMatMulConfig& c, uint32_t K) { + if (c.tile_m == 0 || c.tile_n == 0 || + c.tile_m % kSubgroupMatrixM != 0 || c.tile_n % kSubgroupMatrixN != 0) { + return false; + } + const uint32_t k_blocks = K / kSubgroupMatrixK; + if (c.split_k == 0 || c.split_k > k_blocks) { + return false; + } + return c.tile_m * c.tile_n * c.split_k <= kMaxScratchElems; +} + +// Fallback config selection when no pretuned entry applies. The goal is to keep +// the GPU busy without over-subscribing it: pick the tile whose independent +// output-tile grid just fills the resident subgroups, preferring larger tiles +// (more data reuse) among those that qualify, and only using smaller tiles when +// nothing else would fill the machine. Split-K then adds cooperative subgroups +// to reach up to 2x occupancy, subject to the per-subgroup K-work minimum and +// the scratch (SLM) budget. +SgMatMulConfig HeuristicConfig(std::string_view arch, uint32_t M, uint32_t N, uint32_t K) { + // HwSubgroups returns 0 for an unrecognized arch; fall back to a conservative + // default so the occupancy target is still reasonable. + uint32_t hw = HwSubgroups(arch); + if (hw == 0) { + hw = 256; + } + const uint32_t k_blocks = K / kSubgroupMatrixK; + auto tile_count = [](uint32_t dim, uint32_t tile) { return (dim + tile - 1) / tile; }; + + // Choose tile_m x tile_n. Skip tiles larger than the dimension (they only waste + // lanes). Prefer the largest-area tile whose grid already fills the hardware + // (num_tiles >= hw); if none does, take the tile that yields the most + // independent tiles (largest area breaks ties). + uint32_t tile_m = kTileMCandidates[0]; + uint32_t tile_n = kTileNCandidates[0]; + uint32_t best_tiles = 0; // most output tiles seen so far (used only while under-filling) + uint32_t best_area = 0; // tile_m * tile_n of the current pick (tie-breaker: larger reuse wins) + bool filled = false; // true once some tile reaches num_tiles >= hw (machine is filled) + for (uint32_t tm : kTileMCandidates) { + if (tm > M && tm != kTileMCandidates[0]) { + continue; + } + for (uint32_t tn : kTileNCandidates) { + if (tn > N && tn != kTileNCandidates[0]) { + continue; + } + const uint32_t tiles = tile_count(M, tm) * tile_count(N, tn); + const uint32_t area = tm * tn; + if (tiles >= hw) { + // This tile fills the machine on its own. Among all such tiles, keep the + // largest-area one (best operand reuse); this also supersedes any + // under-filling pick made earlier. + if (!filled || area > best_area) { + filled = true; + best_area = area; + tile_m = tm; + tile_n = tn; + } + } else if (!filled && (tiles > best_tiles || (tiles == best_tiles && area > best_area))) { + // No tile has filled the machine yet: chase occupancy by maximizing the + // number of independent tiles, breaking ties toward larger area. + best_tiles = tiles; + best_area = area; + tile_m = tm; + tile_n = tn; + } + } + } + + // Add split-K only while the independent tiles under-fill the machine; cap the + // total at 2x hardware and keep enough K work per subgroup and scratch budget. + const uint32_t num_tiles = tile_count(M, tile_m) * tile_count(N, tile_n); + constexpr uint32_t kMinBlocksPerSplit = 2; + uint32_t split_k = 1; + for (uint32_t cand : kSplitKCandidates) { + if (k_blocks >= cand * kMinBlocksPerSplit && + num_tiles * cand <= 2 * hw && + tile_m * tile_n * cand <= kMaxScratchElems) { + split_k = cand; + } + } + return {tile_m, tile_n, split_k}; +} + +// Looks up a pretuned config for this problem in the baked-in table +// (subgroup_matrix_matmul_tuned.inc). The table holds one sub-table per GPU +// architecture; we match `arch`, then map each problem dimension to the smallest +// grid value >= it (clamped to the largest bucket). Returns nullopt when the +// arch is not covered or no entry matches. +std::optional LookupPretunedConfig(std::string_view arch, uint32_t M, uint32_t N, uint32_t K) { + for (const auto& table : sgmm_tuned::kArchTables) { + if (table.arch != arch) { + continue; + } + auto bucket = [&table](uint32_t d) -> int { + int last = 0; + for (size_t i = 0; i < table.grid_count; ++i) { + if (table.grid[i] >= d) { + return static_cast(i); + } + last = static_cast(i); + } + return last; + }; + const int mi = bucket(M); + const int ni = bucket(N); + const int ki = bucket(K); + for (size_t i = 0; i < table.entry_count; ++i) { + const auto& e = table.entries[i]; + if (e.mi == mi && e.ni == ni && e.ki == ki) { + return SgMatMulConfig{e.tile_m, e.tile_n, e.split_k}; + } + } + break; // arch matched but no entry for this problem; fall through to heuristic + } + return std::nullopt; +} + +// Chooses the tile + split-K config for the given problem: use the pretuned +// table entry when one exists and fits, otherwise fall back to the heuristic. +SgMatMulConfig SelectConfig(std::string_view arch, uint32_t M, uint32_t N, uint32_t K) { + if (const auto tuned = LookupPretunedConfig(arch, M, N, K); tuned && IsConfigValid(*tuned, K)) { + return *tuned; + } + return HeuristicConfig(arch, M, N, K); +} + +// Intel subgroup-matrix MatMul implementation. Loads both A and B directly from +// global memory and runs the subgroup-matrix kernel during Compute. +class SubgroupMatrixMatMulImpl final : public MatMul::MatMulOptImpl { + public: + explicit SubgroupMatrixMatMulImpl(const MatMul& parent) : MatMul::MatMulOptImpl(parent) {} + + Status Compute(ComputeContext& context, /*out*/ bool& handled) override { + handled = false; + + const auto* a = context.Input(0); + const auto* b = context.Input(1); + // B must be a 2D KxN weight; A may be batched ([..., M, K]) and its leading + // dims are folded into M. Anything else falls back. + const auto& a_shape = a->Shape(); + const auto& b_shape = b->Shape(); + if (a_shape.NumDimensions() < 2 || b_shape.NumDimensions() != 2 || + !IsFloat16(*a) || !IsFloat16(*b)) { + return Status::OK(); + } + + const uint32_t K = narrow(a_shape[a_shape.NumDimensions() - 1]); + const uint32_t M = narrow(a_shape.Size() / static_cast(K)); + const uint32_t N = narrow(b_shape[1]); + // K must match B; only K needs to align to the subgroup tiling. M and N + // partial tiles are handled by bounds-checked stores in the kernel. + if (narrow(b_shape[0]) != K || K % kSubgroupMatrixK != 0) { + return Status::OK(); + } + + TensorShapeVector output_dims{a_shape.GetDims().begin(), a_shape.GetDims().end()}; + output_dims.back() = static_cast(N); + TensorShape output_shape{output_dims}; + auto* output = context.Output(0, output_shape); + if (output->Shape().Size() == 0) { + handled = true; + return Status::OK(); + } + + const bool has_bias = context.InputCount() > 2; + const Tensor* bias = has_bias ? context.Input(2) : nullptr; + + // Pick the tile shape and split-K factor: pretuned table when available, + // otherwise the built-in heuristic. + const std::string_view arch = std::string_view{context.AdapterInfo().architecture}; + const SgMatMulConfig config = SelectConfig(arch, M, N, K); + const uint32_t tile_m = config.tile_m; + const uint32_t tile_n = config.tile_n; + const uint32_t split_k = config.split_k; + const uint32_t sg_mat_count_m = tile_m / kSubgroupMatrixM; + const uint32_t sg_mat_count_n = tile_n / kSubgroupMatrixN; + const uint32_t dispatch_x = (N + tile_n - 1) / tile_n; + const uint32_t dispatch_y = (M + tile_m - 1) / tile_m; + + SubgroupMatrixMatMulProgram program{has_bias, sg_mat_count_m, sg_mat_count_n, split_k}; + program.SetWorkgroupSize(kSubgroupMatrixSubgroupSize * split_k); + program.SetDispatchGroupSize(dispatch_x, dispatch_y, 1); + program.CacheHint(has_bias, sg_mat_count_m, sg_mat_count_n, split_k) + .AddInputs({{a, ProgramTensorMetadataDependency::TypeAndRank, 1}, + {b, ProgramTensorMetadataDependency::TypeAndRank, 1}}) + .AddOutput({output, ProgramTensorMetadataDependency::Rank, output->Shape(), 1}) + .AddUniformVariables({{M}, {N}, {K}}); + if (has_bias) { + program.AddInput({bias, ProgramTensorMetadataDependency::None}); + } + ORT_RETURN_IF_ERROR(context.RunProgram(program)); + + handled = true; + return Status::OK(); + } +}; + +} // namespace + +Status SubgroupMatrixMatMulProgram::GenerateShaderCode(ShaderHelper& shader) const { + shader.AddInput("input_a", ShaderUsage::UseUniform); + shader.AddInput("input_b", ShaderUsage::UseUniform); + if (has_bias_) { + shader.AddInput("bias", ShaderUsage::UseUniform); + } + const auto& output = shader.AddOutput("output", ShaderUsage::UseUniform | ShaderUsage::UseElementTypeAlias); + return WGSL_TEMPLATE_APPLY(shader, "vendor/intel/math/subgroup_matrix_matmul.wgsl.template", + WGSL_TEMPLATE_PARAMETER(has_bias, has_bias_), + WGSL_TEMPLATE_PARAMETER(sg_mat_count_m, sg_mat_count_m_), + WGSL_TEMPLATE_PARAMETER(sg_mat_count_n, sg_mat_count_n_), + WGSL_TEMPLATE_PARAMETER(sg_mat_k, kSubgroupMatrixK), + WGSL_TEMPLATE_PARAMETER(sg_mat_m, kSubgroupMatrixM), + WGSL_TEMPLATE_PARAMETER(sg_mat_n, kSubgroupMatrixN), + WGSL_TEMPLATE_PARAMETER(split_k, split_k_), + WGSL_TEMPLATE_VARIABLE(output, output)); +} + +std::unique_ptr CreateSubgroupMatrixMatMulImpl(const ComputeContextBase& context, + const MatMul& parent) { + if (context.AdapterInfo().vendor != std::string_view{"intel"}) { + return nullptr; + } + if (!IsSubgroupMatrixConfigSupported(context, kSubgroupMatrixM, kSubgroupMatrixN, kSubgroupMatrixK)) { + return nullptr; + } + return std::make_unique(parent); +} + +} // namespace intel +} // namespace webgpu +} // namespace onnxruntime + +#endif // !defined(__wasm__) diff --git a/onnxruntime/core/providers/webgpu/vendor/intel/math/subgroup_matrix_matmul.h b/onnxruntime/core/providers/webgpu/vendor/intel/math/subgroup_matrix_matmul.h new file mode 100644 index 0000000000000..f924ec2e9c4f4 --- /dev/null +++ b/onnxruntime/core/providers/webgpu/vendor/intel/math/subgroup_matrix_matmul.h @@ -0,0 +1,66 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +#if !defined(__wasm__) + +#include + +#include "core/providers/webgpu/math/matmul.h" +#include "core/providers/webgpu/program.h" +#include "core/providers/webgpu/shader_helper.h" + +namespace onnxruntime { +namespace webgpu { +namespace intel { + +// Subgroup matrix configuration used by this implementation (Intel Xe2/Xe3, F16). +constexpr uint32_t kSubgroupMatrixM = 8; +constexpr uint32_t kSubgroupMatrixN = 16; +constexpr uint32_t kSubgroupMatrixK = 16; +// One or more 32-lane subgroups compute one output tile. The tile shape is chosen +// adaptively per call from these candidate sizes (must be multiples of the +// subgroup-matrix M/N): TileM in {8,16,32,64}, TileN in {16,32,64}. When the +// output has few tiles, the K dimension is split across up to kSubgroupMatrixMaxSplitK +// subgroups that each accumulate part of K and are reduced in shared memory; the +// workgroup then has kSubgroupMatrixSubgroupSize * split_k threads. +constexpr uint32_t kSubgroupMatrixSubgroupSize = 32; +constexpr uint32_t kSubgroupMatrixMaxTileM = 64; +constexpr uint32_t kSubgroupMatrixMaxTileN = 64; +constexpr uint32_t kSubgroupMatrixMaxSplitK = 8; + +// Computes Y = A @ B (+ optional bias) using subgroupMatrixMultiplyAccumulate. +// sg_mat_count_m/n select how many subgroup matrices the tile spans along M/N. +// split_k is the number of subgroups that cooperatively reduce the K dimension. +class SubgroupMatrixMatMulProgram final : public Program { + public: + SubgroupMatrixMatMulProgram(bool has_bias, uint32_t sg_mat_count_m, uint32_t sg_mat_count_n, uint32_t split_k) + : Program{"SubgroupMatrixMatMul"}, + has_bias_(has_bias), + sg_mat_count_m_(sg_mat_count_m), + sg_mat_count_n_(sg_mat_count_n), + split_k_(split_k) {} + Status GenerateShaderCode(ShaderHelper& sh) const override; + WEBGPU_PROGRAM_DEFINE_UNIFORM_VARIABLES({"M", ProgramUniformVariableDataType::Uint32}, + {"N", ProgramUniformVariableDataType::Uint32}, + {"K", ProgramUniformVariableDataType::Uint32}); + + private: + const bool has_bias_; + const uint32_t sg_mat_count_m_; + const uint32_t sg_mat_count_n_; + const uint32_t split_k_; +}; + +// Creates the Intel subgroup-matrix MatMul implementation if this device supports +// the required 8x16x16 F16 subgroup matrix configuration. Returns nullptr otherwise, +// in which case the caller falls back to the default MatMul path. +std::unique_ptr CreateSubgroupMatrixMatMulImpl(const ComputeContextBase& context, + const MatMul& parent); + +} // namespace intel +} // namespace webgpu +} // namespace onnxruntime + +#endif // !defined(__wasm__) diff --git a/onnxruntime/core/providers/webgpu/vendor/intel/math/subgroup_matrix_matmul.wgsl.template b/onnxruntime/core/providers/webgpu/vendor/intel/math/subgroup_matrix_matmul.wgsl.template new file mode 100644 index 0000000000000..486cfee29eca1 --- /dev/null +++ b/onnxruntime/core/providers/webgpu/vendor/intel/math/subgroup_matrix_matmul.wgsl.template @@ -0,0 +1,458 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// Intel SubgroupMatrix MatMul kernel (8x16x16 config, F16). +// +// Computes Y[MxN] = A[MxK] @ B[KxN] using subgroupMatrixMultiplyAccumulate. +// +// A: activation, loaded directly from global memory as a left operand +// (subgroup_matrix_left), row-major with stride K. +// B: weight, loaded directly from global memory in plain row-major KxN layout as a +// right operand (subgroup_matrix_right) with stride N. +// +// Workgroup: split_k subgroups x 32 lanes (split_k in {1,2,4,8}). +// Tile: kTileM x kTileN, chosen adaptively by the host. Each subgroup computes +// the whole tile as kSgMatCountM x kSgMatCountN subgroup matrices. +// kSgMatCountM is in {1,2,4,8} (TileM in {8,16,32,64}) and kSgMatCountN is in +// {1,2,4} (TileN in {16,32,64}). K iterated in +// sg_mat_k blocks. When split_k > 1 the K blocks are distributed round-robin +// across the subgroups, each accumulates its own partial tile in shared memory, +// and the partials are summed at write-out. +// +// Preconditions enforced by the host: K % sg_mat_k == 0. M and N may be any +// size; partial tiles are handled by bounds-checked stores. Out-of-range A/B +// loads return zero (WebGPU bounds checking). + +#param has_bias +#param sg_mat_k +#param sg_mat_m +#param sg_mat_n +#param sg_mat_count_m +#param sg_mat_count_n +#param split_k + +#use .setByOffset + +const kSgMatM: u32 = u32(sg_mat_m); // Subgroup matrix M dimension (rows) +const kSgMatN: u32 = u32(sg_mat_n); // Subgroup matrix N dimension (columns) +const kSgMatK: u32 = u32(sg_mat_k); // Subgroup matrix K dimension (reduction) +const kSgMatCountM: u32 = u32(sg_mat_count_m); // Number of subgroup matrices per tile along M +const kSgMatCountN: u32 = u32(sg_mat_count_n); // Number of subgroup matrices per tile along N +const kTileM: u32 = kSgMatM * kSgMatCountM; // Tile size along M (output rows per workgroup) +const kTileN: u32 = kSgMatN * kSgMatCountN; // Tile size along N (output columns per workgroup) +const kSplitK: u32 = u32(split_k); // Number of subgroups cooperating along K +const kSubgroupSize: u32 = 32; // Lanes per subgroup + +// Scratch space for kSplitK partial [kTileM, kTileN] tiles, row-major. Each +// split-K subgroup accumulates its slice of K into its own slot; the slots are +// summed during write-back. Storing here also lets us write to global memory +// with M/N bounds checks for dimensions that are not multiples of the tile size. +var scratch: array; + +$MAIN { + let n_tile = workgroup_id.x; // which kTileN-wide column tile + let global_base_n = n_tile * kTileN; + let m_tile = workgroup_id.y; // which kTileM-tall row tile + let m_base = m_tile * kTileM; + let k_blocks = uniforms.K / kSgMatK; + let sg_index = local_idx / kSubgroupSize; // which split-K subgroup (0..kSplitK-1) + let sg_lane = local_idx % kSubgroupSize; // lane within the subgroup (0..kSubgroupSize-1) + let sg_scratch_base = sg_index * kTileM * kTileN; // this subgroup's scratch slot + + // Accumulators: kSgMatCountM M blocks x kSgMatCountN N blocks (sg_mat_c_). + var sg_mat_c0_0: subgroup_matrix_result; +#if sg_mat_count_n >= 2 + var sg_mat_c0_1: subgroup_matrix_result; +#endif +#if sg_mat_count_n >= 3 + var sg_mat_c0_2: subgroup_matrix_result; +#endif +#if sg_mat_count_n >= 4 + var sg_mat_c0_3: subgroup_matrix_result; +#endif +#if sg_mat_count_m >= 2 + var sg_mat_c1_0: subgroup_matrix_result; +#if sg_mat_count_n >= 2 + var sg_mat_c1_1: subgroup_matrix_result; +#endif +#if sg_mat_count_n >= 3 + var sg_mat_c1_2: subgroup_matrix_result; +#endif +#if sg_mat_count_n >= 4 + var sg_mat_c1_3: subgroup_matrix_result; +#endif +#endif +#if sg_mat_count_m >= 3 + var sg_mat_c2_0: subgroup_matrix_result; +#if sg_mat_count_n >= 2 + var sg_mat_c2_1: subgroup_matrix_result; +#endif +#if sg_mat_count_n >= 3 + var sg_mat_c2_2: subgroup_matrix_result; +#endif +#if sg_mat_count_n >= 4 + var sg_mat_c2_3: subgroup_matrix_result; +#endif +#endif +#if sg_mat_count_m >= 4 + var sg_mat_c3_0: subgroup_matrix_result; +#if sg_mat_count_n >= 2 + var sg_mat_c3_1: subgroup_matrix_result; +#endif +#if sg_mat_count_n >= 3 + var sg_mat_c3_2: subgroup_matrix_result; +#endif +#if sg_mat_count_n >= 4 + var sg_mat_c3_3: subgroup_matrix_result; +#endif +#endif +#if sg_mat_count_m >= 5 + var sg_mat_c4_0: subgroup_matrix_result; +#if sg_mat_count_n >= 2 + var sg_mat_c4_1: subgroup_matrix_result; +#endif +#if sg_mat_count_n >= 3 + var sg_mat_c4_2: subgroup_matrix_result; +#endif +#if sg_mat_count_n >= 4 + var sg_mat_c4_3: subgroup_matrix_result; +#endif +#endif +#if sg_mat_count_m >= 6 + var sg_mat_c5_0: subgroup_matrix_result; +#if sg_mat_count_n >= 2 + var sg_mat_c5_1: subgroup_matrix_result; +#endif +#if sg_mat_count_n >= 3 + var sg_mat_c5_2: subgroup_matrix_result; +#endif +#if sg_mat_count_n >= 4 + var sg_mat_c5_3: subgroup_matrix_result; +#endif +#endif +#if sg_mat_count_m >= 7 + var sg_mat_c6_0: subgroup_matrix_result; +#if sg_mat_count_n >= 2 + var sg_mat_c6_1: subgroup_matrix_result; +#endif +#if sg_mat_count_n >= 3 + var sg_mat_c6_2: subgroup_matrix_result; +#endif +#if sg_mat_count_n >= 4 + var sg_mat_c6_3: subgroup_matrix_result; +#endif +#endif +#if sg_mat_count_m >= 8 + var sg_mat_c7_0: subgroup_matrix_result; +#if sg_mat_count_n >= 2 + var sg_mat_c7_1: subgroup_matrix_result; +#endif +#if sg_mat_count_n >= 3 + var sg_mat_c7_2: subgroup_matrix_result; +#endif +#if sg_mat_count_n >= 4 + var sg_mat_c7_3: subgroup_matrix_result; +#endif +#endif + + for (var kb: u32 = sg_index; kb < k_blocks; kb = kb + kSplitK) { + // Load the B right tiles for this K block (KxN row-major, stride N). + let b_base = kb * kSgMatK * uniforms.N + global_base_n; + var sg_mat_b0: subgroup_matrix_right = + subgroupMatrixLoad>( + &input_b, b_base + 0 * kSgMatN, false, uniforms.N); +#if sg_mat_count_n >= 2 + var sg_mat_b1: subgroup_matrix_right = + subgroupMatrixLoad>( + &input_b, b_base + 1 * kSgMatN, false, uniforms.N); +#endif +#if sg_mat_count_n >= 3 + var sg_mat_b2: subgroup_matrix_right = + subgroupMatrixLoad>( + &input_b, b_base + 2 * kSgMatN, false, uniforms.N); +#endif +#if sg_mat_count_n >= 4 + var sg_mat_b3: subgroup_matrix_right = + subgroupMatrixLoad>( + &input_b, b_base + 3 * kSgMatN, false, uniforms.N); +#endif + + // Load the A left tiles (one per M block), row-major with stride K. + let a_col = kb * kSgMatK; + var sg_mat_a0: subgroup_matrix_left = + subgroupMatrixLoad>( + &input_a, (m_base + 0 * kSgMatM) * uniforms.K + a_col, false, uniforms.K); +#if sg_mat_count_m >= 2 + var sg_mat_a1: subgroup_matrix_left = + subgroupMatrixLoad>( + &input_a, (m_base + 1 * kSgMatM) * uniforms.K + a_col, false, uniforms.K); +#endif +#if sg_mat_count_m >= 3 + var sg_mat_a2: subgroup_matrix_left = + subgroupMatrixLoad>( + &input_a, (m_base + 2 * kSgMatM) * uniforms.K + a_col, false, uniforms.K); +#endif +#if sg_mat_count_m >= 4 + var sg_mat_a3: subgroup_matrix_left = + subgroupMatrixLoad>( + &input_a, (m_base + 3 * kSgMatM) * uniforms.K + a_col, false, uniforms.K); +#endif +#if sg_mat_count_m >= 5 + var sg_mat_a4: subgroup_matrix_left = + subgroupMatrixLoad>( + &input_a, (m_base + 4 * kSgMatM) * uniforms.K + a_col, false, uniforms.K); +#endif +#if sg_mat_count_m >= 6 + var sg_mat_a5: subgroup_matrix_left = + subgroupMatrixLoad>( + &input_a, (m_base + 5 * kSgMatM) * uniforms.K + a_col, false, uniforms.K); +#endif +#if sg_mat_count_m >= 7 + var sg_mat_a6: subgroup_matrix_left = + subgroupMatrixLoad>( + &input_a, (m_base + 6 * kSgMatM) * uniforms.K + a_col, false, uniforms.K); +#endif +#if sg_mat_count_m >= 8 + var sg_mat_a7: subgroup_matrix_left = + subgroupMatrixLoad>( + &input_a, (m_base + 7 * kSgMatM) * uniforms.K + a_col, false, uniforms.K); +#endif + + // Accumulate every (M block, N block) pair. + sg_mat_c0_0 = subgroupMatrixMultiplyAccumulate(sg_mat_a0, sg_mat_b0, sg_mat_c0_0); +#if sg_mat_count_n >= 2 + sg_mat_c0_1 = subgroupMatrixMultiplyAccumulate(sg_mat_a0, sg_mat_b1, sg_mat_c0_1); +#endif +#if sg_mat_count_n >= 3 + sg_mat_c0_2 = subgroupMatrixMultiplyAccumulate(sg_mat_a0, sg_mat_b2, sg_mat_c0_2); +#endif +#if sg_mat_count_n >= 4 + sg_mat_c0_3 = subgroupMatrixMultiplyAccumulate(sg_mat_a0, sg_mat_b3, sg_mat_c0_3); +#endif +#if sg_mat_count_m >= 2 + sg_mat_c1_0 = subgroupMatrixMultiplyAccumulate(sg_mat_a1, sg_mat_b0, sg_mat_c1_0); +#if sg_mat_count_n >= 2 + sg_mat_c1_1 = subgroupMatrixMultiplyAccumulate(sg_mat_a1, sg_mat_b1, sg_mat_c1_1); +#endif +#if sg_mat_count_n >= 3 + sg_mat_c1_2 = subgroupMatrixMultiplyAccumulate(sg_mat_a1, sg_mat_b2, sg_mat_c1_2); +#endif +#if sg_mat_count_n >= 4 + sg_mat_c1_3 = subgroupMatrixMultiplyAccumulate(sg_mat_a1, sg_mat_b3, sg_mat_c1_3); +#endif +#endif +#if sg_mat_count_m >= 3 + sg_mat_c2_0 = subgroupMatrixMultiplyAccumulate(sg_mat_a2, sg_mat_b0, sg_mat_c2_0); +#if sg_mat_count_n >= 2 + sg_mat_c2_1 = subgroupMatrixMultiplyAccumulate(sg_mat_a2, sg_mat_b1, sg_mat_c2_1); +#endif +#if sg_mat_count_n >= 3 + sg_mat_c2_2 = subgroupMatrixMultiplyAccumulate(sg_mat_a2, sg_mat_b2, sg_mat_c2_2); +#endif +#if sg_mat_count_n >= 4 + sg_mat_c2_3 = subgroupMatrixMultiplyAccumulate(sg_mat_a2, sg_mat_b3, sg_mat_c2_3); +#endif +#endif +#if sg_mat_count_m >= 4 + sg_mat_c3_0 = subgroupMatrixMultiplyAccumulate(sg_mat_a3, sg_mat_b0, sg_mat_c3_0); +#if sg_mat_count_n >= 2 + sg_mat_c3_1 = subgroupMatrixMultiplyAccumulate(sg_mat_a3, sg_mat_b1, sg_mat_c3_1); +#endif +#if sg_mat_count_n >= 3 + sg_mat_c3_2 = subgroupMatrixMultiplyAccumulate(sg_mat_a3, sg_mat_b2, sg_mat_c3_2); +#endif +#if sg_mat_count_n >= 4 + sg_mat_c3_3 = subgroupMatrixMultiplyAccumulate(sg_mat_a3, sg_mat_b3, sg_mat_c3_3); +#endif +#endif +#if sg_mat_count_m >= 5 + sg_mat_c4_0 = subgroupMatrixMultiplyAccumulate(sg_mat_a4, sg_mat_b0, sg_mat_c4_0); +#if sg_mat_count_n >= 2 + sg_mat_c4_1 = subgroupMatrixMultiplyAccumulate(sg_mat_a4, sg_mat_b1, sg_mat_c4_1); +#endif +#if sg_mat_count_n >= 3 + sg_mat_c4_2 = subgroupMatrixMultiplyAccumulate(sg_mat_a4, sg_mat_b2, sg_mat_c4_2); +#endif +#if sg_mat_count_n >= 4 + sg_mat_c4_3 = subgroupMatrixMultiplyAccumulate(sg_mat_a4, sg_mat_b3, sg_mat_c4_3); +#endif +#endif +#if sg_mat_count_m >= 6 + sg_mat_c5_0 = subgroupMatrixMultiplyAccumulate(sg_mat_a5, sg_mat_b0, sg_mat_c5_0); +#if sg_mat_count_n >= 2 + sg_mat_c5_1 = subgroupMatrixMultiplyAccumulate(sg_mat_a5, sg_mat_b1, sg_mat_c5_1); +#endif +#if sg_mat_count_n >= 3 + sg_mat_c5_2 = subgroupMatrixMultiplyAccumulate(sg_mat_a5, sg_mat_b2, sg_mat_c5_2); +#endif +#if sg_mat_count_n >= 4 + sg_mat_c5_3 = subgroupMatrixMultiplyAccumulate(sg_mat_a5, sg_mat_b3, sg_mat_c5_3); +#endif +#endif +#if sg_mat_count_m >= 7 + sg_mat_c6_0 = subgroupMatrixMultiplyAccumulate(sg_mat_a6, sg_mat_b0, sg_mat_c6_0); +#if sg_mat_count_n >= 2 + sg_mat_c6_1 = subgroupMatrixMultiplyAccumulate(sg_mat_a6, sg_mat_b1, sg_mat_c6_1); +#endif +#if sg_mat_count_n >= 3 + sg_mat_c6_2 = subgroupMatrixMultiplyAccumulate(sg_mat_a6, sg_mat_b2, sg_mat_c6_2); +#endif +#if sg_mat_count_n >= 4 + sg_mat_c6_3 = subgroupMatrixMultiplyAccumulate(sg_mat_a6, sg_mat_b3, sg_mat_c6_3); +#endif +#endif +#if sg_mat_count_m >= 8 + sg_mat_c7_0 = subgroupMatrixMultiplyAccumulate(sg_mat_a7, sg_mat_b0, sg_mat_c7_0); +#if sg_mat_count_n >= 2 + sg_mat_c7_1 = subgroupMatrixMultiplyAccumulate(sg_mat_a7, sg_mat_b1, sg_mat_c7_1); +#endif +#if sg_mat_count_n >= 3 + sg_mat_c7_2 = subgroupMatrixMultiplyAccumulate(sg_mat_a7, sg_mat_b2, sg_mat_c7_2); +#endif +#if sg_mat_count_n >= 4 + sg_mat_c7_3 = subgroupMatrixMultiplyAccumulate(sg_mat_a7, sg_mat_b3, sg_mat_c7_3); +#endif +#endif + } + + // Store this subgroup's partial results into its split-K slot of scratch, + // laid out as kSplitK x [kTileM, kTileN] row-major. Offset of block (mi, ni) + // within a slot = mi * kSgMatM * kTileN + ni * kSgMatN, stride kTileN. + subgroupMatrixStore(&scratch, sg_scratch_base + 0 * kSgMatM * kTileN + 0 * kSgMatN, sg_mat_c0_0, false, kTileN); +#if sg_mat_count_n >= 2 + subgroupMatrixStore(&scratch, sg_scratch_base + 0 * kSgMatM * kTileN + 1 * kSgMatN, sg_mat_c0_1, false, kTileN); +#endif +#if sg_mat_count_n >= 3 + subgroupMatrixStore(&scratch, sg_scratch_base + 0 * kSgMatM * kTileN + 2 * kSgMatN, sg_mat_c0_2, false, kTileN); +#endif +#if sg_mat_count_n >= 4 + subgroupMatrixStore(&scratch, sg_scratch_base + 0 * kSgMatM * kTileN + 3 * kSgMatN, sg_mat_c0_3, false, kTileN); +#endif +#if sg_mat_count_m >= 2 + subgroupMatrixStore(&scratch, sg_scratch_base + 1 * kSgMatM * kTileN + 0 * kSgMatN, sg_mat_c1_0, false, kTileN); +#if sg_mat_count_n >= 2 + subgroupMatrixStore(&scratch, sg_scratch_base + 1 * kSgMatM * kTileN + 1 * kSgMatN, sg_mat_c1_1, false, kTileN); +#endif +#if sg_mat_count_n >= 3 + subgroupMatrixStore(&scratch, sg_scratch_base + 1 * kSgMatM * kTileN + 2 * kSgMatN, sg_mat_c1_2, false, kTileN); +#endif +#if sg_mat_count_n >= 4 + subgroupMatrixStore(&scratch, sg_scratch_base + 1 * kSgMatM * kTileN + 3 * kSgMatN, sg_mat_c1_3, false, kTileN); +#endif +#endif +#if sg_mat_count_m >= 3 + subgroupMatrixStore(&scratch, sg_scratch_base + 2 * kSgMatM * kTileN + 0 * kSgMatN, sg_mat_c2_0, false, kTileN); +#if sg_mat_count_n >= 2 + subgroupMatrixStore(&scratch, sg_scratch_base + 2 * kSgMatM * kTileN + 1 * kSgMatN, sg_mat_c2_1, false, kTileN); +#endif +#if sg_mat_count_n >= 3 + subgroupMatrixStore(&scratch, sg_scratch_base + 2 * kSgMatM * kTileN + 2 * kSgMatN, sg_mat_c2_2, false, kTileN); +#endif +#if sg_mat_count_n >= 4 + subgroupMatrixStore(&scratch, sg_scratch_base + 2 * kSgMatM * kTileN + 3 * kSgMatN, sg_mat_c2_3, false, kTileN); +#endif +#endif +#if sg_mat_count_m >= 4 + subgroupMatrixStore(&scratch, sg_scratch_base + 3 * kSgMatM * kTileN + 0 * kSgMatN, sg_mat_c3_0, false, kTileN); +#if sg_mat_count_n >= 2 + subgroupMatrixStore(&scratch, sg_scratch_base + 3 * kSgMatM * kTileN + 1 * kSgMatN, sg_mat_c3_1, false, kTileN); +#endif +#if sg_mat_count_n >= 3 + subgroupMatrixStore(&scratch, sg_scratch_base + 3 * kSgMatM * kTileN + 2 * kSgMatN, sg_mat_c3_2, false, kTileN); +#endif +#if sg_mat_count_n >= 4 + subgroupMatrixStore(&scratch, sg_scratch_base + 3 * kSgMatM * kTileN + 3 * kSgMatN, sg_mat_c3_3, false, kTileN); +#endif +#endif +#if sg_mat_count_m >= 5 + subgroupMatrixStore(&scratch, sg_scratch_base + 4 * kSgMatM * kTileN + 0 * kSgMatN, sg_mat_c4_0, false, kTileN); +#if sg_mat_count_n >= 2 + subgroupMatrixStore(&scratch, sg_scratch_base + 4 * kSgMatM * kTileN + 1 * kSgMatN, sg_mat_c4_1, false, kTileN); +#endif +#if sg_mat_count_n >= 3 + subgroupMatrixStore(&scratch, sg_scratch_base + 4 * kSgMatM * kTileN + 2 * kSgMatN, sg_mat_c4_2, false, kTileN); +#endif +#if sg_mat_count_n >= 4 + subgroupMatrixStore(&scratch, sg_scratch_base + 4 * kSgMatM * kTileN + 3 * kSgMatN, sg_mat_c4_3, false, kTileN); +#endif +#endif +#if sg_mat_count_m >= 6 + subgroupMatrixStore(&scratch, sg_scratch_base + 5 * kSgMatM * kTileN + 0 * kSgMatN, sg_mat_c5_0, false, kTileN); +#if sg_mat_count_n >= 2 + subgroupMatrixStore(&scratch, sg_scratch_base + 5 * kSgMatM * kTileN + 1 * kSgMatN, sg_mat_c5_1, false, kTileN); +#endif +#if sg_mat_count_n >= 3 + subgroupMatrixStore(&scratch, sg_scratch_base + 5 * kSgMatM * kTileN + 2 * kSgMatN, sg_mat_c5_2, false, kTileN); +#endif +#if sg_mat_count_n >= 4 + subgroupMatrixStore(&scratch, sg_scratch_base + 5 * kSgMatM * kTileN + 3 * kSgMatN, sg_mat_c5_3, false, kTileN); +#endif +#endif +#if sg_mat_count_m >= 7 + subgroupMatrixStore(&scratch, sg_scratch_base + 6 * kSgMatM * kTileN + 0 * kSgMatN, sg_mat_c6_0, false, kTileN); +#if sg_mat_count_n >= 2 + subgroupMatrixStore(&scratch, sg_scratch_base + 6 * kSgMatM * kTileN + 1 * kSgMatN, sg_mat_c6_1, false, kTileN); +#endif +#if sg_mat_count_n >= 3 + subgroupMatrixStore(&scratch, sg_scratch_base + 6 * kSgMatM * kTileN + 2 * kSgMatN, sg_mat_c6_2, false, kTileN); +#endif +#if sg_mat_count_n >= 4 + subgroupMatrixStore(&scratch, sg_scratch_base + 6 * kSgMatM * kTileN + 3 * kSgMatN, sg_mat_c6_3, false, kTileN); +#endif +#endif +#if sg_mat_count_m >= 8 + subgroupMatrixStore(&scratch, sg_scratch_base + 7 * kSgMatM * kTileN + 0 * kSgMatN, sg_mat_c7_0, false, kTileN); +#if sg_mat_count_n >= 2 + subgroupMatrixStore(&scratch, sg_scratch_base + 7 * kSgMatM * kTileN + 1 * kSgMatN, sg_mat_c7_1, false, kTileN); +#endif +#if sg_mat_count_n >= 3 + subgroupMatrixStore(&scratch, sg_scratch_base + 7 * kSgMatM * kTileN + 2 * kSgMatN, sg_mat_c7_2, false, kTileN); +#endif +#if sg_mat_count_n >= 4 + subgroupMatrixStore(&scratch, sg_scratch_base + 7 * kSgMatM * kTileN + 3 * kSgMatN, sg_mat_c7_3, false, kTileN); +#endif +#endif + +#if split_k >= 2 + // Make all subgroups' partial tiles visible before the reduction. + workgroupBarrier(); + + // Sum pass: a single subgroup reduces the kSplitK partial [kTileM, kTileN] + // tiles into slot 0 of scratch. Each lane owns a strided set of element + // positions and sums that position across all kSplitK slots. Writing slot 0 + // is safe: a position is only overwritten by the same lane that already read + // it as the slot-0 term of its own sum. + if (sg_index == 0u) { + for (var idx: u32 = sg_lane; idx < kTileM * kTileN; idx = idx + kSubgroupSize) { + var acc: f16 = f16(0); + for (var s: u32 = 0; s < kSplitK; s++) { + acc += scratch[s * kTileM * kTileN + idx]; + } + scratch[idx] = acc; + } + } + // Publish the summed tile (slot 0) to every subgroup for the write-out pass. + workgroupBarrier(); +#endif + + // Write-out pass: every subgroup writes out whole M-rows from the summed tile + // in slot 0, striding by kSplitK subgroups (subgroup sg_index handles rows + // sg_index, sg_index + kSplitK, ...). The subgroup's lanes cooperate on a + // row's N elements (strided by the subgroup size). M and N are bounds-checked + // so non-multiple dimensions only write valid data. + let n_count = min(kTileN, uniforms.N - global_base_n); + for (var r: u32 = sg_index; r < kTileM; r = r + kSplitK) { + let global_m = m_base + r; + if (global_m < uniforms.M) { + let scratch_base = r * kTileN; + let out_base = global_m * uniforms.N + global_base_n; + for (var i: u32 = sg_lane; i < n_count; i = i + kSubgroupSize) { + var val = output_element_t(scratch[scratch_base + i]); +#if has_bias + val += bias[global_base_n + i]; +#endif + output.setByOffset(out_base + i, val); + } + } + } +} // MAIN diff --git a/onnxruntime/core/providers/webgpu/vendor/intel/math/subgroup_matrix_matmul_tuned.inc b/onnxruntime/core/providers/webgpu/vendor/intel/math/subgroup_matrix_matmul_tuned.inc new file mode 100644 index 0000000000000..284b94e543ffd --- /dev/null +++ b/onnxruntime/core/providers/webgpu/vendor/intel/math/subgroup_matrix_matmul_tuned.inc @@ -0,0 +1,3873 @@ +// Auto-generated by tools/python/gen_sgmm_tuned_table.py. Do not edit. +// Source: offline WebGpuSgMatMulTuning sweeps, one table per GPU architecture. + +namespace sgmm_tuned { + +struct Entry { + uint16_t mi; // index into the arch grid for M + uint16_t ni; // index into the arch grid for N + uint16_t ki; // index into the arch grid for K + uint16_t tile_m; + uint16_t tile_n; + uint16_t split_k; +}; + +struct ArchTable { + std::string_view arch; + const uint32_t* grid; + size_t grid_count; + const Entry* entries; + size_t entry_count; +}; + +namespace arch_xe_3lpg { // arch: xe-3lpg +constexpr uint32_t kGrid[] = {8, 16, 32, 48, 64, 96, 128, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096}; +constexpr Entry kEntries[] = { + {0, 0, 1, 8, 16, 1}, + {0, 0, 2, 8, 16, 1}, + {0, 0, 3, 8, 16, 2}, + {0, 0, 4, 8, 16, 4}, + {0, 0, 5, 8, 16, 2}, + {0, 0, 6, 8, 16, 8}, + {0, 0, 7, 8, 32, 8}, + {0, 0, 8, 8, 16, 4}, + {0, 0, 9, 8, 16, 4}, + {0, 0, 10, 16, 16, 8}, + {0, 0, 11, 8, 16, 4}, + {0, 0, 12, 16, 16, 8}, + {0, 0, 13, 8, 16, 4}, + {0, 0, 14, 8, 16, 4}, + {0, 0, 15, 8, 16, 8}, + {0, 1, 1, 8, 16, 1}, + {0, 1, 2, 8, 16, 2}, + {0, 1, 3, 8, 16, 1}, + {0, 1, 4, 8, 16, 4}, + {0, 1, 5, 8, 16, 2}, + {0, 1, 6, 8, 16, 8}, + {0, 1, 7, 8, 16, 4}, + {0, 1, 8, 8, 16, 8}, + {0, 1, 9, 16, 16, 8}, + {0, 1, 10, 8, 16, 4}, + {0, 1, 11, 8, 32, 8}, + {0, 1, 12, 16, 16, 8}, + {0, 1, 13, 16, 32, 8}, + {0, 1, 14, 8, 16, 4}, + {0, 1, 15, 32, 16, 8}, + {0, 2, 1, 8, 16, 1}, + {0, 2, 2, 8, 16, 1}, + {0, 2, 3, 8, 32, 1}, + {0, 2, 4, 8, 32, 2}, + {0, 2, 5, 8, 32, 4}, + {0, 2, 6, 8, 32, 4}, + {0, 2, 7, 8, 16, 8}, + {0, 2, 8, 8, 16, 4}, + {0, 2, 9, 8, 16, 4}, + {0, 2, 10, 16, 16, 8}, + {0, 2, 11, 8, 16, 8}, + {0, 2, 12, 16, 16, 8}, + {0, 2, 13, 8, 32, 8}, + {0, 2, 14, 8, 32, 8}, + {0, 2, 15, 8, 16, 8}, + {0, 3, 1, 8, 32, 1}, + {0, 3, 2, 8, 32, 1}, + {0, 3, 3, 8, 16, 2}, + {0, 3, 4, 8, 16, 4}, + {0, 3, 5, 8, 32, 4}, + {0, 3, 6, 8, 16, 8}, + {0, 3, 7, 8, 16, 4}, + {0, 3, 8, 8, 32, 8}, + {0, 3, 9, 8, 16, 8}, + {0, 3, 10, 8, 16, 8}, + {0, 3, 11, 8, 32, 8}, + {0, 3, 12, 16, 16, 8}, + {0, 3, 13, 8, 16, 8}, + {0, 3, 14, 32, 16, 8}, + {0, 3, 15, 32, 16, 8}, + {0, 4, 1, 8, 32, 1}, + {0, 4, 2, 8, 16, 1}, + {0, 4, 3, 8, 16, 1}, + {0, 4, 4, 8, 16, 4}, + {0, 4, 5, 8, 16, 4}, + {0, 4, 6, 8, 16, 8}, + {0, 4, 7, 8, 16, 4}, + {0, 4, 8, 8, 16, 8}, + {0, 4, 9, 8, 16, 4}, + {0, 4, 10, 8, 16, 8}, + {0, 4, 11, 8, 16, 8}, + {0, 4, 12, 16, 16, 8}, + {0, 4, 13, 8, 16, 8}, + {0, 4, 14, 16, 16, 8}, + {0, 4, 15, 8, 32, 8}, + {0, 5, 1, 8, 32, 1}, + {0, 5, 2, 8, 16, 2}, + {0, 5, 3, 8, 32, 2}, + {0, 5, 4, 8, 16, 4}, + {0, 5, 5, 8, 32, 4}, + {0, 5, 6, 8, 32, 4}, + {0, 5, 7, 8, 32, 8}, + {0, 5, 8, 8, 32, 8}, + {0, 5, 9, 8, 16, 4}, + {0, 5, 10, 8, 64, 8}, + {0, 5, 11, 8, 16, 4}, + {0, 5, 12, 8, 16, 8}, + {0, 5, 13, 8, 32, 8}, + {0, 5, 14, 16, 16, 8}, + {0, 5, 15, 8, 16, 8}, + {0, 6, 1, 16, 32, 1}, + {0, 6, 2, 16, 16, 1}, + {0, 6, 3, 8, 16, 2}, + {0, 6, 4, 8, 16, 4}, + {0, 6, 5, 8, 16, 2}, + {0, 6, 6, 8, 16, 8}, + {0, 6, 7, 16, 32, 8}, + {0, 6, 8, 16, 16, 8}, + {0, 6, 9, 8, 16, 8}, + {0, 6, 10, 8, 16, 4}, + {0, 6, 11, 16, 16, 8}, + {0, 6, 12, 16, 16, 8}, + {0, 6, 13, 32, 16, 8}, + {0, 6, 14, 8, 32, 8}, + {0, 6, 15, 16, 32, 8}, + {0, 7, 1, 8, 32, 1}, + {0, 7, 2, 8, 16, 2}, + {0, 7, 3, 8, 16, 1}, + {0, 7, 4, 8, 16, 4}, + {0, 7, 5, 8, 32, 4}, + {0, 7, 6, 8, 32, 4}, + {0, 7, 7, 8, 16, 4}, + {0, 7, 8, 8, 16, 4}, + {0, 7, 9, 16, 16, 8}, + {0, 7, 10, 8, 16, 4}, + {0, 7, 11, 8, 16, 4}, + {0, 7, 12, 8, 16, 4}, + {0, 7, 13, 16, 16, 8}, + {0, 7, 14, 8, 32, 8}, + {0, 7, 15, 16, 16, 8}, + {0, 8, 1, 8, 32, 1}, + {0, 8, 2, 8, 32, 1}, + {0, 8, 3, 8, 16, 1}, + {0, 8, 4, 16, 32, 4}, + {0, 8, 5, 8, 16, 4}, + {0, 8, 6, 8, 16, 4}, + {0, 8, 7, 8, 16, 4}, + {0, 8, 8, 8, 32, 8}, + {0, 8, 9, 8, 16, 4}, + {0, 8, 10, 16, 32, 8}, + {0, 8, 11, 8, 32, 8}, + {0, 8, 12, 8, 16, 4}, + {0, 8, 13, 8, 16, 4}, + {0, 8, 14, 8, 16, 4}, + {0, 8, 15, 16, 16, 8}, + {0, 9, 1, 8, 32, 1}, + {0, 9, 2, 8, 32, 1}, + {0, 9, 3, 8, 32, 1}, + {0, 9, 4, 8, 16, 2}, + {0, 9, 5, 8, 16, 2}, + {0, 9, 6, 8, 32, 8}, + {0, 9, 7, 8, 32, 8}, + {0, 9, 8, 16, 32, 8}, + {0, 9, 9, 8, 32, 8}, + {0, 9, 10, 8, 32, 8}, + {0, 9, 11, 8, 32, 8}, + {0, 9, 12, 8, 32, 8}, + {0, 9, 13, 8, 32, 8}, + {0, 9, 14, 8, 16, 4}, + {0, 9, 15, 8, 16, 4}, + {0, 10, 1, 8, 32, 1}, + {0, 10, 2, 8, 32, 1}, + {0, 10, 3, 8, 16, 1}, + {0, 10, 4, 8, 16, 4}, + {0, 10, 5, 8, 16, 4}, + {0, 10, 6, 8, 32, 8}, + {0, 10, 7, 8, 32, 8}, + {0, 10, 8, 8, 16, 4}, + {0, 10, 9, 8, 16, 4}, + {0, 10, 10, 8, 32, 4}, + {0, 10, 11, 8, 32, 8}, + {0, 10, 12, 16, 16, 8}, + {0, 10, 13, 8, 16, 4}, + {0, 10, 14, 8, 32, 8}, + {0, 10, 15, 16, 16, 8}, + {0, 11, 1, 8, 16, 1}, + {0, 11, 2, 8, 16, 1}, + {0, 11, 3, 8, 16, 2}, + {0, 11, 4, 8, 32, 1}, + {0, 11, 5, 8, 16, 1}, + {0, 11, 6, 8, 16, 4}, + {0, 11, 7, 8, 16, 4}, + {0, 11, 8, 8, 32, 8}, + {0, 11, 9, 8, 64, 8}, + {0, 11, 10, 8, 16, 4}, + {0, 11, 11, 8, 32, 8}, + {0, 11, 12, 8, 32, 8}, + {0, 11, 13, 16, 16, 4}, + {0, 11, 14, 8, 64, 8}, + {0, 11, 15, 8, 32, 8}, + {0, 12, 1, 8, 32, 1}, + {0, 12, 2, 8, 32, 1}, + {0, 12, 3, 8, 32, 1}, + {0, 12, 4, 8, 32, 1}, + {0, 12, 5, 8, 32, 4}, + {0, 12, 6, 8, 32, 8}, + {0, 12, 7, 8, 16, 4}, + {0, 12, 8, 8, 32, 4}, + {0, 12, 9, 8, 16, 4}, + {0, 12, 10, 16, 32, 8}, + {0, 12, 11, 8, 32, 4}, + {0, 12, 12, 8, 64, 4}, + {0, 12, 13, 16, 64, 8}, + {0, 12, 14, 16, 32, 8}, + {0, 12, 15, 16, 32, 8}, + {0, 13, 1, 8, 16, 1}, + {0, 13, 2, 8, 32, 1}, + {0, 13, 3, 16, 32, 1}, + {0, 13, 4, 8, 16, 2}, + {0, 13, 5, 8, 32, 4}, + {0, 13, 6, 8, 32, 2}, + {0, 13, 7, 8, 16, 2}, + {0, 13, 8, 8, 16, 4}, + {0, 13, 9, 8, 16, 4}, + {0, 13, 10, 8, 16, 4}, + {0, 13, 11, 8, 32, 4}, + {0, 13, 12, 8, 32, 4}, + {0, 13, 13, 16, 32, 4}, + {0, 13, 14, 8, 64, 8}, + {0, 13, 15, 8, 16, 4}, + {0, 14, 1, 8, 32, 1}, + {0, 14, 2, 8, 16, 2}, + {0, 14, 3, 8, 16, 2}, + {0, 14, 4, 8, 16, 1}, + {0, 14, 5, 8, 16, 1}, + {0, 14, 6, 8, 32, 1}, + {0, 14, 7, 8, 16, 8}, + {0, 14, 8, 16, 16, 8}, + {0, 14, 9, 8, 32, 4}, + {0, 14, 10, 8, 16, 8}, + {0, 14, 11, 8, 32, 2}, + {0, 14, 12, 16, 32, 4}, + {0, 14, 13, 8, 16, 4}, + {0, 14, 14, 8, 32, 4}, + {0, 14, 15, 8, 16, 4}, + {0, 15, 1, 8, 16, 1}, + {0, 15, 2, 8, 16, 1}, + {0, 15, 3, 8, 32, 1}, + {0, 15, 4, 8, 32, 4}, + {0, 15, 5, 8, 32, 2}, + {0, 15, 6, 8, 16, 4}, + {0, 15, 7, 16, 16, 8}, + {0, 15, 8, 16, 32, 8}, + {0, 15, 9, 16, 64, 8}, + {0, 15, 10, 16, 16, 4}, + {0, 15, 11, 8, 16, 1}, + {0, 15, 12, 16, 16, 4}, + {0, 15, 13, 8, 64, 4}, + {0, 15, 14, 8, 64, 4}, + {0, 15, 15, 8, 64, 4}, + {1, 0, 1, 8, 16, 1}, + {1, 0, 2, 8, 16, 1}, + {1, 0, 3, 16, 16, 1}, + {1, 0, 4, 8, 16, 4}, + {1, 0, 5, 8, 16, 2}, + {1, 0, 6, 16, 16, 8}, + {1, 0, 7, 8, 16, 8}, + {1, 0, 8, 8, 16, 4}, + {1, 0, 9, 8, 16, 4}, + {1, 0, 10, 8, 16, 4}, + {1, 0, 11, 8, 32, 8}, + {1, 0, 12, 8, 32, 8}, + {1, 0, 13, 8, 32, 8}, + {1, 0, 14, 32, 16, 8}, + {1, 0, 15, 8, 64, 8}, + {1, 1, 1, 8, 16, 1}, + {1, 1, 2, 8, 32, 2}, + {1, 1, 3, 8, 16, 1}, + {1, 1, 4, 8, 16, 4}, + {1, 1, 5, 8, 16, 4}, + {1, 1, 6, 8, 16, 4}, + {1, 1, 7, 8, 16, 4}, + {1, 1, 8, 8, 16, 4}, + {1, 1, 9, 8, 16, 8}, + {1, 1, 10, 8, 32, 8}, + {1, 1, 11, 16, 32, 8}, + {1, 1, 12, 32, 16, 8}, + {1, 1, 13, 16, 16, 8}, + {1, 1, 14, 16, 32, 8}, + {1, 1, 15, 16, 16, 8}, + {1, 2, 1, 8, 32, 1}, + {1, 2, 2, 8, 32, 1}, + {1, 2, 3, 8, 16, 1}, + {1, 2, 4, 16, 16, 4}, + {1, 2, 5, 8, 32, 4}, + {1, 2, 6, 8, 16, 8}, + {1, 2, 7, 8, 16, 4}, + {1, 2, 8, 16, 16, 8}, + {1, 2, 9, 8, 32, 8}, + {1, 2, 10, 8, 16, 8}, + {1, 2, 11, 16, 32, 8}, + {1, 2, 12, 8, 16, 8}, + {1, 2, 13, 8, 16, 8}, + {1, 2, 14, 8, 16, 8}, + {1, 2, 15, 8, 32, 8}, + {1, 3, 1, 8, 16, 1}, + {1, 3, 2, 8, 16, 2}, + {1, 3, 3, 8, 16, 2}, + {1, 3, 4, 8, 16, 2}, + {1, 3, 5, 8, 32, 4}, + {1, 3, 6, 8, 16, 8}, + {1, 3, 7, 8, 16, 8}, + {1, 3, 8, 8, 32, 8}, + {1, 3, 9, 16, 16, 8}, + {1, 3, 10, 16, 16, 8}, + {1, 3, 11, 16, 16, 8}, + {1, 3, 12, 8, 16, 8}, + {1, 3, 13, 8, 32, 8}, + {1, 3, 14, 8, 16, 8}, + {1, 3, 15, 32, 16, 8}, + {1, 4, 1, 8, 32, 1}, + {1, 4, 2, 8, 16, 2}, + {1, 4, 3, 8, 16, 2}, + {1, 4, 4, 8, 32, 4}, + {1, 4, 5, 16, 16, 4}, + {1, 4, 6, 8, 32, 4}, + {1, 4, 7, 8, 32, 8}, + {1, 4, 8, 8, 16, 8}, + {1, 4, 9, 8, 16, 8}, + {1, 4, 10, 8, 16, 4}, + {1, 4, 11, 8, 16, 8}, + {1, 4, 12, 8, 16, 4}, + {1, 4, 13, 16, 16, 8}, + {1, 4, 14, 16, 32, 8}, + {1, 4, 15, 8, 16, 8}, + {1, 5, 1, 8, 16, 1}, + {1, 5, 2, 8, 16, 1}, + {1, 5, 3, 8, 16, 1}, + {1, 5, 4, 8, 16, 4}, + {1, 5, 5, 8, 16, 4}, + {1, 5, 6, 8, 16, 4}, + {1, 5, 7, 16, 32, 8}, + {1, 5, 8, 8, 32, 8}, + {1, 5, 9, 8, 16, 4}, + {1, 5, 10, 8, 16, 8}, + {1, 5, 11, 16, 32, 8}, + {1, 5, 12, 16, 16, 8}, + {1, 5, 13, 8, 32, 8}, + {1, 5, 14, 32, 16, 8}, + {1, 5, 15, 8, 16, 8}, + {1, 6, 1, 8, 32, 1}, + {1, 6, 2, 8, 32, 1}, + {1, 6, 3, 8, 32, 2}, + {1, 6, 4, 8, 16, 4}, + {1, 6, 5, 8, 16, 4}, + {1, 6, 6, 8, 16, 4}, + {1, 6, 7, 8, 32, 8}, + {1, 6, 8, 8, 16, 4}, + {1, 6, 9, 8, 16, 8}, + {1, 6, 10, 8, 32, 8}, + {1, 6, 11, 8, 16, 4}, + {1, 6, 12, 8, 16, 8}, + {1, 6, 13, 8, 64, 8}, + {1, 6, 14, 8, 16, 4}, + {1, 6, 15, 8, 16, 4}, + {1, 7, 1, 8, 16, 1}, + {1, 7, 2, 8, 16, 2}, + {1, 7, 3, 8, 16, 2}, + {1, 7, 4, 8, 32, 4}, + {1, 7, 5, 8, 16, 4}, + {1, 7, 6, 8, 32, 8}, + {1, 7, 7, 8, 16, 4}, + {1, 7, 8, 8, 32, 4}, + {1, 7, 9, 16, 32, 8}, + {1, 7, 10, 8, 16, 8}, + {1, 7, 11, 32, 16, 8}, + {1, 7, 12, 32, 16, 8}, + {1, 7, 13, 32, 16, 8}, + {1, 7, 14, 8, 32, 4}, + {1, 7, 15, 16, 16, 8}, + {1, 8, 1, 8, 16, 1}, + {1, 8, 2, 8, 32, 1}, + {1, 8, 3, 8, 32, 2}, + {1, 8, 4, 8, 16, 2}, + {1, 8, 5, 8, 16, 4}, + {1, 8, 6, 16, 16, 8}, + {1, 8, 7, 8, 16, 4}, + {1, 8, 8, 8, 16, 8}, + {1, 8, 9, 8, 32, 4}, + {1, 8, 10, 16, 16, 4}, + {1, 8, 11, 16, 64, 8}, + {1, 8, 12, 8, 16, 4}, + {1, 8, 13, 16, 32, 8}, + {1, 8, 14, 16, 16, 8}, + {1, 8, 15, 16, 16, 8}, + {1, 9, 1, 8, 32, 1}, + {1, 9, 2, 8, 32, 2}, + {1, 9, 3, 8, 16, 1}, + {1, 9, 4, 8, 32, 4}, + {1, 9, 5, 8, 16, 4}, + {1, 9, 6, 8, 16, 2}, + {1, 9, 7, 16, 16, 4}, + {1, 9, 8, 8, 64, 8}, + {1, 9, 9, 8, 32, 8}, + {1, 9, 10, 16, 32, 8}, + {1, 9, 11, 8, 32, 8}, + {1, 9, 12, 16, 64, 8}, + {1, 9, 13, 16, 32, 8}, + {1, 9, 14, 16, 32, 8}, + {1, 9, 15, 32, 16, 8}, + {1, 10, 1, 8, 16, 1}, + {1, 10, 2, 8, 32, 2}, + {1, 10, 3, 8, 32, 2}, + {1, 10, 4, 16, 32, 4}, + {1, 10, 5, 8, 16, 4}, + {1, 10, 6, 8, 64, 8}, + {1, 10, 7, 16, 16, 8}, + {1, 10, 8, 8, 64, 8}, + {1, 10, 9, 8, 32, 2}, + {1, 10, 10, 8, 32, 4}, + {1, 10, 11, 16, 32, 4}, + {1, 10, 12, 8, 16, 4}, + {1, 10, 13, 16, 32, 8}, + {1, 10, 14, 16, 16, 4}, + {1, 10, 15, 16, 32, 8}, + {1, 11, 1, 8, 16, 1}, + {1, 11, 2, 8, 32, 2}, + {1, 11, 3, 8, 16, 1}, + {1, 11, 4, 8, 16, 1}, + {1, 11, 5, 8, 32, 1}, + {1, 11, 6, 8, 16, 2}, + {1, 11, 7, 16, 64, 4}, + {1, 11, 8, 16, 16, 4}, + {1, 11, 9, 16, 16, 8}, + {1, 11, 10, 16, 16, 8}, + {1, 11, 11, 8, 64, 4}, + {1, 11, 12, 16, 16, 8}, + {1, 11, 13, 16, 64, 8}, + {1, 11, 14, 16, 16, 8}, + {1, 11, 15, 16, 16, 4}, + {1, 12, 1, 8, 32, 1}, + {1, 12, 2, 8, 16, 1}, + {1, 12, 3, 16, 32, 1}, + {1, 12, 4, 8, 16, 4}, + {1, 12, 5, 8, 32, 1}, + {1, 12, 6, 8, 32, 2}, + {1, 12, 7, 16, 16, 8}, + {1, 12, 8, 16, 32, 2}, + {1, 12, 9, 16, 32, 4}, + {1, 12, 10, 8, 32, 8}, + {1, 12, 11, 8, 32, 8}, + {1, 12, 12, 8, 16, 4}, + {1, 12, 13, 8, 16, 4}, + {1, 12, 14, 8, 32, 4}, + {1, 12, 15, 8, 32, 8}, + {1, 13, 1, 8, 16, 1}, + {1, 13, 2, 8, 32, 2}, + {1, 13, 3, 8, 16, 1}, + {1, 13, 4, 16, 16, 1}, + {1, 13, 5, 8, 16, 4}, + {1, 13, 6, 16, 32, 1}, + {1, 13, 7, 8, 32, 8}, + {1, 13, 8, 8, 32, 8}, + {1, 13, 9, 16, 32, 4}, + {1, 13, 10, 8, 32, 8}, + {1, 13, 11, 16, 64, 2}, + {1, 13, 12, 32, 32, 8}, + {1, 13, 13, 8, 32, 8}, + {1, 13, 14, 8, 64, 4}, + {1, 13, 15, 16, 16, 4}, + {1, 14, 1, 8, 16, 1}, + {1, 14, 2, 8, 32, 1}, + {1, 14, 3, 16, 16, 2}, + {1, 14, 4, 32, 32, 4}, + {1, 14, 5, 8, 16, 2}, + {1, 14, 6, 16, 32, 2}, + {1, 14, 7, 8, 32, 8}, + {1, 14, 8, 8, 16, 8}, + {1, 14, 9, 8, 32, 4}, + {1, 14, 10, 8, 32, 8}, + {1, 14, 11, 8, 16, 4}, + {1, 14, 12, 16, 64, 8}, + {1, 14, 13, 8, 32, 8}, + {1, 14, 14, 16, 32, 8}, + {1, 14, 15, 16, 32, 8}, + {1, 15, 1, 16, 32, 1}, + {1, 15, 2, 8, 32, 1}, + {1, 15, 3, 8, 32, 1}, + {1, 15, 4, 32, 32, 2}, + {1, 15, 5, 8, 32, 4}, + {1, 15, 6, 8, 64, 4}, + {1, 15, 7, 16, 16, 4}, + {1, 15, 8, 8, 32, 4}, + {1, 15, 9, 16, 16, 4}, + {1, 15, 10, 8, 32, 8}, + {1, 15, 11, 16, 32, 4}, + {1, 15, 12, 8, 32, 4}, + {1, 15, 13, 16, 16, 2}, + {1, 15, 14, 16, 64, 4}, + {1, 15, 15, 16, 64, 4}, + {2, 0, 1, 8, 16, 1}, + {2, 0, 2, 8, 16, 1}, + {2, 0, 3, 8, 16, 1}, + {2, 0, 4, 8, 16, 4}, + {2, 0, 5, 8, 16, 1}, + {2, 0, 6, 8, 16, 4}, + {2, 0, 7, 8, 16, 4}, + {2, 0, 8, 8, 16, 4}, + {2, 0, 9, 8, 16, 8}, + {2, 0, 10, 16, 32, 8}, + {2, 0, 11, 8, 16, 4}, + {2, 0, 12, 8, 16, 8}, + {2, 0, 13, 8, 16, 8}, + {2, 0, 14, 16, 32, 8}, + {2, 0, 15, 8, 16, 8}, + {2, 1, 1, 8, 32, 1}, + {2, 1, 2, 8, 32, 2}, + {2, 1, 3, 8, 16, 1}, + {2, 1, 4, 8, 16, 4}, + {2, 1, 5, 8, 16, 4}, + {2, 1, 6, 8, 16, 8}, + {2, 1, 7, 8, 16, 4}, + {2, 1, 8, 8, 16, 8}, + {2, 1, 9, 8, 16, 8}, + {2, 1, 10, 16, 32, 8}, + {2, 1, 11, 8, 32, 8}, + {2, 1, 12, 16, 16, 8}, + {2, 1, 13, 8, 16, 4}, + {2, 1, 14, 8, 32, 8}, + {2, 1, 15, 16, 32, 8}, + {2, 2, 1, 16, 16, 1}, + {2, 2, 2, 8, 32, 1}, + {2, 2, 3, 8, 16, 1}, + {2, 2, 4, 8, 16, 4}, + {2, 2, 5, 8, 32, 4}, + {2, 2, 6, 8, 16, 8}, + {2, 2, 7, 8, 32, 8}, + {2, 2, 8, 8, 16, 4}, + {2, 2, 9, 8, 32, 8}, + {2, 2, 10, 16, 32, 8}, + {2, 2, 11, 8, 16, 8}, + {2, 2, 12, 8, 32, 8}, + {2, 2, 13, 16, 16, 8}, + {2, 2, 14, 8, 32, 8}, + {2, 2, 15, 8, 64, 8}, + {2, 3, 1, 8, 16, 1}, + {2, 3, 2, 8, 16, 1}, + {2, 3, 3, 8, 16, 1}, + {2, 3, 4, 8, 16, 2}, + {2, 3, 5, 8, 16, 2}, + {2, 3, 6, 8, 16, 4}, + {2, 3, 7, 8, 16, 8}, + {2, 3, 8, 8, 32, 8}, + {2, 3, 9, 8, 16, 8}, + {2, 3, 10, 16, 32, 8}, + {2, 3, 11, 8, 32, 8}, + {2, 3, 12, 8, 64, 8}, + {2, 3, 13, 16, 32, 8}, + {2, 3, 14, 16, 16, 8}, + {2, 3, 15, 16, 32, 8}, + {2, 4, 1, 8, 32, 1}, + {2, 4, 2, 8, 16, 1}, + {2, 4, 3, 8, 32, 1}, + {2, 4, 4, 8, 32, 4}, + {2, 4, 5, 8, 16, 4}, + {2, 4, 6, 8, 16, 8}, + {2, 4, 7, 8, 16, 4}, + {2, 4, 8, 8, 16, 8}, + {2, 4, 9, 8, 16, 8}, + {2, 4, 10, 8, 32, 8}, + {2, 4, 11, 8, 32, 8}, + {2, 4, 12, 8, 16, 8}, + {2, 4, 13, 8, 64, 8}, + {2, 4, 14, 8, 16, 8}, + {2, 4, 15, 8, 16, 8}, + {2, 5, 1, 8, 32, 1}, + {2, 5, 2, 8, 16, 2}, + {2, 5, 3, 8, 16, 2}, + {2, 5, 4, 8, 32, 4}, + {2, 5, 5, 8, 32, 4}, + {2, 5, 6, 8, 32, 8}, + {2, 5, 7, 8, 32, 4}, + {2, 5, 8, 8, 32, 8}, + {2, 5, 9, 8, 16, 4}, + {2, 5, 10, 8, 64, 8}, + {2, 5, 11, 16, 32, 8}, + {2, 5, 12, 16, 32, 8}, + {2, 5, 13, 8, 16, 8}, + {2, 5, 14, 16, 16, 8}, + {2, 5, 15, 8, 16, 8}, + {2, 6, 1, 16, 16, 1}, + {2, 6, 2, 8, 16, 1}, + {2, 6, 3, 8, 32, 1}, + {2, 6, 4, 8, 16, 4}, + {2, 6, 5, 8, 16, 4}, + {2, 6, 6, 8, 16, 8}, + {2, 6, 7, 8, 16, 8}, + {2, 6, 8, 8, 16, 8}, + {2, 6, 9, 16, 32, 8}, + {2, 6, 10, 8, 32, 8}, + {2, 6, 11, 16, 32, 8}, + {2, 6, 12, 8, 16, 4}, + {2, 6, 13, 8, 16, 4}, + {2, 6, 14, 8, 16, 8}, + {2, 6, 15, 16, 16, 8}, + {2, 7, 1, 8, 64, 1}, + {2, 7, 2, 8, 32, 2}, + {2, 7, 3, 8, 32, 1}, + {2, 7, 4, 8, 16, 4}, + {2, 7, 5, 8, 32, 4}, + {2, 7, 6, 8, 32, 8}, + {2, 7, 7, 8, 32, 4}, + {2, 7, 8, 8, 16, 4}, + {2, 7, 9, 32, 16, 4}, + {2, 7, 10, 8, 16, 8}, + {2, 7, 11, 8, 32, 8}, + {2, 7, 12, 16, 16, 8}, + {2, 7, 13, 32, 16, 8}, + {2, 7, 14, 16, 32, 8}, + {2, 7, 15, 8, 16, 8}, + {2, 8, 1, 8, 16, 1}, + {2, 8, 2, 8, 16, 1}, + {2, 8, 3, 8, 32, 1}, + {2, 8, 4, 8, 32, 4}, + {2, 8, 5, 8, 16, 4}, + {2, 8, 6, 8, 32, 8}, + {2, 8, 7, 8, 16, 8}, + {2, 8, 8, 8, 16, 4}, + {2, 8, 9, 16, 64, 8}, + {2, 8, 10, 32, 16, 4}, + {2, 8, 11, 8, 16, 8}, + {2, 8, 12, 8, 16, 4}, + {2, 8, 13, 16, 16, 4}, + {2, 8, 14, 16, 32, 4}, + {2, 8, 15, 8, 32, 8}, + {2, 9, 1, 8, 32, 1}, + {2, 9, 2, 8, 32, 1}, + {2, 9, 3, 8, 32, 2}, + {2, 9, 4, 8, 32, 1}, + {2, 9, 5, 8, 32, 4}, + {2, 9, 6, 16, 32, 4}, + {2, 9, 7, 8, 32, 4}, + {2, 9, 8, 32, 16, 8}, + {2, 9, 9, 16, 16, 8}, + {2, 9, 10, 8, 16, 8}, + {2, 9, 11, 16, 32, 8}, + {2, 9, 12, 8, 16, 8}, + {2, 9, 13, 8, 16, 4}, + {2, 9, 14, 8, 16, 4}, + {2, 9, 15, 8, 32, 8}, + {2, 10, 1, 8, 64, 1}, + {2, 10, 2, 8, 32, 2}, + {2, 10, 3, 16, 16, 1}, + {2, 10, 4, 8, 32, 1}, + {2, 10, 5, 8, 32, 4}, + {2, 10, 6, 16, 16, 4}, + {2, 10, 7, 8, 32, 4}, + {2, 10, 8, 16, 16, 8}, + {2, 10, 9, 32, 32, 8}, + {2, 10, 10, 8, 16, 4}, + {2, 10, 11, 8, 32, 8}, + {2, 10, 12, 8, 32, 4}, + {2, 10, 13, 8, 16, 4}, + {2, 10, 14, 16, 64, 8}, + {2, 10, 15, 8, 32, 8}, + {2, 11, 1, 8, 16, 1}, + {2, 11, 2, 8, 16, 2}, + {2, 11, 3, 8, 16, 1}, + {2, 11, 4, 8, 16, 4}, + {2, 11, 5, 8, 64, 4}, + {2, 11, 6, 16, 16, 4}, + {2, 11, 7, 8, 16, 2}, + {2, 11, 8, 8, 32, 8}, + {2, 11, 9, 8, 16, 8}, + {2, 11, 10, 16, 16, 8}, + {2, 11, 11, 8, 16, 4}, + {2, 11, 12, 8, 32, 8}, + {2, 11, 13, 8, 32, 8}, + {2, 11, 14, 16, 64, 8}, + {2, 11, 15, 16, 64, 8}, + {2, 12, 1, 8, 16, 1}, + {2, 12, 2, 8, 32, 1}, + {2, 12, 3, 16, 16, 1}, + {2, 12, 4, 8, 16, 1}, + {2, 12, 5, 16, 16, 2}, + {2, 12, 6, 8, 16, 4}, + {2, 12, 7, 16, 32, 4}, + {2, 12, 8, 8, 16, 4}, + {2, 12, 9, 8, 32, 8}, + {2, 12, 10, 8, 32, 4}, + {2, 12, 11, 16, 32, 8}, + {2, 12, 12, 16, 64, 4}, + {2, 12, 13, 16, 32, 8}, + {2, 12, 14, 32, 16, 8}, + {2, 12, 15, 16, 32, 8}, + {2, 13, 1, 16, 16, 1}, + {2, 13, 2, 16, 32, 1}, + {2, 13, 3, 16, 16, 2}, + {2, 13, 4, 8, 16, 4}, + {2, 13, 5, 8, 32, 2}, + {2, 13, 6, 8, 32, 4}, + {2, 13, 7, 16, 16, 8}, + {2, 13, 8, 8, 32, 4}, + {2, 13, 9, 16, 16, 8}, + {2, 13, 10, 16, 32, 8}, + {2, 13, 11, 32, 32, 8}, + {2, 13, 12, 16, 16, 4}, + {2, 13, 13, 16, 64, 8}, + {2, 13, 14, 8, 64, 8}, + {2, 13, 15, 16, 64, 4}, + {2, 14, 1, 8, 32, 1}, + {2, 14, 2, 8, 64, 2}, + {2, 14, 3, 8, 16, 1}, + {2, 14, 4, 16, 32, 2}, + {2, 14, 5, 8, 16, 4}, + {2, 14, 6, 8, 16, 4}, + {2, 14, 7, 16, 16, 8}, + {2, 14, 8, 32, 16, 8}, + {2, 14, 9, 16, 32, 4}, + {2, 14, 10, 8, 32, 4}, + {2, 14, 11, 16, 32, 8}, + {2, 14, 12, 16, 16, 2}, + {2, 14, 13, 16, 32, 2}, + {2, 14, 14, 16, 32, 4}, + {2, 14, 15, 16, 64, 4}, + {2, 15, 1, 8, 64, 1}, + {2, 15, 2, 32, 16, 1}, + {2, 15, 3, 8, 32, 1}, + {2, 15, 4, 8, 64, 4}, + {2, 15, 5, 16, 64, 4}, + {2, 15, 6, 8, 32, 2}, + {2, 15, 7, 16, 32, 4}, + {2, 15, 8, 16, 32, 4}, + {2, 15, 9, 16, 32, 4}, + {2, 15, 10, 16, 32, 2}, + {2, 15, 11, 16, 32, 8}, + {2, 15, 12, 32, 16, 4}, + {2, 15, 13, 32, 32, 8}, + {2, 15, 14, 16, 64, 4}, + {2, 15, 15, 16, 32, 4}, + {3, 0, 1, 8, 16, 1}, + {3, 0, 2, 8, 16, 1}, + {3, 0, 3, 8, 16, 2}, + {3, 0, 4, 8, 16, 4}, + {3, 0, 5, 8, 16, 4}, + {3, 0, 6, 8, 16, 4}, + {3, 0, 7, 8, 16, 4}, + {3, 0, 8, 8, 32, 8}, + {3, 0, 9, 8, 16, 4}, + {3, 0, 10, 8, 16, 8}, + {3, 0, 11, 8, 16, 8}, + {3, 0, 12, 8, 16, 4}, + {3, 0, 13, 8, 16, 8}, + {3, 0, 14, 8, 16, 8}, + {3, 0, 15, 8, 16, 8}, + {3, 1, 1, 8, 16, 1}, + {3, 1, 2, 8, 32, 1}, + {3, 1, 3, 8, 16, 1}, + {3, 1, 4, 8, 16, 4}, + {3, 1, 5, 8, 32, 4}, + {3, 1, 6, 8, 16, 4}, + {3, 1, 7, 8, 16, 4}, + {3, 1, 8, 8, 16, 8}, + {3, 1, 9, 8, 16, 4}, + {3, 1, 10, 8, 16, 8}, + {3, 1, 11, 8, 32, 8}, + {3, 1, 12, 8, 16, 8}, + {3, 1, 13, 16, 32, 8}, + {3, 1, 14, 8, 16, 4}, + {3, 1, 15, 8, 16, 8}, + {3, 2, 1, 8, 32, 1}, + {3, 2, 2, 8, 32, 2}, + {3, 2, 3, 16, 16, 1}, + {3, 2, 4, 8, 32, 2}, + {3, 2, 5, 8, 32, 4}, + {3, 2, 6, 16, 16, 4}, + {3, 2, 7, 8, 32, 8}, + {3, 2, 8, 8, 32, 8}, + {3, 2, 9, 16, 16, 8}, + {3, 2, 10, 8, 16, 8}, + {3, 2, 11, 16, 16, 8}, + {3, 2, 12, 32, 16, 8}, + {3, 2, 13, 32, 16, 8}, + {3, 2, 14, 32, 16, 8}, + {3, 2, 15, 32, 16, 8}, + {3, 3, 1, 8, 16, 1}, + {3, 3, 2, 8, 16, 1}, + {3, 3, 3, 8, 16, 2}, + {3, 3, 4, 8, 16, 4}, + {3, 3, 5, 8, 16, 2}, + {3, 3, 6, 8, 16, 4}, + {3, 3, 7, 8, 16, 4}, + {3, 3, 8, 16, 16, 8}, + {3, 3, 9, 8, 32, 8}, + {3, 3, 10, 16, 32, 8}, + {3, 3, 11, 8, 16, 8}, + {3, 3, 12, 16, 32, 8}, + {3, 3, 13, 8, 16, 8}, + {3, 3, 14, 8, 16, 4}, + {3, 3, 15, 8, 16, 8}, + {3, 4, 1, 8, 16, 1}, + {3, 4, 2, 8, 32, 1}, + {3, 4, 3, 8, 32, 1}, + {3, 4, 4, 8, 16, 4}, + {3, 4, 5, 8, 16, 2}, + {3, 4, 6, 8, 32, 4}, + {3, 4, 7, 8, 16, 4}, + {3, 4, 8, 8, 32, 8}, + {3, 4, 9, 8, 32, 8}, + {3, 4, 10, 8, 16, 8}, + {3, 4, 11, 8, 16, 8}, + {3, 4, 12, 8, 16, 8}, + {3, 4, 13, 8, 32, 8}, + {3, 4, 14, 8, 16, 8}, + {3, 4, 15, 8, 16, 8}, + {3, 5, 1, 8, 32, 1}, + {3, 5, 2, 8, 32, 1}, + {3, 5, 3, 8, 32, 2}, + {3, 5, 4, 8, 32, 1}, + {3, 5, 5, 8, 32, 2}, + {3, 5, 6, 8, 16, 8}, + {3, 5, 7, 8, 32, 8}, + {3, 5, 8, 8, 16, 8}, + {3, 5, 9, 8, 64, 8}, + {3, 5, 10, 8, 32, 4}, + {3, 5, 11, 8, 16, 4}, + {3, 5, 12, 16, 16, 4}, + {3, 5, 13, 32, 16, 8}, + {3, 5, 14, 16, 32, 8}, + {3, 5, 15, 32, 16, 8}, + {3, 6, 1, 8, 32, 1}, + {3, 6, 2, 8, 32, 2}, + {3, 6, 3, 8, 32, 1}, + {3, 6, 4, 8, 32, 4}, + {3, 6, 5, 8, 32, 4}, + {3, 6, 6, 8, 32, 8}, + {3, 6, 7, 16, 16, 8}, + {3, 6, 8, 8, 16, 8}, + {3, 6, 9, 8, 32, 8}, + {3, 6, 10, 8, 32, 8}, + {3, 6, 11, 8, 32, 8}, + {3, 6, 12, 8, 32, 8}, + {3, 6, 13, 8, 16, 8}, + {3, 6, 14, 16, 16, 8}, + {3, 6, 15, 16, 32, 8}, + {3, 7, 1, 8, 16, 1}, + {3, 7, 2, 8, 32, 1}, + {3, 7, 3, 8, 16, 2}, + {3, 7, 4, 8, 16, 4}, + {3, 7, 5, 8, 16, 4}, + {3, 7, 6, 8, 32, 4}, + {3, 7, 7, 8, 32, 8}, + {3, 7, 8, 8, 32, 8}, + {3, 7, 9, 8, 32, 8}, + {3, 7, 10, 16, 16, 8}, + {3, 7, 11, 8, 32, 8}, + {3, 7, 12, 8, 32, 8}, + {3, 7, 13, 8, 16, 8}, + {3, 7, 14, 8, 32, 8}, + {3, 7, 15, 16, 16, 8}, + {3, 8, 1, 8, 32, 1}, + {3, 8, 2, 8, 32, 1}, + {3, 8, 3, 8, 32, 1}, + {3, 8, 4, 8, 16, 4}, + {3, 8, 5, 8, 16, 4}, + {3, 8, 6, 8, 16, 4}, + {3, 8, 7, 8, 16, 8}, + {3, 8, 8, 8, 16, 4}, + {3, 8, 9, 16, 32, 4}, + {3, 8, 10, 16, 16, 4}, + {3, 8, 11, 16, 16, 8}, + {3, 8, 12, 16, 64, 8}, + {3, 8, 13, 32, 16, 4}, + {3, 8, 14, 8, 32, 8}, + {3, 8, 15, 16, 16, 8}, + {3, 9, 1, 16, 16, 1}, + {3, 9, 2, 8, 16, 2}, + {3, 9, 3, 16, 32, 2}, + {3, 9, 4, 16, 32, 4}, + {3, 9, 5, 8, 16, 4}, + {3, 9, 6, 8, 32, 4}, + {3, 9, 7, 16, 32, 8}, + {3, 9, 8, 8, 16, 4}, + {3, 9, 9, 8, 32, 8}, + {3, 9, 10, 8, 16, 8}, + {3, 9, 11, 8, 16, 4}, + {3, 9, 12, 8, 32, 8}, + {3, 9, 13, 8, 32, 8}, + {3, 9, 14, 16, 16, 4}, + {3, 9, 15, 16, 32, 8}, + {3, 10, 1, 16, 32, 1}, + {3, 10, 2, 8, 16, 1}, + {3, 10, 3, 8, 32, 1}, + {3, 10, 4, 8, 16, 4}, + {3, 10, 5, 8, 32, 4}, + {3, 10, 6, 16, 32, 2}, + {3, 10, 7, 16, 16, 2}, + {3, 10, 8, 32, 16, 4}, + {3, 10, 9, 16, 32, 4}, + {3, 10, 10, 8, 32, 4}, + {3, 10, 11, 16, 16, 8}, + {3, 10, 12, 16, 16, 8}, + {3, 10, 13, 16, 32, 8}, + {3, 10, 14, 8, 64, 8}, + {3, 10, 15, 16, 32, 8}, + {3, 11, 1, 16, 16, 1}, + {3, 11, 2, 8, 64, 1}, + {3, 11, 3, 8, 32, 1}, + {3, 11, 4, 32, 16, 1}, + {3, 11, 5, 8, 32, 1}, + {3, 11, 6, 8, 32, 8}, + {3, 11, 7, 8, 32, 4}, + {3, 11, 8, 16, 32, 4}, + {3, 11, 9, 8, 32, 4}, + {3, 11, 10, 16, 32, 8}, + {3, 11, 11, 8, 32, 8}, + {3, 11, 12, 16, 16, 4}, + {3, 11, 13, 16, 16, 8}, + {3, 11, 14, 16, 64, 8}, + {3, 11, 15, 16, 32, 8}, + {3, 12, 1, 8, 32, 1}, + {3, 12, 2, 8, 32, 2}, + {3, 12, 3, 16, 32, 1}, + {3, 12, 4, 8, 32, 1}, + {3, 12, 5, 16, 16, 4}, + {3, 12, 6, 16, 32, 2}, + {3, 12, 7, 16, 16, 4}, + {3, 12, 8, 16, 16, 8}, + {3, 12, 9, 16, 32, 8}, + {3, 12, 10, 8, 32, 2}, + {3, 12, 11, 16, 16, 4}, + {3, 12, 12, 16, 64, 8}, + {3, 12, 13, 16, 16, 4}, + {3, 12, 14, 16, 32, 8}, + {3, 12, 15, 16, 64, 4}, + {3, 13, 1, 8, 32, 1}, + {3, 13, 2, 8, 32, 1}, + {3, 13, 3, 16, 32, 2}, + {3, 13, 4, 8, 32, 4}, + {3, 13, 5, 8, 32, 2}, + {3, 13, 6, 8, 32, 8}, + {3, 13, 7, 8, 32, 4}, + {3, 13, 8, 16, 32, 4}, + {3, 13, 9, 16, 32, 4}, + {3, 13, 10, 16, 32, 4}, + {3, 13, 11, 8, 32, 8}, + {3, 13, 12, 16, 16, 2}, + {3, 13, 13, 16, 64, 8}, + {3, 13, 14, 16, 32, 8}, + {3, 13, 15, 16, 64, 8}, + {3, 14, 1, 8, 32, 1}, + {3, 14, 2, 8, 32, 2}, + {3, 14, 3, 8, 64, 1}, + {3, 14, 4, 8, 32, 4}, + {3, 14, 5, 16, 32, 2}, + {3, 14, 6, 8, 32, 4}, + {3, 14, 7, 8, 32, 4}, + {3, 14, 8, 16, 32, 4}, + {3, 14, 9, 16, 16, 8}, + {3, 14, 10, 8, 16, 4}, + {3, 14, 11, 16, 64, 4}, + {3, 14, 12, 16, 64, 4}, + {3, 14, 13, 16, 32, 8}, + {3, 14, 14, 16, 32, 8}, + {3, 14, 15, 16, 64, 4}, + {3, 15, 1, 16, 16, 1}, + {3, 15, 2, 8, 16, 2}, + {3, 15, 3, 16, 32, 2}, + {3, 15, 4, 8, 32, 1}, + {3, 15, 5, 16, 32, 4}, + {3, 15, 6, 8, 32, 1}, + {3, 15, 7, 16, 32, 4}, + {3, 15, 8, 16, 32, 2}, + {3, 15, 9, 16, 32, 2}, + {3, 15, 10, 16, 32, 4}, + {3, 15, 11, 16, 32, 8}, + {3, 15, 12, 16, 32, 4}, + {3, 15, 13, 16, 32, 2}, + {3, 15, 14, 16, 32, 8}, + {3, 15, 15, 16, 32, 8}, + {4, 0, 1, 16, 16, 1}, + {4, 0, 2, 8, 16, 1}, + {4, 0, 3, 8, 16, 1}, + {4, 0, 4, 8, 16, 4}, + {4, 0, 5, 8, 16, 4}, + {4, 0, 6, 8, 16, 4}, + {4, 0, 7, 8, 16, 4}, + {4, 0, 8, 16, 16, 8}, + {4, 0, 9, 8, 16, 4}, + {4, 0, 10, 8, 16, 4}, + {4, 0, 11, 8, 16, 8}, + {4, 0, 12, 8, 16, 8}, + {4, 0, 13, 16, 16, 8}, + {4, 0, 14, 8, 16, 8}, + {4, 0, 15, 8, 32, 8}, + {4, 1, 1, 8, 32, 1}, + {4, 1, 2, 16, 16, 1}, + {4, 1, 3, 8, 32, 1}, + {4, 1, 4, 8, 16, 4}, + {4, 1, 5, 8, 16, 4}, + {4, 1, 6, 8, 16, 4}, + {4, 1, 7, 16, 16, 8}, + {4, 1, 8, 8, 16, 8}, + {4, 1, 9, 8, 16, 8}, + {4, 1, 10, 16, 16, 8}, + {4, 1, 11, 8, 16, 8}, + {4, 1, 12, 8, 16, 8}, + {4, 1, 13, 8, 16, 8}, + {4, 1, 14, 16, 16, 8}, + {4, 1, 15, 8, 16, 8}, + {4, 2, 1, 8, 32, 1}, + {4, 2, 2, 8, 32, 1}, + {4, 2, 3, 8, 32, 2}, + {4, 2, 4, 8, 32, 2}, + {4, 2, 5, 8, 32, 4}, + {4, 2, 6, 8, 32, 4}, + {4, 2, 7, 8, 16, 4}, + {4, 2, 8, 16, 32, 8}, + {4, 2, 9, 8, 16, 4}, + {4, 2, 10, 8, 16, 8}, + {4, 2, 11, 8, 16, 8}, + {4, 2, 12, 16, 16, 8}, + {4, 2, 13, 8, 16, 8}, + {4, 2, 14, 8, 16, 8}, + {4, 2, 15, 8, 16, 8}, + {4, 3, 1, 8, 32, 1}, + {4, 3, 2, 8, 16, 1}, + {4, 3, 3, 8, 32, 1}, + {4, 3, 4, 8, 16, 4}, + {4, 3, 5, 8, 32, 4}, + {4, 3, 6, 8, 16, 4}, + {4, 3, 7, 8, 16, 8}, + {4, 3, 8, 16, 16, 8}, + {4, 3, 9, 8, 64, 8}, + {4, 3, 10, 16, 16, 4}, + {4, 3, 11, 8, 16, 4}, + {4, 3, 12, 8, 16, 8}, + {4, 3, 13, 16, 32, 8}, + {4, 3, 14, 16, 16, 8}, + {4, 3, 15, 8, 16, 8}, + {4, 4, 1, 8, 32, 1}, + {4, 4, 2, 8, 32, 1}, + {4, 4, 3, 8, 16, 2}, + {4, 4, 4, 8, 16, 4}, + {4, 4, 5, 8, 32, 2}, + {4, 4, 6, 8, 32, 4}, + {4, 4, 7, 8, 32, 4}, + {4, 4, 8, 8, 32, 4}, + {4, 4, 9, 8, 32, 8}, + {4, 4, 10, 8, 32, 8}, + {4, 4, 11, 8, 16, 8}, + {4, 4, 12, 8, 16, 8}, + {4, 4, 13, 8, 64, 8}, + {4, 4, 14, 8, 16, 4}, + {4, 4, 15, 8, 16, 8}, + {4, 5, 1, 8, 16, 1}, + {4, 5, 2, 8, 32, 1}, + {4, 5, 3, 8, 16, 1}, + {4, 5, 4, 8, 16, 4}, + {4, 5, 5, 8, 32, 4}, + {4, 5, 6, 8, 32, 4}, + {4, 5, 7, 16, 16, 8}, + {4, 5, 8, 8, 32, 8}, + {4, 5, 9, 8, 32, 8}, + {4, 5, 10, 16, 16, 8}, + {4, 5, 11, 8, 32, 8}, + {4, 5, 12, 8, 16, 8}, + {4, 5, 13, 8, 32, 4}, + {4, 5, 14, 16, 16, 8}, + {4, 5, 15, 16, 16, 8}, + {4, 6, 1, 8, 32, 1}, + {4, 6, 2, 8, 32, 1}, + {4, 6, 3, 8, 16, 2}, + {4, 6, 4, 8, 32, 4}, + {4, 6, 5, 8, 16, 4}, + {4, 6, 6, 8, 32, 8}, + {4, 6, 7, 8, 32, 8}, + {4, 6, 8, 16, 16, 8}, + {4, 6, 9, 8, 32, 8}, + {4, 6, 10, 8, 32, 8}, + {4, 6, 11, 8, 64, 8}, + {4, 6, 12, 8, 16, 8}, + {4, 6, 13, 8, 32, 8}, + {4, 6, 14, 16, 16, 4}, + {4, 6, 15, 8, 32, 8}, + {4, 7, 1, 8, 32, 1}, + {4, 7, 2, 8, 32, 1}, + {4, 7, 3, 8, 32, 1}, + {4, 7, 4, 8, 16, 4}, + {4, 7, 5, 16, 16, 4}, + {4, 7, 6, 16, 32, 4}, + {4, 7, 7, 16, 32, 4}, + {4, 7, 8, 8, 32, 8}, + {4, 7, 9, 8, 16, 8}, + {4, 7, 10, 16, 32, 8}, + {4, 7, 11, 8, 16, 4}, + {4, 7, 12, 16, 16, 4}, + {4, 7, 13, 8, 16, 4}, + {4, 7, 14, 16, 32, 8}, + {4, 7, 15, 8, 16, 8}, + {4, 8, 1, 8, 16, 1}, + {4, 8, 2, 8, 32, 1}, + {4, 8, 3, 16, 32, 2}, + {4, 8, 4, 8, 32, 4}, + {4, 8, 5, 8, 16, 4}, + {4, 8, 6, 8, 32, 4}, + {4, 8, 7, 8, 16, 4}, + {4, 8, 8, 16, 16, 8}, + {4, 8, 9, 8, 32, 8}, + {4, 8, 10, 8, 16, 8}, + {4, 8, 11, 16, 16, 8}, + {4, 8, 12, 8, 32, 8}, + {4, 8, 13, 16, 16, 8}, + {4, 8, 14, 16, 32, 8}, + {4, 8, 15, 8, 32, 8}, + {4, 9, 1, 8, 16, 1}, + {4, 9, 2, 8, 16, 1}, + {4, 9, 3, 16, 16, 1}, + {4, 9, 4, 8, 16, 4}, + {4, 9, 5, 8, 16, 4}, + {4, 9, 6, 8, 16, 4}, + {4, 9, 7, 16, 16, 4}, + {4, 9, 8, 32, 16, 8}, + {4, 9, 9, 8, 32, 4}, + {4, 9, 10, 16, 32, 4}, + {4, 9, 11, 16, 16, 8}, + {4, 9, 12, 16, 64, 8}, + {4, 9, 13, 8, 16, 4}, + {4, 9, 14, 8, 32, 8}, + {4, 9, 15, 8, 32, 8}, + {4, 10, 1, 8, 32, 1}, + {4, 10, 2, 8, 32, 1}, + {4, 10, 3, 8, 16, 1}, + {4, 10, 4, 8, 16, 4}, + {4, 10, 5, 8, 16, 4}, + {4, 10, 6, 16, 16, 4}, + {4, 10, 7, 8, 32, 4}, + {4, 10, 8, 8, 32, 8}, + {4, 10, 9, 8, 16, 4}, + {4, 10, 10, 16, 32, 8}, + {4, 10, 11, 32, 16, 4}, + {4, 10, 12, 32, 32, 8}, + {4, 10, 13, 16, 64, 8}, + {4, 10, 14, 8, 32, 8}, + {4, 10, 15, 16, 32, 8}, + {4, 11, 1, 8, 32, 1}, + {4, 11, 2, 8, 16, 1}, + {4, 11, 3, 8, 32, 1}, + {4, 11, 4, 8, 32, 2}, + {4, 11, 5, 16, 32, 4}, + {4, 11, 6, 8, 32, 4}, + {4, 11, 7, 8, 32, 8}, + {4, 11, 8, 8, 32, 8}, + {4, 11, 9, 16, 64, 4}, + {4, 11, 10, 8, 32, 4}, + {4, 11, 11, 8, 32, 8}, + {4, 11, 12, 16, 32, 8}, + {4, 11, 13, 32, 32, 8}, + {4, 11, 14, 16, 16, 8}, + {4, 11, 15, 16, 32, 8}, + {4, 12, 1, 8, 32, 1}, + {4, 12, 2, 8, 32, 1}, + {4, 12, 3, 8, 32, 2}, + {4, 12, 4, 8, 32, 4}, + {4, 12, 5, 8, 32, 4}, + {4, 12, 6, 8, 32, 2}, + {4, 12, 7, 16, 32, 4}, + {4, 12, 8, 8, 32, 8}, + {4, 12, 9, 16, 32, 4}, + {4, 12, 10, 8, 32, 8}, + {4, 12, 11, 8, 32, 8}, + {4, 12, 12, 32, 16, 8}, + {4, 12, 13, 16, 32, 8}, + {4, 12, 14, 16, 32, 8}, + {4, 12, 15, 16, 32, 8}, + {4, 13, 1, 8, 32, 1}, + {4, 13, 2, 8, 32, 1}, + {4, 13, 3, 16, 32, 2}, + {4, 13, 4, 8, 32, 4}, + {4, 13, 5, 16, 32, 2}, + {4, 13, 6, 16, 16, 1}, + {4, 13, 7, 16, 32, 4}, + {4, 13, 8, 16, 32, 4}, + {4, 13, 9, 16, 32, 2}, + {4, 13, 10, 16, 32, 4}, + {4, 13, 11, 16, 32, 4}, + {4, 13, 12, 32, 16, 4}, + {4, 13, 13, 16, 32, 4}, + {4, 13, 14, 16, 32, 8}, + {4, 13, 15, 32, 32, 8}, + {4, 14, 1, 16, 64, 1}, + {4, 14, 2, 8, 32, 1}, + {4, 14, 3, 8, 16, 1}, + {4, 14, 4, 8, 32, 2}, + {4, 14, 5, 32, 16, 4}, + {4, 14, 6, 16, 32, 4}, + {4, 14, 7, 8, 32, 4}, + {4, 14, 8, 32, 16, 8}, + {4, 14, 9, 16, 64, 4}, + {4, 14, 10, 16, 32, 8}, + {4, 14, 11, 16, 64, 4}, + {4, 14, 12, 16, 32, 8}, + {4, 14, 13, 16, 32, 8}, + {4, 14, 14, 16, 32, 8}, + {4, 14, 15, 16, 32, 8}, + {4, 15, 1, 8, 32, 1}, + {4, 15, 2, 8, 32, 1}, + {4, 15, 3, 8, 16, 1}, + {4, 15, 4, 16, 32, 2}, + {4, 15, 5, 8, 32, 1}, + {4, 15, 6, 8, 32, 1}, + {4, 15, 7, 16, 32, 4}, + {4, 15, 8, 16, 32, 4}, + {4, 15, 9, 32, 32, 4}, + {4, 15, 10, 32, 32, 4}, + {4, 15, 11, 16, 32, 4}, + {4, 15, 12, 32, 32, 2}, + {4, 15, 13, 32, 32, 4}, + {4, 15, 14, 32, 32, 4}, + {4, 15, 15, 32, 32, 4}, + {5, 0, 1, 8, 16, 1}, + {5, 0, 2, 8, 16, 1}, + {5, 0, 3, 8, 16, 2}, + {5, 0, 4, 8, 16, 4}, + {5, 0, 5, 8, 16, 4}, + {5, 0, 6, 8, 16, 4}, + {5, 0, 7, 16, 16, 8}, + {5, 0, 8, 16, 16, 8}, + {5, 0, 9, 8, 16, 8}, + {5, 0, 10, 8, 16, 8}, + {5, 0, 11, 16, 16, 8}, + {5, 0, 12, 8, 16, 8}, + {5, 0, 13, 16, 16, 8}, + {5, 0, 14, 16, 16, 8}, + {5, 0, 15, 8, 16, 8}, + {5, 1, 1, 8, 32, 1}, + {5, 1, 2, 8, 32, 1}, + {5, 1, 3, 8, 16, 1}, + {5, 1, 4, 8, 16, 4}, + {5, 1, 5, 8, 16, 4}, + {5, 1, 6, 8, 16, 8}, + {5, 1, 7, 8, 16, 4}, + {5, 1, 8, 8, 16, 8}, + {5, 1, 9, 16, 16, 8}, + {5, 1, 10, 8, 16, 8}, + {5, 1, 11, 16, 32, 8}, + {5, 1, 12, 8, 16, 8}, + {5, 1, 13, 8, 16, 4}, + {5, 1, 14, 8, 16, 8}, + {5, 1, 15, 16, 16, 8}, + {5, 2, 1, 8, 16, 1}, + {5, 2, 2, 8, 16, 1}, + {5, 2, 3, 8, 16, 1}, + {5, 2, 4, 8, 16, 4}, + {5, 2, 5, 8, 16, 4}, + {5, 2, 6, 8, 16, 4}, + {5, 2, 7, 8, 16, 4}, + {5, 2, 8, 16, 32, 8}, + {5, 2, 9, 8, 32, 8}, + {5, 2, 10, 8, 16, 8}, + {5, 2, 11, 16, 16, 8}, + {5, 2, 12, 8, 16, 8}, + {5, 2, 13, 8, 16, 8}, + {5, 2, 14, 16, 16, 8}, + {5, 2, 15, 8, 16, 8}, + {5, 3, 1, 8, 16, 1}, + {5, 3, 2, 8, 16, 1}, + {5, 3, 3, 8, 16, 2}, + {5, 3, 4, 8, 16, 4}, + {5, 3, 5, 8, 16, 4}, + {5, 3, 6, 8, 16, 4}, + {5, 3, 7, 8, 32, 4}, + {5, 3, 8, 8, 16, 4}, + {5, 3, 9, 8, 32, 8}, + {5, 3, 10, 8, 16, 4}, + {5, 3, 11, 8, 16, 8}, + {5, 3, 12, 8, 16, 8}, + {5, 3, 13, 16, 32, 8}, + {5, 3, 14, 8, 16, 8}, + {5, 3, 15, 8, 16, 8}, + {5, 4, 1, 8, 16, 1}, + {5, 4, 2, 8, 16, 1}, + {5, 4, 3, 8, 16, 2}, + {5, 4, 4, 8, 16, 4}, + {5, 4, 5, 8, 16, 4}, + {5, 4, 6, 8, 32, 8}, + {5, 4, 7, 8, 16, 4}, + {5, 4, 8, 8, 16, 8}, + {5, 4, 9, 16, 16, 8}, + {5, 4, 10, 8, 16, 8}, + {5, 4, 11, 8, 16, 8}, + {5, 4, 12, 8, 64, 8}, + {5, 4, 13, 16, 32, 8}, + {5, 4, 14, 8, 16, 8}, + {5, 4, 15, 16, 16, 8}, + {5, 5, 1, 8, 16, 1}, + {5, 5, 2, 8, 16, 1}, + {5, 5, 3, 8, 16, 1}, + {5, 5, 4, 8, 16, 4}, + {5, 5, 5, 8, 16, 4}, + {5, 5, 6, 8, 16, 8}, + {5, 5, 7, 8, 16, 4}, + {5, 5, 8, 32, 16, 8}, + {5, 5, 9, 8, 16, 4}, + {5, 5, 10, 8, 16, 8}, + {5, 5, 11, 16, 16, 8}, + {5, 5, 12, 8, 16, 8}, + {5, 5, 13, 8, 16, 4}, + {5, 5, 14, 8, 64, 8}, + {5, 5, 15, 16, 32, 8}, + {5, 6, 1, 8, 16, 1}, + {5, 6, 2, 8, 16, 1}, + {5, 6, 3, 8, 16, 1}, + {5, 6, 4, 8, 16, 4}, + {5, 6, 5, 8, 16, 4}, + {5, 6, 6, 8, 16, 4}, + {5, 6, 7, 8, 16, 4}, + {5, 6, 8, 8, 16, 4}, + {5, 6, 9, 8, 16, 8}, + {5, 6, 10, 8, 16, 8}, + {5, 6, 11, 8, 32, 8}, + {5, 6, 12, 8, 64, 8}, + {5, 6, 13, 16, 16, 8}, + {5, 6, 14, 8, 16, 8}, + {5, 6, 15, 16, 16, 4}, + {5, 7, 1, 8, 16, 1}, + {5, 7, 2, 8, 16, 1}, + {5, 7, 3, 16, 16, 1}, + {5, 7, 4, 8, 16, 1}, + {5, 7, 5, 8, 16, 4}, + {5, 7, 6, 8, 16, 4}, + {5, 7, 7, 32, 16, 8}, + {5, 7, 8, 16, 16, 8}, + {5, 7, 9, 8, 16, 4}, + {5, 7, 10, 8, 32, 8}, + {5, 7, 11, 8, 32, 8}, + {5, 7, 12, 8, 32, 8}, + {5, 7, 13, 16, 16, 4}, + {5, 7, 14, 32, 16, 8}, + {5, 7, 15, 8, 16, 8}, + {5, 8, 1, 8, 32, 1}, + {5, 8, 2, 8, 16, 1}, + {5, 8, 3, 8, 16, 1}, + {5, 8, 4, 8, 16, 2}, + {5, 8, 5, 8, 16, 4}, + {5, 8, 6, 8, 16, 4}, + {5, 8, 7, 16, 32, 8}, + {5, 8, 8, 8, 32, 8}, + {5, 8, 9, 16, 32, 8}, + {5, 8, 10, 16, 64, 8}, + {5, 8, 11, 16, 16, 8}, + {5, 8, 12, 16, 16, 8}, + {5, 8, 13, 16, 64, 8}, + {5, 8, 14, 8, 16, 8}, + {5, 8, 15, 16, 16, 8}, + {5, 9, 1, 16, 32, 1}, + {5, 9, 2, 8, 16, 1}, + {5, 9, 3, 8, 16, 2}, + {5, 9, 4, 16, 16, 1}, + {5, 9, 5, 16, 16, 1}, + {5, 9, 6, 8, 16, 4}, + {5, 9, 7, 8, 32, 8}, + {5, 9, 8, 16, 64, 8}, + {5, 9, 9, 16, 32, 8}, + {5, 9, 10, 8, 32, 8}, + {5, 9, 11, 16, 16, 4}, + {5, 9, 12, 8, 32, 8}, + {5, 9, 13, 8, 32, 8}, + {5, 9, 14, 16, 32, 8}, + {5, 9, 15, 16, 16, 8}, + {5, 10, 1, 8, 32, 1}, + {5, 10, 2, 8, 16, 1}, + {5, 10, 3, 8, 16, 1}, + {5, 10, 4, 8, 32, 1}, + {5, 10, 5, 8, 32, 2}, + {5, 10, 6, 16, 16, 4}, + {5, 10, 7, 16, 16, 8}, + {5, 10, 8, 8, 64, 4}, + {5, 10, 9, 32, 16, 4}, + {5, 10, 10, 32, 32, 8}, + {5, 10, 11, 16, 32, 8}, + {5, 10, 12, 16, 32, 8}, + {5, 10, 13, 16, 32, 4}, + {5, 10, 14, 16, 32, 8}, + {5, 10, 15, 16, 16, 8}, + {5, 11, 1, 8, 16, 1}, + {5, 11, 2, 8, 16, 1}, + {5, 11, 3, 8, 16, 1}, + {5, 11, 4, 8, 32, 1}, + {5, 11, 5, 8, 32, 4}, + {5, 11, 6, 8, 32, 1}, + {5, 11, 7, 16, 32, 2}, + {5, 11, 8, 16, 16, 4}, + {5, 11, 9, 16, 16, 8}, + {5, 11, 10, 32, 16, 4}, + {5, 11, 11, 8, 32, 8}, + {5, 11, 12, 8, 32, 8}, + {5, 11, 13, 16, 32, 8}, + {5, 11, 14, 16, 64, 8}, + {5, 11, 15, 16, 32, 8}, + {5, 12, 1, 8, 32, 1}, + {5, 12, 2, 8, 32, 1}, + {5, 12, 3, 16, 32, 2}, + {5, 12, 4, 8, 32, 4}, + {5, 12, 5, 16, 32, 1}, + {5, 12, 6, 16, 32, 1}, + {5, 12, 7, 16, 16, 4}, + {5, 12, 8, 16, 16, 8}, + {5, 12, 9, 16, 16, 4}, + {5, 12, 10, 16, 32, 8}, + {5, 12, 11, 16, 32, 8}, + {5, 12, 12, 16, 16, 8}, + {5, 12, 13, 32, 32, 4}, + {5, 12, 14, 16, 32, 8}, + {5, 12, 15, 16, 32, 8}, + {5, 13, 1, 8, 32, 1}, + {5, 13, 2, 16, 32, 1}, + {5, 13, 3, 8, 32, 1}, + {5, 13, 4, 8, 32, 1}, + {5, 13, 5, 16, 32, 2}, + {5, 13, 6, 16, 32, 4}, + {5, 13, 7, 8, 32, 4}, + {5, 13, 8, 16, 32, 4}, + {5, 13, 9, 16, 64, 4}, + {5, 13, 10, 32, 32, 4}, + {5, 13, 11, 16, 64, 4}, + {5, 13, 12, 16, 32, 4}, + {5, 13, 13, 16, 64, 4}, + {5, 13, 14, 32, 32, 4}, + {5, 13, 15, 32, 32, 4}, + {5, 14, 1, 8, 32, 1}, + {5, 14, 2, 8, 32, 1}, + {5, 14, 3, 16, 32, 2}, + {5, 14, 4, 8, 64, 1}, + {5, 14, 5, 16, 32, 4}, + {5, 14, 6, 16, 32, 4}, + {5, 14, 7, 32, 16, 4}, + {5, 14, 8, 16, 32, 4}, + {5, 14, 9, 16, 32, 4}, + {5, 14, 10, 16, 32, 4}, + {5, 14, 11, 32, 32, 4}, + {5, 14, 12, 16, 32, 8}, + {5, 14, 13, 16, 32, 8}, + {5, 14, 14, 32, 32, 4}, + {5, 14, 15, 16, 32, 8}, + {5, 15, 1, 16, 32, 1}, + {5, 15, 2, 8, 32, 1}, + {5, 15, 3, 32, 32, 1}, + {5, 15, 4, 8, 32, 2}, + {5, 15, 5, 16, 32, 1}, + {5, 15, 6, 16, 32, 1}, + {5, 15, 7, 16, 32, 4}, + {5, 15, 8, 16, 32, 4}, + {5, 15, 9, 32, 32, 2}, + {5, 15, 10, 16, 32, 4}, + {5, 15, 11, 32, 32, 2}, + {5, 15, 12, 32, 32, 4}, + {5, 15, 13, 32, 32, 4}, + {5, 15, 14, 32, 32, 4}, + {5, 15, 15, 32, 32, 4}, + {6, 0, 1, 8, 16, 1}, + {6, 0, 2, 16, 16, 1}, + {6, 0, 3, 8, 16, 1}, + {6, 0, 4, 8, 16, 4}, + {6, 0, 5, 8, 16, 2}, + {6, 0, 6, 8, 16, 4}, + {6, 0, 7, 16, 16, 8}, + {6, 0, 8, 8, 32, 8}, + {6, 0, 9, 8, 32, 8}, + {6, 0, 10, 8, 32, 8}, + {6, 0, 11, 8, 16, 8}, + {6, 0, 12, 8, 16, 4}, + {6, 0, 13, 8, 32, 8}, + {6, 0, 14, 8, 16, 8}, + {6, 0, 15, 8, 16, 4}, + {6, 1, 1, 8, 16, 1}, + {6, 1, 2, 8, 16, 2}, + {6, 1, 3, 8, 32, 2}, + {6, 1, 4, 8, 16, 4}, + {6, 1, 5, 8, 32, 4}, + {6, 1, 6, 8, 16, 4}, + {6, 1, 7, 8, 16, 4}, + {6, 1, 8, 16, 32, 8}, + {6, 1, 9, 8, 32, 8}, + {6, 1, 10, 8, 32, 4}, + {6, 1, 11, 8, 16, 8}, + {6, 1, 12, 8, 64, 8}, + {6, 1, 13, 16, 16, 8}, + {6, 1, 14, 8, 32, 8}, + {6, 1, 15, 16, 16, 8}, + {6, 2, 1, 8, 32, 1}, + {6, 2, 2, 8, 32, 2}, + {6, 2, 3, 8, 32, 1}, + {6, 2, 4, 8, 32, 4}, + {6, 2, 5, 8, 16, 4}, + {6, 2, 6, 8, 16, 8}, + {6, 2, 7, 16, 16, 8}, + {6, 2, 8, 8, 64, 8}, + {6, 2, 9, 8, 32, 8}, + {6, 2, 10, 8, 16, 8}, + {6, 2, 11, 8, 16, 8}, + {6, 2, 12, 32, 16, 8}, + {6, 2, 13, 16, 32, 8}, + {6, 2, 14, 8, 64, 8}, + {6, 2, 15, 16, 16, 4}, + {6, 3, 1, 8, 16, 1}, + {6, 3, 2, 8, 16, 2}, + {6, 3, 3, 8, 16, 2}, + {6, 3, 4, 8, 16, 4}, + {6, 3, 5, 8, 16, 4}, + {6, 3, 6, 8, 16, 8}, + {6, 3, 7, 16, 16, 8}, + {6, 3, 8, 8, 16, 8}, + {6, 3, 9, 16, 32, 8}, + {6, 3, 10, 8, 32, 8}, + {6, 3, 11, 8, 16, 8}, + {6, 3, 12, 8, 32, 8}, + {6, 3, 13, 8, 64, 8}, + {6, 3, 14, 8, 16, 8}, + {6, 3, 15, 8, 32, 8}, + {6, 4, 1, 8, 16, 1}, + {6, 4, 2, 8, 32, 1}, + {6, 4, 3, 8, 32, 1}, + {6, 4, 4, 8, 16, 4}, + {6, 4, 5, 8, 32, 4}, + {6, 4, 6, 8, 16, 4}, + {6, 4, 7, 8, 16, 4}, + {6, 4, 8, 8, 16, 4}, + {6, 4, 9, 8, 32, 8}, + {6, 4, 10, 8, 64, 8}, + {6, 4, 11, 16, 16, 8}, + {6, 4, 12, 8, 16, 8}, + {6, 4, 13, 16, 16, 8}, + {6, 4, 14, 8, 16, 8}, + {6, 4, 15, 8, 16, 8}, + {6, 5, 1, 8, 32, 1}, + {6, 5, 2, 8, 16, 1}, + {6, 5, 3, 8, 32, 1}, + {6, 5, 4, 8, 16, 4}, + {6, 5, 5, 16, 16, 4}, + {6, 5, 6, 8, 32, 8}, + {6, 5, 7, 16, 16, 4}, + {6, 5, 8, 16, 16, 8}, + {6, 5, 9, 16, 16, 8}, + {6, 5, 10, 8, 16, 4}, + {6, 5, 11, 16, 32, 8}, + {6, 5, 12, 8, 64, 8}, + {6, 5, 13, 16, 64, 8}, + {6, 5, 14, 8, 16, 8}, + {6, 5, 15, 8, 32, 8}, + {6, 6, 1, 8, 32, 1}, + {6, 6, 2, 8, 16, 2}, + {6, 6, 3, 8, 32, 1}, + {6, 6, 4, 8, 32, 2}, + {6, 6, 5, 16, 16, 4}, + {6, 6, 6, 8, 16, 4}, + {6, 6, 7, 16, 32, 8}, + {6, 6, 8, 8, 16, 8}, + {6, 6, 9, 8, 16, 8}, + {6, 6, 10, 16, 32, 8}, + {6, 6, 11, 8, 32, 8}, + {6, 6, 12, 16, 16, 4}, + {6, 6, 13, 16, 16, 8}, + {6, 6, 14, 8, 32, 8}, + {6, 6, 15, 8, 64, 8}, + {6, 7, 1, 8, 16, 1}, + {6, 7, 2, 8, 16, 1}, + {6, 7, 3, 16, 16, 2}, + {6, 7, 4, 8, 16, 4}, + {6, 7, 5, 8, 16, 4}, + {6, 7, 6, 8, 16, 2}, + {6, 7, 7, 8, 32, 4}, + {6, 7, 8, 8, 64, 8}, + {6, 7, 9, 8, 32, 8}, + {6, 7, 10, 16, 16, 4}, + {6, 7, 11, 8, 32, 8}, + {6, 7, 12, 16, 16, 8}, + {6, 7, 13, 16, 16, 8}, + {6, 7, 14, 8, 16, 4}, + {6, 7, 15, 8, 64, 8}, + {6, 8, 1, 8, 32, 1}, + {6, 8, 2, 8, 32, 1}, + {6, 8, 3, 8, 16, 1}, + {6, 8, 4, 8, 32, 4}, + {6, 8, 5, 8, 16, 1}, + {6, 8, 6, 8, 32, 4}, + {6, 8, 7, 32, 16, 4}, + {6, 8, 8, 16, 16, 4}, + {6, 8, 9, 16, 16, 8}, + {6, 8, 10, 8, 32, 8}, + {6, 8, 11, 16, 32, 8}, + {6, 8, 12, 8, 64, 8}, + {6, 8, 13, 8, 64, 8}, + {6, 8, 14, 16, 32, 8}, + {6, 8, 15, 16, 32, 8}, + {6, 9, 1, 8, 32, 1}, + {6, 9, 2, 8, 32, 1}, + {6, 9, 3, 8, 16, 1}, + {6, 9, 4, 8, 32, 2}, + {6, 9, 5, 8, 32, 2}, + {6, 9, 6, 8, 32, 4}, + {6, 9, 7, 8, 32, 4}, + {6, 9, 8, 16, 32, 4}, + {6, 9, 9, 32, 16, 8}, + {6, 9, 10, 32, 32, 8}, + {6, 9, 11, 32, 16, 8}, + {6, 9, 12, 16, 16, 8}, + {6, 9, 13, 8, 32, 8}, + {6, 9, 14, 8, 32, 8}, + {6, 9, 15, 16, 32, 8}, + {6, 10, 1, 8, 32, 1}, + {6, 10, 2, 8, 32, 1}, + {6, 10, 3, 8, 32, 1}, + {6, 10, 4, 8, 32, 1}, + {6, 10, 5, 8, 16, 1}, + {6, 10, 6, 8, 32, 4}, + {6, 10, 7, 32, 16, 2}, + {6, 10, 8, 16, 32, 4}, + {6, 10, 9, 8, 32, 8}, + {6, 10, 10, 16, 32, 4}, + {6, 10, 11, 32, 32, 8}, + {6, 10, 12, 16, 32, 4}, + {6, 10, 13, 16, 32, 8}, + {6, 10, 14, 16, 16, 8}, + {6, 10, 15, 16, 64, 8}, + {6, 11, 1, 8, 32, 1}, + {6, 11, 2, 8, 32, 1}, + {6, 11, 3, 8, 32, 1}, + {6, 11, 4, 8, 32, 1}, + {6, 11, 5, 16, 32, 2}, + {6, 11, 6, 8, 32, 2}, + {6, 11, 7, 8, 32, 2}, + {6, 11, 8, 16, 16, 4}, + {6, 11, 9, 16, 32, 8}, + {6, 11, 10, 8, 64, 8}, + {6, 11, 11, 8, 32, 8}, + {6, 11, 12, 32, 16, 8}, + {6, 11, 13, 16, 32, 8}, + {6, 11, 14, 32, 32, 8}, + {6, 11, 15, 16, 32, 8}, + {6, 12, 1, 8, 32, 1}, + {6, 12, 2, 16, 32, 1}, + {6, 12, 3, 8, 32, 1}, + {6, 12, 4, 8, 32, 1}, + {6, 12, 5, 8, 32, 1}, + {6, 12, 6, 8, 64, 4}, + {6, 12, 7, 16, 32, 4}, + {6, 12, 8, 16, 32, 2}, + {6, 12, 9, 32, 32, 4}, + {6, 12, 10, 16, 16, 4}, + {6, 12, 11, 16, 32, 4}, + {6, 12, 12, 16, 32, 8}, + {6, 12, 13, 16, 32, 8}, + {6, 12, 14, 32, 32, 4}, + {6, 12, 15, 32, 32, 4}, + {6, 13, 1, 16, 32, 1}, + {6, 13, 2, 8, 32, 1}, + {6, 13, 3, 16, 16, 1}, + {6, 13, 4, 8, 32, 1}, + {6, 13, 5, 32, 32, 2}, + {6, 13, 6, 32, 16, 1}, + {6, 13, 7, 16, 32, 4}, + {6, 13, 8, 16, 32, 8}, + {6, 13, 9, 32, 32, 8}, + {6, 13, 10, 32, 32, 4}, + {6, 13, 11, 16, 32, 4}, + {6, 13, 12, 32, 32, 4}, + {6, 13, 13, 32, 32, 4}, + {6, 13, 14, 32, 32, 4}, + {6, 13, 15, 32, 32, 4}, + {6, 14, 1, 8, 64, 1}, + {6, 14, 2, 32, 32, 1}, + {6, 14, 3, 16, 32, 1}, + {6, 14, 4, 16, 32, 1}, + {6, 14, 5, 8, 32, 1}, + {6, 14, 6, 16, 32, 4}, + {6, 14, 7, 16, 32, 4}, + {6, 14, 8, 16, 32, 4}, + {6, 14, 9, 16, 32, 4}, + {6, 14, 10, 16, 32, 8}, + {6, 14, 11, 16, 32, 4}, + {6, 14, 12, 32, 32, 8}, + {6, 14, 13, 32, 32, 8}, + {6, 14, 14, 32, 32, 8}, + {6, 14, 15, 32, 32, 8}, + {6, 15, 1, 16, 32, 1}, + {6, 15, 2, 8, 32, 1}, + {6, 15, 3, 16, 32, 1}, + {6, 15, 4, 8, 32, 1}, + {6, 15, 5, 8, 32, 1}, + {6, 15, 6, 16, 32, 1}, + {6, 15, 7, 32, 32, 4}, + {6, 15, 8, 32, 32, 4}, + {6, 15, 9, 16, 32, 2}, + {6, 15, 10, 32, 32, 8}, + {6, 15, 11, 32, 32, 2}, + {6, 15, 12, 32, 32, 4}, + {6, 15, 13, 32, 32, 4}, + {6, 15, 14, 32, 32, 4}, + {6, 15, 15, 32, 32, 4}, + {7, 0, 1, 8, 16, 1}, + {7, 0, 2, 16, 16, 1}, + {7, 0, 3, 8, 16, 1}, + {7, 0, 4, 8, 16, 4}, + {7, 0, 5, 8, 16, 4}, + {7, 0, 6, 8, 16, 8}, + {7, 0, 7, 8, 64, 8}, + {7, 0, 8, 8, 16, 8}, + {7, 0, 9, 8, 64, 8}, + {7, 0, 10, 8, 64, 8}, + {7, 0, 11, 16, 16, 8}, + {7, 0, 12, 8, 32, 8}, + {7, 0, 13, 8, 16, 8}, + {7, 0, 14, 8, 16, 8}, + {7, 0, 15, 8, 16, 8}, + {7, 1, 1, 8, 16, 1}, + {7, 1, 2, 8, 16, 1}, + {7, 1, 3, 8, 16, 2}, + {7, 1, 4, 8, 16, 4}, + {7, 1, 5, 8, 16, 2}, + {7, 1, 6, 8, 16, 4}, + {7, 1, 7, 8, 16, 4}, + {7, 1, 8, 8, 16, 4}, + {7, 1, 9, 8, 16, 8}, + {7, 1, 10, 8, 16, 8}, + {7, 1, 11, 8, 32, 8}, + {7, 1, 12, 8, 32, 8}, + {7, 1, 13, 8, 32, 8}, + {7, 1, 14, 8, 16, 8}, + {7, 1, 15, 8, 32, 8}, + {7, 2, 1, 8, 32, 1}, + {7, 2, 2, 8, 16, 1}, + {7, 2, 3, 8, 32, 2}, + {7, 2, 4, 8, 16, 4}, + {7, 2, 5, 8, 16, 2}, + {7, 2, 6, 8, 32, 4}, + {7, 2, 7, 16, 16, 8}, + {7, 2, 8, 16, 32, 8}, + {7, 2, 9, 8, 32, 8}, + {7, 2, 10, 8, 64, 8}, + {7, 2, 11, 16, 16, 8}, + {7, 2, 12, 16, 32, 8}, + {7, 2, 13, 8, 64, 8}, + {7, 2, 14, 8, 16, 8}, + {7, 2, 15, 8, 32, 8}, + {7, 3, 1, 8, 32, 1}, + {7, 3, 2, 8, 16, 1}, + {7, 3, 3, 8, 32, 1}, + {7, 3, 4, 8, 16, 2}, + {7, 3, 5, 8, 16, 4}, + {7, 3, 6, 8, 16, 4}, + {7, 3, 7, 8, 32, 4}, + {7, 3, 8, 8, 16, 4}, + {7, 3, 9, 8, 32, 8}, + {7, 3, 10, 8, 16, 8}, + {7, 3, 11, 16, 16, 8}, + {7, 3, 12, 8, 16, 8}, + {7, 3, 13, 8, 32, 8}, + {7, 3, 14, 8, 16, 8}, + {7, 3, 15, 8, 16, 4}, + {7, 4, 1, 8, 16, 1}, + {7, 4, 2, 8, 32, 1}, + {7, 4, 3, 8, 32, 2}, + {7, 4, 4, 8, 32, 2}, + {7, 4, 5, 8, 16, 4}, + {7, 4, 6, 8, 16, 4}, + {7, 4, 7, 8, 16, 8}, + {7, 4, 8, 8, 16, 4}, + {7, 4, 9, 8, 32, 8}, + {7, 4, 10, 8, 64, 8}, + {7, 4, 11, 16, 16, 8}, + {7, 4, 12, 16, 32, 8}, + {7, 4, 13, 16, 16, 8}, + {7, 4, 14, 8, 32, 8}, + {7, 4, 15, 16, 32, 8}, + {7, 5, 1, 8, 16, 1}, + {7, 5, 2, 16, 16, 1}, + {7, 5, 3, 8, 32, 2}, + {7, 5, 4, 8, 16, 4}, + {7, 5, 5, 8, 16, 4}, + {7, 5, 6, 8, 16, 4}, + {7, 5, 7, 8, 16, 4}, + {7, 5, 8, 8, 32, 4}, + {7, 5, 9, 8, 32, 8}, + {7, 5, 10, 8, 32, 4}, + {7, 5, 11, 16, 16, 8}, + {7, 5, 12, 8, 32, 8}, + {7, 5, 13, 8, 64, 8}, + {7, 5, 14, 8, 64, 8}, + {7, 5, 15, 16, 16, 8}, + {7, 6, 1, 8, 16, 1}, + {7, 6, 2, 8, 16, 2}, + {7, 6, 3, 16, 32, 1}, + {7, 6, 4, 16, 16, 4}, + {7, 6, 5, 8, 16, 4}, + {7, 6, 6, 8, 16, 4}, + {7, 6, 7, 8, 16, 2}, + {7, 6, 8, 16, 32, 8}, + {7, 6, 9, 8, 16, 8}, + {7, 6, 10, 16, 32, 8}, + {7, 6, 11, 8, 32, 8}, + {7, 6, 12, 16, 16, 8}, + {7, 6, 13, 16, 32, 8}, + {7, 6, 14, 16, 32, 8}, + {7, 6, 15, 16, 32, 8}, + {7, 7, 1, 8, 32, 1}, + {7, 7, 2, 8, 32, 1}, + {7, 7, 3, 8, 32, 1}, + {7, 7, 4, 8, 32, 2}, + {7, 7, 5, 8, 32, 2}, + {7, 7, 6, 16, 32, 1}, + {7, 7, 7, 8, 16, 2}, + {7, 7, 8, 16, 16, 2}, + {7, 7, 9, 16, 32, 8}, + {7, 7, 10, 16, 16, 4}, + {7, 7, 11, 16, 32, 8}, + {7, 7, 12, 16, 16, 8}, + {7, 7, 13, 16, 32, 8}, + {7, 7, 14, 16, 32, 8}, + {7, 7, 15, 16, 32, 8}, + {7, 8, 1, 16, 32, 1}, + {7, 8, 2, 8, 16, 1}, + {7, 8, 3, 16, 16, 1}, + {7, 8, 4, 8, 32, 1}, + {7, 8, 5, 8, 32, 2}, + {7, 8, 6, 16, 32, 2}, + {7, 8, 7, 8, 32, 8}, + {7, 8, 8, 8, 32, 4}, + {7, 8, 9, 16, 32, 8}, + {7, 8, 10, 32, 16, 4}, + {7, 8, 11, 16, 32, 8}, + {7, 8, 12, 16, 64, 8}, + {7, 8, 13, 16, 32, 8}, + {7, 8, 14, 32, 32, 8}, + {7, 8, 15, 16, 32, 4}, + {7, 9, 1, 8, 16, 1}, + {7, 9, 2, 8, 32, 1}, + {7, 9, 3, 8, 32, 1}, + {7, 9, 4, 8, 32, 1}, + {7, 9, 5, 8, 32, 1}, + {7, 9, 6, 8, 32, 1}, + {7, 9, 7, 8, 32, 4}, + {7, 9, 8, 32, 16, 4}, + {7, 9, 9, 16, 32, 4}, + {7, 9, 10, 32, 32, 4}, + {7, 9, 11, 16, 64, 4}, + {7, 9, 12, 16, 64, 8}, + {7, 9, 13, 16, 32, 8}, + {7, 9, 14, 16, 32, 8}, + {7, 9, 15, 32, 32, 8}, + {7, 10, 1, 8, 32, 1}, + {7, 10, 2, 8, 32, 1}, + {7, 10, 3, 16, 32, 1}, + {7, 10, 4, 32, 32, 4}, + {7, 10, 5, 8, 32, 1}, + {7, 10, 6, 16, 16, 2}, + {7, 10, 7, 16, 32, 1}, + {7, 10, 8, 16, 32, 2}, + {7, 10, 9, 32, 32, 8}, + {7, 10, 10, 16, 32, 4}, + {7, 10, 11, 16, 64, 4}, + {7, 10, 12, 16, 64, 4}, + {7, 10, 13, 16, 64, 4}, + {7, 10, 14, 32, 32, 8}, + {7, 10, 15, 32, 32, 4}, + {7, 11, 1, 16, 32, 1}, + {7, 11, 2, 16, 32, 1}, + {7, 11, 3, 16, 32, 1}, + {7, 11, 4, 8, 32, 1}, + {7, 11, 5, 16, 32, 1}, + {7, 11, 6, 16, 32, 2}, + {7, 11, 7, 32, 32, 2}, + {7, 11, 8, 16, 32, 4}, + {7, 11, 9, 16, 32, 4}, + {7, 11, 10, 16, 32, 8}, + {7, 11, 11, 16, 32, 4}, + {7, 11, 12, 16, 32, 8}, + {7, 11, 13, 32, 32, 4}, + {7, 11, 14, 32, 32, 8}, + {7, 11, 15, 32, 32, 8}, + {7, 12, 1, 8, 32, 1}, + {7, 12, 2, 16, 32, 1}, + {7, 12, 3, 8, 32, 1}, + {7, 12, 4, 8, 32, 1}, + {7, 12, 5, 16, 32, 1}, + {7, 12, 6, 16, 32, 1}, + {7, 12, 7, 16, 32, 4}, + {7, 12, 8, 32, 32, 2}, + {7, 12, 9, 32, 32, 2}, + {7, 12, 10, 16, 32, 4}, + {7, 12, 11, 16, 32, 8}, + {7, 12, 12, 32, 32, 8}, + {7, 12, 13, 64, 16, 2}, + {7, 12, 14, 32, 32, 2}, + {7, 12, 15, 32, 32, 8}, + {7, 13, 1, 16, 64, 1}, + {7, 13, 2, 8, 32, 1}, + {7, 13, 3, 16, 32, 1}, + {7, 13, 4, 16, 32, 1}, + {7, 13, 5, 16, 32, 1}, + {7, 13, 6, 32, 32, 1}, + {7, 13, 7, 16, 32, 4}, + {7, 13, 8, 16, 32, 4}, + {7, 13, 9, 16, 32, 4}, + {7, 13, 10, 32, 32, 8}, + {7, 13, 11, 32, 32, 8}, + {7, 13, 12, 32, 32, 4}, + {7, 13, 13, 32, 32, 4}, + {7, 13, 14, 32, 32, 8}, + {7, 13, 15, 32, 32, 2}, + {7, 14, 1, 8, 32, 1}, + {7, 14, 2, 32, 32, 1}, + {7, 14, 3, 32, 32, 1}, + {7, 14, 4, 32, 32, 1}, + {7, 14, 5, 32, 32, 1}, + {7, 14, 6, 32, 32, 1}, + {7, 14, 7, 32, 32, 1}, + {7, 14, 8, 32, 32, 1}, + {7, 14, 9, 32, 32, 4}, + {7, 14, 10, 32, 32, 4}, + {7, 14, 11, 32, 32, 8}, + {7, 14, 12, 32, 32, 8}, + {7, 14, 13, 32, 32, 4}, + {7, 14, 14, 32, 32, 8}, + {7, 14, 15, 32, 32, 8}, + {7, 15, 1, 16, 32, 1}, + {7, 15, 2, 32, 32, 1}, + {7, 15, 3, 16, 32, 1}, + {7, 15, 4, 16, 32, 1}, + {7, 15, 5, 32, 32, 1}, + {7, 15, 6, 32, 32, 1}, + {7, 15, 7, 32, 32, 2}, + {7, 15, 8, 32, 32, 2}, + {7, 15, 9, 32, 32, 2}, + {7, 15, 10, 32, 32, 2}, + {7, 15, 11, 32, 32, 2}, + {7, 15, 12, 32, 32, 4}, + {7, 15, 13, 32, 32, 2}, + {7, 15, 14, 32, 32, 2}, + {7, 15, 15, 32, 32, 2}, + {8, 0, 1, 8, 16, 1}, + {8, 0, 2, 8, 16, 1}, + {8, 0, 3, 8, 16, 1}, + {8, 0, 4, 8, 16, 4}, + {8, 0, 5, 8, 16, 4}, + {8, 0, 6, 8, 16, 4}, + {8, 0, 7, 8, 16, 2}, + {8, 0, 8, 8, 16, 8}, + {8, 0, 9, 8, 16, 4}, + {8, 0, 10, 16, 16, 8}, + {8, 0, 11, 8, 32, 8}, + {8, 0, 12, 16, 16, 8}, + {8, 0, 13, 8, 16, 8}, + {8, 0, 14, 8, 64, 8}, + {8, 0, 15, 8, 16, 8}, + {8, 1, 1, 8, 32, 1}, + {8, 1, 2, 8, 16, 1}, + {8, 1, 3, 8, 16, 1}, + {8, 1, 4, 8, 16, 4}, + {8, 1, 5, 8, 16, 2}, + {8, 1, 6, 8, 16, 4}, + {8, 1, 7, 8, 16, 4}, + {8, 1, 8, 8, 16, 8}, + {8, 1, 9, 16, 16, 8}, + {8, 1, 10, 8, 32, 4}, + {8, 1, 11, 8, 16, 8}, + {8, 1, 12, 8, 16, 8}, + {8, 1, 13, 8, 32, 8}, + {8, 1, 14, 8, 16, 8}, + {8, 1, 15, 8, 32, 8}, + {8, 2, 1, 16, 16, 1}, + {8, 2, 2, 8, 16, 1}, + {8, 2, 3, 8, 16, 1}, + {8, 2, 4, 8, 16, 2}, + {8, 2, 5, 8, 32, 4}, + {8, 2, 6, 8, 32, 2}, + {8, 2, 7, 8, 32, 4}, + {8, 2, 8, 8, 16, 4}, + {8, 2, 9, 32, 16, 8}, + {8, 2, 10, 8, 16, 8}, + {8, 2, 11, 8, 16, 8}, + {8, 2, 12, 8, 16, 8}, + {8, 2, 13, 8, 16, 8}, + {8, 2, 14, 8, 16, 8}, + {8, 2, 15, 8, 16, 8}, + {8, 3, 1, 8, 32, 1}, + {8, 3, 2, 8, 16, 1}, + {8, 3, 3, 8, 16, 1}, + {8, 3, 4, 16, 16, 4}, + {8, 3, 5, 8, 16, 4}, + {8, 3, 6, 16, 16, 8}, + {8, 3, 7, 16, 32, 4}, + {8, 3, 8, 8, 32, 4}, + {8, 3, 9, 32, 16, 8}, + {8, 3, 10, 8, 32, 8}, + {8, 3, 11, 8, 16, 4}, + {8, 3, 12, 16, 16, 8}, + {8, 3, 13, 16, 16, 8}, + {8, 3, 14, 8, 32, 4}, + {8, 3, 15, 16, 16, 8}, + {8, 4, 1, 8, 16, 1}, + {8, 4, 2, 8, 16, 1}, + {8, 4, 3, 8, 32, 1}, + {8, 4, 4, 8, 16, 2}, + {8, 4, 5, 8, 16, 4}, + {8, 4, 6, 8, 16, 4}, + {8, 4, 7, 16, 16, 4}, + {8, 4, 8, 16, 32, 8}, + {8, 4, 9, 16, 16, 4}, + {8, 4, 10, 8, 32, 8}, + {8, 4, 11, 8, 32, 8}, + {8, 4, 12, 8, 64, 8}, + {8, 4, 13, 16, 16, 8}, + {8, 4, 14, 16, 16, 8}, + {8, 4, 15, 8, 32, 8}, + {8, 5, 1, 16, 16, 1}, + {8, 5, 2, 8, 32, 1}, + {8, 5, 3, 8, 32, 1}, + {8, 5, 4, 16, 16, 4}, + {8, 5, 5, 8, 16, 4}, + {8, 5, 6, 16, 32, 4}, + {8, 5, 7, 8, 32, 4}, + {8, 5, 8, 8, 64, 8}, + {8, 5, 9, 16, 32, 8}, + {8, 5, 10, 8, 32, 8}, + {8, 5, 11, 8, 64, 8}, + {8, 5, 12, 8, 32, 8}, + {8, 5, 13, 16, 32, 8}, + {8, 5, 14, 16, 32, 8}, + {8, 5, 15, 16, 32, 8}, + {8, 6, 1, 8, 16, 1}, + {8, 6, 2, 8, 16, 2}, + {8, 6, 3, 16, 16, 1}, + {8, 6, 4, 8, 32, 4}, + {8, 6, 5, 8, 32, 4}, + {8, 6, 6, 16, 32, 2}, + {8, 6, 7, 8, 32, 2}, + {8, 6, 8, 16, 16, 4}, + {8, 6, 9, 16, 32, 4}, + {8, 6, 10, 8, 32, 8}, + {8, 6, 11, 32, 16, 8}, + {8, 6, 12, 32, 16, 8}, + {8, 6, 13, 32, 16, 8}, + {8, 6, 14, 16, 32, 8}, + {8, 6, 15, 16, 32, 8}, + {8, 7, 1, 8, 16, 1}, + {8, 7, 2, 8, 16, 1}, + {8, 7, 3, 16, 16, 1}, + {8, 7, 4, 16, 16, 1}, + {8, 7, 5, 16, 16, 1}, + {8, 7, 6, 16, 16, 2}, + {8, 7, 7, 8, 32, 4}, + {8, 7, 8, 8, 64, 8}, + {8, 7, 9, 16, 32, 8}, + {8, 7, 10, 16, 64, 8}, + {8, 7, 11, 16, 64, 8}, + {8, 7, 12, 32, 16, 4}, + {8, 7, 13, 16, 64, 8}, + {8, 7, 14, 16, 32, 8}, + {8, 7, 15, 32, 32, 8}, + {8, 8, 1, 8, 32, 1}, + {8, 8, 2, 8, 32, 1}, + {8, 8, 3, 16, 16, 1}, + {8, 8, 4, 16, 16, 1}, + {8, 8, 5, 16, 16, 1}, + {8, 8, 6, 16, 32, 2}, + {8, 8, 7, 16, 32, 4}, + {8, 8, 8, 16, 32, 2}, + {8, 8, 9, 16, 32, 8}, + {8, 8, 10, 16, 16, 4}, + {8, 8, 11, 32, 32, 4}, + {8, 8, 12, 16, 32, 8}, + {8, 8, 13, 16, 32, 8}, + {8, 8, 14, 32, 32, 8}, + {8, 8, 15, 16, 64, 8}, + {8, 9, 1, 8, 32, 1}, + {8, 9, 2, 16, 16, 1}, + {8, 9, 3, 16, 16, 1}, + {8, 9, 4, 32, 16, 1}, + {8, 9, 5, 8, 32, 1}, + {8, 9, 6, 8, 64, 2}, + {8, 9, 7, 8, 32, 1}, + {8, 9, 8, 16, 32, 4}, + {8, 9, 9, 32, 16, 8}, + {8, 9, 10, 32, 32, 4}, + {8, 9, 11, 32, 32, 4}, + {8, 9, 12, 32, 32, 4}, + {8, 9, 13, 32, 32, 4}, + {8, 9, 14, 32, 32, 4}, + {8, 9, 15, 32, 32, 4}, + {8, 10, 1, 8, 32, 1}, + {8, 10, 2, 16, 32, 1}, + {8, 10, 3, 16, 32, 1}, + {8, 10, 4, 32, 16, 1}, + {8, 10, 5, 16, 16, 1}, + {8, 10, 6, 16, 16, 1}, + {8, 10, 7, 32, 32, 2}, + {8, 10, 8, 16, 64, 2}, + {8, 10, 9, 32, 32, 4}, + {8, 10, 10, 32, 32, 4}, + {8, 10, 11, 16, 32, 4}, + {8, 10, 12, 32, 32, 8}, + {8, 10, 13, 16, 64, 8}, + {8, 10, 14, 16, 32, 4}, + {8, 10, 15, 32, 32, 8}, + {8, 11, 1, 8, 32, 1}, + {8, 11, 2, 16, 32, 1}, + {8, 11, 3, 16, 32, 1}, + {8, 11, 4, 32, 16, 1}, + {8, 11, 5, 16, 64, 2}, + {8, 11, 6, 16, 32, 1}, + {8, 11, 7, 16, 32, 1}, + {8, 11, 8, 16, 32, 2}, + {8, 11, 9, 16, 64, 2}, + {8, 11, 10, 32, 32, 2}, + {8, 11, 11, 16, 64, 4}, + {8, 11, 12, 32, 32, 4}, + {8, 11, 13, 32, 32, 8}, + {8, 11, 14, 32, 32, 8}, + {8, 11, 15, 32, 32, 4}, + {8, 12, 1, 8, 32, 1}, + {8, 12, 2, 8, 32, 1}, + {8, 12, 3, 16, 32, 1}, + {8, 12, 4, 32, 32, 1}, + {8, 12, 5, 32, 32, 1}, + {8, 12, 6, 16, 32, 2}, + {8, 12, 7, 32, 32, 1}, + {8, 12, 8, 16, 32, 4}, + {8, 12, 9, 32, 32, 2}, + {8, 12, 10, 16, 32, 4}, + {8, 12, 11, 32, 32, 8}, + {8, 12, 12, 32, 32, 4}, + {8, 12, 13, 32, 32, 4}, + {8, 12, 14, 32, 32, 4}, + {8, 12, 15, 32, 32, 8}, + {8, 13, 1, 16, 32, 1}, + {8, 13, 2, 16, 32, 1}, + {8, 13, 3, 16, 32, 1}, + {8, 13, 4, 32, 32, 1}, + {8, 13, 5, 16, 32, 1}, + {8, 13, 6, 32, 32, 1}, + {8, 13, 7, 32, 32, 1}, + {8, 13, 8, 16, 32, 4}, + {8, 13, 9, 32, 32, 4}, + {8, 13, 10, 32, 32, 4}, + {8, 13, 11, 32, 32, 4}, + {8, 13, 12, 32, 32, 4}, + {8, 13, 13, 64, 16, 1}, + {8, 13, 14, 32, 32, 2}, + {8, 13, 15, 16, 64, 2}, + {8, 14, 1, 16, 32, 1}, + {8, 14, 2, 16, 32, 1}, + {8, 14, 3, 8, 64, 1}, + {8, 14, 4, 16, 32, 1}, + {8, 14, 5, 16, 32, 1}, + {8, 14, 6, 32, 32, 1}, + {8, 14, 7, 16, 32, 1}, + {8, 14, 8, 32, 32, 4}, + {8, 14, 9, 32, 32, 4}, + {8, 14, 10, 32, 32, 4}, + {8, 14, 11, 32, 32, 4}, + {8, 14, 12, 16, 32, 8}, + {8, 14, 13, 32, 32, 4}, + {8, 14, 14, 32, 32, 8}, + {8, 14, 15, 32, 32, 8}, + {8, 15, 1, 16, 32, 1}, + {8, 15, 2, 16, 32, 1}, + {8, 15, 3, 16, 32, 1}, + {8, 15, 4, 16, 32, 1}, + {8, 15, 5, 32, 32, 1}, + {8, 15, 6, 16, 32, 1}, + {8, 15, 7, 32, 32, 1}, + {8, 15, 8, 32, 32, 1}, + {8, 15, 9, 32, 32, 2}, + {8, 15, 10, 32, 32, 2}, + {8, 15, 11, 32, 32, 2}, + {8, 15, 12, 32, 32, 2}, + {8, 15, 13, 64, 32, 1}, + {8, 15, 14, 64, 16, 1}, + {8, 15, 15, 64, 16, 1}, + {9, 0, 1, 16, 32, 1}, + {9, 0, 2, 16, 16, 1}, + {9, 0, 3, 8, 16, 1}, + {9, 0, 4, 8, 32, 4}, + {9, 0, 5, 8, 16, 4}, + {9, 0, 6, 8, 32, 8}, + {9, 0, 7, 16, 32, 8}, + {9, 0, 8, 8, 16, 8}, + {9, 0, 9, 8, 32, 4}, + {9, 0, 10, 8, 64, 8}, + {9, 0, 11, 16, 16, 8}, + {9, 0, 12, 8, 16, 4}, + {9, 0, 13, 8, 16, 8}, + {9, 0, 14, 16, 16, 8}, + {9, 0, 15, 8, 16, 8}, + {9, 1, 1, 8, 16, 1}, + {9, 1, 2, 8, 16, 2}, + {9, 1, 3, 16, 16, 2}, + {9, 1, 4, 8, 32, 4}, + {9, 1, 5, 8, 16, 4}, + {9, 1, 6, 16, 16, 4}, + {9, 1, 7, 16, 32, 4}, + {9, 1, 8, 32, 16, 8}, + {9, 1, 9, 16, 16, 4}, + {9, 1, 10, 8, 16, 4}, + {9, 1, 11, 16, 16, 4}, + {9, 1, 12, 8, 16, 8}, + {9, 1, 13, 8, 16, 8}, + {9, 1, 14, 8, 16, 8}, + {9, 1, 15, 8, 16, 8}, + {9, 2, 1, 8, 32, 1}, + {9, 2, 2, 8, 16, 2}, + {9, 2, 3, 8, 32, 2}, + {9, 2, 4, 8, 32, 2}, + {9, 2, 5, 8, 32, 4}, + {9, 2, 6, 16, 16, 4}, + {9, 2, 7, 8, 32, 2}, + {9, 2, 8, 8, 32, 4}, + {9, 2, 9, 16, 16, 8}, + {9, 2, 10, 16, 64, 8}, + {9, 2, 11, 8, 32, 8}, + {9, 2, 12, 8, 16, 4}, + {9, 2, 13, 8, 32, 8}, + {9, 2, 14, 16, 32, 8}, + {9, 2, 15, 8, 32, 8}, + {9, 3, 1, 16, 16, 1}, + {9, 3, 2, 8, 16, 1}, + {9, 3, 3, 16, 16, 1}, + {9, 3, 4, 8, 16, 4}, + {9, 3, 5, 16, 16, 1}, + {9, 3, 6, 8, 16, 4}, + {9, 3, 7, 8, 16, 8}, + {9, 3, 8, 8, 32, 8}, + {9, 3, 9, 8, 16, 4}, + {9, 3, 10, 8, 16, 8}, + {9, 3, 11, 8, 32, 8}, + {9, 3, 12, 8, 64, 8}, + {9, 3, 13, 8, 16, 4}, + {9, 3, 14, 8, 32, 8}, + {9, 3, 15, 16, 32, 8}, + {9, 4, 1, 8, 32, 1}, + {9, 4, 2, 8, 16, 1}, + {9, 4, 3, 8, 16, 2}, + {9, 4, 4, 8, 32, 4}, + {9, 4, 5, 16, 16, 1}, + {9, 4, 6, 8, 16, 4}, + {9, 4, 7, 8, 32, 2}, + {9, 4, 8, 8, 32, 4}, + {9, 4, 9, 8, 64, 8}, + {9, 4, 10, 8, 32, 4}, + {9, 4, 11, 8, 32, 4}, + {9, 4, 12, 8, 32, 4}, + {9, 4, 13, 8, 64, 8}, + {9, 4, 14, 8, 64, 8}, + {9, 4, 15, 16, 32, 8}, + {9, 5, 1, 8, 32, 1}, + {9, 5, 2, 16, 32, 1}, + {9, 5, 3, 8, 32, 2}, + {9, 5, 4, 16, 32, 1}, + {9, 5, 5, 16, 16, 2}, + {9, 5, 6, 8, 32, 4}, + {9, 5, 7, 16, 16, 2}, + {9, 5, 8, 16, 16, 4}, + {9, 5, 9, 16, 16, 4}, + {9, 5, 10, 8, 32, 4}, + {9, 5, 11, 8, 32, 4}, + {9, 5, 12, 16, 32, 8}, + {9, 5, 13, 16, 32, 8}, + {9, 5, 14, 16, 32, 8}, + {9, 5, 15, 16, 32, 8}, + {9, 6, 1, 8, 16, 1}, + {9, 6, 2, 8, 32, 2}, + {9, 6, 3, 16, 16, 1}, + {9, 6, 4, 8, 32, 2}, + {9, 6, 5, 8, 16, 1}, + {9, 6, 6, 8, 32, 2}, + {9, 6, 7, 8, 32, 8}, + {9, 6, 8, 32, 16, 4}, + {9, 6, 9, 32, 16, 8}, + {9, 6, 10, 32, 32, 8}, + {9, 6, 11, 16, 32, 8}, + {9, 6, 12, 16, 16, 4}, + {9, 6, 13, 16, 32, 8}, + {9, 6, 14, 32, 16, 8}, + {9, 6, 15, 16, 32, 8}, + {9, 7, 1, 8, 32, 1}, + {9, 7, 2, 8, 32, 1}, + {9, 7, 3, 8, 32, 1}, + {9, 7, 4, 8, 32, 2}, + {9, 7, 5, 16, 16, 2}, + {9, 7, 6, 16, 16, 2}, + {9, 7, 7, 16, 16, 2}, + {9, 7, 8, 8, 32, 4}, + {9, 7, 9, 16, 16, 4}, + {9, 7, 10, 16, 32, 4}, + {9, 7, 11, 16, 64, 8}, + {9, 7, 12, 16, 32, 8}, + {9, 7, 13, 16, 32, 8}, + {9, 7, 14, 32, 32, 8}, + {9, 7, 15, 16, 64, 8}, + {9, 8, 1, 8, 32, 1}, + {9, 8, 2, 8, 32, 1}, + {9, 8, 3, 16, 32, 1}, + {9, 8, 4, 8, 32, 1}, + {9, 8, 5, 32, 32, 2}, + {9, 8, 6, 16, 32, 2}, + {9, 8, 7, 16, 32, 2}, + {9, 8, 8, 32, 32, 4}, + {9, 8, 9, 32, 32, 2}, + {9, 8, 10, 32, 32, 4}, + {9, 8, 11, 16, 64, 4}, + {9, 8, 12, 32, 32, 4}, + {9, 8, 13, 32, 32, 4}, + {9, 8, 14, 32, 32, 4}, + {9, 8, 15, 32, 32, 4}, + {9, 9, 1, 8, 32, 1}, + {9, 9, 2, 8, 64, 1}, + {9, 9, 3, 16, 32, 1}, + {9, 9, 4, 8, 32, 1}, + {9, 9, 5, 16, 32, 1}, + {9, 9, 6, 16, 32, 1}, + {9, 9, 7, 16, 32, 4}, + {9, 9, 8, 16, 64, 2}, + {9, 9, 9, 32, 32, 4}, + {9, 9, 10, 16, 64, 4}, + {9, 9, 11, 32, 32, 8}, + {9, 9, 12, 32, 32, 8}, + {9, 9, 13, 32, 32, 8}, + {9, 9, 14, 32, 32, 8}, + {9, 9, 15, 32, 32, 8}, + {9, 10, 1, 8, 32, 1}, + {9, 10, 2, 8, 32, 1}, + {9, 10, 3, 16, 32, 1}, + {9, 10, 4, 8, 32, 1}, + {9, 10, 5, 32, 32, 2}, + {9, 10, 6, 16, 32, 2}, + {9, 10, 7, 32, 32, 2}, + {9, 10, 8, 16, 32, 2}, + {9, 10, 9, 16, 64, 2}, + {9, 10, 10, 32, 32, 2}, + {9, 10, 11, 32, 32, 2}, + {9, 10, 12, 32, 32, 8}, + {9, 10, 13, 32, 32, 8}, + {9, 10, 14, 32, 32, 8}, + {9, 10, 15, 32, 32, 8}, + {9, 11, 1, 16, 32, 1}, + {9, 11, 2, 32, 32, 1}, + {9, 11, 3, 8, 64, 1}, + {9, 11, 4, 16, 32, 1}, + {9, 11, 5, 16, 32, 1}, + {9, 11, 6, 32, 32, 1}, + {9, 11, 7, 16, 32, 2}, + {9, 11, 8, 32, 32, 4}, + {9, 11, 9, 32, 32, 2}, + {9, 11, 10, 32, 32, 4}, + {9, 11, 11, 32, 32, 4}, + {9, 11, 12, 32, 32, 8}, + {9, 11, 13, 32, 32, 8}, + {9, 11, 14, 32, 32, 8}, + {9, 11, 15, 32, 32, 8}, + {9, 12, 1, 8, 64, 1}, + {9, 12, 2, 16, 32, 1}, + {9, 12, 3, 16, 32, 1}, + {9, 12, 4, 16, 32, 1}, + {9, 12, 5, 32, 32, 1}, + {9, 12, 6, 32, 32, 1}, + {9, 12, 7, 32, 32, 1}, + {9, 12, 8, 32, 32, 1}, + {9, 12, 9, 32, 32, 4}, + {9, 12, 10, 32, 32, 4}, + {9, 12, 11, 16, 32, 4}, + {9, 12, 12, 32, 32, 4}, + {9, 12, 13, 32, 32, 8}, + {9, 12, 14, 32, 32, 8}, + {9, 12, 15, 32, 32, 8}, + {9, 13, 1, 8, 64, 1}, + {9, 13, 2, 32, 32, 1}, + {9, 13, 3, 16, 32, 1}, + {9, 13, 4, 32, 32, 1}, + {9, 13, 5, 16, 32, 1}, + {9, 13, 6, 16, 32, 1}, + {9, 13, 7, 16, 32, 2}, + {9, 13, 8, 32, 32, 2}, + {9, 13, 9, 32, 32, 4}, + {9, 13, 10, 32, 32, 2}, + {9, 13, 11, 32, 32, 4}, + {9, 13, 12, 32, 32, 4}, + {9, 13, 13, 32, 32, 2}, + {9, 13, 14, 32, 32, 8}, + {9, 13, 15, 32, 32, 1}, + {9, 14, 1, 16, 32, 1}, + {9, 14, 2, 16, 32, 1}, + {9, 14, 3, 16, 32, 1}, + {9, 14, 4, 32, 32, 1}, + {9, 14, 5, 32, 32, 1}, + {9, 14, 6, 32, 32, 1}, + {9, 14, 7, 32, 32, 2}, + {9, 14, 8, 32, 32, 2}, + {9, 14, 9, 32, 32, 4}, + {9, 14, 10, 32, 32, 4}, + {9, 14, 11, 32, 32, 4}, + {9, 14, 12, 32, 32, 8}, + {9, 14, 13, 32, 32, 8}, + {9, 14, 14, 64, 32, 8}, + {9, 14, 15, 32, 32, 4}, + {9, 15, 1, 16, 64, 1}, + {9, 15, 2, 32, 32, 1}, + {9, 15, 3, 16, 32, 1}, + {9, 15, 4, 32, 32, 1}, + {9, 15, 5, 16, 32, 1}, + {9, 15, 6, 16, 32, 1}, + {9, 15, 7, 32, 32, 1}, + {9, 15, 8, 32, 32, 2}, + {9, 15, 9, 32, 32, 2}, + {9, 15, 10, 32, 32, 4}, + {9, 15, 11, 32, 32, 4}, + {9, 15, 12, 32, 32, 8}, + {9, 15, 13, 32, 32, 4}, + {9, 15, 14, 32, 32, 8}, + {9, 15, 15, 32, 32, 8}, + {10, 0, 1, 8, 16, 1}, + {10, 0, 2, 8, 16, 1}, + {10, 0, 3, 8, 16, 1}, + {10, 0, 4, 8, 16, 2}, + {10, 0, 5, 8, 16, 4}, + {10, 0, 6, 8, 16, 8}, + {10, 0, 7, 16, 16, 8}, + {10, 0, 8, 16, 16, 4}, + {10, 0, 9, 16, 16, 2}, + {10, 0, 10, 8, 16, 8}, + {10, 0, 11, 8, 32, 8}, + {10, 0, 12, 16, 16, 4}, + {10, 0, 13, 16, 32, 8}, + {10, 0, 14, 8, 16, 8}, + {10, 0, 15, 8, 16, 8}, + {10, 1, 1, 16, 32, 1}, + {10, 1, 2, 8, 16, 1}, + {10, 1, 3, 8, 16, 1}, + {10, 1, 4, 8, 16, 4}, + {10, 1, 5, 16, 16, 2}, + {10, 1, 6, 8, 32, 2}, + {10, 1, 7, 16, 32, 4}, + {10, 1, 8, 16, 16, 2}, + {10, 1, 9, 8, 16, 4}, + {10, 1, 10, 16, 16, 8}, + {10, 1, 11, 8, 16, 4}, + {10, 1, 12, 16, 16, 4}, + {10, 1, 13, 32, 16, 8}, + {10, 1, 14, 8, 16, 8}, + {10, 1, 15, 8, 16, 8}, + {10, 2, 1, 8, 16, 1}, + {10, 2, 2, 8, 16, 1}, + {10, 2, 3, 8, 16, 1}, + {10, 2, 4, 8, 16, 2}, + {10, 2, 5, 8, 16, 4}, + {10, 2, 6, 8, 16, 4}, + {10, 2, 7, 32, 16, 8}, + {10, 2, 8, 16, 16, 8}, + {10, 2, 9, 16, 64, 8}, + {10, 2, 10, 8, 16, 4}, + {10, 2, 11, 8, 16, 4}, + {10, 2, 12, 8, 32, 8}, + {10, 2, 13, 16, 16, 4}, + {10, 2, 14, 16, 16, 8}, + {10, 2, 15, 8, 32, 8}, + {10, 3, 1, 16, 32, 1}, + {10, 3, 2, 8, 32, 1}, + {10, 3, 3, 8, 32, 1}, + {10, 3, 4, 16, 16, 4}, + {10, 3, 5, 8, 16, 4}, + {10, 3, 6, 16, 16, 2}, + {10, 3, 7, 16, 16, 4}, + {10, 3, 8, 16, 16, 4}, + {10, 3, 9, 64, 16, 8}, + {10, 3, 10, 8, 32, 4}, + {10, 3, 11, 8, 32, 4}, + {10, 3, 12, 16, 16, 4}, + {10, 3, 13, 8, 64, 8}, + {10, 3, 14, 16, 16, 4}, + {10, 3, 15, 16, 16, 4}, + {10, 4, 1, 8, 16, 1}, + {10, 4, 2, 8, 32, 2}, + {10, 4, 3, 8, 32, 2}, + {10, 4, 4, 8, 32, 2}, + {10, 4, 5, 8, 16, 4}, + {10, 4, 6, 16, 32, 4}, + {10, 4, 7, 8, 32, 4}, + {10, 4, 8, 8, 32, 4}, + {10, 4, 9, 16, 32, 4}, + {10, 4, 10, 16, 16, 4}, + {10, 4, 11, 16, 16, 4}, + {10, 4, 12, 16, 16, 4}, + {10, 4, 13, 16, 32, 8}, + {10, 4, 14, 16, 32, 8}, + {10, 4, 15, 16, 16, 4}, + {10, 5, 1, 8, 16, 1}, + {10, 5, 2, 8, 16, 1}, + {10, 5, 3, 8, 16, 1}, + {10, 5, 4, 8, 16, 1}, + {10, 5, 5, 16, 32, 2}, + {10, 5, 6, 8, 16, 4}, + {10, 5, 7, 16, 32, 2}, + {10, 5, 8, 16, 32, 8}, + {10, 5, 9, 16, 64, 8}, + {10, 5, 10, 8, 32, 4}, + {10, 5, 11, 8, 32, 4}, + {10, 5, 12, 8, 32, 4}, + {10, 5, 13, 32, 16, 8}, + {10, 5, 14, 32, 32, 8}, + {10, 5, 15, 32, 32, 8}, + {10, 6, 1, 8, 16, 1}, + {10, 6, 2, 8, 16, 1}, + {10, 6, 3, 8, 16, 1}, + {10, 6, 4, 8, 32, 1}, + {10, 6, 5, 16, 32, 1}, + {10, 6, 6, 16, 16, 2}, + {10, 6, 7, 32, 16, 2}, + {10, 6, 8, 16, 32, 4}, + {10, 6, 9, 32, 16, 2}, + {10, 6, 10, 16, 32, 4}, + {10, 6, 11, 32, 32, 8}, + {10, 6, 12, 32, 32, 8}, + {10, 6, 13, 16, 32, 8}, + {10, 6, 14, 32, 32, 8}, + {10, 6, 15, 32, 32, 8}, + {10, 7, 1, 16, 32, 1}, + {10, 7, 2, 16, 16, 1}, + {10, 7, 3, 32, 16, 1}, + {10, 7, 4, 8, 64, 1}, + {10, 7, 5, 16, 32, 1}, + {10, 7, 6, 8, 16, 1}, + {10, 7, 7, 32, 32, 4}, + {10, 7, 8, 16, 32, 2}, + {10, 7, 9, 16, 32, 4}, + {10, 7, 10, 32, 32, 4}, + {10, 7, 11, 32, 32, 4}, + {10, 7, 12, 32, 32, 4}, + {10, 7, 13, 32, 32, 4}, + {10, 7, 14, 32, 32, 4}, + {10, 7, 15, 32, 32, 4}, + {10, 8, 1, 8, 32, 1}, + {10, 8, 2, 8, 32, 1}, + {10, 8, 3, 16, 16, 1}, + {10, 8, 4, 16, 32, 1}, + {10, 8, 5, 16, 64, 2}, + {10, 8, 6, 16, 16, 1}, + {10, 8, 7, 16, 32, 2}, + {10, 8, 8, 32, 32, 2}, + {10, 8, 9, 32, 32, 2}, + {10, 8, 10, 32, 32, 2}, + {10, 8, 11, 32, 32, 4}, + {10, 8, 12, 32, 32, 4}, + {10, 8, 13, 32, 32, 4}, + {10, 8, 14, 32, 32, 8}, + {10, 8, 15, 32, 32, 4}, + {10, 9, 1, 16, 32, 1}, + {10, 9, 2, 16, 32, 1}, + {10, 9, 3, 16, 32, 1}, + {10, 9, 4, 16, 32, 1}, + {10, 9, 5, 32, 32, 1}, + {10, 9, 6, 32, 32, 1}, + {10, 9, 7, 16, 32, 1}, + {10, 9, 8, 32, 32, 2}, + {10, 9, 9, 16, 64, 4}, + {10, 9, 10, 64, 16, 2}, + {10, 9, 11, 32, 32, 2}, + {10, 9, 12, 32, 32, 8}, + {10, 9, 13, 32, 32, 8}, + {10, 9, 14, 32, 32, 8}, + {10, 9, 15, 32, 32, 8}, + {10, 10, 1, 8, 32, 1}, + {10, 10, 2, 32, 32, 1}, + {10, 10, 3, 8, 32, 1}, + {10, 10, 4, 32, 32, 1}, + {10, 10, 5, 32, 32, 1}, + {10, 10, 6, 32, 32, 1}, + {10, 10, 7, 32, 32, 2}, + {10, 10, 8, 32, 32, 1}, + {10, 10, 9, 32, 32, 1}, + {10, 10, 10, 32, 32, 4}, + {10, 10, 11, 32, 32, 4}, + {10, 10, 12, 32, 32, 8}, + {10, 10, 13, 32, 32, 8}, + {10, 10, 14, 32, 32, 8}, + {10, 10, 15, 32, 32, 8}, + {10, 11, 1, 64, 32, 1}, + {10, 11, 2, 16, 32, 1}, + {10, 11, 3, 16, 32, 1}, + {10, 11, 4, 16, 32, 1}, + {10, 11, 5, 16, 32, 1}, + {10, 11, 6, 16, 32, 1}, + {10, 11, 7, 16, 32, 1}, + {10, 11, 8, 64, 16, 1}, + {10, 11, 9, 64, 16, 1}, + {10, 11, 10, 64, 16, 1}, + {10, 11, 11, 32, 32, 4}, + {10, 11, 12, 32, 32, 4}, + {10, 11, 13, 32, 32, 4}, + {10, 11, 14, 32, 32, 8}, + {10, 11, 15, 32, 32, 8}, + {10, 12, 1, 16, 32, 1}, + {10, 12, 2, 16, 32, 1}, + {10, 12, 3, 32, 32, 1}, + {10, 12, 4, 32, 32, 1}, + {10, 12, 5, 16, 32, 1}, + {10, 12, 6, 16, 32, 1}, + {10, 12, 7, 32, 32, 2}, + {10, 12, 8, 32, 32, 2}, + {10, 12, 9, 32, 32, 4}, + {10, 12, 10, 32, 32, 4}, + {10, 12, 11, 32, 32, 4}, + {10, 12, 12, 32, 32, 4}, + {10, 12, 13, 32, 32, 8}, + {10, 12, 14, 32, 32, 8}, + {10, 12, 15, 32, 32, 8}, + {10, 13, 1, 8, 64, 1}, + {10, 13, 2, 16, 32, 1}, + {10, 13, 3, 32, 32, 1}, + {10, 13, 4, 32, 32, 1}, + {10, 13, 5, 32, 32, 1}, + {10, 13, 6, 32, 32, 1}, + {10, 13, 7, 32, 32, 2}, + {10, 13, 8, 32, 32, 2}, + {10, 13, 9, 32, 32, 2}, + {10, 13, 10, 32, 32, 2}, + {10, 13, 11, 32, 32, 2}, + {10, 13, 12, 32, 32, 4}, + {10, 13, 13, 32, 32, 8}, + {10, 13, 14, 32, 32, 8}, + {10, 13, 15, 64, 32, 1}, + {10, 14, 1, 16, 32, 1}, + {10, 14, 2, 16, 32, 1}, + {10, 14, 3, 16, 32, 1}, + {10, 14, 4, 32, 32, 1}, + {10, 14, 5, 32, 32, 1}, + {10, 14, 6, 32, 32, 1}, + {10, 14, 7, 16, 32, 1}, + {10, 14, 8, 32, 32, 2}, + {10, 14, 9, 32, 32, 2}, + {10, 14, 10, 32, 32, 4}, + {10, 14, 11, 32, 32, 4}, + {10, 14, 12, 32, 32, 4}, + {10, 14, 13, 32, 32, 8}, + {10, 14, 14, 16, 64, 1}, + {10, 14, 15, 64, 32, 1}, + {10, 15, 1, 16, 32, 1}, + {10, 15, 2, 32, 32, 1}, + {10, 15, 3, 16, 32, 1}, + {10, 15, 4, 32, 32, 1}, + {10, 15, 5, 32, 32, 1}, + {10, 15, 6, 32, 32, 1}, + {10, 15, 7, 32, 32, 2}, + {10, 15, 8, 32, 32, 2}, + {10, 15, 9, 32, 32, 4}, + {10, 15, 10, 32, 32, 4}, + {10, 15, 11, 64, 32, 1}, + {10, 15, 12, 64, 32, 1}, + {10, 15, 13, 64, 32, 1}, + {10, 15, 14, 16, 64, 1}, + {10, 15, 15, 32, 32, 8}, + {11, 0, 1, 8, 16, 1}, + {11, 0, 2, 8, 32, 1}, + {11, 0, 3, 8, 32, 1}, + {11, 0, 4, 8, 16, 2}, + {11, 0, 5, 16, 16, 1}, + {11, 0, 6, 8, 16, 1}, + {11, 0, 7, 8, 16, 2}, + {11, 0, 8, 8, 16, 4}, + {11, 0, 9, 8, 16, 4}, + {11, 0, 10, 32, 16, 8}, + {11, 0, 11, 8, 64, 4}, + {11, 0, 12, 32, 16, 8}, + {11, 0, 13, 8, 16, 4}, + {11, 0, 14, 16, 16, 8}, + {11, 0, 15, 8, 16, 4}, + {11, 1, 1, 8, 16, 1}, + {11, 1, 2, 8, 16, 1}, + {11, 1, 3, 8, 16, 2}, + {11, 1, 4, 8, 16, 4}, + {11, 1, 5, 8, 16, 2}, + {11, 1, 6, 8, 16, 8}, + {11, 1, 7, 8, 16, 2}, + {11, 1, 8, 8, 16, 4}, + {11, 1, 9, 8, 16, 4}, + {11, 1, 10, 8, 32, 4}, + {11, 1, 11, 8, 16, 4}, + {11, 1, 12, 16, 16, 8}, + {11, 1, 13, 8, 16, 4}, + {11, 1, 14, 16, 16, 8}, + {11, 1, 15, 16, 16, 8}, + {11, 2, 1, 8, 16, 1}, + {11, 2, 2, 8, 16, 1}, + {11, 2, 3, 16, 16, 2}, + {11, 2, 4, 8, 32, 4}, + {11, 2, 5, 8, 16, 2}, + {11, 2, 6, 8, 16, 4}, + {11, 2, 7, 32, 16, 8}, + {11, 2, 8, 8, 16, 4}, + {11, 2, 9, 8, 64, 8}, + {11, 2, 10, 8, 16, 4}, + {11, 2, 11, 8, 32, 4}, + {11, 2, 12, 8, 32, 8}, + {11, 2, 13, 8, 32, 4}, + {11, 2, 14, 16, 16, 4}, + {11, 2, 15, 8, 32, 4}, + {11, 3, 1, 8, 16, 1}, + {11, 3, 2, 16, 16, 2}, + {11, 3, 3, 8, 32, 2}, + {11, 3, 4, 8, 32, 2}, + {11, 3, 5, 8, 32, 4}, + {11, 3, 6, 64, 16, 8}, + {11, 3, 7, 16, 16, 4}, + {11, 3, 8, 16, 16, 4}, + {11, 3, 9, 16, 16, 4}, + {11, 3, 10, 16, 16, 4}, + {11, 3, 11, 16, 16, 4}, + {11, 3, 12, 8, 64, 8}, + {11, 3, 13, 8, 64, 8}, + {11, 3, 14, 16, 16, 4}, + {11, 3, 15, 8, 64, 8}, + {11, 4, 1, 8, 32, 1}, + {11, 4, 2, 8, 32, 2}, + {11, 4, 3, 8, 32, 2}, + {11, 4, 4, 8, 32, 2}, + {11, 4, 5, 16, 16, 4}, + {11, 4, 6, 8, 16, 1}, + {11, 4, 7, 8, 64, 8}, + {11, 4, 8, 64, 16, 8}, + {11, 4, 9, 8, 16, 4}, + {11, 4, 10, 8, 32, 4}, + {11, 4, 11, 8, 32, 4}, + {11, 4, 12, 8, 64, 8}, + {11, 4, 13, 8, 64, 8}, + {11, 4, 14, 8, 64, 8}, + {11, 4, 15, 32, 32, 8}, + {11, 5, 1, 8, 16, 1}, + {11, 5, 2, 8, 32, 2}, + {11, 5, 3, 8, 16, 1}, + {11, 5, 4, 8, 64, 1}, + {11, 5, 5, 16, 16, 1}, + {11, 5, 6, 16, 32, 1}, + {11, 5, 7, 8, 32, 2}, + {11, 5, 8, 16, 16, 4}, + {11, 5, 9, 8, 32, 4}, + {11, 5, 10, 32, 32, 8}, + {11, 5, 11, 32, 32, 8}, + {11, 5, 12, 16, 16, 2}, + {11, 5, 13, 32, 32, 8}, + {11, 5, 14, 32, 32, 8}, + {11, 5, 15, 32, 32, 8}, + {11, 6, 1, 8, 16, 1}, + {11, 6, 2, 8, 16, 1}, + {11, 6, 3, 8, 32, 1}, + {11, 6, 4, 8, 64, 2}, + {11, 6, 5, 8, 32, 2}, + {11, 6, 6, 8, 64, 2}, + {11, 6, 7, 32, 32, 4}, + {11, 6, 8, 16, 16, 4}, + {11, 6, 9, 32, 32, 4}, + {11, 6, 10, 16, 16, 4}, + {11, 6, 11, 32, 32, 8}, + {11, 6, 12, 32, 32, 8}, + {11, 6, 13, 16, 64, 8}, + {11, 6, 14, 32, 32, 4}, + {11, 6, 15, 32, 32, 8}, + {11, 7, 1, 8, 64, 1}, + {11, 7, 2, 16, 32, 1}, + {11, 7, 3, 16, 64, 1}, + {11, 7, 4, 32, 32, 1}, + {11, 7, 5, 16, 16, 1}, + {11, 7, 6, 16, 16, 2}, + {11, 7, 7, 16, 32, 2}, + {11, 7, 8, 32, 32, 4}, + {11, 7, 9, 32, 32, 4}, + {11, 7, 10, 32, 32, 4}, + {11, 7, 11, 32, 32, 4}, + {11, 7, 12, 16, 64, 4}, + {11, 7, 13, 32, 32, 2}, + {11, 7, 14, 32, 32, 8}, + {11, 7, 15, 32, 32, 8}, + {11, 8, 1, 8, 32, 1}, + {11, 8, 2, 8, 32, 1}, + {11, 8, 3, 8, 64, 1}, + {11, 8, 4, 32, 32, 1}, + {11, 8, 5, 16, 32, 1}, + {11, 8, 6, 16, 32, 1}, + {11, 8, 7, 32, 32, 2}, + {11, 8, 8, 32, 32, 2}, + {11, 8, 9, 32, 32, 2}, + {11, 8, 10, 32, 32, 2}, + {11, 8, 11, 32, 32, 2}, + {11, 8, 12, 32, 32, 2}, + {11, 8, 13, 32, 32, 2}, + {11, 8, 14, 32, 32, 2}, + {11, 8, 15, 32, 32, 2}, + {11, 9, 1, 8, 32, 1}, + {11, 9, 2, 16, 32, 1}, + {11, 9, 3, 16, 32, 1}, + {11, 9, 4, 16, 32, 1}, + {11, 9, 5, 16, 32, 1}, + {11, 9, 6, 32, 32, 1}, + {11, 9, 7, 16, 32, 1}, + {11, 9, 8, 32, 32, 4}, + {11, 9, 9, 32, 32, 2}, + {11, 9, 10, 32, 32, 4}, + {11, 9, 11, 32, 32, 4}, + {11, 9, 12, 32, 32, 4}, + {11, 9, 13, 32, 32, 8}, + {11, 9, 14, 32, 32, 8}, + {11, 9, 15, 32, 32, 8}, + {11, 10, 1, 16, 32, 1}, + {11, 10, 2, 16, 32, 1}, + {11, 10, 3, 16, 32, 1}, + {11, 10, 4, 16, 32, 1}, + {11, 10, 5, 32, 32, 1}, + {11, 10, 6, 32, 32, 1}, + {11, 10, 7, 32, 32, 1}, + {11, 10, 8, 32, 32, 1}, + {11, 10, 9, 64, 16, 1}, + {11, 10, 10, 32, 32, 4}, + {11, 10, 11, 64, 16, 1}, + {11, 10, 12, 32, 32, 4}, + {11, 10, 13, 32, 32, 8}, + {11, 10, 14, 32, 32, 8}, + {11, 10, 15, 32, 32, 8}, + {11, 11, 1, 16, 32, 1}, + {11, 11, 2, 16, 32, 1}, + {11, 11, 3, 16, 32, 1}, + {11, 11, 4, 16, 32, 1}, + {11, 11, 5, 16, 32, 1}, + {11, 11, 6, 16, 32, 1}, + {11, 11, 7, 32, 32, 2}, + {11, 11, 8, 32, 32, 2}, + {11, 11, 9, 32, 32, 2}, + {11, 11, 10, 32, 32, 4}, + {11, 11, 11, 32, 32, 4}, + {11, 11, 12, 32, 32, 4}, + {11, 11, 13, 32, 32, 8}, + {11, 11, 14, 32, 32, 8}, + {11, 11, 15, 32, 32, 8}, + {11, 12, 1, 16, 32, 1}, + {11, 12, 2, 16, 32, 1}, + {11, 12, 3, 16, 32, 1}, + {11, 12, 4, 32, 32, 1}, + {11, 12, 5, 32, 32, 1}, + {11, 12, 6, 64, 32, 1}, + {11, 12, 7, 32, 32, 2}, + {11, 12, 8, 32, 32, 2}, + {11, 12, 9, 32, 32, 4}, + {11, 12, 10, 32, 32, 4}, + {11, 12, 11, 32, 32, 4}, + {11, 12, 12, 32, 32, 8}, + {11, 12, 13, 32, 32, 8}, + {11, 12, 14, 32, 32, 8}, + {11, 12, 15, 32, 32, 2}, + {11, 13, 1, 16, 64, 1}, + {11, 13, 2, 8, 64, 1}, + {11, 13, 3, 64, 32, 1}, + {11, 13, 4, 32, 32, 1}, + {11, 13, 5, 32, 32, 1}, + {11, 13, 6, 16, 32, 1}, + {11, 13, 7, 32, 32, 2}, + {11, 13, 8, 32, 32, 2}, + {11, 13, 9, 32, 32, 2}, + {11, 13, 10, 32, 32, 2}, + {11, 13, 11, 32, 32, 4}, + {11, 13, 12, 32, 32, 8}, + {11, 13, 13, 64, 16, 8}, + {11, 13, 14, 16, 64, 1}, + {11, 13, 15, 64, 32, 1}, + {11, 14, 1, 16, 32, 1}, + {11, 14, 2, 32, 32, 1}, + {11, 14, 3, 32, 32, 1}, + {11, 14, 4, 32, 32, 1}, + {11, 14, 5, 32, 32, 1}, + {11, 14, 6, 32, 32, 1}, + {11, 14, 7, 16, 32, 1}, + {11, 14, 8, 32, 32, 2}, + {11, 14, 9, 32, 32, 2}, + {11, 14, 10, 32, 32, 4}, + {11, 14, 11, 32, 32, 4}, + {11, 14, 12, 32, 32, 4}, + {11, 14, 13, 32, 32, 8}, + {11, 14, 14, 64, 32, 1}, + {11, 14, 15, 32, 32, 4}, + {11, 15, 1, 8, 32, 1}, + {11, 15, 2, 32, 32, 1}, + {11, 15, 3, 32, 32, 1}, + {11, 15, 4, 16, 32, 1}, + {11, 15, 5, 32, 32, 1}, + {11, 15, 6, 32, 32, 1}, + {11, 15, 7, 32, 32, 2}, + {11, 15, 8, 32, 32, 2}, + {11, 15, 9, 32, 32, 4}, + {11, 15, 10, 64, 32, 1}, + {11, 15, 11, 64, 32, 1}, + {11, 15, 12, 64, 32, 1}, + {11, 15, 13, 32, 32, 4}, + {11, 15, 14, 64, 32, 1}, + {11, 15, 15, 32, 32, 1}, + {12, 0, 1, 16, 32, 1}, + {12, 0, 2, 8, 16, 1}, + {12, 0, 3, 8, 32, 2}, + {12, 0, 4, 8, 32, 4}, + {12, 0, 5, 16, 16, 2}, + {12, 0, 6, 16, 16, 8}, + {12, 0, 7, 16, 32, 2}, + {12, 0, 8, 8, 32, 4}, + {12, 0, 9, 8, 16, 4}, + {12, 0, 10, 16, 16, 2}, + {12, 0, 11, 16, 32, 8}, + {12, 0, 12, 8, 16, 4}, + {12, 0, 13, 8, 16, 4}, + {12, 0, 14, 16, 16, 8}, + {12, 0, 15, 8, 16, 4}, + {12, 1, 1, 8, 16, 1}, + {12, 1, 2, 16, 16, 1}, + {12, 1, 3, 16, 32, 1}, + {12, 1, 4, 16, 16, 1}, + {12, 1, 5, 16, 16, 1}, + {12, 1, 6, 8, 16, 4}, + {12, 1, 7, 16, 16, 8}, + {12, 1, 8, 16, 16, 8}, + {12, 1, 9, 8, 16, 4}, + {12, 1, 10, 8, 16, 4}, + {12, 1, 11, 8, 16, 4}, + {12, 1, 12, 8, 16, 8}, + {12, 1, 13, 8, 16, 8}, + {12, 1, 14, 8, 32, 8}, + {12, 1, 15, 8, 16, 4}, + {12, 2, 1, 8, 16, 1}, + {12, 2, 2, 8, 16, 2}, + {12, 2, 3, 16, 16, 1}, + {12, 2, 4, 8, 16, 4}, + {12, 2, 5, 8, 32, 4}, + {12, 2, 6, 8, 16, 1}, + {12, 2, 7, 32, 16, 8}, + {12, 2, 8, 8, 32, 4}, + {12, 2, 9, 8, 16, 4}, + {12, 2, 10, 8, 16, 8}, + {12, 2, 11, 8, 32, 8}, + {12, 2, 12, 8, 32, 8}, + {12, 2, 13, 16, 16, 4}, + {12, 2, 14, 8, 32, 8}, + {12, 2, 15, 8, 32, 4}, + {12, 3, 1, 8, 16, 1}, + {12, 3, 2, 16, 16, 1}, + {12, 3, 3, 8, 16, 1}, + {12, 3, 4, 8, 64, 1}, + {12, 3, 5, 8, 16, 4}, + {12, 3, 6, 8, 16, 1}, + {12, 3, 7, 32, 16, 4}, + {12, 3, 8, 8, 32, 8}, + {12, 3, 9, 8, 32, 8}, + {12, 3, 10, 16, 16, 4}, + {12, 3, 11, 64, 16, 4}, + {12, 3, 12, 64, 16, 8}, + {12, 3, 13, 32, 32, 4}, + {12, 3, 14, 32, 32, 8}, + {12, 3, 15, 32, 32, 4}, + {12, 4, 1, 16, 16, 1}, + {12, 4, 2, 16, 16, 1}, + {12, 4, 3, 8, 16, 1}, + {12, 4, 4, 16, 16, 2}, + {12, 4, 5, 8, 16, 1}, + {12, 4, 6, 16, 32, 1}, + {12, 4, 7, 8, 32, 4}, + {12, 4, 8, 8, 64, 8}, + {12, 4, 9, 8, 32, 8}, + {12, 4, 10, 32, 16, 4}, + {12, 4, 11, 32, 32, 8}, + {12, 4, 12, 32, 32, 4}, + {12, 4, 13, 64, 16, 4}, + {12, 4, 14, 64, 16, 8}, + {12, 4, 15, 32, 32, 8}, + {12, 5, 1, 16, 32, 1}, + {12, 5, 2, 8, 32, 1}, + {12, 5, 3, 16, 16, 1}, + {12, 5, 4, 8, 32, 2}, + {12, 5, 5, 64, 16, 2}, + {12, 5, 6, 16, 16, 4}, + {12, 5, 7, 8, 32, 4}, + {12, 5, 8, 8, 32, 2}, + {12, 5, 9, 32, 32, 4}, + {12, 5, 10, 32, 32, 4}, + {12, 5, 11, 64, 16, 4}, + {12, 5, 12, 32, 32, 4}, + {12, 5, 13, 32, 32, 4}, + {12, 5, 14, 32, 32, 4}, + {12, 5, 15, 32, 32, 4}, + {12, 6, 1, 8, 32, 1}, + {12, 6, 2, 8, 32, 1}, + {12, 6, 3, 32, 16, 1}, + {12, 6, 4, 32, 32, 1}, + {12, 6, 5, 16, 16, 1}, + {12, 6, 6, 16, 32, 1}, + {12, 6, 7, 16, 32, 2}, + {12, 6, 8, 16, 16, 1}, + {12, 6, 9, 32, 32, 4}, + {12, 6, 10, 32, 32, 4}, + {12, 6, 11, 32, 32, 4}, + {12, 6, 12, 32, 32, 4}, + {12, 6, 13, 32, 32, 4}, + {12, 6, 14, 32, 32, 4}, + {12, 6, 15, 32, 32, 4}, + {12, 7, 1, 8, 16, 1}, + {12, 7, 2, 32, 16, 1}, + {12, 7, 3, 32, 32, 1}, + {12, 7, 4, 32, 32, 1}, + {12, 7, 5, 32, 32, 1}, + {12, 7, 6, 16, 32, 1}, + {12, 7, 7, 32, 32, 2}, + {12, 7, 8, 32, 32, 2}, + {12, 7, 9, 32, 32, 2}, + {12, 7, 10, 32, 32, 2}, + {12, 7, 11, 32, 32, 4}, + {12, 7, 12, 32, 32, 2}, + {12, 7, 13, 32, 32, 2}, + {12, 7, 14, 32, 32, 2}, + {12, 7, 15, 32, 32, 4}, + {12, 8, 1, 16, 32, 1}, + {12, 8, 2, 16, 32, 1}, + {12, 8, 3, 16, 32, 1}, + {12, 8, 4, 16, 32, 1}, + {12, 8, 5, 16, 32, 1}, + {12, 8, 6, 16, 32, 1}, + {12, 8, 7, 32, 32, 1}, + {12, 8, 8, 32, 32, 1}, + {12, 8, 9, 32, 32, 2}, + {12, 8, 10, 32, 32, 2}, + {12, 8, 11, 32, 32, 4}, + {12, 8, 12, 32, 32, 4}, + {12, 8, 13, 64, 16, 1}, + {12, 8, 14, 32, 32, 4}, + {12, 8, 15, 64, 16, 1}, + {12, 9, 1, 8, 32, 1}, + {12, 9, 2, 16, 32, 1}, + {12, 9, 3, 16, 32, 1}, + {12, 9, 4, 64, 32, 1}, + {12, 9, 5, 16, 32, 1}, + {12, 9, 6, 32, 32, 1}, + {12, 9, 7, 64, 16, 1}, + {12, 9, 8, 64, 32, 1}, + {12, 9, 9, 32, 32, 1}, + {12, 9, 10, 32, 32, 4}, + {12, 9, 11, 64, 16, 1}, + {12, 9, 12, 64, 16, 1}, + {12, 9, 13, 64, 16, 1}, + {12, 9, 14, 64, 32, 1}, + {12, 9, 15, 64, 32, 1}, + {12, 10, 1, 16, 32, 1}, + {12, 10, 2, 16, 32, 1}, + {12, 10, 3, 32, 32, 1}, + {12, 10, 4, 32, 32, 1}, + {12, 10, 5, 16, 32, 1}, + {12, 10, 6, 16, 32, 1}, + {12, 10, 7, 32, 32, 2}, + {12, 10, 8, 32, 32, 2}, + {12, 10, 9, 32, 32, 4}, + {12, 10, 10, 32, 32, 4}, + {12, 10, 11, 32, 32, 4}, + {12, 10, 12, 32, 32, 4}, + {12, 10, 13, 32, 32, 8}, + {12, 10, 14, 32, 32, 8}, + {12, 10, 15, 32, 32, 8}, + {12, 11, 1, 16, 32, 1}, + {12, 11, 2, 16, 32, 1}, + {12, 11, 3, 16, 32, 1}, + {12, 11, 4, 16, 32, 1}, + {12, 11, 5, 16, 32, 1}, + {12, 11, 6, 16, 32, 1}, + {12, 11, 7, 16, 32, 1}, + {12, 11, 8, 32, 32, 2}, + {12, 11, 9, 32, 32, 2}, + {12, 11, 10, 32, 32, 4}, + {12, 11, 11, 32, 32, 4}, + {12, 11, 12, 32, 32, 4}, + {12, 11, 13, 32, 32, 8}, + {12, 11, 14, 64, 32, 1}, + {12, 11, 15, 64, 32, 1}, + {12, 12, 1, 8, 64, 1}, + {12, 12, 2, 16, 32, 1}, + {12, 12, 3, 32, 32, 1}, + {12, 12, 4, 32, 32, 1}, + {12, 12, 5, 32, 32, 1}, + {12, 12, 6, 32, 32, 1}, + {12, 12, 7, 32, 32, 1}, + {12, 12, 8, 32, 32, 2}, + {12, 12, 9, 32, 32, 2}, + {12, 12, 10, 32, 32, 4}, + {12, 12, 11, 32, 32, 4}, + {12, 12, 12, 64, 32, 1}, + {12, 12, 13, 32, 32, 8}, + {12, 12, 14, 32, 32, 8}, + {12, 12, 15, 64, 32, 1}, + {12, 13, 1, 16, 32, 1}, + {12, 13, 2, 32, 32, 1}, + {12, 13, 3, 16, 32, 1}, + {12, 13, 4, 16, 32, 1}, + {12, 13, 5, 16, 32, 1}, + {12, 13, 6, 32, 32, 1}, + {12, 13, 7, 32, 32, 2}, + {12, 13, 8, 32, 32, 2}, + {12, 13, 9, 32, 32, 2}, + {12, 13, 10, 32, 32, 4}, + {12, 13, 11, 64, 32, 1}, + {12, 13, 12, 64, 32, 1}, + {12, 13, 13, 32, 32, 4}, + {12, 13, 14, 32, 32, 8}, + {12, 13, 15, 32, 32, 1}, + {12, 14, 1, 16, 64, 1}, + {12, 14, 2, 32, 32, 1}, + {12, 14, 3, 32, 32, 1}, + {12, 14, 4, 32, 32, 1}, + {12, 14, 5, 32, 32, 1}, + {12, 14, 6, 32, 32, 1}, + {12, 14, 7, 32, 32, 1}, + {12, 14, 8, 32, 32, 2}, + {12, 14, 9, 16, 64, 2}, + {12, 14, 10, 32, 32, 4}, + {12, 14, 11, 32, 32, 4}, + {12, 14, 12, 32, 32, 8}, + {12, 14, 13, 32, 32, 8}, + {12, 14, 14, 32, 32, 4}, + {12, 14, 15, 32, 32, 8}, + {12, 15, 1, 32, 32, 1}, + {12, 15, 2, 16, 32, 1}, + {12, 15, 3, 32, 32, 1}, + {12, 15, 4, 32, 32, 1}, + {12, 15, 5, 32, 32, 1}, + {12, 15, 6, 16, 32, 1}, + {12, 15, 7, 32, 32, 2}, + {12, 15, 8, 64, 32, 1}, + {12, 15, 9, 64, 32, 1}, + {12, 15, 10, 64, 32, 1}, + {12, 15, 11, 64, 32, 1}, + {12, 15, 12, 64, 32, 1}, + {12, 15, 13, 64, 32, 1}, + {12, 15, 14, 64, 32, 1}, + {12, 15, 15, 64, 32, 8}, + {13, 0, 1, 16, 16, 1}, + {13, 0, 2, 8, 32, 1}, + {13, 0, 3, 8, 32, 2}, + {13, 0, 4, 8, 16, 1}, + {13, 0, 5, 8, 16, 1}, + {13, 0, 6, 16, 16, 2}, + {13, 0, 7, 8, 16, 2}, + {13, 0, 8, 8, 16, 4}, + {13, 0, 9, 16, 32, 4}, + {13, 0, 10, 64, 16, 8}, + {13, 0, 11, 8, 16, 4}, + {13, 0, 12, 8, 16, 4}, + {13, 0, 13, 16, 16, 4}, + {13, 0, 14, 8, 16, 4}, + {13, 0, 15, 16, 16, 4}, + {13, 1, 1, 8, 16, 1}, + {13, 1, 2, 8, 16, 1}, + {13, 1, 3, 8, 16, 1}, + {13, 1, 4, 8, 16, 4}, + {13, 1, 5, 8, 16, 4}, + {13, 1, 6, 8, 16, 4}, + {13, 1, 7, 8, 16, 8}, + {13, 1, 8, 8, 16, 8}, + {13, 1, 9, 8, 16, 4}, + {13, 1, 10, 8, 16, 4}, + {13, 1, 11, 8, 16, 4}, + {13, 1, 12, 8, 16, 4}, + {13, 1, 13, 16, 16, 4}, + {13, 1, 14, 16, 16, 4}, + {13, 1, 15, 32, 16, 8}, + {13, 2, 1, 8, 32, 1}, + {13, 2, 2, 16, 32, 1}, + {13, 2, 3, 8, 32, 1}, + {13, 2, 4, 8, 32, 1}, + {13, 2, 5, 8, 32, 2}, + {13, 2, 6, 16, 32, 4}, + {13, 2, 7, 8, 32, 2}, + {13, 2, 8, 8, 32, 4}, + {13, 2, 9, 8, 16, 4}, + {13, 2, 10, 8, 32, 4}, + {13, 2, 11, 16, 32, 8}, + {13, 2, 12, 16, 32, 8}, + {13, 2, 13, 16, 32, 4}, + {13, 2, 14, 32, 32, 8}, + {13, 2, 15, 16, 32, 4}, + {13, 3, 1, 8, 16, 1}, + {13, 3, 2, 8, 64, 1}, + {13, 3, 3, 16, 16, 2}, + {13, 3, 4, 8, 16, 1}, + {13, 3, 5, 8, 64, 1}, + {13, 3, 6, 16, 32, 1}, + {13, 3, 7, 8, 64, 8}, + {13, 3, 8, 16, 16, 4}, + {13, 3, 9, 8, 64, 8}, + {13, 3, 10, 8, 64, 8}, + {13, 3, 11, 16, 64, 8}, + {13, 3, 12, 16, 64, 8}, + {13, 3, 13, 16, 64, 8}, + {13, 3, 14, 8, 64, 8}, + {13, 3, 15, 8, 64, 8}, + {13, 4, 1, 8, 32, 1}, + {13, 4, 2, 8, 32, 1}, + {13, 4, 3, 8, 64, 1}, + {13, 4, 4, 8, 32, 1}, + {13, 4, 5, 16, 32, 1}, + {13, 4, 6, 16, 32, 2}, + {13, 4, 7, 32, 32, 4}, + {13, 4, 8, 8, 64, 8}, + {13, 4, 9, 8, 32, 4}, + {13, 4, 10, 16, 32, 8}, + {13, 4, 11, 32, 32, 4}, + {13, 4, 12, 16, 64, 8}, + {13, 4, 13, 16, 64, 8}, + {13, 4, 14, 32, 32, 4}, + {13, 4, 15, 16, 64, 8}, + {13, 5, 1, 16, 16, 1}, + {13, 5, 2, 8, 64, 1}, + {13, 5, 3, 8, 32, 1}, + {13, 5, 4, 16, 32, 1}, + {13, 5, 5, 32, 32, 2}, + {13, 5, 6, 16, 32, 2}, + {13, 5, 7, 32, 32, 4}, + {13, 5, 8, 32, 32, 4}, + {13, 5, 9, 32, 32, 4}, + {13, 5, 10, 32, 32, 8}, + {13, 5, 11, 32, 32, 4}, + {13, 5, 12, 32, 32, 4}, + {13, 5, 13, 32, 32, 4}, + {13, 5, 14, 32, 32, 4}, + {13, 5, 15, 32, 32, 4}, + {13, 6, 1, 8, 64, 1}, + {13, 6, 2, 8, 64, 1}, + {13, 6, 3, 32, 32, 1}, + {13, 6, 4, 16, 32, 1}, + {13, 6, 5, 8, 32, 1}, + {13, 6, 6, 16, 32, 2}, + {13, 6, 7, 32, 32, 4}, + {13, 6, 8, 32, 32, 2}, + {13, 6, 9, 32, 32, 2}, + {13, 6, 10, 16, 64, 4}, + {13, 6, 11, 32, 32, 4}, + {13, 6, 12, 16, 64, 8}, + {13, 6, 13, 16, 64, 8}, + {13, 6, 14, 32, 32, 4}, + {13, 6, 15, 32, 32, 2}, + {13, 7, 1, 16, 32, 1}, + {13, 7, 2, 16, 32, 1}, + {13, 7, 3, 16, 32, 1}, + {13, 7, 4, 32, 32, 1}, + {13, 7, 5, 16, 32, 1}, + {13, 7, 6, 16, 32, 1}, + {13, 7, 7, 16, 32, 2}, + {13, 7, 8, 32, 32, 4}, + {13, 7, 9, 32, 32, 2}, + {13, 7, 10, 32, 32, 4}, + {13, 7, 11, 32, 32, 4}, + {13, 7, 12, 32, 32, 4}, + {13, 7, 13, 32, 32, 4}, + {13, 7, 14, 32, 32, 4}, + {13, 7, 15, 32, 32, 2}, + {13, 8, 1, 8, 64, 1}, + {13, 8, 2, 16, 32, 1}, + {13, 8, 3, 16, 32, 1}, + {13, 8, 4, 16, 32, 1}, + {13, 8, 5, 32, 32, 1}, + {13, 8, 6, 32, 32, 1}, + {13, 8, 7, 32, 32, 2}, + {13, 8, 8, 64, 16, 1}, + {13, 8, 9, 32, 32, 4}, + {13, 8, 10, 32, 32, 4}, + {13, 8, 11, 32, 32, 4}, + {13, 8, 12, 32, 32, 4}, + {13, 8, 13, 32, 32, 8}, + {13, 8, 14, 64, 32, 1}, + {13, 8, 15, 64, 32, 1}, + {13, 9, 1, 8, 64, 1}, + {13, 9, 2, 16, 32, 1}, + {13, 9, 3, 16, 32, 1}, + {13, 9, 4, 16, 32, 1}, + {13, 9, 5, 16, 32, 1}, + {13, 9, 6, 32, 32, 1}, + {13, 9, 7, 32, 32, 2}, + {13, 9, 8, 32, 32, 2}, + {13, 9, 9, 32, 32, 2}, + {13, 9, 10, 32, 32, 2}, + {13, 9, 11, 32, 32, 4}, + {13, 9, 12, 32, 32, 4}, + {13, 9, 13, 32, 32, 8}, + {13, 9, 14, 32, 32, 8}, + {13, 9, 15, 32, 32, 2}, + {13, 10, 1, 16, 32, 1}, + {13, 10, 2, 16, 32, 1}, + {13, 10, 3, 64, 32, 1}, + {13, 10, 4, 64, 32, 1}, + {13, 10, 5, 32, 32, 1}, + {13, 10, 6, 16, 32, 1}, + {13, 10, 7, 32, 32, 2}, + {13, 10, 8, 32, 32, 2}, + {13, 10, 9, 32, 32, 2}, + {13, 10, 10, 32, 32, 4}, + {13, 10, 11, 32, 32, 4}, + {13, 10, 12, 32, 32, 4}, + {13, 10, 13, 32, 32, 8}, + {13, 10, 14, 64, 32, 1}, + {13, 10, 15, 32, 32, 2}, + {13, 11, 1, 32, 32, 1}, + {13, 11, 2, 32, 32, 1}, + {13, 11, 3, 8, 64, 1}, + {13, 11, 4, 32, 32, 1}, + {13, 11, 5, 32, 32, 1}, + {13, 11, 6, 16, 32, 1}, + {13, 11, 7, 16, 32, 1}, + {13, 11, 8, 32, 32, 2}, + {13, 11, 9, 32, 32, 2}, + {13, 11, 10, 32, 32, 4}, + {13, 11, 11, 64, 32, 1}, + {13, 11, 12, 32, 32, 4}, + {13, 11, 13, 16, 32, 1}, + {13, 11, 14, 32, 32, 2}, + {13, 11, 15, 32, 32, 4}, + {13, 12, 1, 32, 32, 1}, + {13, 12, 2, 8, 64, 1}, + {13, 12, 3, 16, 32, 1}, + {13, 12, 4, 16, 32, 1}, + {13, 12, 5, 32, 32, 1}, + {13, 12, 6, 32, 32, 1}, + {13, 12, 7, 16, 32, 1}, + {13, 12, 8, 32, 32, 2}, + {13, 12, 9, 32, 32, 2}, + {13, 12, 10, 32, 32, 4}, + {13, 12, 11, 32, 32, 4}, + {13, 12, 12, 8, 64, 4}, + {13, 12, 13, 32, 32, 8}, + {13, 12, 14, 32, 32, 8}, + {13, 12, 15, 32, 32, 4}, + {13, 13, 1, 16, 32, 1}, + {13, 13, 2, 64, 32, 1}, + {13, 13, 3, 16, 32, 1}, + {13, 13, 4, 32, 32, 1}, + {13, 13, 5, 16, 32, 1}, + {13, 13, 6, 32, 32, 2}, + {13, 13, 7, 32, 32, 2}, + {13, 13, 8, 32, 32, 2}, + {13, 13, 9, 32, 32, 4}, + {13, 13, 10, 64, 32, 1}, + {13, 13, 11, 64, 32, 1}, + {13, 13, 12, 64, 32, 1}, + {13, 13, 13, 32, 32, 8}, + {13, 13, 14, 64, 32, 1}, + {13, 13, 15, 64, 32, 1}, + {13, 14, 1, 16, 32, 1}, + {13, 14, 2, 32, 32, 1}, + {13, 14, 3, 32, 32, 1}, + {13, 14, 4, 32, 32, 1}, + {13, 14, 5, 32, 32, 1}, + {13, 14, 6, 16, 32, 1}, + {13, 14, 7, 16, 32, 1}, + {13, 14, 8, 32, 32, 2}, + {13, 14, 9, 32, 32, 2}, + {13, 14, 10, 32, 32, 4}, + {13, 14, 11, 32, 32, 4}, + {13, 14, 12, 64, 32, 4}, + {13, 14, 13, 32, 32, 8}, + {13, 14, 14, 32, 32, 4}, + {13, 14, 15, 32, 32, 4}, + {13, 15, 1, 16, 32, 1}, + {13, 15, 2, 32, 32, 1}, + {13, 15, 3, 32, 32, 1}, + {13, 15, 4, 32, 32, 1}, + {13, 15, 5, 16, 32, 1}, + {13, 15, 6, 16, 32, 1}, + {13, 15, 7, 32, 32, 2}, + {13, 15, 8, 32, 32, 2}, + {13, 15, 9, 64, 32, 1}, + {13, 15, 10, 32, 32, 4}, + {13, 15, 11, 64, 32, 1}, + {13, 15, 12, 32, 32, 4}, + {13, 15, 13, 32, 32, 4}, + {13, 15, 14, 64, 32, 1}, + {13, 15, 15, 64, 32, 4}, + {14, 0, 1, 16, 16, 1}, + {14, 0, 2, 8, 16, 1}, + {14, 0, 3, 8, 16, 2}, + {14, 0, 4, 16, 16, 2}, + {14, 0, 5, 16, 16, 1}, + {14, 0, 6, 8, 32, 4}, + {14, 0, 7, 8, 16, 4}, + {14, 0, 8, 16, 16, 2}, + {14, 0, 9, 8, 64, 8}, + {14, 0, 10, 8, 16, 4}, + {14, 0, 11, 16, 16, 8}, + {14, 0, 12, 16, 16, 8}, + {14, 0, 13, 16, 16, 4}, + {14, 0, 14, 16, 16, 8}, + {14, 0, 15, 16, 16, 4}, + {14, 1, 1, 32, 16, 1}, + {14, 1, 2, 32, 16, 2}, + {14, 1, 3, 8, 16, 1}, + {14, 1, 4, 16, 16, 4}, + {14, 1, 5, 8, 32, 4}, + {14, 1, 6, 8, 16, 2}, + {14, 1, 7, 8, 32, 4}, + {14, 1, 8, 16, 16, 8}, + {14, 1, 9, 16, 32, 8}, + {14, 1, 10, 8, 16, 8}, + {14, 1, 11, 16, 16, 8}, + {14, 1, 12, 8, 16, 4}, + {14, 1, 13, 8, 16, 4}, + {14, 1, 14, 16, 16, 8}, + {14, 1, 15, 16, 16, 8}, + {14, 2, 1, 8, 64, 1}, + {14, 2, 2, 16, 16, 1}, + {14, 2, 3, 16, 16, 1}, + {14, 2, 4, 8, 16, 2}, + {14, 2, 5, 8, 32, 2}, + {14, 2, 6, 8, 32, 4}, + {14, 2, 7, 8, 32, 2}, + {14, 2, 8, 8, 32, 4}, + {14, 2, 9, 16, 32, 2}, + {14, 2, 10, 16, 16, 4}, + {14, 2, 11, 8, 32, 8}, + {14, 2, 12, 16, 32, 8}, + {14, 2, 13, 8, 32, 4}, + {14, 2, 14, 16, 32, 4}, + {14, 2, 15, 16, 32, 8}, + {14, 3, 1, 8, 16, 1}, + {14, 3, 2, 16, 16, 2}, + {14, 3, 3, 32, 32, 1}, + {14, 3, 4, 16, 16, 1}, + {14, 3, 5, 8, 16, 2}, + {14, 3, 6, 16, 16, 4}, + {14, 3, 7, 8, 64, 8}, + {14, 3, 8, 16, 16, 4}, + {14, 3, 9, 32, 16, 2}, + {14, 3, 10, 8, 64, 8}, + {14, 3, 11, 32, 32, 4}, + {14, 3, 12, 32, 32, 4}, + {14, 3, 13, 64, 16, 4}, + {14, 3, 14, 32, 32, 4}, + {14, 3, 15, 32, 32, 4}, + {14, 4, 1, 8, 32, 1}, + {14, 4, 2, 16, 16, 1}, + {14, 4, 3, 8, 64, 1}, + {14, 4, 4, 64, 16, 1}, + {14, 4, 5, 16, 32, 2}, + {14, 4, 6, 16, 32, 1}, + {14, 4, 7, 8, 32, 4}, + {14, 4, 8, 8, 32, 4}, + {14, 4, 9, 8, 64, 8}, + {14, 4, 10, 32, 32, 4}, + {14, 4, 11, 32, 32, 4}, + {14, 4, 12, 32, 32, 4}, + {14, 4, 13, 32, 32, 4}, + {14, 4, 14, 32, 32, 4}, + {14, 4, 15, 32, 32, 4}, + {14, 5, 1, 16, 32, 1}, + {14, 5, 2, 16, 32, 1}, + {14, 5, 3, 16, 32, 1}, + {14, 5, 4, 16, 32, 1}, + {14, 5, 5, 32, 16, 1}, + {14, 5, 6, 8, 32, 1}, + {14, 5, 7, 8, 32, 4}, + {14, 5, 8, 32, 32, 2}, + {14, 5, 9, 32, 32, 2}, + {14, 5, 10, 32, 32, 2}, + {14, 5, 11, 32, 32, 4}, + {14, 5, 12, 32, 32, 2}, + {14, 5, 13, 32, 32, 2}, + {14, 5, 14, 32, 32, 2}, + {14, 5, 15, 32, 32, 2}, + {14, 6, 1, 8, 32, 1}, + {14, 6, 2, 8, 32, 1}, + {14, 6, 3, 8, 64, 1}, + {14, 6, 4, 32, 32, 1}, + {14, 6, 5, 64, 16, 1}, + {14, 6, 6, 16, 32, 1}, + {14, 6, 7, 16, 32, 1}, + {14, 6, 8, 32, 32, 2}, + {14, 6, 9, 32, 32, 2}, + {14, 6, 10, 32, 32, 2}, + {14, 6, 11, 32, 32, 2}, + {14, 6, 12, 32, 32, 2}, + {14, 6, 13, 32, 32, 2}, + {14, 6, 14, 32, 32, 2}, + {14, 6, 15, 32, 32, 2}, + {14, 7, 1, 16, 32, 1}, + {14, 7, 2, 16, 32, 1}, + {14, 7, 3, 32, 32, 1}, + {14, 7, 4, 64, 32, 1}, + {14, 7, 5, 64, 32, 1}, + {14, 7, 6, 64, 32, 1}, + {14, 7, 7, 64, 32, 1}, + {14, 7, 8, 64, 32, 1}, + {14, 7, 9, 64, 16, 1}, + {14, 7, 10, 64, 32, 1}, + {14, 7, 11, 64, 16, 1}, + {14, 7, 12, 64, 32, 1}, + {14, 7, 13, 64, 32, 1}, + {14, 7, 14, 64, 32, 1}, + {14, 7, 15, 32, 32, 1}, + {14, 8, 1, 8, 64, 1}, + {14, 8, 2, 16, 32, 1}, + {14, 8, 3, 16, 32, 1}, + {14, 8, 4, 16, 32, 1}, + {14, 8, 5, 32, 32, 1}, + {14, 8, 6, 16, 32, 1}, + {14, 8, 7, 32, 32, 2}, + {14, 8, 8, 32, 32, 4}, + {14, 8, 9, 32, 32, 2}, + {14, 8, 10, 32, 32, 2}, + {14, 8, 11, 32, 32, 4}, + {14, 8, 12, 32, 32, 4}, + {14, 8, 13, 32, 32, 4}, + {14, 8, 14, 32, 32, 2}, + {14, 8, 15, 64, 32, 1}, + {14, 9, 1, 16, 32, 1}, + {14, 9, 2, 16, 32, 1}, + {14, 9, 3, 16, 32, 1}, + {14, 9, 4, 16, 32, 1}, + {14, 9, 5, 64, 32, 1}, + {14, 9, 6, 16, 32, 1}, + {14, 9, 7, 16, 32, 1}, + {14, 9, 8, 32, 32, 2}, + {14, 9, 9, 32, 32, 2}, + {14, 9, 10, 32, 32, 4}, + {14, 9, 11, 32, 32, 4}, + {14, 9, 12, 64, 32, 1}, + {14, 9, 13, 64, 32, 1}, + {14, 9, 14, 64, 32, 1}, + {14, 9, 15, 64, 32, 1}, + {14, 10, 1, 16, 32, 1}, + {14, 10, 2, 16, 32, 1}, + {14, 10, 3, 16, 32, 1}, + {14, 10, 4, 16, 32, 1}, + {14, 10, 5, 32, 32, 1}, + {14, 10, 6, 32, 32, 1}, + {14, 10, 7, 64, 32, 1}, + {14, 10, 8, 32, 32, 2}, + {14, 10, 9, 32, 32, 2}, + {14, 10, 10, 32, 32, 2}, + {14, 10, 11, 64, 32, 1}, + {14, 10, 12, 32, 32, 4}, + {14, 10, 13, 32, 32, 4}, + {14, 10, 14, 32, 32, 4}, + {14, 10, 15, 64, 32, 1}, + {14, 11, 1, 8, 64, 1}, + {14, 11, 2, 16, 32, 1}, + {14, 11, 3, 16, 32, 1}, + {14, 11, 4, 16, 32, 1}, + {14, 11, 5, 32, 32, 1}, + {14, 11, 6, 32, 32, 1}, + {14, 11, 7, 16, 32, 1}, + {14, 11, 8, 64, 32, 1}, + {14, 11, 9, 64, 32, 1}, + {14, 11, 10, 32, 32, 2}, + {14, 11, 11, 32, 32, 4}, + {14, 11, 12, 32, 32, 4}, + {14, 11, 13, 8, 64, 1}, + {14, 11, 14, 64, 32, 1}, + {14, 11, 15, 64, 32, 1}, + {14, 12, 1, 16, 32, 1}, + {14, 12, 2, 16, 32, 1}, + {14, 12, 3, 16, 32, 1}, + {14, 12, 4, 64, 32, 1}, + {14, 12, 5, 32, 32, 1}, + {14, 12, 6, 32, 32, 1}, + {14, 12, 7, 32, 32, 2}, + {14, 12, 8, 16, 64, 4}, + {14, 12, 9, 32, 32, 8}, + {14, 12, 10, 32, 32, 4}, + {14, 12, 11, 32, 32, 4}, + {14, 12, 12, 32, 32, 8}, + {14, 12, 13, 32, 32, 2}, + {14, 12, 14, 64, 32, 1}, + {14, 12, 15, 64, 32, 1}, + {14, 13, 1, 8, 32, 1}, + {14, 13, 2, 32, 32, 1}, + {14, 13, 3, 32, 32, 1}, + {14, 13, 4, 32, 32, 1}, + {14, 13, 5, 16, 32, 1}, + {14, 13, 6, 32, 32, 1}, + {14, 13, 7, 32, 32, 2}, + {14, 13, 8, 32, 32, 2}, + {14, 13, 9, 64, 32, 1}, + {14, 13, 10, 64, 32, 1}, + {14, 13, 11, 64, 32, 1}, + {14, 13, 12, 32, 32, 2}, + {14, 13, 13, 32, 32, 8}, + {14, 13, 14, 64, 32, 1}, + {14, 13, 15, 64, 32, 1}, + {14, 14, 1, 8, 32, 1}, + {14, 14, 2, 32, 32, 1}, + {14, 14, 3, 16, 32, 1}, + {14, 14, 4, 32, 32, 1}, + {14, 14, 5, 32, 32, 1}, + {14, 14, 6, 32, 32, 1}, + {14, 14, 7, 16, 32, 1}, + {14, 14, 8, 32, 32, 2}, + {14, 14, 9, 32, 32, 2}, + {14, 14, 10, 32, 32, 2}, + {14, 14, 11, 64, 32, 1}, + {14, 14, 12, 32, 32, 4}, + {14, 14, 13, 32, 32, 4}, + {14, 14, 14, 64, 32, 1}, + {14, 14, 15, 64, 32, 1}, + {14, 15, 1, 16, 64, 1}, + {14, 15, 2, 32, 32, 1}, + {14, 15, 3, 32, 32, 1}, + {14, 15, 4, 32, 32, 1}, + {14, 15, 5, 64, 32, 1}, + {14, 15, 6, 16, 32, 1}, + {14, 15, 7, 64, 16, 1}, + {14, 15, 8, 8, 32, 1}, + {14, 15, 9, 64, 32, 1}, + {14, 15, 10, 64, 32, 1}, + {14, 15, 11, 64, 32, 1}, + {14, 15, 12, 64, 32, 1}, + {14, 15, 13, 64, 32, 2}, + {14, 15, 14, 64, 32, 1}, + {14, 15, 15, 64, 32, 1}, + {15, 0, 1, 16, 16, 1}, + {15, 0, 2, 8, 16, 2}, + {15, 0, 3, 32, 16, 1}, + {15, 0, 4, 16, 16, 1}, + {15, 0, 5, 16, 16, 4}, + {15, 0, 6, 8, 32, 2}, + {15, 0, 7, 8, 16, 8}, + {15, 0, 8, 16, 16, 4}, + {15, 0, 9, 8, 16, 4}, + {15, 0, 10, 8, 16, 8}, + {15, 0, 11, 8, 16, 4}, + {15, 0, 12, 8, 16, 4}, + {15, 0, 13, 8, 16, 8}, + {15, 0, 14, 8, 16, 4}, + {15, 0, 15, 8, 16, 8}, + {15, 1, 1, 8, 16, 1}, + {15, 1, 2, 8, 64, 2}, + {15, 1, 3, 16, 16, 2}, + {15, 1, 4, 16, 16, 1}, + {15, 1, 5, 8, 16, 2}, + {15, 1, 6, 8, 16, 8}, + {15, 1, 7, 8, 16, 4}, + {15, 1, 8, 16, 32, 4}, + {15, 1, 9, 8, 16, 4}, + {15, 1, 10, 8, 16, 8}, + {15, 1, 11, 8, 16, 4}, + {15, 1, 12, 8, 16, 4}, + {15, 1, 13, 8, 16, 8}, + {15, 1, 14, 8, 16, 4}, + {15, 1, 15, 8, 16, 8}, + {15, 2, 1, 8, 32, 1}, + {15, 2, 2, 8, 32, 1}, + {15, 2, 3, 8, 32, 2}, + {15, 2, 4, 16, 32, 2}, + {15, 2, 5, 8, 32, 1}, + {15, 2, 6, 16, 16, 4}, + {15, 2, 7, 8, 32, 4}, + {15, 2, 8, 8, 16, 4}, + {15, 2, 9, 8, 32, 4}, + {15, 2, 10, 8, 32, 4}, + {15, 2, 11, 16, 32, 4}, + {15, 2, 12, 16, 32, 8}, + {15, 2, 13, 32, 32, 4}, + {15, 2, 14, 16, 32, 8}, + {15, 2, 15, 16, 32, 8}, + {15, 3, 1, 8, 64, 1}, + {15, 3, 2, 8, 16, 2}, + {15, 3, 3, 16, 16, 1}, + {15, 3, 4, 8, 16, 2}, + {15, 3, 5, 8, 16, 2}, + {15, 3, 6, 8, 32, 2}, + {15, 3, 7, 8, 64, 8}, + {15, 3, 8, 16, 64, 8}, + {15, 3, 9, 8, 64, 8}, + {15, 3, 10, 8, 64, 8}, + {15, 3, 11, 8, 64, 8}, + {15, 3, 12, 8, 64, 8}, + {15, 3, 13, 8, 64, 8}, + {15, 3, 14, 8, 64, 8}, + {15, 3, 15, 8, 64, 8}, + {15, 4, 1, 8, 32, 1}, + {15, 4, 2, 16, 16, 1}, + {15, 4, 3, 8, 32, 2}, + {15, 4, 4, 32, 32, 2}, + {15, 4, 5, 8, 32, 2}, + {15, 4, 6, 8, 32, 2}, + {15, 4, 7, 8, 32, 4}, + {15, 4, 8, 8, 64, 8}, + {15, 4, 9, 8, 64, 8}, + {15, 4, 10, 8, 64, 8}, + {15, 4, 11, 16, 64, 8}, + {15, 4, 12, 16, 64, 4}, + {15, 4, 13, 8, 64, 8}, + {15, 4, 14, 16, 64, 4}, + {15, 4, 15, 8, 64, 8}, + {15, 5, 1, 8, 32, 1}, + {15, 5, 2, 8, 32, 1}, + {15, 5, 3, 16, 32, 1}, + {15, 5, 4, 16, 32, 1}, + {15, 5, 5, 32, 16, 1}, + {15, 5, 6, 8, 32, 2}, + {15, 5, 7, 32, 32, 2}, + {15, 5, 8, 32, 32, 4}, + {15, 5, 9, 32, 32, 4}, + {15, 5, 10, 32, 32, 8}, + {15, 5, 11, 32, 32, 4}, + {15, 5, 12, 32, 32, 2}, + {15, 5, 13, 32, 32, 2}, + {15, 5, 14, 32, 32, 2}, + {15, 5, 15, 32, 32, 2}, + {15, 6, 1, 8, 32, 1}, + {15, 6, 2, 8, 32, 1}, + {15, 6, 3, 16, 32, 1}, + {15, 6, 4, 16, 32, 1}, + {15, 6, 5, 32, 32, 1}, + {15, 6, 6, 32, 32, 2}, + {15, 6, 7, 16, 64, 4}, + {15, 6, 8, 16, 64, 4}, + {15, 6, 9, 16, 64, 4}, + {15, 6, 10, 16, 64, 4}, + {15, 6, 11, 16, 64, 4}, + {15, 6, 12, 16, 64, 4}, + {15, 6, 13, 16, 64, 4}, + {15, 6, 14, 16, 32, 1}, + {15, 6, 15, 16, 64, 4}, + {15, 7, 1, 8, 64, 1}, + {15, 7, 2, 16, 32, 1}, + {15, 7, 3, 8, 64, 1}, + {15, 7, 4, 16, 32, 1}, + {15, 7, 5, 32, 32, 1}, + {15, 7, 6, 16, 32, 1}, + {15, 7, 7, 32, 32, 2}, + {15, 7, 8, 32, 32, 2}, + {15, 7, 9, 16, 64, 4}, + {15, 7, 10, 16, 64, 4}, + {15, 7, 11, 32, 32, 2}, + {15, 7, 12, 32, 32, 2}, + {15, 7, 13, 32, 32, 2}, + {15, 7, 14, 64, 32, 1}, + {15, 7, 15, 32, 32, 2}, + {15, 8, 1, 16, 64, 1}, + {15, 8, 2, 16, 32, 1}, + {15, 8, 3, 16, 32, 1}, + {15, 8, 4, 64, 32, 1}, + {15, 8, 5, 64, 32, 1}, + {15, 8, 6, 32, 32, 1}, + {15, 8, 7, 32, 32, 2}, + {15, 8, 8, 64, 32, 1}, + {15, 8, 9, 16, 64, 4}, + {15, 8, 10, 32, 32, 4}, + {15, 8, 11, 32, 32, 4}, + {15, 8, 12, 64, 32, 1}, + {15, 8, 13, 32, 32, 2}, + {15, 8, 14, 64, 32, 1}, + {15, 8, 15, 64, 32, 1}, + {15, 9, 1, 8, 64, 1}, + {15, 9, 2, 16, 32, 1}, + {15, 9, 3, 64, 32, 1}, + {15, 9, 4, 16, 32, 1}, + {15, 9, 5, 32, 32, 1}, + {15, 9, 6, 16, 32, 1}, + {15, 9, 7, 32, 32, 1}, + {15, 9, 8, 32, 32, 2}, + {15, 9, 9, 32, 32, 2}, + {15, 9, 10, 32, 32, 4}, + {15, 9, 11, 32, 32, 2}, + {15, 9, 12, 32, 32, 4}, + {15, 9, 13, 8, 64, 4}, + {15, 9, 14, 64, 32, 1}, + {15, 9, 15, 64, 32, 1}, + {15, 10, 1, 8, 64, 1}, + {15, 10, 2, 16, 64, 1}, + {15, 10, 3, 64, 32, 1}, + {15, 10, 4, 32, 32, 1}, + {15, 10, 5, 64, 32, 1}, + {15, 10, 6, 32, 32, 1}, + {15, 10, 7, 16, 32, 1}, + {15, 10, 8, 32, 32, 2}, + {15, 10, 9, 32, 32, 2}, + {15, 10, 10, 32, 32, 4}, + {15, 10, 11, 32, 32, 4}, + {15, 10, 12, 32, 32, 4}, + {15, 10, 13, 32, 32, 2}, + {15, 10, 14, 64, 32, 1}, + {15, 10, 15, 64, 32, 1}, + {15, 11, 1, 8, 64, 1}, + {15, 11, 2, 8, 64, 1}, + {15, 11, 3, 8, 64, 1}, + {15, 11, 4, 8, 64, 1}, + {15, 11, 5, 64, 32, 1}, + {15, 11, 6, 16, 32, 1}, + {15, 11, 7, 32, 32, 2}, + {15, 11, 8, 32, 32, 2}, + {15, 11, 9, 32, 32, 2}, + {15, 11, 10, 32, 32, 4}, + {15, 11, 11, 32, 32, 4}, + {15, 11, 12, 16, 32, 2}, + {15, 11, 13, 32, 32, 2}, + {15, 11, 14, 64, 32, 1}, + {15, 11, 15, 64, 32, 1}, + {15, 12, 1, 16, 32, 1}, + {15, 12, 2, 32, 32, 1}, + {15, 12, 3, 32, 32, 1}, + {15, 12, 4, 32, 32, 1}, + {15, 12, 5, 32, 32, 1}, + {15, 12, 6, 32, 32, 1}, + {15, 12, 7, 16, 32, 1}, + {15, 12, 8, 32, 32, 2}, + {15, 12, 9, 32, 32, 2}, + {15, 12, 10, 32, 32, 4}, + {15, 12, 11, 8, 64, 1}, + {15, 12, 12, 64, 32, 1}, + {15, 12, 13, 32, 32, 1}, + {15, 12, 14, 64, 32, 1}, + {15, 12, 15, 64, 32, 1}, + {15, 13, 1, 8, 32, 1}, + {15, 13, 2, 32, 32, 1}, + {15, 13, 3, 32, 32, 1}, + {15, 13, 4, 32, 32, 1}, + {15, 13, 5, 16, 32, 1}, + {15, 13, 6, 16, 32, 1}, + {15, 13, 7, 32, 32, 2}, + {15, 13, 8, 32, 32, 2}, + {15, 13, 9, 64, 32, 1}, + {15, 13, 10, 64, 32, 1}, + {15, 13, 11, 64, 32, 1}, + {15, 13, 12, 64, 32, 1}, + {15, 13, 13, 64, 32, 1}, + {15, 13, 14, 64, 32, 1}, + {15, 13, 15, 64, 32, 1}, + {15, 14, 1, 32, 32, 1}, + {15, 14, 2, 32, 32, 1}, + {15, 14, 3, 32, 32, 1}, + {15, 14, 4, 32, 32, 1}, + {15, 14, 5, 32, 32, 1}, + {15, 14, 6, 16, 32, 1}, + {15, 14, 7, 16, 64, 1}, + {15, 14, 8, 16, 64, 1}, + {15, 14, 9, 32, 32, 2}, + {15, 14, 10, 8, 64, 1}, + {15, 14, 11, 32, 32, 4}, + {15, 14, 12, 64, 32, 1}, + {15, 14, 13, 64, 32, 2}, + {15, 14, 14, 64, 32, 1}, + {15, 14, 15, 64, 32, 1}, + {15, 15, 1, 32, 32, 1}, + {15, 15, 2, 32, 32, 1}, + {15, 15, 3, 32, 32, 1}, + {15, 15, 4, 16, 32, 1}, + {15, 15, 5, 16, 32, 1}, + {15, 15, 6, 16, 32, 1}, + {15, 15, 7, 8, 64, 1}, + {15, 15, 8, 16, 64, 1}, + {15, 15, 9, 32, 32, 2}, + {15, 15, 10, 64, 32, 1}, + {15, 15, 11, 32, 32, 4}, + {15, 15, 12, 8, 64, 2}, + {15, 15, 13, 8, 64, 2}, + {15, 15, 14, 64, 32, 1}, + {15, 15, 15, 64, 32, 2}, +}; +} // namespace arch_xe_3lpg + +constexpr ArchTable kArchTables[] = { + {"xe-3lpg", arch_xe_3lpg::kGrid, 16, arch_xe_3lpg::kEntries, 3840}, +}; + +} // namespace sgmm_tuned diff --git a/onnxruntime/test/providers/cpu/math/matmul_test.cc b/onnxruntime/test/providers/cpu/math/matmul_test.cc index f624ecf57d05e..734cc62459c28 100644 --- a/onnxruntime/test/providers/cpu/math/matmul_test.cc +++ b/onnxruntime/test/providers/cpu/math/matmul_test.cc @@ -687,6 +687,112 @@ TEST(MathOpTest, MatMulBatchedSplitK) { .RunWithConfig(); } +#if defined(USE_WEBGPU) +// f16 MatMul cases that exercise the Intel 8x16x16 subgroup-matrix impl. +// The host picks the tile shape adaptively (TileM in {8,16,32,64}, TileN in +// {16,32,64}); M and N may be any size and K must be a multiple of 16. When the +// output has few tiles and K is large, the host also splits K across multiple +// cooperating subgroups (split_k in {1,2,4,8}) that reduce in shared memory. B +// is a constant initializer. On non-Intel hardware these fall back to the +// default impl but still validate correctness. +static void RunSubgroupMatrixMatMulTest(const std::vector& a_dims, int64_t K, int64_t N) { + int64_t M = 1; + for (size_t i = 0; i + 1 < a_dims.size(); ++i) { + M *= a_dims[i]; + } + + std::vector A_f32(M * K); + std::vector B_f32(K * N); + for (int64_t i = 0; i < M * K; ++i) { + A_f32[i] = static_cast((i % 7) - 3) * 0.1f; + } + for (int64_t i = 0; i < K * N; ++i) { + B_f32[i] = static_cast((i % 5) - 2) * 0.1f; + } + + std::vector Y_f32(M * N, 0.0f); + for (int64_t m = 0; m < M; ++m) { + for (int64_t n = 0; n < N; ++n) { + float sum = 0.0f; + for (int64_t k = 0; k < K; ++k) { + sum += A_f32[m * K + k] * B_f32[k * N + n]; + } + Y_f32[m * N + n] = sum; + } + } + + std::vector f_A(A_f32.size()); + std::vector f_B(B_f32.size()); + std::vector f_Y(Y_f32.size()); + ConvertFloatToMLFloat16(A_f32.data(), f_A.data(), static_cast(A_f32.size())); + ConvertFloatToMLFloat16(B_f32.data(), f_B.data(), static_cast(B_f32.size())); + ConvertFloatToMLFloat16(Y_f32.data(), f_Y.data(), static_cast(Y_f32.size())); + + std::vector y_dims = a_dims; + y_dims.back() = N; + + OpTester test("MatMul", 14); + test.AddInput("A", a_dims, f_A); + test.AddInput("B", {K, N}, f_B, /*is_initializer=*/true); + test.AddOutput("Y", y_dims, f_Y); + test.SetOutputTolerance(0.02f); + test.ConfigExcludeEps({kTensorrtExecutionProvider}) + .Config(run_with_tunable_op) + .RunWithConfig(); +} + +// A single test with many sub-cases that just barely cover the tile/split-K +// candidate space: TileM in {8,16,32,64}, TileN in {16,32,64}, split_k in +// {1,2,4,8}, plus the partial-edge, batched, and scratch-cap boundaries. Each +// sub-case runs under a SCOPED_TRACE so a failure names the exact shape. +TEST(MathOpTest, MatMulSubgroupMatrix) { + struct Case { + const char* name; + std::vector a_dims; + int64_t K; + int64_t N; + }; + + const std::vector cases = { + // TileM coverage: M selects the largest TileM candidate <= M. + {"TileM8 (M=8 -> TileM=8)", {8, 64}, 64, 64}, + {"TileM16 (M=16 -> TileM=16)", {16, 64}, 64, 32}, + {"TileM32 (M=32 -> TileM=32)", {32, 64}, 64, 16}, + {"TileM64 (M=64 -> TileM=64)", {64, 64}, 64, 64}, + // TileN coverage: N selects the largest TileN candidate <= N. + {"TileN16 (N=16 -> TileN=16)", {32, 64}, 64, 16}, + {"TileN32 (N=32 -> TileN=32)", {16, 64}, 64, 32}, + {"TileN64 (N=64 -> TileN=64)", {64, 128}, 128, 64}, + // Partial edges: M and N not multiples of the tile; bounds-checked stores. + {"PartialMN (M=40,N=48)", {40, 64}, 64, 48}, + {"LargeNonAligned (M=100,N=96)", {100, 80}, 80, 96}, + // Below-minimum and minimum boundaries. + {"TinyM (M=4 -> TileM=8 partial)", {4, 64}, 64, 32}, + {"MinK (single K block)", {32, 16}, 16, 32}, + // Batched A folds leading dims into M. + {"Batched (2*32 -> M=64)", {2, 32, 64}, 64, 64}, + // Split-K coverage: one small output tile with growing K drives split_k. + // K=64 (4 blocks) -> 2, K=128 (8 blocks) -> 4, K=256 (16 blocks) -> 8. + {"SplitK2 (K=64 -> split_k=2)", {8, 64}, 64, 16}, + {"SplitK4 (K=128 -> split_k=4)", {8, 128}, 128, 16}, + {"SplitK8 (K=256 -> split_k=8)", {8, 256}, 256, 16}, + // K=144 -> 9 K-blocks, not divisible by split_k=4; round-robin K split. + {"SplitKUnevenBlocks (K=144)", {8, 144}, 144, 16}, + // Split-K with a partial N edge tile (N=24 -> two TileN=16 tiles). + {"SplitKPartialN (N=24)", {8, 256}, 256, 24}, + // Largest tile (64x64) with K=256: split_k capped at 4 by scratch budget. + {"SplitKScratchCap (64x64,K=256)", {64, 256}, 256, 64}, + // Batched A folds to M=8; one tile + K=256 -> split_k=8. + {"SplitKBatched (2*4 -> M=8)", {2, 4, 256}, 256, 16}, + }; + + for (const auto& c : cases) { + SCOPED_TRACE(c.name); + RunSubgroupMatrixMatMulTest(c.a_dims, c.K, c.N); + } +} +#endif // defined(USE_WEBGPU) + #endif } // namespace test