From cd62874d8754f8b664dcc154c2958d87e4854c39 Mon Sep 17 00:00:00 2001 From: Daniel Vega-Myhre Date: Tue, 7 Jan 2025 14:07:37 -0800 Subject: [PATCH 1/9] add fp8 conversion kernel that writes both row and column major outputs (#1494) --- .../kernels/fp8_dynamic_tensorwise.py | 129 ++++++++++++++++++ .../kernels/fp8_dynamic_tensorwise_test.py | 95 +++++++++++-- 2 files changed, 209 insertions(+), 15 deletions(-) diff --git a/torchao/prototype/float8nocompile/kernels/fp8_dynamic_tensorwise.py b/torchao/prototype/float8nocompile/kernels/fp8_dynamic_tensorwise.py index 213b6bb5a..2493cbe3e 100644 --- a/torchao/prototype/float8nocompile/kernels/fp8_dynamic_tensorwise.py +++ b/torchao/prototype/float8nocompile/kernels/fp8_dynamic_tensorwise.py @@ -255,6 +255,55 @@ def to_fp8_col_major_t( tl.store(out_ptr + out_offs, fp8_vals, mask=out_mask) +@triton.autotune( + configs=kernel_configs_2D, + key=["num_elements"], +) +@triton.jit +def _to_fp8_row_and_col_major( + input_ptr, + row_major_out_ptr, + col_major_out_ptr, + scale_ptr, + num_elements: int, + fp8_dtype_min: float, + fp8_dtype_max: float, + num_rows: int, + num_cols: int, + input_dtype: tl.constexpr, + output_dtype: tl.constexpr, + BLOCK_SIZE_ROWS: tl.constexpr, + BLOCK_SIZE_COLS: tl.constexpr, + EPS: tl.constexpr, +): + block_row_id = tl.program_id(axis=0) + block_col_id = tl.program_id(axis=1) + + # load scaling factor + scale = tl.load(scale_ptr).to(tl.float32) + + # load block of input tensor + block_row_start = block_row_id * BLOCK_SIZE_ROWS + block_col_start = block_col_id * BLOCK_SIZE_COLS + block_row_offs = block_row_start + tl.arange(0, BLOCK_SIZE_ROWS) + block_col_offs = block_col_start + tl.arange(0, BLOCK_SIZE_COLS) + block_offs = block_row_offs[:, None] * num_cols + block_col_offs[None, :] + mask = (block_row_offs[:, None] < num_rows) & (block_col_offs[None, :] < num_cols) + vals = tl.load(input_ptr + block_offs, mask=mask).to(input_dtype) + + # perform conversion + vals = vals * scale + fp8_vals = tl.clamp(vals, min=fp8_dtype_min, max=fp8_dtype_max).to(output_dtype) + + # write row major output + row_major_offs = block_row_offs[:, None] * num_cols + block_col_offs[None, :] + tl.store(row_major_out_ptr + row_major_offs, fp8_vals, mask=mask) + + # write column major output + col_major_offs = block_col_offs[None, :] * num_rows + block_row_offs[:, None] + tl.store(col_major_out_ptr + col_major_offs, fp8_vals, mask=mask) + + @triton.autotune(configs=kernel_configs_1D, key=["num_elements"]) @triton.jit def _amax_atomic( @@ -573,6 +622,86 @@ def hp_to_fp8_col_major_t( return fp8_tensor_col_major_t +def hp_to_fp8_row_and_col_major( + hp_tensor: torch.Tensor, + fp8_dtype: torch.dtype, + linear_mm_config: LinearMMConfig, + gemm_input_role: GemmInputRole = GemmInputRole.INPUT, + algo: KernelAlgorithm = KernelAlgorithm.ATOMIC_MAX, +) -> Float8Tensor: + assert hp_tensor.is_contiguous(), "input tensor must be contiguous" + + tl_input_dtype = FP8_DTYPE_MAP[hp_tensor.dtype] + tl_output_dtype = FP8_DTYPE_MAP[fp8_dtype] + + fp8_dtype_min = torch.finfo(fp8_dtype).min + fp8_dtype_max = torch.finfo(fp8_dtype).max + + # compute scaling factor for tensor + scale = _hp_tensor_to_scale( + hp_tensor, + tl_input_dtype, + fp8_dtype_max, + algo, + ) + + # perform fp8 conversion + orig_shape = hp_tensor.shape + num_elements = hp_tensor.numel() + + # preallocate necessary output tensors + fp8_output_row_major = torch.empty( + orig_shape, dtype=fp8_dtype, device=hp_tensor.device + ) + fp8_output_col_major = torch.empty( + orig_shape, dtype=fp8_dtype, device=hp_tensor.device + ) + + # launch triton kernel to perform conversion + num_rows, num_cols = orig_shape + grid = lambda meta: ( + triton.cdiv(num_rows, meta["BLOCK_SIZE_ROWS"]), + triton.cdiv(num_cols, meta["BLOCK_SIZE_COLS"]), + ) + _to_fp8_row_and_col_major[grid]( + hp_tensor, + fp8_output_row_major, + fp8_output_col_major, + scale, + num_elements, + fp8_dtype_min, + fp8_dtype_max, + num_rows, + num_cols, + input_dtype=tl_input_dtype, + output_dtype=tl_output_dtype, + EPS=EPS, + ) + + # for col major we need to update the strides to reflect the new memory layout + col_major_strides = (1, num_rows) + fp8_output_col_major = fp8_output_col_major.as_strided( + fp8_output_col_major.size(), col_major_strides + ) + + # wrap outputs in Float8Tensors + fp8_tensor_row_major = Float8Tensor( + fp8_output_row_major, + scale, + orig_dtype=hp_tensor.dtype, + linear_mm_config=linear_mm_config, + gemm_input_role=gemm_input_role, + ) + fp8_tensor_col_major = Float8Tensor( + fp8_output_col_major, + scale, + orig_dtype=hp_tensor.dtype, + linear_mm_config=linear_mm_config, + gemm_input_role=gemm_input_role, + ) + return fp8_tensor_row_major, fp8_tensor_col_major + + def _hp_tensor_to_scale( hp_tensor: torch.Tensor, tl_input_dtype: tl.core.dtype, diff --git a/torchao/prototype/float8nocompile/kernels/fp8_dynamic_tensorwise_test.py b/torchao/prototype/float8nocompile/kernels/fp8_dynamic_tensorwise_test.py index a9b5491d2..02dce5ea4 100644 --- a/torchao/prototype/float8nocompile/kernels/fp8_dynamic_tensorwise_test.py +++ b/torchao/prototype/float8nocompile/kernels/fp8_dynamic_tensorwise_test.py @@ -6,6 +6,7 @@ from torchao.prototype.float8nocompile.kernels.fp8_dynamic_tensorwise import ( hp_to_fp8_col_major, hp_to_fp8_col_major_t, + hp_to_fp8_row_and_col_major, hp_to_fp8_row_major, hp_to_fp8_row_major_t, KernelAlgorithm, @@ -43,9 +44,7 @@ def test_fp8_hp_to_fp8_row_major(input_shape: tuple[int, int], algo: KernelAlgor ) # check scales - assert torch.allclose( - x_fp8_row_major._scale, y_fp8_row_major._scale, atol=0, rtol=0 - ) + assert torch.eq(x_fp8_row_major._scale, y_fp8_row_major._scale) # check data assert torch.all(torch.eq(x_fp8_row_major._data, y_fp8_row_major._data)) @@ -109,9 +108,7 @@ def test_fp8_hp_to_fp8_row_major_t(input_shape: tuple[int, int], algo: KernelAlg ) # check scales - assert torch.allclose( - x_fp8_row_major_t._scale, y_fp8_row_major_t._scale, atol=0, rtol=0 - ) + assert torch.eq(x_fp8_row_major_t._scale, y_fp8_row_major_t._scale) # check data assert torch.all(torch.eq(x_fp8_row_major_t._data, y_fp8_row_major_t._data)) @@ -173,9 +170,7 @@ def test_fp8_hp_to_fp8_col_major(input_shape: tuple[int, int], algo: KernelAlgor ) # check scales - assert torch.allclose( - x_fp8_col_major._scale, y_fp8_col_major._scale, atol=0, rtol=0 - ) + assert torch.eq(x_fp8_col_major._scale, y_fp8_col_major._scale) # check data assert torch.all(torch.eq(x_fp8_col_major._data, y_fp8_col_major._data)) @@ -237,14 +232,10 @@ def test_fp8_hp_to_fp8_col_major_t(input_shape: tuple[int, int], algo: KernelAlg ) # check scales - assert torch.allclose( - x_fp8_col_major_t._scale, y_fp8_col_major_t._scale, atol=0, rtol=0 - ) + assert torch.eq(x_fp8_col_major_t._scale, y_fp8_col_major_t._scale) # check data - assert torch.all( - torch.eq(x_fp8_col_major_t._data, y_fp8_col_major_t._data, atol=0, rtol=0) - ) + assert torch.all(torch.eq(x_fp8_col_major_t._data, y_fp8_col_major_t._data)) # check shapes assert x_fp8_col_major_t.shape == y_fp8_col_major_t.shape @@ -269,3 +260,77 @@ def test_fp8_hp_to_fp8_col_major_t(input_shape: tuple[int, int], algo: KernelAlg torch.float8_e4m3fn, LinearMMConfig(), ) + + +@pytest.mark.parametrize( + "algo", + [KernelAlgorithm.REDUCTION, KernelAlgorithm.ATOMIC_MAX], +) +@pytest.mark.parametrize( + "input_shape", + [(2, 4), (32, 16), (512, 512)], +) +def test_fp8_hp_to_fp8_row_and_col_major( + input_shape: tuple[int, int], algo: KernelAlgorithm +): + assert torch.cuda.is_available() + device = "cuda" + input_bf16 = torch.randn(input_shape, dtype=torch.bfloat16, device=device) + x_bf16 = input_bf16.clone().detach().to(device) + y_bf16 = input_bf16.clone().detach().to(device) + + # production implementation + x_fp8_row_major = hp_tensor_to_float8_dynamic( + x_bf16, + torch.float8_e4m3fn, + LinearMMConfig(), + ) + x_fp8_col_major = x_fp8_row_major.t().contiguous().t() + + # float8nocompile triton implementation + y_fp8_row_major, y_fp8_col_major = hp_to_fp8_row_and_col_major( + y_bf16, + torch.float8_e4m3fn, + LinearMMConfig(), + algo=algo, + ) + + # check scales + assert torch.eq(x_fp8_row_major._scale, y_fp8_row_major._scale) + assert torch.eq(x_fp8_col_major._scale, y_fp8_col_major._scale) + + # check data + assert torch.all(torch.eq(x_fp8_row_major._data, y_fp8_row_major._data)) + assert torch.all(torch.eq(x_fp8_col_major._data, y_fp8_col_major._data)) + + # check shapes + assert x_fp8_row_major.shape == y_fp8_row_major.shape + assert x_fp8_col_major.shape == y_fp8_col_major.shape + + # check strides + assert x_fp8_row_major.stride() == y_fp8_row_major.stride() + assert x_fp8_col_major.stride() == y_fp8_col_major.stride() + + # check memory layout + assert is_row_major(x_fp8_row_major.stride()) + assert is_row_major(y_fp8_row_major.stride()) + assert not is_row_major(x_fp8_col_major.stride()) + assert not is_row_major(y_fp8_col_major.stride()) + + # check underlying memory layout + assert ( + x_fp8_row_major._data.storage().tolist() + == y_fp8_row_major._data.storage().tolist() + ) + assert ( + x_fp8_col_major._data.storage().tolist() + == y_fp8_col_major._data.storage().tolist() + ) + + # assert that error is raised when input tensor is not contiguous + with pytest.raises(AssertionError, match="tensor must be contiguous"): + hp_to_fp8_row_and_col_major( + y_bf16.t(), # transpose so tensor memory layout is no longer contiguous + torch.float8_e4m3fn, + LinearMMConfig(), + ) From 5a0d6622bdcc7eed281ef29b5cf5376b95d178ab Mon Sep 17 00:00:00 2001 From: Daniel Vega-Myhre Date: Tue, 7 Jan 2025 16:07:44 -0800 Subject: [PATCH 2/9] add torch autograd funcs wrapping new fp8 conversion kernels (#1495) --- .../float8nocompile_scaling_utils.py | 170 ++++++++++++------ 1 file changed, 113 insertions(+), 57 deletions(-) diff --git a/torchao/prototype/float8nocompile/float8nocompile_scaling_utils.py b/torchao/prototype/float8nocompile/float8nocompile_scaling_utils.py index 4feb437d1..b709dcb85 100644 --- a/torchao/prototype/float8nocompile/float8nocompile_scaling_utils.py +++ b/torchao/prototype/float8nocompile/float8nocompile_scaling_utils.py @@ -16,54 +16,81 @@ GemmInputRole, LinearMMConfig, ) + from torchao.prototype.float8nocompile.kernels.fp8_dynamic_tensorwise import ( + hp_to_fp8_col_major, + hp_to_fp8_col_major_t, + hp_to_fp8_row_and_col_major, + hp_to_fp8_row_major, + hp_to_fp8_row_major_t, KernelAlgorithm, - triton_hp_tensor_to_float8_dynamic, ) -# avoid division by zero when calculating scale -# TODO: align this value with NVIDIA's assumptions (current value is a guess) -EPS = 1e-12 +class ToFP8RowAndColumnMajor(torch.autograd.Function): + """ + A differentiable conversion to fp8. + * forward: convert from high precision to float8 and produces both row-major and column-major outputs + * backward: pass the gradient without changes + """ + + @staticmethod + def forward( + ctx, + tensor: torch.Tensor, + float8_dtype: torch.dtype, + linear_mm_config: LinearMMConfig, + gemm_input_role: GemmInputRole, + kernel_algo: KernelAlgorithm = KernelAlgorithm.ATOMIC_MAX, + ): + fp8_row_major, fp8_col_major = hp_to_fp8_row_and_col_major( + tensor, + float8_dtype, + linear_mm_config, + gemm_input_role, + algo=kernel_algo, + ) + return fp8_row_major, fp8_col_major -def hp_tensor_to_float8nocompile_dynamic( - hp_tensor: torch.Tensor, - float8_dtype: torch.dtype, - linear_mm_config: LinearMMConfig, - gemm_input_role: GemmInputRole = GemmInputRole.INPUT, -) -> Float8Tensor: + @staticmethod + def backward(ctx, g): + return g, None, None, None, None + + +class ToFP8RowMajor(torch.autograd.Function): """ - Given a high precision tensor `hp_tensor`, - scales `hp_tensor` dynamically and returns a `Float8Tensor` of the result. - - Args: - hp_tensor: the tensor to convert - float8_dtype: the float8 dtype to use - linear_mm_config: Defines the configuration for the scaled_mm for - the 3 fwd/bwd gemms of linear - gemm_input_role: Defines the role of this tensor (input, weight or grad_output) in - the 3 fwd/bwd gemms of linear + A differentiable conversion to fp8 in row-major layout. + * forward: convert from high precision to float8 with row-major memory layout + * backward: pass the gradient without changes """ - # TODO(danielvegamyhre): replace this torch implementation with custom triton kernel - # torch.compile and eager show different numerics for 1.0 / float32, - # upcast to float64 to ensure same numeric between compile and eager - amax = torch.max(torch.abs(hp_tensor)).to(torch.float64) - scale = torch.finfo(float8_dtype).max / torch.clamp(amax, min=EPS) - scale = scale.to(torch.float32) # scale must be fp32 - return _ToFloat8ConstrFunc.apply( - hp_tensor, - scale, - float8_dtype, - linear_mm_config, - gemm_input_role, - None, - ) - - -class Float8NoCompileConversionFunc(torch.autograd.Function): + + @staticmethod + def forward( + ctx, + tensor: torch.Tensor, + float8_dtype: torch.dtype, + linear_mm_config: LinearMMConfig, + gemm_input_role: GemmInputRole, + kernel_algo: KernelAlgorithm = KernelAlgorithm.ATOMIC_MAX, + ): + fp8_row_major = hp_to_fp8_row_major( + tensor, + float8_dtype, + linear_mm_config, + gemm_input_role, + algo=kernel_algo, + ) + return fp8_row_major + + @staticmethod + def backward(ctx, g): + return g, None, None, None, None + + +class ToFP8RowMajorT(torch.autograd.Function): """ - A differentiable conversion to fp8. - * forward: convert from high precision to float8 + A differentiable conversion to fp8 with transposed dimensions in row-major layout. + * forward: convert from high precision to float8 with transposed dimensions with row-major memory layout * backward: pass the gradient without changes """ @@ -76,24 +103,25 @@ def forward( gemm_input_role: GemmInputRole, kernel_algo: KernelAlgorithm = KernelAlgorithm.ATOMIC_MAX, ): - return triton_hp_tensor_to_float8_dynamic( + fp8_row_major_t = hp_to_fp8_row_major_t( tensor, float8_dtype, linear_mm_config, gemm_input_role, algo=kernel_algo, ) + return fp8_row_major_t @staticmethod def backward(ctx, g): - return g, None, None, None, None, None + return g, None, None, None, None -class NoopFwToFloat8NoCompileBwDynamic(torch.autograd.Function): +class ToFP8ColumnMajor(torch.autograd.Function): """ - A differentiable conversion to fp8. - * forward: no-op - * backward: convert to float8 with tensor-wise dynamic scaling + A differentiable conversion to fp8 in column-major layout. + * forward: convert from high precision to float8 with column-major memory layout + * backward: pass the gradient without changes """ @staticmethod @@ -102,20 +130,48 @@ def forward( tensor: torch.Tensor, float8_dtype: torch.dtype, linear_mm_config: LinearMMConfig, + gemm_input_role: GemmInputRole, kernel_algo: KernelAlgorithm = KernelAlgorithm.ATOMIC_MAX, ): - ctx.linear_mm_config = linear_mm_config - ctx.target_dtype = float8_dtype - ctx.kernel_algo = kernel_algo - return tensor + fp8_col_major = hp_to_fp8_col_major( + tensor, + float8_dtype, + linear_mm_config, + gemm_input_role, + algo=kernel_algo, + ) + return fp8_col_major + + @staticmethod + def backward(ctx, g): + return g, None, None, None, None + + +class ToFP8ColumnMajorT(torch.autograd.Function): + """ + A differentiable conversion to fp8 with transposed dimensions in column-major layout. + * forward: convert from high precision to float8 with transposed dimensions in column-major memory layout. + * backward: pass the gradient without changes + """ @staticmethod - def backward(ctx, gradY): - fp8_tensor = triton_hp_tensor_to_float8_dynamic( - gradY, - ctx.target_dtype, - ctx.linear_mm_config, - GemmInputRole.GRAD_OUTPUT, - ctx.kernel_algo, + def forward( + ctx, + tensor: torch.Tensor, + float8_dtype: torch.dtype, + linear_mm_config: LinearMMConfig, + gemm_input_role: GemmInputRole, + kernel_algo: KernelAlgorithm = KernelAlgorithm.ATOMIC_MAX, + ): + fp8_col_major_t = hp_to_fp8_col_major_t( + tensor, + float8_dtype, + linear_mm_config, + gemm_input_role, + algo=kernel_algo, ) - return fp8_tensor, None, None, None + return fp8_col_major_t + + @staticmethod + def backward(ctx, g): + return g, None, None, None, None From 2c3d44c96945a1ae1409baf68e7c4dd18f26dfc4 Mon Sep 17 00:00:00 2001 From: dongxiaolong <774848421@qq.com> Date: Wed, 8 Jan 2025 08:38:45 +0800 Subject: [PATCH 3/9] =?UTF-8?q?=F0=9F=90=9B=20Fix:=20Memory=20leak=20in=20?= =?UTF-8?q?image=20processing=20endpoint=20(#1513)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/sam2_amg_server/server.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/examples/sam2_amg_server/server.py b/examples/sam2_amg_server/server.py index 1617dcd9e..2fa216176 100644 --- a/examples/sam2_amg_server/server.py +++ b/examples/sam2_amg_server/server.py @@ -555,19 +555,21 @@ async def upload_image(image: UploadFile = File(...)): response_future = asyncio.Future() await request_queue.put((image_tensor, response_future)) masks = await response_future - - # Save an example - plt.figure(figsize=(image_tensor.shape[1]/100., image_tensor.shape[0]/100.), dpi=100) + + # Create figure and ensure it's closed after generating response + fig = plt.figure(figsize=(image_tensor.shape[1]/100., image_tensor.shape[0]/100.), dpi=100) plt.imshow(image_tensor) show_anns(masks, rle_to_mask) plt.axis('off') plt.tight_layout() + buf = BytesIO() plt.savefig(buf, format='png') buf.seek(0) + plt.close(fig) # Close figure after we're done with it + return StreamingResponse(buf, media_type="image/png") - # uvicorn.run(app, host=host, port=port, log_level="info") uvicorn.run(app, host=host, port=port) From d42a382a9d023c9234cbfd9694ebf3dc417b1ab8 Mon Sep 17 00:00:00 2001 From: Apurva Jain Date: Tue, 7 Jan 2025 17:01:59 -0800 Subject: [PATCH 4/9] Lint torchao folder (#1518) --- ruff.toml | 17 +- torchao/__init__.py | 22 +- torchao/prototype/autoround/__init__.py | 6 + torchao/prototype/autoround/autoround_llm.py | 3 +- torchao/prototype/autoround/core.py | 3 +- torchao/prototype/autoround/eval_autoround.py | 4 +- torchao/prototype/autoround/multi_tensor.py | 3 +- torchao/prototype/autoround/utils.py | 2 +- torchao/prototype/awq/__init__.py | 10 +- torchao/prototype/awq/api.py | 114 +- torchao/prototype/awq/core.py | 88 +- torchao/prototype/awq/example.py | 266 +- torchao/prototype/common/triton/matmul.py | 2 +- .../common/triton/matmul_perf_model.py | 21 +- torchao/prototype/custom_fp_utils.py | 16 +- torchao/prototype/dora/dora_layer.py | 5 - torchao/prototype/dora/kernels/common.py | 8 +- .../prototype/dora/kernels/custom_autotune.py | 4 +- torchao/prototype/dora/kernels/smallk.py | 6 +- torchao/prototype/dtypes/__init__.py | 4 +- torchao/prototype/dtypes/bitnet.py | 79 +- torchao/prototype/dtypes/uint2.py | 104 +- torchao/prototype/dtypes/uintgen.py | 99 +- .../float8nocompile/benchmark/benchmark.py | 2 +- .../float8nocompile/float8nocompile_linear.py | 7 +- .../float8nocompile_linear_utils.py | 3 - .../float8nocompile_scaling_utils.py | 2 +- .../kernels/fp8_dynamic_tensorwise.py | 4 +- .../kernels/fp8_dynamic_tensorwise_test.py | 3 +- torchao/prototype/galore/__init__.py | 2 +- torchao/prototype/galore/kernels/__init__.py | 8 + .../galore/kernels/adam_downproj_fused.py | 16 +- torchao/prototype/galore/kernels/adam_step.py | 2 - .../galore/kernels/custom_autotune.py | 8 +- torchao/prototype/galore/kernels/matmul.py | 7 +- torchao/prototype/galore/kernels/quant.py | 4 +- .../prototype/galore/optim/galore_torch.py | 7 +- torchao/prototype/galore/utils.py | 2 - torchao/prototype/hqq/__init__.py | 7 +- torchao/prototype/hqq/example.py | 184 +- torchao/prototype/hqq/hqq_tinygemm_linear.py | 15 +- torchao/prototype/hqq/kernels.py | 4 +- torchao/prototype/hqq/mixed_mm.py | 2 +- .../mx_formats/benchmarks/bench_qdq.py | 6 +- torchao/prototype/mx_formats/custom_cast.py | 16 +- .../prototype/mx_formats/fp_format_spec.py | 10 +- torchao/prototype/mx_formats/mx_tensor.py | 9 +- .../prototype/quantization/autoquant_v2.py | 68 +- .../scripts/BO_acc_modelsize.py | 329 +- .../scripts/BO_acc_throughput.py | 375 +- .../mixed_precision/scripts/__init__.py | 4 + .../mixed_precision/scripts/fit.py | 99 +- .../mixed_precision/scripts/hessian_grad.py | 119 +- .../mixed_precision/scripts/hessian_vhp.py | 98 +- .../mixed_precision/scripts/mp_quant_eval.py | 224 +- .../mixed_precision/scripts/naive_intNwo.py | 61 +- .../mixed_precision/scripts/utils.py | 66 +- .../prototype/quantized_training/__init__.py | 19 +- .../prototype/quantized_training/bitnet.py | 62 +- torchao/prototype/quantized_training/int8.py | 52 +- .../int8_mixed_precision.py | 21 +- .../prototype/quantized_training/int8_mm.py | 19 +- torchao/prototype/smoothquant/__init__.py | 12 +- torchao/prototype/smoothquant/api.py | 76 +- torchao/prototype/smoothquant/core.py | 38 +- torchao/prototype/smoothquant/example.py | 180 +- torchao/prototype/sparsity/__init__.py | 13 + torchao/prototype/sparsity/pruner/__init__.py | 15 +- .../pruner/base_structured_sparsifier.py | 12 +- .../sparsity/pruner/lstm_saliency_pruner.py | 6 +- .../prototype/sparsity/pruner/match_utils.py | 10 +- .../sparsity/pruner/parametrization.py | 1 - .../sparsity/pruner/prune_functions.py | 9 +- .../sparsity/pruner/saliency_pruner.py | 4 +- .../sparsity/scheduler/base_scheduler.py | 3 - .../sparsity/scheduler/cubic_scheduler.py | 36 +- .../sparsity/scheduler/lambda_scheduler.py | 14 +- .../sparsity/sparsifier/base_sparsifier.py | 10 +- .../sparsifier/nearly_diagonal_sparsifier.py | 10 +- .../prototype/sparsity/sparsifier/utils.py | 10 +- .../sparsifier/weight_norm_sparsifier.py | 88 +- .../sparsity/superblock/benchmark.py | 3 +- .../sparsity/superblock/blocksparse.py | 5 +- .../prototype/sparsity/superblock/evaluate.py | 1 - .../sparsity/superblock/supermask.py | 216 +- .../prototype/sparsity/superblock/train.py | 5 +- .../prototype/sparsity/superblock/utils.py | 12 +- torchao/prototype/spinquant/__init__.py | 4 + .../prototype/spinquant/_hadamard_matrices.py | 99322 +++++++++++++++- torchao/prototype/spinquant/hadamard_utils.py | 42 +- torchao/prototype/spinquant/spinquant.py | 66 +- torchao/prototype/splitk/__init__.py | 5 + torchao/prototype/splitk/splitk_gemm.py | 97 +- 93 files changed, 101873 insertions(+), 1284 deletions(-) diff --git a/ruff.toml b/ruff.toml index bbd40a487..3df55e96e 100644 --- a/ruff.toml +++ b/ruff.toml @@ -3,20 +3,13 @@ # To add a new path: Simply add it to the 'include' list. # Example: To lint all files in every subfolder of 'test', add "test/**/*" include = [ - "torchao/float8/**/*.py", - "torchao/quantization/**/*.py", - "torchao/dtypes/**/*.py", - "torchao/sparsity/**/*.py", - "torchao/profiler/**/*.py", - "torchao/testing/**/*.py", - "torchao/_models/**/*.py", - "torchao/kernel/**/*.py", - "torchao/prototype/low_bit_optim/**.py", - "torchao/utils.py", - "torchao/ops.py", - "torchao/_executorch_ops.py", + "torchao/**/*.py", "test/**/*.py", ] +exclude = [ + "torchao/experimental/**/*.py", +] + lint.select = ["F", "I"] lint.ignore = ["E731"] diff --git a/torchao/__init__.py b/torchao/__init__.py index dd3ddbc81..3e00bf6c5 100644 --- a/torchao/__init__.py +++ b/torchao/__init__.py @@ -1,28 +1,33 @@ -import torch import logging # torch/nested/_internal/nested_tensor.py:417: UserWarning: Failed to initialize NumPy: No module named 'numpy' import warnings -warnings.filterwarnings("ignore", message="Failed to initialize NumPy: No module named 'numpy'") + +import torch + +warnings.filterwarnings( + "ignore", message="Failed to initialize NumPy: No module named 'numpy'" +) # We use this "hack" to set torchao.__version__ correctly # the version of ao is dependent on environment variables for multiple architectures # For local development this will default to whatever is version.txt # For release builds this will be set the version+architecture_postfix -from importlib.metadata import version, PackageNotFoundError +from importlib.metadata import PackageNotFoundError, version + try: __version__ = version("torchao") except PackageNotFoundError: - __version__ = 'unknown' # In case this logic breaks don't break the build + __version__ = "unknown" # In case this logic breaks don't break the build _IS_FBCODE = ( - hasattr(torch._utils_internal, "IS_FBSOURCE") and - torch._utils_internal.IS_FBSOURCE + hasattr(torch._utils_internal, "IS_FBSOURCE") and torch._utils_internal.IS_FBSOURCE ) if not _IS_FBCODE: try: from pathlib import Path + so_files = list(Path(__file__).parent.glob("_C*.so")) assert len(so_files) == 1, f"Expected one _C*.so file, found {len(so_files)}" torch.ops.load_library(so_files[0]) @@ -34,14 +39,15 @@ autoquant, quantize_, ) -from . import dtypes -from . import testing + +from . import dtypes, testing __all__ = [ "dtypes", "autoquant", "quantize_", "testing", + "ops", ] # test-pytorchbot diff --git a/torchao/prototype/autoround/__init__.py b/torchao/prototype/autoround/__init__.py index 4c2ff65ad..6ae0d7ecb 100644 --- a/torchao/prototype/autoround/__init__.py +++ b/torchao/prototype/autoround/__init__.py @@ -3,3 +3,9 @@ prepare_model_for_applying_auto_round_, ) from torchao.prototype.autoround.multi_tensor import MultiTensor + +__all__ = [ + "apply_auto_round", + "prepare_model_for_applying_auto_round_", + "MultiTensor", +] diff --git a/torchao/prototype/autoround/autoround_llm.py b/torchao/prototype/autoround/autoround_llm.py index f1cb528bf..f20bb038b 100644 --- a/torchao/prototype/autoround/autoround_llm.py +++ b/torchao/prototype/autoround/autoround_llm.py @@ -1,5 +1,4 @@ import argparse -import logging from typing import Optional import torch @@ -67,7 +66,7 @@ def quantize_model_with_autoround_( multi_t_input_ids = MultiTensor(input_ids_lst) # The optimization is applied during the forward pass - out = model(multi_t_input_ids) + model(multi_t_input_ids) # Step 3. Apply the quantization quantize_(model, apply_auto_round(), is_target_module, device=device) diff --git a/torchao/prototype/autoround/core.py b/torchao/prototype/autoround/core.py index 1b7c86f6d..0504b5ea2 100644 --- a/torchao/prototype/autoround/core.py +++ b/torchao/prototype/autoround/core.py @@ -3,12 +3,11 @@ from typing import Any, Callable, Dict, Optional, Tuple import torch -from torch.utils._pytree import tree_flatten, tree_unflatten import torchao.prototype.autoround.utils as ar_utils import torchao.quantization as ao_quant from torchao.dtypes import TensorCoreTiledLayout, to_affine_quantized_intx_static -from torchao.prototype.autoround.multi_tensor import _multi_tensor_config, MultiTensor +from torchao.prototype.autoround.multi_tensor import MultiTensor, _multi_tensor_config from torchao.quantization.quant_primitives import ZeroPointDomain from torchao.utils import find_multiple diff --git a/torchao/prototype/autoround/eval_autoround.py b/torchao/prototype/autoround/eval_autoround.py index c28a0fc39..0e5308ca3 100644 --- a/torchao/prototype/autoround/eval_autoround.py +++ b/torchao/prototype/autoround/eval_autoround.py @@ -42,7 +42,7 @@ def run_evaluation(model, tokenizer, tasks, compile=False, batch_size=4): from lm_eval.evaluator import evaluate from lm_eval.models.huggingface import HFLM from lm_eval.tasks import get_task_dict - except ImportError as e: + except ImportError: print( """ Error: The 'lm_eval' module was not found. @@ -70,7 +70,7 @@ def bench_accuracy(model, tokenizer, tasks, msg=""): from torchao.prototype.autoround.hf_eval_utils import run_evaluation torch.cuda.empty_cache() - res = run_evaluation(model, tokenizer, tasks=tasks) + run_evaluation(model, tokenizer, tasks=tasks) torch.cuda.empty_cache() diff --git a/torchao/prototype/autoround/multi_tensor.py b/torchao/prototype/autoround/multi_tensor.py index 72af4d854..441ae2e83 100644 --- a/torchao/prototype/autoround/multi_tensor.py +++ b/torchao/prototype/autoround/multi_tensor.py @@ -101,7 +101,8 @@ def grouped_to_flat(cls, grouped): min( [True] + [ # handle situation where tuples have size 0 - tup[0] == x for x in tup # check all elements match + tup[0] == x + for x in tup # check all elements match ] ) for tup in flat_tups diff --git a/torchao/prototype/autoround/utils.py b/torchao/prototype/autoround/utils.py index 634c2269a..9269164c8 100644 --- a/torchao/prototype/autoround/utils.py +++ b/torchao/prototype/autoround/utils.py @@ -146,7 +146,7 @@ def get_float_model_info(model_name_or_path, torch_dtype=torch.float32): logging.warning(f"Detected decoder class: {decoder_cls}") if decoder_cls is None: raise ValueError( - f"Cannot detect the decoder class from the model, please provide it manually." + "Cannot detect the decoder class from the model, please provide it manually." ) return model, tokenizer, decoder_cls diff --git a/torchao/prototype/awq/__init__.py b/torchao/prototype/awq/__init__.py index ca9381d57..570b0821d 100644 --- a/torchao/prototype/awq/__init__.py +++ b/torchao/prototype/awq/__init__.py @@ -1,2 +1,8 @@ -from .api import insert_awq_observer_, awq_uintx -from .core import AWQObservedLinear \ No newline at end of file +from .api import awq_uintx, insert_awq_observer_ +from .core import AWQObservedLinear + +__all__ = [ + "awq_uintx", + "insert_awq_observer_", + "AWQObservedLinear", +] diff --git a/torchao/prototype/awq/api.py b/torchao/prototype/awq/api.py index d0f3ebc0d..70fe96429 100644 --- a/torchao/prototype/awq/api.py +++ b/torchao/prototype/awq/api.py @@ -1,28 +1,37 @@ import torch -import torch.nn.functional as F +from torchao.dtypes import ( + TensorCoreTiledLayout, + to_affine_quantized_intx, +) +from torchao.dtypes.uintx.uintx_layout import _DTYPE_TO_BIT_WIDTH, UintxLayout +from torchao.quantization import to_weight_tensor_with_linear_activation_scale_metadata from torchao.quantization.granularity import PerGroup +from torchao.quantization.quant_api import _replace_with_custom_fn_if_matches_filter from torchao.quantization.quant_primitives import ( + _DTYPE_TO_QVALUE_BOUNDS, MappingType, ZeroPointDomain, - _DTYPE_TO_QVALUE_BOUNDS, ) -from torchao.quantization import to_weight_tensor_with_linear_activation_scale_metadata -from torchao.quantization.quant_api import _replace_with_custom_fn_if_matches_filter -from torchao.dtypes.uintx.uintx_layout import _DTYPE_TO_BIT_WIDTH, UintxLayout -from torchao.dtypes import( - to_affine_quantized_intx, - TensorCoreTiledLayout, + +from .core import ( + AWQObservedLinear, + AWQObserver, ) -from .core import( - AWQObserver, - AWQObservedLinear, -) +assert ( + len(_DTYPE_TO_BIT_WIDTH) > 0 +), "Error importing low bit torch.uint dtypes. Please upgrade to torch 2.3+" -assert len(_DTYPE_TO_BIT_WIDTH) > 0, "Error importing low bit torch.uint dtypes. Please upgrade to torch 2.3+" -def insert_awq_observer_(model: torch.nn.Module, n_validation_examples: int, validation_sequence_len: int, quant_dtype: torch.dtype = torch.uint4, scale_search_space_size: int = 20, group_size: int = 128): +def insert_awq_observer_( + model: torch.nn.Module, + n_validation_examples: int, + validation_sequence_len: int, + quant_dtype: torch.dtype = torch.uint4, + scale_search_space_size: int = 20, + group_size: int = 128, +): """ Inserts AWQObserver into Linear layers of a given model. @@ -35,38 +44,44 @@ def insert_awq_observer_(model: torch.nn.Module, n_validation_examples: int, val group_size: Quantization granularity. Use -1 for channel wise quantization """ _is_linear = lambda m, fqn: isinstance(m, torch.nn.Linear) - assert quant_dtype in _DTYPE_TO_BIT_WIDTH or quant_dtype == torch.uint8, "Invalid quant_dtype. Please use torch.uint1 .. torch.uint8" + assert ( + quant_dtype in _DTYPE_TO_BIT_WIDTH or quant_dtype == torch.uint8 + ), "Invalid quant_dtype. Please use torch.uint1 .. torch.uint8" # AQT config mapping_type = MappingType.ASYMMETRIC quantization_granularity = PerGroup(group_size) quant_min = 0 - quant_max = 255 if quant_dtype == torch.uint8 else 2 ** _DTYPE_TO_BIT_WIDTH[quant_dtype] - 1 + quant_max = ( + 255 if quant_dtype == torch.uint8 else 2 ** _DTYPE_TO_BIT_WIDTH[quant_dtype] - 1 + ) eps = torch.finfo(torch.float32).eps preserve_zero = True zero_point_dtype = torch.int64 zero_point_domain = ZeroPointDomain.INT - def replace_with_observer(layer): # creates observer and replaces linear layers with AWQObservedLinear layers observer = AWQObserver( layer.weight, - layer.bias, - quantization_granularity, + layer.bias, + quantization_granularity, mapping_type, - quant_dtype, + quant_dtype, n_validation_examples, validation_sequence_len, scale_search_space_size, - preserve_zero = preserve_zero, - zero_point_domain = zero_point_domain, - zero_point_dtype = zero_point_dtype, + preserve_zero=preserve_zero, + zero_point_domain=zero_point_domain, + zero_point_dtype=zero_point_dtype, quant_min=quant_min, - quant_max = quant_max, - eps = eps) + quant_max=quant_max, + eps=eps, + ) return AWQObservedLinear.from_float(layer, observer) + _replace_with_custom_fn_if_matches_filter(model, replace_with_observer, _is_linear) + def _observed_linear_subclass_inserter(constructor): """ Replaces unquantized AWQObservedLinear instances with quantized linear instances. @@ -74,19 +89,30 @@ def _observed_linear_subclass_inserter(constructor): Args: constructor: the function which applies quantization to the AWQObservedLinear layer """ + def insert_subclass(observed_linear): # creates the new linear layer using constructor - linear = torch.nn.Linear(observed_linear.in_features, observed_linear.out_features, observed_linear.bias!=None, device=observed_linear.weight.device, dtype=observed_linear.weight.dtype) - linear.weight = torch.nn.Parameter(constructor(observed_linear), requires_grad=False) + linear = torch.nn.Linear( + observed_linear.in_features, + observed_linear.out_features, + observed_linear.bias != None, + device=observed_linear.weight.device, + dtype=observed_linear.weight.dtype, + ) + linear.weight = torch.nn.Parameter( + constructor(observed_linear), requires_grad=False + ) linear.bias = observed_linear.bias return linear return insert_subclass - -def awq_uintx(quant_dtype: torch.dtype = torch.uint4, - group_size: int = 64, - use_hqq: bool = False,): + +def awq_uintx( + quant_dtype: torch.dtype = torch.uint4, + group_size: int = 64, + use_hqq: bool = False, +): """ Quantizes linear layers when passed into quantize_() @@ -95,8 +121,10 @@ def awq_uintx(quant_dtype: torch.dtype = torch.uint4, group_size: Quantization granularity. Use -1 for channel wise quantization weight_quant_fn: The quantization function to be used, which takes in the weight and returns the quantized weight. If None, then affine uint4 quantization is used """ - assert quant_dtype in _DTYPE_TO_BIT_WIDTH or quant_dtype == torch.uint8, "Invalid quant_dtype. Please use torch.uint1 .. torch.uint8" - + assert ( + quant_dtype in _DTYPE_TO_BIT_WIDTH or quant_dtype == torch.uint8 + ), "Invalid quant_dtype. Please use torch.uint1 .. torch.uint8" + def weight_quant_func(observed_linear): equalization_scale = observed_linear.act_obs.calculate_qparams() # AQT config @@ -114,7 +142,7 @@ def weight_quant_func(observed_linear): zero_point_dtype = torch.int64 zero_point_domain = ZeroPointDomain.INT _layout = UintxLayout(quant_dtype) - + mapping_type = MappingType.ASYMMETRIC block_size = (1, group_size) quant_min = _DTYPE_TO_QVALUE_BOUNDS[quant_dtype][0] @@ -122,16 +150,20 @@ def weight_quant_func(observed_linear): qw = to_affine_quantized_intx( observed_linear.weight * equalization_scale, mapping_type, - block_size, - target_dtype, quant_min, - quant_max, eps, + block_size, + target_dtype, + quant_min, + quant_max, + eps, zero_point_dtype=zero_point_dtype, preserve_zero=preserve_zero, zero_point_domain=zero_point_domain, _layout=_layout, - use_hqq=use_hqq + use_hqq=use_hqq, ) - - return to_weight_tensor_with_linear_activation_scale_metadata(qw, equalization_scale) - + + return to_weight_tensor_with_linear_activation_scale_metadata( + qw, equalization_scale + ) + return _observed_linear_subclass_inserter(weight_quant_func) diff --git a/torchao/prototype/awq/core.py b/torchao/prototype/awq/core.py index 89f615e9e..6882f3ade 100644 --- a/torchao/prototype/awq/core.py +++ b/torchao/prototype/awq/core.py @@ -1,24 +1,23 @@ -from dataclasses import dataclass -from typing import Tuple, Optional +from typing import Optional import torch import torch.nn.functional as F -from torch.utils._python_dispatch import return_and_correct_aliasing -from torchao.dtypes.uintx.uintx_layout import _DTYPE_TO_BIT_WIDTH, UintxLayout from torchao.dtypes import to_affine_quantized_intx +from torchao.dtypes.uintx.uintx_layout import UintxLayout from torchao.quantization.granularity import Granularity +from torchao.quantization.observer import ( + AffineQuantizedObserverBase, +) from torchao.quantization.quant_primitives import ( MappingType, ZeroPointDomain, ) -from torchao.quantization.observer import ( - AffineQuantizedObserverBase, -) class AWQObserver(AffineQuantizedObserverBase): - def __init__(self, + def __init__( + self, weight: torch.Tensor, bias: torch.Tensor, quantization_granularity: Granularity, @@ -33,7 +32,7 @@ def __init__(self, scale_dtype: Optional[torch.dtype] = None, zero_point_dtype: Optional[torch.dtype] = None, preserve_zero: Optional[bool] = True, - zero_point_domain = ZeroPointDomain.INT, + zero_point_domain=ZeroPointDomain.INT, ): """ A custom observer for Activation aware Weight Quantization (AWQ) @@ -43,7 +42,7 @@ def __init__(self, bias: The bias tensor to be observed. quantization_granularity: Granularity which specifies how many weights share the same scale/zero point input_dtype: The data type of the input tensor. - mapping_type: Always set to asymmetric + mapping_type: Always set to asymmetric target_dtype: The target data type of the quantized tensor n_validation_examples: Number of examples used to calibrate observer validation_sequence_len: Number of tokens in each example @@ -60,14 +59,14 @@ def __init__(self, super().__init__( mapping_type, target_dtype, - quantization_granularity, - quant_min = quant_min, - quant_max = quant_max, - eps = eps, - scale_dtype = scale_dtype, - zero_point_dtype = zero_point_dtype, - preserve_zero = preserve_zero, - zero_point_domain = zero_point_domain, + quantization_granularity, + quant_min=quant_min, + quant_max=quant_max, + eps=eps, + scale_dtype=scale_dtype, + zero_point_dtype=zero_point_dtype, + preserve_zero=preserve_zero, + zero_point_domain=zero_point_domain, ) self.quantization_granularity = quantization_granularity self.weight = weight @@ -79,9 +78,10 @@ def __init__(self, self.outputs = [] self.scale_options = scale_search_space_size self.device = self.weight.device - self.average = torch.zeros((1,weight.shape[1]), device= self.device) + self.average = torch.zeros((1, weight.shape[1]), device=self.device) if self.bias is not None: self.bias.to(self.device) + @torch.no_grad() def forward(self, input: torch.Tensor, output: torch.Tensor): # import pdb @@ -92,19 +92,19 @@ def forward(self, input: torch.Tensor, output: torch.Tensor): self.outputs.append(output.to("cpu")) self.calibration_token_count += input.shape[-2] self.average += input.abs().sum(-2) - - def calculate_qparams(self): # import pdb # pdb.set_trace() - assert self.outputs != None, "calibrate observer first by running model on exemplar data" - self.average /= (self.calibration_token_count) + assert ( + self.outputs != None + ), "calibrate observer first by running model on exemplar data" + self.average /= self.calibration_token_count for i in range(self.n_validation_examples): self.inputs[i] = self.inputs[i].to(self.device) self.outputs[i] = self.outputs[i].to(self.device) - best_loss = float('inf') + best_loss = float("inf") best_scales = None for i in range(self.scale_options): ratio = i * 1 / self.scale_options @@ -114,22 +114,22 @@ def calculate_qparams(self): # regardless of weight dtype, we have to store as packed uint8 tensors tensor_dtype = torch.uint8 w = to_affine_quantized_intx( - self.weight*scales, + self.weight * scales, self.mapping_type, (1, self.quantization_granularity.group_size), tensor_dtype, - quant_min = self.quant_min, - quant_max = self.quant_max, - eps = self.eps, - scale_dtype = self.scale_dtype, - zero_point_dtype = self.zero_point_dtype, - preserve_zero = self.preserve_zero, - zero_point_domain = self.zero_point_domain, - _layout = layout + quant_min=self.quant_min, + quant_max=self.quant_max, + eps=self.eps, + scale_dtype=self.scale_dtype, + zero_point_dtype=self.zero_point_dtype, + preserve_zero=self.preserve_zero, + zero_point_domain=self.zero_point_domain, + _layout=layout, ) loss = 0 for i in range(self.n_validation_examples): - q_out = F.linear(self.inputs[i]/scales, w, self.bias) + q_out = F.linear(self.inputs[i] / scales, w, self.bias) loss += (self.outputs[i] - q_out).pow(2).mean().item() if loss < best_loss: best_scales = scales @@ -139,8 +139,17 @@ def calculate_qparams(self): self.outputs[i].to("cpu") return best_scales.detach() + class AWQObservedLinear(torch.nn.Linear): - def __init__(self, in_features: int, out_features: int, act_obs: torch.nn.Module, bias: bool = True, device=None, dtype=None): + def __init__( + self, + in_features: int, + out_features: int, + act_obs: torch.nn.Module, + bias: bool = True, + device=None, + dtype=None, + ): super().__init__(in_features, out_features, bias, device, dtype) self.act_obs = act_obs @@ -151,7 +160,14 @@ def forward(self, input: torch.Tensor): @classmethod def from_float(cls, float_linear: torch.nn.Linear, act_obs: AWQObserver): - observed_linear = cls(float_linear.in_features, float_linear.out_features, act_obs, False, device=float_linear.weight.device, dtype=float_linear.weight.dtype) + observed_linear = cls( + float_linear.in_features, + float_linear.out_features, + act_obs, + False, + device=float_linear.weight.device, + dtype=float_linear.weight.dtype, + ) observed_linear.weight = float_linear.weight observed_linear.bias = float_linear.bias return observed_linear diff --git a/torchao/prototype/awq/example.py b/torchao/prototype/awq/example.py index 8d8cc0ce7..a2cc6082d 100644 --- a/torchao/prototype/awq/example.py +++ b/torchao/prototype/awq/example.py @@ -1,11 +1,13 @@ -import torch import argparse -from transformers import AutoModelForCausalLM, AutoTokenizer +import time + +import torch from datasets import load_dataset from tqdm import tqdm -import time -from torchao.prototype.awq import insert_awq_observer_, AWQObservedLinear, awq_uintx -from torchao.quantization import quantize_, int4_weight_only, uintx_weight_only +from transformers import AutoModelForCausalLM, AutoTokenizer + +from torchao.prototype.awq import AWQObservedLinear, awq_uintx, insert_awq_observer_ +from torchao.quantization import int4_weight_only, quantize_ # adapted from: https://github.com/mit-han-lab/llm-awq/blob/main/awq/entry.py#L255 @@ -29,28 +31,35 @@ def get_calib_dataset(tokenizer=None, n_samples=100, block_size=512): break cat_samples = torch.cat(samples, dim=1) - return [cat_samples[:, i * block_size : (i + 1) * block_size] for i in range(n_samples)] + return [ + cat_samples[:, i * block_size : (i + 1) * block_size] for i in range(n_samples) + ] + # from https://github.com/mobiusml/hqq/blob/master/examples/llama2_benchmark/eval_model.py -def wiki2_eval(model, tokenizer, sequence_length, stride=512, verbose=True, device="cuda"): +def wiki2_eval( + model, tokenizer, sequence_length, stride=512, verbose=True, device="cuda" +): model.eval() - tokenizer.pad_token = tokenizer.eos_token - tokenizer.padding_side = "right" + tokenizer.pad_token = tokenizer.eos_token + tokenizer.padding_side = "right" tokenizer.add_eos_token = False - dataset = load_dataset('wikitext', 'wikitext-2-raw-v1', split='test') - encodings = tokenizer('\n\n'.join(dataset['text']), return_tensors='pt') + dataset = load_dataset("wikitext", "wikitext-2-raw-v1", split="test") + encodings = tokenizer("\n\n".join(dataset["text"]), return_tensors="pt") - encodings['input_ids'] = encodings['input_ids'].to(device) + encodings["input_ids"] = encodings["input_ids"].to(device) lls, t = [], [] - for i in tqdm(range(0, encodings['input_ids'].size(1), stride), disable=not verbose): - begin_loc = max(i + stride - sequence_length, 0) - end_loc = min(i + stride, encodings['input_ids'].size(1)) - trg_len = end_loc - i - input_ids = encodings['input_ids'][:,begin_loc:end_loc] + for i in tqdm( + range(0, encodings["input_ids"].size(1), stride), disable=not verbose + ): + begin_loc = max(i + stride - sequence_length, 0) + end_loc = min(i + stride, encodings["input_ids"].size(1)) + trg_len = end_loc - i + input_ids = encodings["input_ids"][:, begin_loc:end_loc] target_ids = input_ids.clone() - target_ids[:,:-trg_len] = -100 #ignore context + target_ids[:, :-trg_len] = -100 # ignore context t1 = time.time() with torch.no_grad(): @@ -58,109 +67,136 @@ def wiki2_eval(model, tokenizer, sequence_length, stride=512, verbose=True, devi if device.startswith("cuda"): torch.cuda.synchronize() t2 = time.time() - t.append((t2-t1)) + t.append((t2 - t1)) lls.append(log_likelihood) del input_ids, target_ids - ppl = float(torch.exp(torch.stack(lls).sum() / end_loc)) - pred_time = sum(t)/len(t) - if(verbose): - print('perplexity', ppl) - print('time', str(pred_time) + ' sec') + ppl = float(torch.exp(torch.stack(lls).sum() / end_loc)) + pred_time = sum(t) / len(t) + if verbose: + print("perplexity", ppl) + print("time", str(pred_time) + " sec") + + return {"perplexity": ppl, "prediction_time": pred_time} + - return {'perplexity':ppl, 'prediction_time':pred_time} - # adapted from Hicham Badri (@mobicham) def benchmark(model, tokenizer, max_length, tasks=None, device="cuda"): - import numpy as np - import copy import lm_eval - model.eval(); + import numpy as np + + model.eval() model.config.use_cache = False try: - lm_eval.tasks.initialize_tasks() + lm_eval.tasks.initialize_tasks() except: pass model_eval = lm_eval.models.huggingface.HFLM(pretrained=model, tokenizer=tokenizer) - eval_batch_size = 1 #8 + eval_batch_size = 1 # 8 if tasks is None: - tasks = ["PPL","truthfulqa_mc2", "winogrande", "arc_challenge", "hellaswag", "gsm8k", "mmlu"] + tasks = [ + "PPL", + "truthfulqa_mc2", + "winogrande", + "arc_challenge", + "hellaswag", + "gsm8k", + "mmlu", + ] results = {} if "PPL" in tasks: - results["perplexity"] = wiki2_eval(model, tokenizer, 512, verbose=True, device=device) + results["perplexity"] = wiki2_eval( + model, tokenizer, 512, verbose=True, device=device + ) ############################################ if "truthfulqa_mc2" in tasks: - for task in [("truthfulqa_mc2", 0)]: + for task in [("truthfulqa_mc2", 0)]: tag, fewshot = task - results[tag] = lm_eval.evaluator.simple_evaluate(model_eval, tasks=[tag], num_fewshot=fewshot, batch_size=eval_batch_size)['results'] + results[tag] = lm_eval.evaluator.simple_evaluate( + model_eval, tasks=[tag], num_fewshot=fewshot, batch_size=eval_batch_size + )["results"] print(tag, results[tag]) if "winogrande" in tasks: for task in [("winogrande", 5)]: tag, fewshot = task - results[tag] = lm_eval.evaluator.simple_evaluate(model_eval, tasks=[tag], num_fewshot=fewshot, batch_size=eval_batch_size)['results'] + results[tag] = lm_eval.evaluator.simple_evaluate( + model_eval, tasks=[tag], num_fewshot=fewshot, batch_size=eval_batch_size + )["results"] print(tag, results[tag]) if "arc_challenge" in tasks: - for task in [("arc_challenge", 25)]: + for task in [("arc_challenge", 25)]: tag, fewshot = task - results[tag] = lm_eval.evaluator.simple_evaluate(model_eval, tasks=[tag], num_fewshot=fewshot, batch_size=eval_batch_size)['results'] + results[tag] = lm_eval.evaluator.simple_evaluate( + model_eval, tasks=[tag], num_fewshot=fewshot, batch_size=eval_batch_size + )["results"] print(tag, results[tag]) - + # ############################################ if "hellaswag" in tasks: - for task in [("hellaswag", 10)]: + for task in [("hellaswag", 10)]: tag, fewshot = task - results[tag] = lm_eval.evaluator.simple_evaluate(model_eval, tasks=[tag], num_fewshot=fewshot, batch_size=eval_batch_size)['results'] + results[tag] = lm_eval.evaluator.simple_evaluate( + model_eval, tasks=[tag], num_fewshot=fewshot, batch_size=eval_batch_size + )["results"] print(tag, results[tag]) if "gsm8k" in tasks: for task in [("gsm8k", 5)]: tag, fewshot = task - results[tag] = lm_eval.evaluator.simple_evaluate(model_eval, tasks=[tag], num_fewshot=fewshot, batch_size=eval_batch_size)['results'] + results[tag] = lm_eval.evaluator.simple_evaluate( + model_eval, tasks=[tag], num_fewshot=fewshot, batch_size=eval_batch_size + )["results"] print(tag, results[tag]) # ############################################ - - results_1 = copy.deepcopy(results) + if "mmlu" in tasks: - #MMLU + # MMLU results_mmlu = {} - for task in [("mmlu", 5)]: + for task in [("mmlu", 5)]: tag, fewshot = task - results_mmlu[tag] = lm_eval.evaluator.simple_evaluate(model_eval, tasks=[tag], num_fewshot=fewshot, batch_size=eval_batch_size)['results'] + results_mmlu[tag] = lm_eval.evaluator.simple_evaluate( + model_eval, tasks=[tag], num_fewshot=fewshot, batch_size=eval_batch_size + )["results"] print(tag, results_mmlu[tag]) - - mmlu_list = "hendrycksTest-abstract_algebra,hendrycksTest-anatomy,hendrycksTest-astronomy,hendrycksTest-business_ethics,hendrycksTest-clinical_knowledge,hendrycksTest-college_biology,hendrycksTest-college_chemistry,hendrycksTest-college_computer_science,hendrycksTest-college_mathematics,hendrycksTest-college_medicine,hendrycksTest-college_physics,hendrycksTest-computer_security,hendrycksTest-conceptual_physics,hendrycksTest-econometrics,hendrycksTest-electrical_engineering,hendrycksTest-elementary_mathematics,hendrycksTest-formal_logic,hendrycksTest-global_facts,hendrycksTest-high_school_biology,hendrycksTest-high_school_chemistry,hendrycksTest-high_school_computer_science,hendrycksTest-high_school_european_history,hendrycksTest-high_school_geography,hendrycksTest-high_school_government_and_politics,hendrycksTest-high_school_macroeconomics,hendrycksTest-high_school_mathematics,hendrycksTest-high_school_microeconomics,hendrycksTest-high_school_physics,hendrycksTest-high_school_psychology,hendrycksTest-high_school_statistics,hendrycksTest-high_school_us_history,hendrycksTest-high_school_world_history,hendrycksTest-human_aging,hendrycksTest-human_sexuality,hendrycksTest-international_law,hendrycksTest-jurisprudence,hendrycksTest-logical_fallacies,hendrycksTest-machine_learning,hendrycksTest-management,hendrycksTest-marketing,hendrycksTest-medical_genetics,hendrycksTest-miscellaneous,hendrycksTest-moral_disputes,hendrycksTest-moral_scenarios,hendrycksTest-nutrition,hendrycksTest-philosophy,hendrycksTest-prehistory,hendrycksTest-professional_accounting,hendrycksTest-professional_law,hendrycksTest-professional_medicine,hendrycksTest-professional_psychology,hendrycksTest-public_relations,hendrycksTest-security_studies,hendrycksTest-sociology,hendrycksTest-us_foreign_policy,hendrycksTest-virology,hendrycksTest-world_religions" - mmlu_list = [l.replace('hendrycksTest-','') for l in mmlu_list.split(',')] - results_mmlu = results_mmlu['mmlu'] - + + mmlu_list = "hendrycksTest-abstract_algebra,hendrycksTest-anatomy,hendrycksTest-astronomy,hendrycksTest-business_ethics,hendrycksTest-clinical_knowledge,hendrycksTest-college_biology,hendrycksTest-college_chemistry,hendrycksTest-college_computer_science,hendrycksTest-college_mathematics,hendrycksTest-college_medicine,hendrycksTest-college_physics,hendrycksTest-computer_security,hendrycksTest-conceptual_physics,hendrycksTest-econometrics,hendrycksTest-electrical_engineering,hendrycksTest-elementary_mathematics,hendrycksTest-formal_logic,hendrycksTest-global_facts,hendrycksTest-high_school_biology,hendrycksTest-high_school_chemistry,hendrycksTest-high_school_computer_science,hendrycksTest-high_school_european_history,hendrycksTest-high_school_geography,hendrycksTest-high_school_government_and_politics,hendrycksTest-high_school_macroeconomics,hendrycksTest-high_school_mathematics,hendrycksTest-high_school_microeconomics,hendrycksTest-high_school_physics,hendrycksTest-high_school_psychology,hendrycksTest-high_school_statistics,hendrycksTest-high_school_us_history,hendrycksTest-high_school_world_history,hendrycksTest-human_aging,hendrycksTest-human_sexuality,hendrycksTest-international_law,hendrycksTest-jurisprudence,hendrycksTest-logical_fallacies,hendrycksTest-machine_learning,hendrycksTest-management,hendrycksTest-marketing,hendrycksTest-medical_genetics,hendrycksTest-miscellaneous,hendrycksTest-moral_disputes,hendrycksTest-moral_scenarios,hendrycksTest-nutrition,hendrycksTest-philosophy,hendrycksTest-prehistory,hendrycksTest-professional_accounting,hendrycksTest-professional_law,hendrycksTest-professional_medicine,hendrycksTest-professional_psychology,hendrycksTest-public_relations,hendrycksTest-security_studies,hendrycksTest-sociology,hendrycksTest-us_foreign_policy,hendrycksTest-virology,hendrycksTest-world_religions" + mmlu_list = [l.replace("hendrycksTest-", "") for l in mmlu_list.split(",")] + results_mmlu = results_mmlu["mmlu"] + k = [] for r in results_mmlu: if np.any([(l in r) for l in mmlu_list]): - k.append(results_mmlu[r]['acc,none']) - - assert len(k)==57 - print('MMLU avg acc', np.mean(k)) - - results['mmlu'] = np.mean(k) + k.append(results_mmlu[r]["acc,none"]) + + assert len(k) == 57 + print("MMLU avg acc", np.mean(k)) + + results["mmlu"] = np.mean(k) return results def wikitext2_ppl( - repo_id: str, - quant: str, - tasks: list[str], - calibration_size: int, - validation_size:int, - device: str, - precision:torch.dtype, - sequence_length: int, - compile: bool, - model_save_path: str): + repo_id: str, + quant: str, + tasks: list[str], + calibration_size: int, + validation_size: int, + device: str, + precision: torch.dtype, + sequence_length: int, + compile: bool, + model_save_path: str, +): print(f"Loading model on {device}...") torch.manual_seed(34) t0 = time.time() # load any model with torch.nn.linear layers tokenizer = AutoTokenizer.from_pretrained(repo_id) - model = AutoModelForCausalLM.from_pretrained(repo_id, torch_dtype=precision).eval().to(device) + model = ( + AutoModelForCausalLM.from_pretrained(repo_id, torch_dtype=precision) + .eval() + .to(device) + ) print(f"Time to load model: {time.time() - t0:.02f} seconds") if quant.startswith("awq"): quant_dtype = quant.split("-")[1] @@ -169,18 +205,30 @@ def wikitext2_ppl( print(f"running {quant_dtype} calibration") t0 = time.time() # insert observers to find average magnitude and calculate scales - insert_awq_observer_(model,validation_size, sequence_length, quant_dtype=quant_dtype, group_size=group_size) - calibration_data = get_calib_dataset(tokenizer=tokenizer, n_samples=calibration_size, block_size=sequence_length) + insert_awq_observer_( + model, + validation_size, + sequence_length, + quant_dtype=quant_dtype, + group_size=group_size, + ) + calibration_data = get_calib_dataset( + tokenizer=tokenizer, n_samples=calibration_size, block_size=sequence_length + ) for batch in calibration_data: model(batch.to(device)) batch.to("cpu") print(f"time for calibration: {time.time() - t0:.02f} seconds") - + is_observed_linear = lambda m, fqn: isinstance(m, AWQObservedLinear) use_hqq = "hqq" in quant print(f"running {quant_dtype} quantization") t0 = time.time() - quantize_(model, awq_uintx(quant_dtype=quant_dtype, group_size = group_size, use_hqq=use_hqq), is_observed_linear) + quantize_( + model, + awq_uintx(quant_dtype=quant_dtype, group_size=group_size, use_hqq=use_hqq), + is_observed_linear, + ) print(f"time for quantization: {time.time() - t0:.02f} seconds") if model_save_path is not None: print(f"Saving model to {model_save_path}") @@ -189,27 +237,69 @@ def wikitext2_ppl( group_size = int(quant.split("-")[1]) use_hqq = "hqq" in quant print(f"running {quant} quantization with group size {group_size}") - quantize_(model, int4_weight_only(group_size=group_size, use_hqq= use_hqq)) + quantize_(model, int4_weight_only(group_size=group_size, use_hqq=use_hqq)) if compile: model = torch.compile(model) - + return benchmark(model, tokenizer, sequence_length, tasks=tasks, device=device) + if __name__ == "__main__": - parser = argparse.ArgumentParser(description="Evaluate a model with the specified parameters.") - + parser = argparse.ArgumentParser( + description="Evaluate a model with the specified parameters." + ) # Optional arguments with default values parser.add_argument("repo", type=str, help="Repository ID of the model.") - parser.add_argument("quant", type=str, help="Quantization method. Options are either awq-uint- for x =[1..8], int4wo-, or int4wo--hqq.") - parser.add_argument("--tasks", type=list[str], help="Task to benchmark model on. Either PPL or QA", default=["PPL"]) - parser.add_argument("--calibration_samples", type=int, default=10, help="Number of samples to use for calibration. Default is 10.") - parser.add_argument("--validation_size", type=int, default=1, help="Validation size. Default is 1.") - parser.add_argument("--device", type=str, default="cuda", help="Device to run the evaluation on. Default is 'cuda'.") - parser.add_argument("--precision", type=str, default="bfloat16", help="Precision type. Default is 'bfloat16'.") - parser.add_argument("--seq_len", type=int, default=512, help="Length of examples to calibrate and evaluate model on. Default is 512") - parser.add_argument("--compile", action="store_true", help="Flag to indicate if compilation is required.") - parser.add_argument("--model_save_path", type=str, default=None, help="Path to store the scale values.") + parser.add_argument( + "quant", + type=str, + help="Quantization method. Options are either awq-uint- for x =[1..8], int4wo-, or int4wo--hqq.", + ) + parser.add_argument( + "--tasks", + type=list[str], + help="Task to benchmark model on. Either PPL or QA", + default=["PPL"], + ) + parser.add_argument( + "--calibration_samples", + type=int, + default=10, + help="Number of samples to use for calibration. Default is 10.", + ) + parser.add_argument( + "--validation_size", type=int, default=1, help="Validation size. Default is 1." + ) + parser.add_argument( + "--device", + type=str, + default="cuda", + help="Device to run the evaluation on. Default is 'cuda'.", + ) + parser.add_argument( + "--precision", + type=str, + default="bfloat16", + help="Precision type. Default is 'bfloat16'.", + ) + parser.add_argument( + "--seq_len", + type=int, + default=512, + help="Length of examples to calibrate and evaluate model on. Default is 512", + ) + parser.add_argument( + "--compile", + action="store_true", + help="Flag to indicate if compilation is required.", + ) + parser.add_argument( + "--model_save_path", + type=str, + default=None, + help="Path to store the scale values.", + ) args = parser.parse_args() @@ -225,7 +315,7 @@ def wikitext2_ppl( args.precision, args.seq_len, args.compile, - args.model_save_path + args.model_save_path, ) - print(f"{args.quant} Results: {ppl}") \ No newline at end of file + print(f"{args.quant} Results: {ppl}") diff --git a/torchao/prototype/common/triton/matmul.py b/torchao/prototype/common/triton/matmul.py index acd605336..5b86bce96 100644 --- a/torchao/prototype/common/triton/matmul.py +++ b/torchao/prototype/common/triton/matmul.py @@ -1,7 +1,7 @@ import torch - from triton import Config, autotune, cdiv, heuristics, jit from triton import language as tl + from .matmul_perf_model import early_config_prune, estimate_matmul_time _ordered_datatypes = [torch.int8, torch.float16, torch.bfloat16, torch.float32] diff --git a/torchao/prototype/common/triton/matmul_perf_model.py b/torchao/prototype/common/triton/matmul_perf_model.py index fd47ffc64..7bbb5e63a 100644 --- a/torchao/prototype/common/triton/matmul_perf_model.py +++ b/torchao/prototype/common/triton/matmul_perf_model.py @@ -1,4 +1,3 @@ - # Source: https://github.com/triton-lang/kernels/blob/main/kernels/matmul_perf_model.py # This file is taken from the upstream triton-lang/kernels repo. @@ -40,10 +39,13 @@ def get_tensorcore_tflops(device, num_ctas, num_warps, dtype): total_warps = num_ctas * min(num_warps, 4) if hasattr(driver, "active"): num_subcores = ( - driver.active.utils.get_device_properties(device)["multiprocessor_count"] * 4 + driver.active.utils.get_device_properties(device)["multiprocessor_count"] + * 4 ) # on recent GPUs else: - num_subcores = driver.utils.get_device_properties(device)["multiprocessor_count"] * 4 # on recent GPUs + num_subcores = ( + driver.utils.get_device_properties(device)["multiprocessor_count"] * 4 + ) # on recent GPUs tflops = ( min(num_subcores, total_warps) @@ -58,10 +60,13 @@ def get_simd_tflops(device, num_ctas, num_warps, dtype): total_warps = num_ctas * min(num_warps, 4) if hasattr(driver, "active"): num_subcores = ( - driver.active.utils.get_device_properties(device)["multiprocessor_count"] * 4 + driver.active.utils.get_device_properties(device)["multiprocessor_count"] + * 4 ) # on recent GPUs else: - num_subcores = driver.utils.get_device_properties(device)["multiprocessor_count"] * 4 # on recent GPUs + num_subcores = ( + driver.utils.get_device_properties(device)["multiprocessor_count"] * 4 + ) # on recent GPUs tflops = ( min(num_subcores, total_warps) @@ -116,11 +121,12 @@ def estimate_matmul_time( # time to load data if hasattr(driver, "active"): - num_sm = driver.active.utils.get_device_properties(device)["multiprocessor_count"] + num_sm = driver.active.utils.get_device_properties(device)[ + "multiprocessor_count" + ] else: num_sm = driver.utils.get_device_properties(device)["multiprocessor_count"] - active_cta_ratio = min(1, num_ctas / num_sm) active_cta_ratio_bw1 = min( 1, num_ctas / 32 @@ -191,7 +197,6 @@ def early_config_prune(configs, named_args, **kwargs): "max_shared_mem" ] - required_shared_memory = (BLOCK_M + BLOCK_N) * BLOCK_K * num_stages * dtsize if required_shared_memory <= max_shared_memory: pruned_configs.append(config) diff --git a/torchao/prototype/custom_fp_utils.py b/torchao/prototype/custom_fp_utils.py index 41a9e399e..3d8de6f0d 100644 --- a/torchao/prototype/custom_fp_utils.py +++ b/torchao/prototype/custom_fp_utils.py @@ -55,7 +55,7 @@ def _f32_to_floatx_unpacked(x: Tensor, ebits: int, mbits: int) -> Tensor: magic_adder = _n_ones(MBITS_F32 - mbits - 1) # all E bits and M bits are 1s - max_normal = 2 ** (_n_ones(ebits) - exp_bias) * (_n_ones(mbits + 1) / (2 ** mbits)) + max_normal = 2 ** (_n_ones(ebits) - exp_bias) * (_n_ones(mbits + 1) / (2**mbits)) # E bits = 1, M bits = 0 min_normal = 2 ** (1 - exp_bias) @@ -71,7 +71,9 @@ def _f32_to_floatx_unpacked(x: Tensor, ebits: int, mbits: int) -> Tensor: denorm_mask_int = denorm_exp << MBITS_F32 # reinterpret int32 as float32 - denorm_mask_float = torch.tensor(denorm_mask_int, dtype=torch.int32).view(torch.float32) + denorm_mask_float = torch.tensor(denorm_mask_int, dtype=torch.int32).view( + torch.float32 + ) # save the sign # Note that we have torch.uint32, but some ops like cpu bit shifts @@ -208,17 +210,21 @@ def _floatx_unpacked_to_f32(x: Tensor, ebits: int, mbits: int) -> Tensor: # i=2, j=100,101,110,111 # and so on for i in range(mbits): - for mantissa_cmp in range(1 << i, 1 << (i+1)): + for mantissa_cmp in range(1 << i, 1 << (i + 1)): # left shift mantissa until it overflows (create an implicit 1) # subtract exponent by the same amount left_shift = mbits - i - mantissa_f32 = (mantissa_cmp - (1 << i)) << (left_shift + MBITS_F32 - mbits) + mantissa_f32 = (mantissa_cmp - (1 << i)) << ( + left_shift + MBITS_F32 - mbits + ) exp_biased_f32 = (denormal_exp_biased - left_shift) << MBITS_F32 # we can update this in-place since the values won't overlap # torch.compile() may complain unsupported operand type(s) for |: 'SymInt' and 'int' # thus we use + instead of | here - mantissa_lp_int32[mantissa_lp_int32 == mantissa_cmp] = exp_biased_f32 + mantissa_f32 + mantissa_lp_int32[mantissa_lp_int32 == mantissa_cmp] = ( + exp_biased_f32 + mantissa_f32 + ) result = torch.where(denormal_mask, mantissa_lp_int32, result) diff --git a/torchao/prototype/dora/dora_layer.py b/torchao/prototype/dora/dora_layer.py index e0c97cdcb..c36b1b064 100644 --- a/torchao/prototype/dora/dora_layer.py +++ b/torchao/prototype/dora/dora_layer.py @@ -3,9 +3,6 @@ import bitsandbytes as bnb import torch import torch.nn as nn -from bitsandbytes.nn import Linear4bit -from hqq.core.quantize import BaseQuantizeConfig, HQQBackend, HQQLinear - from prototypes.dora.kernels.matmul import triton_mm from prototypes.dora.kernels.smallk import triton_mm_small_k @@ -190,5 +187,3 @@ def dequantize(self): class HQQDoRALinear(DoRALinear): def dequantize(self): return self.base_layer.dequantize() - - diff --git a/torchao/prototype/dora/kernels/common.py b/torchao/prototype/dora/kernels/common.py index e1b85d238..08cb0b07f 100644 --- a/torchao/prototype/dora/kernels/common.py +++ b/torchao/prototype/dora/kernels/common.py @@ -3,15 +3,9 @@ import torch import triton import triton.language as tl +from triton.runtime import Config # Re-exports -from torchao.prototype.common.triton.matmul import ( - early_config_prune, - estimate_matmul_time, - get_configs_io_bound, - get_higher_dtype, -) -from triton.runtime import Config @unique diff --git a/torchao/prototype/dora/kernels/custom_autotune.py b/torchao/prototype/dora/kernels/custom_autotune.py index f67152068..af074cda6 100644 --- a/torchao/prototype/dora/kernels/custom_autotune.py +++ b/torchao/prototype/dora/kernels/custom_autotune.py @@ -186,10 +186,10 @@ def run(self, *args, **kwargs): f.write( f" ==== Autotune Results ====\nKernel name: {self.kernel_name}\nArgs: {self.arg_names}\nKeys: {self._get_key_combination(args)}\n" ) - f.write(f"\nPruned configs:\n") + f.write("\nPruned configs:\n") for cfg in pruned_configs: f.write(f"{cfg}\n") - f.write(f"Timings:\n") + f.write("Timings:\n") for cfg, timing in sorted_timings.items(): f.write(f"{cfg} {timing} \n") f.write(f"Best config: {self.cache[key]}\n") diff --git a/torchao/prototype/dora/kernels/smallk.py b/torchao/prototype/dora/kernels/smallk.py index b1d04878a..6f9658e79 100644 --- a/torchao/prototype/dora/kernels/smallk.py +++ b/torchao/prototype/dora/kernels/smallk.py @@ -5,12 +5,13 @@ import torch import triton import triton.language as tl -from torchao.prototype.common.triton.matmul import ( +from triton.runtime import driver + +from torchao.prototype.common.triton.matmul import ( estimate_matmul_time, get_configs_io_bound, get_higher_dtype, ) -from triton.runtime import driver from .custom_autotune import Config, autotune @@ -180,7 +181,6 @@ def small_k_early_config_prune(configs, named_args, **kwargs): capability = torch.cuda.get_device_capability() # BLOCK_M, BLOCK_N, BLOCK_K, SPLIT_K, num_warps, num_stages dtsize = named_args["A"].element_size() - dtype = named_args["A"].dtype # 1. make sure we have enough smem pruned_configs = [] diff --git a/torchao/prototype/dtypes/__init__.py b/torchao/prototype/dtypes/__init__.py index 9f16283ac..9393737af 100644 --- a/torchao/prototype/dtypes/__init__.py +++ b/torchao/prototype/dtypes/__init__.py @@ -1,9 +1,7 @@ - -from .uint2 import UInt2Tensor from .bitnet import BitnetTensor +from .uint2 import UInt2Tensor __all__ = [ "BitnetTensor", "UInt2Tensor", ] - diff --git a/torchao/prototype/dtypes/bitnet.py b/torchao/prototype/dtypes/bitnet.py index 61fb15992..72b444acd 100644 --- a/torchao/prototype/dtypes/bitnet.py +++ b/torchao/prototype/dtypes/bitnet.py @@ -1,25 +1,30 @@ import torch -from torchao.prototype.dtypes.uint2 import UInt2Tensor, unpack_uint2, pack_uint2 + +from torchao.prototype.dtypes.uint2 import UInt2Tensor, pack_uint2, unpack_uint2 BITNET_OPS_TABLE = {} + def implements(aten_ops): def decorator(fn): for op in aten_ops: BITNET_OPS_TABLE[op] = fn return fn + return decorator + def _quantize_int2(x: torch.Tensor) -> torch.Tensor: # Quantize the input tensor to int2 quant = x.sign() + 1 quant = BitnetTensor.from_unpacked(quant.to(torch.uint8)) return quant + class BitnetTensor(UInt2Tensor): def __new__(cls, input_tensor: torch.Tensor, **kwargs): return super(BitnetTensor, cls).__new__(cls, input_tensor, **kwargs) - + def __init__(self, input_tensor: torch.Tensor, **kwargs): super(BitnetTensor, self).__init__(input_tensor, **kwargs) @@ -32,32 +37,36 @@ def __tensor_unflatten__(flattened, *meta): @classmethod def from_unpacked(cls, unpacked: torch.Tensor) -> "BitnetTensor": return cls(pack_uint2(unpacked)) - + @classmethod def __torch_dispatch__(cls, func, types, args, kwargs=None): def allowed_subclasses(type): return ( - issubclass(cls, type) or - issubclass(torch._subclasses.fake_tensor.FakeTensor, type) or - issubclass(torch._subclasses.functional_tensor.FunctionalTensor, type) + issubclass(cls, type) + or issubclass(torch._subclasses.fake_tensor.FakeTensor, type) + or issubclass( + torch._subclasses.functional_tensor.FunctionalTensor, type + ) ) - + if not all(allowed_subclasses(t) for t in types): return NotImplemented("Bitnet, Up to the next one to handle") if func in BITNET_OPS_TABLE: return BITNET_OPS_TABLE[func](func, args, kwargs) - raise NotImplementedError(f"Bitnet dispatch: attempting to run {func}, this is not supported") - + raise NotImplementedError( + f"Bitnet dispatch: attempting to run {func}, this is not supported" + ) + @classmethod def from_float(cls, w: torch.Tensor): w_intq = _quantize_int2(w) w_int2 = w_intq.to(device=w.device) return w_int2 - + def clone(self): return BitnetTensor(self.elem.clone()) - + def copy_(self, src): self.elem.copy_(src.elem) return self @@ -65,7 +74,7 @@ def copy_(self, src): def tolist(self): data = unpack_uint2(self.elem).tolist() return data - + def __repr__(self): try: data = unpack_uint2(self.elem).tolist() @@ -78,18 +87,26 @@ def to(self, *args, **kwargs): dtype = args[0] if dtype == torch.int8: return unpack_uint2(self.elem).view(self.shape).view(torch.int8) - elif dtype in (torch.float, torch.float16, torch.bfloat16, torch.int16, torch.int32, torch.int64): + elif dtype in ( + torch.float, + torch.float16, + torch.bfloat16, + torch.int16, + torch.int32, + torch.int64, + ): return unpack_uint2(self.elem).to(torch.int8).to(dtype) elif dtype == torch.uint8: return unpack_uint2(self.elem).view(torch.uint8) elif isinstance(self, BitnetTensor): return self - if 'device' in kwargs: - device = kwargs['device'] + if "device" in kwargs: + device = kwargs["device"] return BitnetTensor(self.elem.to(device=device)) - + return super().to(*args, **kwargs) + @implements([torch.ops.aten.mm.default]) def mm(func, args, kwargs): x, weight = args @@ -100,6 +117,7 @@ def mm(func, args, kwargs): y = torch.mm(x, weight) return y + @implements([torch.ops.aten.addmm.default]) def addmm(func, args, kwargs): bias, x, weight = args @@ -112,6 +130,7 @@ def addmm(func, args, kwargs): y = torch.addmm(bias, x, weight) return y + @implements([torch.ops.aten.t.default]) def t(func, args, kwargs): (tensor,) = args @@ -119,17 +138,26 @@ def t(func, args, kwargs): transposed = unpacked.t() return BitnetTensor(pack_uint2(transposed)) + @implements([torch.ops.aten.detach.default]) def detach(func, args, kwargs): (tensor,) = args return tensor + @implements([torch.ops.aten.to.dtype]) def to_dtype(func, args, kwargs): (tensor, dtype) = args if dtype == torch.int8: return unpack_uint2(tensor.elem).view(torch.uint8) - 1 - elif dtype in (torch.float, torch.float16, torch.bfloat16, torch.int16, torch.int32, torch.int64): + elif dtype in ( + torch.float, + torch.float16, + torch.bfloat16, + torch.int16, + torch.int32, + torch.int64, + ): return unpack_uint2(tensor.elem).to(torch.int8).to(dtype) elif dtype == torch.uint8: return unpack_uint2(tensor.elem).view(torch.uint8) @@ -137,25 +165,36 @@ def to_dtype(func, args, kwargs): return tensor.elem raise NotImplementedError(f"to {dtype} not supported") + @implements([torch.ops.aten._to_copy.default]) def _to_copy(func, args, kwargs): (tensor,) = args dtype = kwargs["dtype"] if dtype == torch.int8: - return BitnetTensor(unpack_uint2(tensor).view(tensor.shape).view(torch.int8) - 1) - elif dtype in (torch.float, torch.float16, torch.bfloat16, torch.int16, torch.int32, torch.int64): + return BitnetTensor( + unpack_uint2(tensor).view(tensor.shape).view(torch.int8) - 1 + ) + elif dtype in ( + torch.float, + torch.float16, + torch.bfloat16, + torch.int16, + torch.int32, + torch.int64, + ): return BitnetTensor(tensor.to(torch.int8).to(dtype)) elif isinstance(tensor, BitnetTensor): return BitnetTensor(tensor) raise NotImplementedError(f"to {dtype} not supported") + @implements([torch.ops.aten.clone.default]) def clone(func, args, kwargs): (tensor,) = args return tensor.clone() + @implements([torch.ops.aten.allclose.default]) def allclose(func, args, kwargs): (a, b) = args return torch.allclose(a.elem, b.elem, **kwargs) - diff --git a/torchao/prototype/dtypes/uint2.py b/torchao/prototype/dtypes/uint2.py index c0e88e94d..9c14d8ae7 100644 --- a/torchao/prototype/dtypes/uint2.py +++ b/torchao/prototype/dtypes/uint2.py @@ -1,10 +1,12 @@ +from dataclasses import dataclass +from typing import Any, Dict, Tuple + import torch import torch._prims_common as utils -from dataclasses import dataclass -from typing import Dict, Any, Tuple UINT2_OPS_TABLE: Dict[Any, Any] = {} + def fill_defaults(args, n, defaults_tail): if n - len(defaults_tail) > len(args): raise RuntimeError("not enough defaults to fill arguments") @@ -13,36 +15,50 @@ def fill_defaults(args, n, defaults_tail): r.append(defaults_tail[i - n + len(defaults_tail)]) return r + def implements(aten_ops): def decorator(fn): for op in aten_ops: UINT2_OPS_TABLE[op] = fn return fn + return decorator + def down_size(size): assert size[-1] % 4 == 0, f"{size} last dim not divisible by 4" return (*size[:-1], size[-1] // 4) + def up_size(size): return (*size[:-1], size[-1] * 4) + def unpack_uint2(uint8_data: torch.Tensor) -> torch.Tensor: shape = uint8_data.shape uint8_data = uint8_data.to(torch.uint8) - first_elements = ((uint8_data >> 6) & 0b11) - second_elements = ((uint8_data >> 4) & 0b11) - third_elements = ((uint8_data >> 2) & 0b11) - fourth_elements = (uint8_data & 0b11) - return torch.stack((first_elements, second_elements, third_elements, fourth_elements), dim=-1).view(up_size(shape)) + first_elements = (uint8_data >> 6) & 0b11 + second_elements = (uint8_data >> 4) & 0b11 + third_elements = (uint8_data >> 2) & 0b11 + fourth_elements = uint8_data & 0b11 + return torch.stack( + (first_elements, second_elements, third_elements, fourth_elements), dim=-1 + ).view(up_size(shape)) + def pack_uint2(uint8_data: torch.Tensor) -> torch.Tensor: shape = uint8_data.shape assert shape[-1] % 4 == 0, f"{shape}, last dim not divisible by 4" uint8_data = uint8_data.contiguous().view(-1) - packed_data = (uint8_data[::4] << 6 | uint8_data[1::4] << 4 | uint8_data[2::4] << 2 | uint8_data[3::4]).view(down_size(shape)) + packed_data = ( + uint8_data[::4] << 6 + | uint8_data[1::4] << 4 + | uint8_data[2::4] << 2 + | uint8_data[3::4] + ).view(down_size(shape)) return packed_data + @dataclass class SubclassTensorArgs: original_shape: torch.Size @@ -52,6 +68,7 @@ class SubclassTensorArgs: device: torch.device requires_grad: bool + class UInt2Tensor(torch.Tensor): def __new__(cls, input_tensor: torch.Tensor): assert input_tensor.dtype == torch.uint8 @@ -61,65 +78,69 @@ def __new__(cls, input_tensor: torch.Tensor): input_tensor.storage_offset(), cls, input_tensor.device, - input_tensor.requires_grad + input_tensor.requires_grad, ) uint2i_tensor = torch.Tensor._make_wrapper_subclass( - cls, + cls, up_size(tensor_meta.original_shape), tensor_meta.original_strides, tensor_meta.storage_offset, - dtype=torch.uint8, #Not sure if this is correct + dtype=torch.uint8, # Not sure if this is correct device=tensor_meta.device, - requires_grad=tensor_meta.requires_grad + requires_grad=tensor_meta.requires_grad, ) return uint2i_tensor - + def __init__(self, input_tensor: torch.Tensor, **kwargs): self.elem = input_tensor @classmethod def from_packed(cls, unpacked): return UInt2Tensor(pack_uint2(unpacked)) - + def tolist(self): return unpack_uint2(self.elem).tolist() - + def __tensor_flatten__(self): return ["elem"], None - + @staticmethod def __tensor_unflatten__(flattened, meta): assert meta is None elem = flattened["elem"] return UInt2Tensor(elem) - + def __hash__(self): return hash(self.elem) - + def __eq__(self, other): return torch.equal(self.elem, other.elem) def __repr__(self): data = unpack_uint2(self.elem).tolist() return f"UInt2Tensor({data}, dtype=torch.uint2)" - + @classmethod def __torch_dispatch__(cls, func, types, args, kwargs=None): - def allowed_subclasses(type): return ( - issubclass(cls, type) or - issubclass(torch._subclasses.fake_tensor.FakeTensor, type) or - issubclass(torch._subclasses.functional_tensor.FunctionalTensor, type) + issubclass(cls, type) + or issubclass(torch._subclasses.fake_tensor.FakeTensor, type) + or issubclass( + torch._subclasses.functional_tensor.FunctionalTensor, type + ) ) - + if not all(allowed_subclasses(t) for t in types): return NotImplemented("Up to the next one to handle") if func in UINT2_OPS_TABLE: return UINT2_OPS_TABLE[func](func, args, kwargs) - raise NotImplementedError(f"UINT2 dispatch: attempting to run {func}, this is not supported") - + raise NotImplementedError( + f"UINT2 dispatch: attempting to run {func}, this is not supported" + ) + + @implements([torch.ops.aten.view.default]) def uint2_view(func, args, kwargs): tensor, size = args @@ -129,6 +150,7 @@ def uint2_view(func, args, kwargs): reshaped_elem = tensor.elem.view(dsize) return UInt2Tensor(reshaped_elem) + @implements([torch.ops.aten.view.dtype]) def view_dtype(func, args, kwargs): tensor, dtype = args @@ -136,11 +158,13 @@ def view_dtype(func, args, kwargs): return unpack_uint2(tensor.elem).to(torch.uint8) raise NotImplementedError(f"view {dtype} not supported") + @implements([torch.ops.aten.clone.default]) def clone(func, args, kwargs): tensor = args[0] return UInt2Tensor(tensor.elem.clone()) + @implements([torch.ops.aten._unsafe_view.default]) def unsafe_view(func, args, kwargs): tensor, size = args @@ -150,6 +174,7 @@ def unsafe_view(func, args, kwargs): reshaped_elem = tensor.elem.view(dsize) return UInt2Tensor(reshaped_elem) + @implements([torch.ops.aten.unbind.int]) def unbind(func, args, kwargs): tensor, dim = fill_defaults(args, 2, [0]) @@ -159,18 +184,27 @@ def unbind(func, args, kwargs): x = tensor.elem.to(torch.uint8).unbind(dim) return x + @implements([torch.ops.aten._to_copy.default]) def to_copy(func, args, kwargs): (tensor,) = args dtype = kwargs["dtype"] if dtype == torch.uint8: return unpack_uint2(tensor.elem).view(tensor.shape).view(torch.uint8) - elif dtype in (torch.float, torch.float16, torch.bfloat16, torch.int16, torch.int32, torch.int64): + elif dtype in ( + torch.float, + torch.float16, + torch.bfloat16, + torch.int16, + torch.int32, + torch.int64, + ): return tensor.to(torch.uint8).to(dtype) elif isinstance(tensor, UInt2Tensor): return tensor raise NotImplementedError(f"to_copy {dtype} not supported") + @implements([torch.ops.aten.select.int]) def select(func, args, kwargs): tensor, dim, index = args @@ -180,6 +214,7 @@ def select(func, args, kwargs): else: raise NotImplementedError(f"select dim={dim}") + @implements([torch.ops.aten.reshape.default]) def reshape(func, args, kwargs): tensor, size = args @@ -189,6 +224,7 @@ def reshape(func, args, kwargs): reshaped_elem = tensor.elem.view(dsize) return UInt2Tensor(reshaped_elem) + def slice_tensor(func, args, kwargs): tensor, dim, start, end, step = fill_defaults(args, 5, [0, None, None, 1]) if dim == tensor.dim() - 1: @@ -203,29 +239,40 @@ def slice_tensor(func, args, kwargs): sliced_elem = tensor.elem[..., start:end:step] return UInt2Tensor(sliced_elem) + @implements([torch.ops.aten.equal.default]) def equal(func, args, kwargs): tensor, other = args return torch.equal(tensor.elem, other.elem) + @implements([torch.ops.aten.detach.default]) def detach(func, args, kwargs): (tensor,) = args detached_elem = tensor.elem.detach() return UInt2Tensor(detached_elem) + @implements([torch.ops.aten.to.dtype]) def to_dtype(func, args, kwargs): (tensor, dtype) = args if dtype == torch.uint8: return unpack_uint2(tensor.elem).view(torch.uint8) - elif dtype in (torch.float, torch.float16, torch.bfloat16, torch.int16, torch.int32, torch.int64): + elif dtype in ( + torch.float, + torch.float16, + torch.bfloat16, + torch.int16, + torch.int32, + torch.int64, + ): return unpack_uint2(tensor.elem).to(torch.uint8).to(dtype) elif isinstance(tensor, UInt2Tensor): return tensor.elem raise NotImplementedError(f"to {dtype} not supported") + @implements([torch.ops.aten.t.default]) def t(func, args, kwargs): (tensor,) = args @@ -233,6 +280,7 @@ def t(func, args, kwargs): transposed = unpacked.t() return UInt2Tensor(pack_uint2(transposed)) + @implements([torch.ops.aten.allclose.default]) def allclose(func, args, kwargs): tensor, other = args diff --git a/torchao/prototype/dtypes/uintgen.py b/torchao/prototype/dtypes/uintgen.py index 1312816f1..192e4ad05 100644 --- a/torchao/prototype/dtypes/uintgen.py +++ b/torchao/prototype/dtypes/uintgen.py @@ -4,6 +4,7 @@ Contains generic functions to pack and unpack uintx (2-7) tensors into uint8 tensors. """ + def down_size_uint2(size): assert size[-1] % 4 == 0, f"{size} last dim not divisible by four" return (*size[:-1], size[-1] // 4) @@ -87,11 +88,24 @@ def pack_uint3(uint8_data: torch.Tensor) -> torch.Tensor: packed_data = torch.stack( ( - ((uint8_data[::8] & 0b111) << 5 | (uint8_data[1::8] & 0b111) << 2 | (uint8_data[2::8] & 0b111) >> 1), - ((uint8_data[2::8] & 0b1) << 7 | (uint8_data[3::8] & 0b111) << 4 | (uint8_data[4::8] & 0b111) << 1 | ((uint8_data[5::8] >> 2) & 1)), - ((uint8_data[5::8] & 0b11) << 6 | (uint8_data[6::8] & 0b111) << 3 | (uint8_data[7::8] & 0b111)), + ( + (uint8_data[::8] & 0b111) << 5 + | (uint8_data[1::8] & 0b111) << 2 + | (uint8_data[2::8] & 0b111) >> 1 + ), + ( + (uint8_data[2::8] & 0b1) << 7 + | (uint8_data[3::8] & 0b111) << 4 + | (uint8_data[4::8] & 0b111) << 1 + | ((uint8_data[5::8] >> 2) & 1) + ), + ( + (uint8_data[5::8] & 0b11) << 6 + | (uint8_data[6::8] & 0b111) << 3 + | (uint8_data[7::8] & 0b111) + ), ), - dim=-1 + dim=-1, ).view(down_size_uint3(shape)) return packed_data @@ -159,10 +173,16 @@ def pack_uint5(uint8_data: torch.Tensor) -> torch.Tensor: packed_data = torch.stack( ( - ((uint8_data[:, 0] & 0b00011111) << 3) | ((uint8_data[:, 1] & 0b00011100) >> 2), - ((uint8_data[:, 1] & 0b00000011) << 6) | ((uint8_data[:, 2] & 0b00011111) << 1) | ((uint8_data[:, 3] & 0b10000) >> 4), - ((uint8_data[:, 3] & 0b00001111) << 4) | ((uint8_data[:, 4] & 0b00011110) >> 1), - ((uint8_data[:, 4] & 0b00000001) << 7) | ((uint8_data[:, 5] & 0b00011111) << 2) | ((uint8_data[:, 6] & 0b0011000) >> 3), + ((uint8_data[:, 0] & 0b00011111) << 3) + | ((uint8_data[:, 1] & 0b00011100) >> 2), + ((uint8_data[:, 1] & 0b00000011) << 6) + | ((uint8_data[:, 2] & 0b00011111) << 1) + | ((uint8_data[:, 3] & 0b10000) >> 4), + ((uint8_data[:, 3] & 0b00001111) << 4) + | ((uint8_data[:, 4] & 0b00011110) >> 1), + ((uint8_data[:, 4] & 0b00000001) << 7) + | ((uint8_data[:, 5] & 0b00011111) << 2) + | ((uint8_data[:, 6] & 0b0011000) >> 3), ((uint8_data[:, 6] & 0b00000111) << 5) | (uint8_data[:, 7] & 0b00011111), ), dim=-1, @@ -186,12 +206,16 @@ def unpack_uint5(packed_data: torch.Tensor) -> torch.Tensor: unpacked_data = torch.stack( ( ((packed_data[:, 0] >> 3) & 0b00011111), - ((packed_data[:, 0] & 0b00000111) << 2) | ((packed_data[:, 1] >> 6) & 0b00000011), + ((packed_data[:, 0] & 0b00000111) << 2) + | ((packed_data[:, 1] >> 6) & 0b00000011), ((packed_data[:, 1] >> 1) & 0b00011111), - ((packed_data[:, 1] & 0b00000001) << 4) | ((packed_data[:, 2] >> 4) & 0b00001111), - ((packed_data[:, 2] & 0b00001111) << 1) | ((packed_data[:, 3] >> 7) & 0b00000001), + ((packed_data[:, 1] & 0b00000001) << 4) + | ((packed_data[:, 2] >> 4) & 0b00001111), + ((packed_data[:, 2] & 0b00001111) << 1) + | ((packed_data[:, 3] >> 7) & 0b00000001), ((packed_data[:, 3] >> 2) & 0b00011111), - ((packed_data[:, 3] & 0b00000011) << 3) | ((packed_data[:, 4] >> 5) & 0b00000111), + ((packed_data[:, 3] & 0b00000011) << 3) + | ((packed_data[:, 4] >> 5) & 0b00000111), packed_data[:, 4] & 0b00011111, ), dim=-1, @@ -231,8 +255,10 @@ def pack_uint6(uint8_data: torch.Tensor) -> torch.Tensor: packed_data = torch.stack( ( - ((uint8_data[:, 0] & 0b00111111) << 2) | ((uint8_data[:, 1] >> 4) & 0b00000011), - ((uint8_data[:, 1] & 0b00001111) << 4) | ((uint8_data[:, 2] >> 2) & 0b00001111), + ((uint8_data[:, 0] & 0b00111111) << 2) + | ((uint8_data[:, 1] >> 4) & 0b00000011), + ((uint8_data[:, 1] & 0b00001111) << 4) + | ((uint8_data[:, 2] >> 2) & 0b00001111), ((uint8_data[:, 2] & 0b00000011) << 6) | (uint8_data[:, 3] & 0b00111111), ), dim=-1, @@ -256,8 +282,10 @@ def unpack_uint6(packed_data: torch.Tensor) -> torch.Tensor: unpacked_data = torch.stack( ( (packed_data[:, 0] >> 2) & 0b00111111, - ((packed_data[:, 0] & 0b00000011) << 4) | ((packed_data[:, 1] >> 4) & 0b00001111), - ((packed_data[:, 1] & 0b00001111) << 2) | ((packed_data[:, 2] >> 6) & 0b00000011), + ((packed_data[:, 0] & 0b00000011) << 4) + | ((packed_data[:, 1] >> 4) & 0b00001111), + ((packed_data[:, 1] & 0b00001111) << 2) + | ((packed_data[:, 2] >> 6) & 0b00000011), packed_data[:, 2] & 0b00111111, ), dim=-1, @@ -301,13 +329,20 @@ def pack_uint7(uint8_data: torch.Tensor) -> torch.Tensor: packed_data = torch.stack( ( - ((uint8_data[:, 0] & 0b01111111) << 1) | ((uint8_data[:, 1] >> 6) & 0b00000001), - ((uint8_data[:, 1] & 0b00111111) << 2) | ((uint8_data[:, 2] >> 5) & 0b00000011), - ((uint8_data[:, 2] & 0b00011111) << 3) | ((uint8_data[:, 3] >> 4) & 0b00000111), - ((uint8_data[:, 3] & 0b00001111) << 4) | ((uint8_data[:, 4] >> 3) & 0b00001111), - ((uint8_data[:, 4] & 0b00000111) << 5) | ((uint8_data[:, 5] >> 2) & 0b00011111), - ((uint8_data[:, 5] & 0b00000011) << 6) | ((uint8_data[:, 6] >> 1) & 0b00111111), - ((uint8_data[:, 6] & 0b00000001) << 7) | ((uint8_data[:, 7] >> 0) & 0b01111111), + ((uint8_data[:, 0] & 0b01111111) << 1) + | ((uint8_data[:, 1] >> 6) & 0b00000001), + ((uint8_data[:, 1] & 0b00111111) << 2) + | ((uint8_data[:, 2] >> 5) & 0b00000011), + ((uint8_data[:, 2] & 0b00011111) << 3) + | ((uint8_data[:, 3] >> 4) & 0b00000111), + ((uint8_data[:, 3] & 0b00001111) << 4) + | ((uint8_data[:, 4] >> 3) & 0b00001111), + ((uint8_data[:, 4] & 0b00000111) << 5) + | ((uint8_data[:, 5] >> 2) & 0b00011111), + ((uint8_data[:, 5] & 0b00000011) << 6) + | ((uint8_data[:, 6] >> 1) & 0b00111111), + ((uint8_data[:, 6] & 0b00000001) << 7) + | ((uint8_data[:, 7] >> 0) & 0b01111111), ), dim=-1, ).view(down_size_uint7(shape)) @@ -330,12 +365,18 @@ def unpack_uint7(packed_data: torch.Tensor) -> torch.Tensor: unpacked_data = torch.stack( ( (packed_data[:, 0] >> 1) & 0b01111111, - ((packed_data[:, 0] & 0b00000001) << 6) | ((packed_data[:, 1] >> 2) & 0b01111111), - ((packed_data[:, 1] & 0b00000011) << 5) | ((packed_data[:, 2] >> 3) & 0b01111111), - ((packed_data[:, 2] & 0b00000111) << 4) | ((packed_data[:, 3] >> 4) & 0b01111111), - ((packed_data[:, 3] & 0b00001111) << 3) | ((packed_data[:, 4] >> 5) & 0b01111111), - ((packed_data[:, 4] & 0b00011111) << 2) | ((packed_data[:, 5] >> 6) & 0b01111111), - ((packed_data[:, 5] & 0b00111111) << 1) | ((packed_data[:, 6] >> 7) & 0b01111111), + ((packed_data[:, 0] & 0b00000001) << 6) + | ((packed_data[:, 1] >> 2) & 0b01111111), + ((packed_data[:, 1] & 0b00000011) << 5) + | ((packed_data[:, 2] >> 3) & 0b01111111), + ((packed_data[:, 2] & 0b00000111) << 4) + | ((packed_data[:, 3] >> 4) & 0b01111111), + ((packed_data[:, 3] & 0b00001111) << 3) + | ((packed_data[:, 4] >> 5) & 0b01111111), + ((packed_data[:, 4] & 0b00011111) << 2) + | ((packed_data[:, 5] >> 6) & 0b01111111), + ((packed_data[:, 5] & 0b00111111) << 1) + | ((packed_data[:, 6] >> 7) & 0b01111111), packed_data[:, 6] & 0b01111111, ), dim=-1, diff --git a/torchao/prototype/float8nocompile/benchmark/benchmark.py b/torchao/prototype/float8nocompile/benchmark/benchmark.py index 3c21fee29..85b97d908 100644 --- a/torchao/prototype/float8nocompile/benchmark/benchmark.py +++ b/torchao/prototype/float8nocompile/benchmark/benchmark.py @@ -9,6 +9,7 @@ from torch import nn from torch._inductor.utils import do_bench_using_profiling from torch.nn import functional as F +from tqdm import tqdm from torchao.float8.float8_linear_utils import convert_to_float8_training from torchao.prototype.float8nocompile.float8nocompile_linear_utils import ( @@ -17,7 +18,6 @@ from torchao.prototype.float8nocompile.kernels.fp8_dynamic_tensorwise import ( KernelAlgorithm, ) -from tqdm import tqdm device = torch.device("cuda") diff --git a/torchao/prototype/float8nocompile/float8nocompile_linear.py b/torchao/prototype/float8nocompile/float8nocompile_linear.py index 331a67744..50ef59ca2 100644 --- a/torchao/prototype/float8nocompile/float8nocompile_linear.py +++ b/torchao/prototype/float8nocompile/float8nocompile_linear.py @@ -7,17 +7,12 @@ A simple module swap UX for a float8 version of `torch.nn.Linear` which does not require `torch.compile` to be performant. """ -from typing import Optional import torch -from torchao.float8.config import Float8LinearConfig, ScalingGranularity, ScalingType -from torchao.float8.distributed_utils import tensor_already_casted_to_fp8 +from torchao.float8.config import Float8LinearConfig from torchao.float8.float8_linear import manual_float8_matmul_with_args_in_float8 -from torchao.float8.float8_scaling_utils import NoopFwToFloat8BwDynamic from torchao.float8.float8_tensor import GemmInputRole, LinearMMConfig, ScaledMMConfig -from torchao.float8.float8_utils import tensor_to_scale - from torchao.prototype.float8nocompile.float8nocompile_scaling_utils import ( Float8NoCompileConversionFunc, NoopFwToFloat8NoCompileBwDynamic, diff --git a/torchao/prototype/float8nocompile/float8nocompile_linear_utils.py b/torchao/prototype/float8nocompile/float8nocompile_linear_utils.py index 9b4723a75..2ab707a4e 100644 --- a/torchao/prototype/float8nocompile/float8nocompile_linear_utils.py +++ b/torchao/prototype/float8nocompile/float8nocompile_linear_utils.py @@ -6,12 +6,9 @@ import logging from typing import Callable, Optional -import torch import torch.nn as nn -from torchao.float8.config import Float8LinearConfig from torchao.float8.float8_linear_utils import swap_linear_layers - from torchao.prototype.float8nocompile.float8nocompile_linear import ( Float8LinearNoCompile, ) diff --git a/torchao/prototype/float8nocompile/float8nocompile_scaling_utils.py b/torchao/prototype/float8nocompile/float8nocompile_scaling_utils.py index b709dcb85..df86b8642 100644 --- a/torchao/prototype/float8nocompile/float8nocompile_scaling_utils.py +++ b/torchao/prototype/float8nocompile/float8nocompile_scaling_utils.py @@ -11,10 +11,10 @@ import torch from torchao.float8.float8_tensor import ( - _ToFloat8ConstrFunc, Float8Tensor, GemmInputRole, LinearMMConfig, + _ToFloat8ConstrFunc, ) from torchao.prototype.float8nocompile.kernels.fp8_dynamic_tensorwise import ( diff --git a/torchao/prototype/float8nocompile/kernels/fp8_dynamic_tensorwise.py b/torchao/prototype/float8nocompile/kernels/fp8_dynamic_tensorwise.py index 2493cbe3e..7da49e20d 100644 --- a/torchao/prototype/float8nocompile/kernels/fp8_dynamic_tensorwise.py +++ b/torchao/prototype/float8nocompile/kernels/fp8_dynamic_tensorwise.py @@ -7,6 +7,7 @@ """ Triton kernels for scaling high precision tensors to float8. """ + from enum import Enum import torch @@ -578,8 +579,6 @@ def hp_to_fp8_col_major_t( assert hp_tensor.is_contiguous(), "input tensor must be contiguous" num_elements = hp_tensor.numel() - input_num_rows, input_num_cols = hp_tensor.shape - output_num_rows, output_num_cols = input_num_cols, input_num_rows tl_input_dtype = FP8_DTYPE_MAP[hp_tensor.dtype] tl_output_dtype = FP8_DTYPE_MAP[fp8_dtype] @@ -708,7 +707,6 @@ def _hp_tensor_to_scale( fp8_dtype_max: float, algo: KernelAlgorithm, ) -> torch.Tensor: - num_elements = hp_tensor.numel() scale_out = torch.empty((), dtype=torch.float32, device=hp_tensor.device) grid = lambda meta: (triton.cdiv(num_elements, meta["BLOCK_SIZE"]),) diff --git a/torchao/prototype/float8nocompile/kernels/fp8_dynamic_tensorwise_test.py b/torchao/prototype/float8nocompile/kernels/fp8_dynamic_tensorwise_test.py index 02dce5ea4..df09728ab 100644 --- a/torchao/prototype/float8nocompile/kernels/fp8_dynamic_tensorwise_test.py +++ b/torchao/prototype/float8nocompile/kernels/fp8_dynamic_tensorwise_test.py @@ -1,15 +1,16 @@ import pytest import torch + from torchao.float8.float8_scaling_utils import hp_tensor_to_float8_dynamic from torchao.float8.float8_tensor import LinearMMConfig from torchao.float8.float8_utils import is_row_major from torchao.prototype.float8nocompile.kernels.fp8_dynamic_tensorwise import ( + KernelAlgorithm, hp_to_fp8_col_major, hp_to_fp8_col_major_t, hp_to_fp8_row_and_col_major, hp_to_fp8_row_major, hp_to_fp8_row_major_t, - KernelAlgorithm, ) diff --git a/torchao/prototype/galore/__init__.py b/torchao/prototype/galore/__init__.py index 4e1edc403..a769e11a1 100644 --- a/torchao/prototype/galore/__init__.py +++ b/torchao/prototype/galore/__init__.py @@ -1 +1 @@ -from .kernels import * +from .kernels import * # noqa: F403 diff --git a/torchao/prototype/galore/kernels/__init__.py b/torchao/prototype/galore/kernels/__init__.py index d8a134717..71129d34a 100644 --- a/torchao/prototype/galore/kernels/__init__.py +++ b/torchao/prototype/galore/kernels/__init__.py @@ -2,3 +2,11 @@ from .adam_step import triton_adam_launcher from .matmul import triton_mm_launcher from .quant import triton_dequant_blockwise, triton_quantize_blockwise + +__all__ = [ + "fused_adam_mm_launcher", + "triton_adam_launcher", + "triton_mm_launcher", + "triton_dequant_blockwise", + "triton_quantize_blockwise", +] diff --git a/torchao/prototype/galore/kernels/adam_downproj_fused.py b/torchao/prototype/galore/kernels/adam_downproj_fused.py index cfdbd4a03..2c2875b81 100644 --- a/torchao/prototype/galore/kernels/adam_downproj_fused.py +++ b/torchao/prototype/galore/kernels/adam_downproj_fused.py @@ -3,13 +3,22 @@ import torch import triton import triton.language as tl -from torchao.prototype.common.triton.matmul_perf_model import early_config_prune, estimate_matmul_time + +from torchao.prototype.common.triton.matmul_perf_model import ( + early_config_prune, + estimate_matmul_time, +) from .adam_step import BETA1, BETA2, EPS from .custom_autotune import Config, autotune -from .matmul import TRITON_ACC_TYPES, get_higher_dtype, init_to_zero +from .matmul import ( + TRITON_ACC_TYPES, + get_higher_dtype, + get_mm_heuristics, + init_to_zero, + to_tl_type, +) from .matmul import get_autotuner as default_mm_autotuner -from .matmul import get_mm_heuristics, to_tl_type logger = logging.getLogger(__name__) @@ -272,7 +281,6 @@ def fused_adam_mm_launcher( output_dtype=None, kernel=None, ): - device = a.device # handle non-contiguous inputs if necessary # a = grad diff --git a/torchao/prototype/galore/kernels/adam_step.py b/torchao/prototype/galore/kernels/adam_step.py index 75b2c870d..0fc058453 100644 --- a/torchao/prototype/galore/kernels/adam_step.py +++ b/torchao/prototype/galore/kernels/adam_step.py @@ -157,8 +157,6 @@ def make_data(M, N, rank, dtype): if __name__ == "__main__": - from triton.testing import do_bench - M = N = 4096 rank = 128 dtype = torch.float32 diff --git a/torchao/prototype/galore/kernels/custom_autotune.py b/torchao/prototype/galore/kernels/custom_autotune.py index 3b7660595..2a8de5d8c 100644 --- a/torchao/prototype/galore/kernels/custom_autotune.py +++ b/torchao/prototype/galore/kernels/custom_autotune.py @@ -16,7 +16,6 @@ class Autotuner(KernelInterface): - def __init__( self, fn, @@ -187,15 +186,15 @@ def run(self, *args, **kwargs): f.write( f" ==== Autotune Results ====\nKernel name: {self.kernel_name}\nArgs: {self.arg_names}\nKeys: {self._get_key_combination(args)}\n" ) - f.write(f"\nPruned configs:\n") + f.write("\nPruned configs:\n") for cfg in pruned_configs: f.write(f"{cfg}\n") - f.write(f"Timings:\n") + f.write("Timings:\n") for cfg, timing in sorted_timings.items(): f.write(f"{cfg} {timing} \n") f.write(f"Best config: {self.cache[key]}\n") config = self.cache[key] - logger.debug(f"\nAutotune: Cache hit! Running best config...") + logger.debug("\nAutotune: Cache hit! Running best config...") else: config = self.configs[0] self.best_config = config @@ -357,7 +356,6 @@ def decorator(fn): class Heuristics(KernelInterface): - def __init__(self, fn, arg_names, values) -> None: self.fn = fn self.values = values diff --git a/torchao/prototype/galore/kernels/matmul.py b/torchao/prototype/galore/kernels/matmul.py index de7e77fb1..5cff909bd 100644 --- a/torchao/prototype/galore/kernels/matmul.py +++ b/torchao/prototype/galore/kernels/matmul.py @@ -1,7 +1,11 @@ import torch import triton import triton.language as tl -from torchao.prototype.common.triton.matmul_perf_model import early_config_prune, estimate_matmul_time + +from torchao.prototype.common.triton.matmul_perf_model import ( + early_config_prune, + estimate_matmul_time, +) from .custom_autotune import Config, autotune, heuristics @@ -330,7 +334,6 @@ def triton_mm_launcher( output_dtype=None, kernel=matmul, ): - device = a.device # handle non-contiguous inputs if necessary # a = grad diff --git a/torchao/prototype/galore/kernels/quant.py b/torchao/prototype/galore/kernels/quant.py index ad1a9b93d..2b3ff27cf 100644 --- a/torchao/prototype/galore/kernels/quant.py +++ b/torchao/prototype/galore/kernels/quant.py @@ -32,7 +32,9 @@ def _dequant_kernel( tl.static_print(q_idx) # NOTE: Must upcast q_idx to int32 (q_idx is tl.uint8, which does not work for pointer indexing) q_vals = tl.load(qmap_ptr + q_idx.to(tl.int32)) - absmax = tl.load(absmax_ptr + group_offsets, mask=group_offsets < (M * N // GROUP_SIZE)) + absmax = tl.load( + absmax_ptr + group_offsets, mask=group_offsets < (M * N // GROUP_SIZE) + ) dq = q_vals * absmax tl.store(dq_ptr + offsets, dq, mask=mask) diff --git a/torchao/prototype/galore/optim/galore_torch.py b/torchao/prototype/galore/optim/galore_torch.py index a44a7f449..b2269a1a7 100644 --- a/torchao/prototype/galore/optim/galore_torch.py +++ b/torchao/prototype/galore/optim/galore_torch.py @@ -8,11 +8,10 @@ from typing import Callable, Iterable, Tuple import torch +from bitsandbytes.optim.optimizer import Optimizer2State from torch import nn from torch.optim import Optimizer -from bitsandbytes.optim.optimizer import Optimizer2State - class GaLoreProjector: def __init__( @@ -26,7 +25,6 @@ def __init__( self.proj_type = proj_type def project(self, full_rank_grad, iter): - if self.proj_type == "std": if full_rank_grad.shape[0] >= full_rank_grad.shape[1]: if self.ortho_matrix is None or iter % self.update_proj_gap == 0: @@ -78,7 +76,6 @@ def project(self, full_rank_grad, iter): return low_rank_grad def project_back(self, low_rank_grad): - if self.proj_type == "std": if low_rank_grad.shape[0] >= low_rank_grad.shape[1]: full_rank_grad = torch.matmul(low_rank_grad, self.ortho_matrix) @@ -334,8 +331,6 @@ def step(self, closure=None): with torch.enable_grad(): loss = closure() - overflows = [] - if not self.initialized: self.check_overrides() self.to_gpu() # needed for fairseq pure fp16 training diff --git a/torchao/prototype/galore/utils.py b/torchao/prototype/galore/utils.py index 41242cbd8..3c1395254 100644 --- a/torchao/prototype/galore/utils.py +++ b/torchao/prototype/galore/utils.py @@ -58,7 +58,6 @@ def __init__( self.ortho_matrix = None def update_orthogonal_matrix(self, full_rank_grad): - if full_rank_grad.shape[0] >= full_rank_grad.shape[1]: self.ortho_matrix = get_orthogonal_matrix( full_rank_grad, self.rank, type="right" @@ -77,7 +76,6 @@ def project(self, full_rank_grad): return low_rank_grad def project_back(self, low_rank_grad): - if low_rank_grad.shape[0] >= low_rank_grad.shape[1]: full_rank_grad = torch.matmul(low_rank_grad, self.ortho_matrix) else: diff --git a/torchao/prototype/hqq/__init__.py b/torchao/prototype/hqq/__init__.py index c97591c47..8c8be63e6 100644 --- a/torchao/prototype/hqq/__init__.py +++ b/torchao/prototype/hqq/__init__.py @@ -1 +1,6 @@ -from .mixed_mm import triton_mixed_mm, pack_2xint4 \ No newline at end of file +from .mixed_mm import pack_2xint4, triton_mixed_mm + +__all__ = [ + "pack_2xint4", + "triton_mixed_mm", +] diff --git a/torchao/prototype/hqq/example.py b/torchao/prototype/hqq/example.py index eb12b2b45..d622f482d 100644 --- a/torchao/prototype/hqq/example.py +++ b/torchao/prototype/hqq/example.py @@ -1,117 +1,169 @@ import torch -from torchao.prototype.hqq.core import HQQQuantizer + +from torchao.dtypes import PlainLayout, TensorCoreTiledLayout from torchao.dtypes.affine_quantized_tensor import ( to_affine_quantized_intx, ) from torchao.quantization import ( - ZeroPointDomain, - MappingType, + MappingType, + ZeroPointDomain, ) -from torchao.dtypes import TensorCoreTiledLayout, PlainLayout -#Parameters +# Parameters device, compute_dtype = "cuda:0", torch.bfloat16 group_size, axis = 64, 1 in_features, out_features = 4096, 11800 torch.random.manual_seed(100) linear_layer = torch.nn.Linear(in_features, out_features, bias=False, device=device) -x = torch.randn((1, linear_layer.in_features), dtype=torch.float, device=device)/20. +x = torch.randn((1, linear_layer.in_features), dtype=torch.float, device=device) / 20.0 y_ref = linear_layer(x) W = linear_layer.weight.data.clone().to(device=device, dtype=compute_dtype) -del linear_layer.weight +del linear_layer.weight ################################################################################################ -#AffineQuantizedTensor example +# AffineQuantizedTensor example ################################################################################################ -print('-------------------------------------------------------------------') -print('AffineQuantizedTensor example') -print('-------------------------------------------------------------------') -mapping_type = MappingType.ASYMMETRIC -block_size = (1, group_size) -target_dtype = torch.uint8 #until sub-byte dtypes are supported -preserve_zero = False +print("-------------------------------------------------------------------") +print("AffineQuantizedTensor example") +print("-------------------------------------------------------------------") +mapping_type = MappingType.ASYMMETRIC +block_size = (1, group_size) +target_dtype = torch.uint8 # until sub-byte dtypes are supported +preserve_zero = False zero_point_domain = ZeroPointDomain.FLOAT -zero_point_dtype = compute_dtype -_layout = PlainLayout() +zero_point_dtype = compute_dtype +_layout = PlainLayout() for nbits in list(range(2, 9))[::-1]: - print('------------------------------------------------------------------------------') + print( + "------------------------------------------------------------------------------" + ) q_tensor_default = to_affine_quantized_intx( - input_float=W, - mapping_type=mapping_type, - block_size=block_size, - target_dtype=target_dtype, - quant_min=0, - quant_max=2**nbits - 1, - zero_point_domain= zero_point_domain, - preserve_zero=preserve_zero, - _layout=_layout, - ) + input_float=W, + mapping_type=mapping_type, + block_size=block_size, + target_dtype=target_dtype, + quant_min=0, + quant_max=2**nbits - 1, + zero_point_domain=zero_point_domain, + preserve_zero=preserve_zero, + _layout=_layout, + ) linear_layer.weight = q_tensor_default - print("nbits", nbits, "| Default dequantization error", (W - q_tensor_default.dequantize()).abs().mean().item()) - print("nbits", nbits, '| Default Dot product error', (y_ref - linear_layer(x.to(compute_dtype))).abs().mean().item()) + print( + "nbits", + nbits, + "| Default dequantization error", + (W - q_tensor_default.dequantize()).abs().mean().item(), + ) + print( + "nbits", + nbits, + "| Default Dot product error", + (y_ref - linear_layer(x.to(compute_dtype))).abs().mean().item(), + ) # nbits 4 | Default dequantization error 0.001953125 # nbits 4 | Default Dot product error 0.005926903802901506 - q_tensor_hqq = to_affine_quantized_intx( - input_float=W, - mapping_type=mapping_type, - block_size=block_size, - target_dtype=target_dtype, - quant_min=0, - quant_max=2**nbits - 1, - zero_point_domain=zero_point_domain, - preserve_zero=preserve_zero, - _layout=_layout, - use_hqq=True, - ) + input_float=W, + mapping_type=mapping_type, + block_size=block_size, + target_dtype=target_dtype, + quant_min=0, + quant_max=2**nbits - 1, + zero_point_domain=zero_point_domain, + preserve_zero=preserve_zero, + _layout=_layout, + use_hqq=True, + ) linear_layer.weight = q_tensor_hqq - print("nbits", nbits, "| HQQ dequantization error", (W - q_tensor_hqq.dequantize()).abs().mean().item()) - print("nbits", nbits, '| HQQ Dot product error', (y_ref - linear_layer(x.to(compute_dtype))).abs().mean().item()) + print( + "nbits", + nbits, + "| HQQ dequantization error", + (W - q_tensor_hqq.dequantize()).abs().mean().item(), + ) + print( + "nbits", + nbits, + "| HQQ Dot product error", + (y_ref - linear_layer(x.to(compute_dtype))).abs().mean().item(), + ) # nbits 4 | HQQ dequantization error 0.0004863739013671875 # nbits 4 | HQQ Dot product error 0.0014713306445628405 ################################################################################################ -#quant_api example +# quant_api example ################################################################################################ -print('-------------------------------------------------------------------') -print('Quant API example') -print('-------------------------------------------------------------------') +print("-------------------------------------------------------------------") +print("Quant API example") +print("-------------------------------------------------------------------") from torchao.quantization.quant_api import int4_weight_only + nbits = 4 target_dtype = torch.int32 -inner_k_tiles = 8 +inner_k_tiles = 8 _layout = TensorCoreTiledLayout(inner_k_tiles=inner_k_tiles) -int4_weight_only_patch_fct = int4_weight_only(group_size=group_size, inner_k_tiles=inner_k_tiles) -linear_layer_default = torch.nn.Linear(in_features, out_features, bias=False, device=device) +int4_weight_only_patch_fct = int4_weight_only( + group_size=group_size, inner_k_tiles=inner_k_tiles +) +linear_layer_default = torch.nn.Linear( + in_features, out_features, bias=False, device=device +) linear_layer_default.weight.data = W.clone() linear_layer_default = int4_weight_only_patch_fct(linear_layer_default) -print("nbits", nbits, "| Default dequantization error", (W - linear_layer_default(torch.eye(W.shape[1], dtype=W.dtype, device=W.device)).T).abs().mean().item()) -print("nbits", nbits, '| Default Dot product error', (y_ref - linear_layer_default(x.to(compute_dtype))).abs().mean().item()) +print( + "nbits", + nbits, + "| Default dequantization error", + (W - linear_layer_default(torch.eye(W.shape[1], dtype=W.dtype, device=W.device)).T) + .abs() + .mean() + .item(), +) +print( + "nbits", + nbits, + "| Default Dot product error", + (y_ref - linear_layer_default(x.to(compute_dtype))).abs().mean().item(), +) # nbits 4 | Default dequantization error 0.000492095947265625 # nbits 4 | Default Dot product error 0.0015244047390297055 q_tensor_hqq = to_affine_quantized_intx( - input_float=W, - mapping_type=mapping_type, - block_size=block_size, - target_dtype=target_dtype, - quant_min=0, - quant_max=2**nbits - 1, - zero_point_domain=zero_point_domain, - preserve_zero=preserve_zero, - _layout=_layout, - use_hqq=True, - ) + input_float=W, + mapping_type=mapping_type, + block_size=block_size, + target_dtype=target_dtype, + quant_min=0, + quant_max=2**nbits - 1, + zero_point_domain=zero_point_domain, + preserve_zero=preserve_zero, + _layout=_layout, + use_hqq=True, +) linear_layer.weight = q_tensor_hqq -print("nbits", nbits, "| HQQ dequantization error", (W - linear_layer(torch.eye(W.shape[1], dtype=W.dtype, device=W.device)).T).abs().mean().item()) -print("nbits", nbits, '| HQQ Dot product error', (y_ref - linear_layer(x.to(compute_dtype))).abs().mean().item()) +print( + "nbits", + nbits, + "| HQQ dequantization error", + (W - linear_layer(torch.eye(W.shape[1], dtype=W.dtype, device=W.device)).T) + .abs() + .mean() + .item(), +) +print( + "nbits", + nbits, + "| HQQ Dot product error", + (y_ref - linear_layer(x.to(compute_dtype))).abs().mean().item(), +) # nbits 4 | HQQ dequantization error 0.0004863739013671875 # nbits 4 | HQQ Dot product error 0.0014699687017127872 diff --git a/torchao/prototype/hqq/hqq_tinygemm_linear.py b/torchao/prototype/hqq/hqq_tinygemm_linear.py index 743c6128a..24c0efbf8 100644 --- a/torchao/prototype/hqq/hqq_tinygemm_linear.py +++ b/torchao/prototype/hqq/hqq_tinygemm_linear.py @@ -1,19 +1,18 @@ - -#mobicham's tinygemm hqq eval script +# mobicham's tinygemm hqq eval script import torch device = "cuda" -import torch, copy -from torch import nn, Tensor - -from hqq.core.quantize import * -from hqq.core.utils import * +import copy import torch.nn.functional as F -from torchao.utils import TORCH_VERSION_AT_LEAST_2_5, TORCH_VERSION_AT_LEAST_2_6 +from hqq.core.quantize import Quantizer +from hqq.core.utils import * # noqa: F401, F403 +from torch import Tensor, nn + from torchao.dtypes.utils import is_device +from torchao.utils import TORCH_VERSION_AT_LEAST_2_5, TORCH_VERSION_AT_LEAST_2_6 class HQQLinearTorchWeightOnlyInt4(torch.nn.Module): diff --git a/torchao/prototype/hqq/kernels.py b/torchao/prototype/hqq/kernels.py index 8409fcb68..103814bb9 100644 --- a/torchao/prototype/hqq/kernels.py +++ b/torchao/prototype/hqq/kernels.py @@ -279,7 +279,7 @@ def _mixed_mm_kernel( # the strides are adjusted accordingly, since we to stride by stride_bk to get rows of BLK_N # and stride_bn to get columns of BLK_K B = B + (rbn[:, None] * stride_bk + rbk[None, :] * stride_bn) - + # Grouping is along K, so in the forward pass, each block loads a row vector of BLK_K x BLK_N # where grouping varies along N, hence the mainloop marches down the K dimension, where # group idx is given by K // QGROUP_SIZE @@ -394,4 +394,4 @@ def _mixed_mm_kernel( mixed_mm_kernel_compute_bound = triton.autotune( configs=get_configs_compute_bound(), key=["M", "N", "K"] )(_mixed_mm) -_mixed_mm_debug = _mixed_mm \ No newline at end of file +_mixed_mm_debug = _mixed_mm diff --git a/torchao/prototype/hqq/mixed_mm.py b/torchao/prototype/hqq/mixed_mm.py index 6a933fa98..a5cb3a6dd 100644 --- a/torchao/prototype/hqq/mixed_mm.py +++ b/torchao/prototype/hqq/mixed_mm.py @@ -171,4 +171,4 @@ def triton_mixed_mm( DEBUG=True, ) - return c \ No newline at end of file + return c diff --git a/torchao/prototype/mx_formats/benchmarks/bench_qdq.py b/torchao/prototype/mx_formats/benchmarks/bench_qdq.py index ffd9d0d05..3886a3792 100644 --- a/torchao/prototype/mx_formats/benchmarks/bench_qdq.py +++ b/torchao/prototype/mx_formats/benchmarks/bench_qdq.py @@ -13,14 +13,13 @@ import fire import tabulate import torch +from torch.profiler import ProfilerActivity, profile -from torch.profiler import profile, ProfilerActivity from torchao.prototype.mx_formats import config from torchao.prototype.mx_formats.constants import ( # noqa: E501 DTYPE_FP4, SUPPORTED_ELEM_DTYPES, ) - from torchao.prototype.mx_formats.mx_tensor import MXTensor from torchao.utils import benchmark_torch_function_in_microseconds @@ -45,8 +44,7 @@ def run(profile_folder: Optional[str] = None): ) if ( - elem_dtype != DTYPE_FP4 - and use_fp4_custom_triton_dequant_kernel # noqa: E501 + elem_dtype != DTYPE_FP4 and use_fp4_custom_triton_dequant_kernel # noqa: E501 ): # custom_triton_kernels only works for fp4 continue diff --git a/torchao/prototype/mx_formats/custom_cast.py b/torchao/prototype/mx_formats/custom_cast.py index ede516482..cda946e28 100644 --- a/torchao/prototype/mx_formats/custom_cast.py +++ b/torchao/prototype/mx_formats/custom_cast.py @@ -5,12 +5,14 @@ # LICENSE file in the root directory of this source tree. import numpy as np - import torch from torch.utils._triton import has_triton +from torchao.prototype.custom_fp_utils import ( + _f32_to_floatx_unpacked, + _floatx_unpacked_to_f32, +) from torchao.utils import TORCH_VERSION_AT_LEAST_2_4 -from torchao.prototype.custom_fp_utils import _f32_to_floatx_unpacked, _floatx_unpacked_to_f32 # TODO(future): if needed, make the below work on previous PyTorch versions, # just need to hunt down the previous location of `libdevice`. An assert @@ -21,8 +23,8 @@ from torchao.prototype.mx_formats.constants import ( E8M0_EXPONENT_BIAS, E8M0_EXPONENT_NAN_VAL, - F32_EXP_BIAS, F4_E2M1_EXP_BIAS, + F32_EXP_BIAS, ) @@ -31,9 +33,7 @@ def get_bits(x: torch.Tensor) -> str: # Numpy has a nice function to get the string representation of binary. # Since we are using ints as views of floats, need to specify the width # to avoid numpy from using two's complement for negative numbers. - return np.binary_repr( - x.cpu().numpy(), width=x.element_size() * bits_per_byte - ) # noqa: E501 + return np.binary_repr(x.cpu().numpy(), width=x.element_size() * bits_per_byte) # noqa: E501 EBITS_F32, MBITS_F32 = 8, 23 @@ -301,9 +301,7 @@ def triton_f4_to_scaled_bf16_kernel( # multiply output by scale # TODO(later): see if manipulating the exponent instead of fp # multiplication is going to give a significant speedup - output = tl.reshape( - output, (BLOCK_SIZE_OUT // mx_block_size, mx_block_size) - ) # noqa: E501 + output = tl.reshape(output, (BLOCK_SIZE_OUT // mx_block_size, mx_block_size)) # noqa: E501 s_fp = tl.reshape(s_fp, (BLOCK_SIZE_S // 1, 1)) output = output * s_fp output = tl.reshape(output, (BLOCK_SIZE_OUT,)) diff --git a/torchao/prototype/mx_formats/fp_format_spec.py b/torchao/prototype/mx_formats/fp_format_spec.py index 2dc518add..bdc0cc4df 100644 --- a/torchao/prototype/mx_formats/fp_format_spec.py +++ b/torchao/prototype/mx_formats/fp_format_spec.py @@ -13,7 +13,6 @@ from typing import Tuple import tabulate - import torch from torchao.prototype.mx_formats.constants import ( @@ -21,7 +20,6 @@ DTYPE_FP6_E2M3, DTYPE_FP6_E3M2, ) - from torchao.prototype.mx_formats.custom_cast import get_bits dtype_to_bitwidth = { @@ -289,9 +287,7 @@ ] float4_e2m1_neg = [] for fp32_ref, formula, _s, e, m, label in float4_e2m1_interesting_values: - float4_e2m1_neg.append( - [-1 * fp32_ref, "-" + formula, "1", e, m, label + "_neg"] - ) # noqa: E501 + float4_e2m1_neg.append([-1 * fp32_ref, "-" + formula, "1", e, m, label + "_neg"]) # noqa: E501 float4_e2m1_interesting_values.extend(float4_e2m1_neg) del float4_e2m1_neg @@ -305,9 +301,7 @@ ] float6_e3m2_neg = [] for fp32_ref, formula, _s, e, m, label in float6_e3m2_interesting_values: - float6_e3m2_neg.append( - [-1 * fp32_ref, "-" + formula, "1", e, m, label + "_neg"] - ) # noqa: E501 + float6_e3m2_neg.append([-1 * fp32_ref, "-" + formula, "1", e, m, label + "_neg"]) # noqa: E501 float6_e3m2_interesting_values.extend(float6_e3m2_neg) del float6_e3m2_neg diff --git a/torchao/prototype/mx_formats/mx_tensor.py b/torchao/prototype/mx_formats/mx_tensor.py index 6efc2f574..2e67f5a4a 100644 --- a/torchao/prototype/mx_formats/mx_tensor.py +++ b/torchao/prototype/mx_formats/mx_tensor.py @@ -28,7 +28,6 @@ DTYPE_FP6_E3M2, E8M0_EXPONENT_BIAS, E8M0_EXPONENT_NAN_VAL, - F32_MIN_NORMAL, F4_E2M1_MAX, F4_E2M1_MAX_POW2, F6_E2M3_MAX, @@ -39,16 +38,16 @@ F8E4M3_MAX_POW2, F8E5M2_MAX, F8E5M2_MAX_POW2, + F32_MIN_NORMAL, SUPPORTED_ELEM_DTYPES, ) - from torchao.prototype.mx_formats.custom_cast import ( - f32_to_f4_unpacked, - f32_to_f6_e2m3_unpacked, - f32_to_f6_e3m2_unpacked, f4_unpacked_to_f32, f6_e2m3_unpacked_to_f32, f6_e3m2_unpacked_to_f32, + f32_to_f4_unpacked, + f32_to_f6_e2m3_unpacked, + f32_to_f6_e3m2_unpacked, pack_uint4, triton_f4_to_scaled_bf16, unpack_uint4, diff --git a/torchao/prototype/quantization/autoquant_v2.py b/torchao/prototype/quantization/autoquant_v2.py index 75bc63339..0780eb3a8 100644 --- a/torchao/prototype/quantization/autoquant_v2.py +++ b/torchao/prototype/quantization/autoquant_v2.py @@ -19,13 +19,27 @@ ) from torchao.float8.inference import Float8MMConfig from torchao.kernel import safe_int_mm -from torchao.quantization.linear_activation_quantized_tensor import ( - LinearActivationQuantizedTensor, +from torchao.prototype.quantization.subgraph_utils.extract_subgraphs import ( + debug_linears_for_float8, + prepare_target_folder, +) +from torchao.quantization import LinearActivationQuantizedTensor +from torchao.quantization.autoquant import ( + AutoQuantizableLinearWeight as AutoQuantizableLinearWeightV1, +) +from torchao.quantization.granularity import ( + PerRow, + PerTensor, ) from torchao.quantization.quant_primitives import ( MappingType, ZeroPointDomain, ) +from torchao.quantization.subclass import ( # noqa + Int8DynamicallyQuantizedLinearWeight, + Int8WeightOnlyQuantizedLinearWeight, + QuantizedLinearWeightBase, +) from torchao.quantization.utils import quantize_activation_per_token_absmax from torchao.utils import ( TORCH_VERSION_AT_LEAST_2_3, @@ -35,24 +49,6 @@ is_sm_at_least_90, ) -from torchao.quantization.granularity import ( - PerRow, - PerTensor, -) -from torchao.quantization.subclass import ( # noqa - Int8DynamicallyQuantizedLinearWeight, - Int8WeightOnlyQuantizedLinearWeight, - QuantizedLinearWeightBase, -) -from torchao.prototype.quantization.subgraph_utils.extract_subgraphs import ( - debug_linears_for_float8, - prepare_target_folder, -) -from torchao.quantization.subclass import QuantizedLinearWeightBase -from torchao.quantization.autoquant import AutoQuantizableLinearWeight as AutoQuantizableLinearWeightV1 -from torchao.dtypes import AffineQuantizedTensor -from torchao.quantization import LinearActivationQuantizedTensor - logging.basicConfig(level=logging.ERROR) # Set the root logger level to ERROR @@ -69,6 +65,7 @@ "_is_linear", ] + def _is_linear(mod, *args): # avoid circular dependencies from torchao.quantization.qat.affine_fake_quantized_tensor import ( @@ -115,6 +112,7 @@ def _graph_equals(g1, g2): # we'll need to think about how to support this more generally LLAMA = True + def check_cache(gm, cls, shapes_and_dtype): for gm_, cls_, shapes_and_dtype_ in AUTOQUANT_CACHE.keys(): graph_equals = _graph_equals(gm_.graph, gm.graph) @@ -340,7 +338,13 @@ def count_shapes(self, do_print=True): else time_for_best_shape ) self.tune_autoquant2( - fqn, m, self.batch_size, inputs, q_cls, shapes_and_dtype, time_for_best_shape + fqn, + m, + self.batch_size, + inputs, + q_cls, + shapes_and_dtype, + time_for_best_shape, ) ran_new_benchmarks = True torch._dynamo.reset() @@ -828,8 +832,8 @@ def from_float(cls, weight): class Float32Tensor(TorchAOBaseTensor): - """ Tensor subclass tensor for fp32 dtype - """ + """Tensor subclass tensor for fp32 dtype""" + def __init__(self, weight): self.weight = weight.to(torch.float32) @@ -852,6 +856,7 @@ def _apply_fn_to_data(self, fn): def from_float(cls, weight): return cls(weight) + @Float32Tensor.implements([torch.nn.functional.linear, aten.linear.default]) def _(func, types, args, kwargs): input_tensor, weight_tensor, bias = ( @@ -861,6 +866,7 @@ def _(func, types, args, kwargs): ) return weight_tensor._quantized_linear_op(input_tensor, weight_tensor, bias) + @Float32Tensor.implements(aten.detach.default) def _(func, types, args, kwargs): return return_and_correct_aliasing( @@ -922,6 +928,7 @@ class AQFloat32LinearWeight(Float32Tensor, AQMixin): (also converts input activation and bias to float32, and restores the original precision after linear) """ + @classmethod def from_float(cls, weight): return super(AQFloat32LinearWeight, cls).from_float(weight) @@ -934,6 +941,7 @@ class AQBFloat16LinearWeight(BFloat16Tensor, AQMixin): (also converts input activation and bias to bfloat16, and restores the original precision after linear) """ + @classmethod def from_float(cls, weight): return super(AQBFloat16LinearWeight, cls).from_float(weight) @@ -946,6 +954,7 @@ class AQFloat16LinearWeight(Float16Tensor, AQMixin): (also converts input activation and bias to float16, and restores the original precision after linear) """ + @classmethod def from_float(cls, weight): return super(AQFloat16LinearWeight, cls).from_float(weight) @@ -1090,9 +1099,18 @@ def get_weight_block_size(x): AQFloat8PerTensorScalingDynamicallyQuantizedLinearWeight, ] -ALL_AUTOQUANT_CLASS_LIST = list(set(DEFAULT_AUTOQUANT_CLASS_LIST + DEFAULT_INT4_AUTOQUANT_CLASS_LIST + DEFAULT_FLOAT_AUTOQUANT_CLASS_LIST)) +ALL_AUTOQUANT_CLASS_LIST = list( + set( + DEFAULT_AUTOQUANT_CLASS_LIST + + DEFAULT_INT4_AUTOQUANT_CLASS_LIST + + DEFAULT_FLOAT_AUTOQUANT_CLASS_LIST + ) +) if is_sm_at_least_89(): - ALL_AUTOQUANT_CLASS_LIST += [AQFloat8WeightOnlyQuantizedLinearWeight, AQFloat8PerTensorScalingDynamicallyQuantizedLinearWeight] + ALL_AUTOQUANT_CLASS_LIST += [ + AQFloat8WeightOnlyQuantizedLinearWeight, + AQFloat8PerTensorScalingDynamicallyQuantizedLinearWeight, + ] if is_sm_at_least_90(): ALL_AUTOQUANT_CLASS_LIST += [AQFloat8PerRowScalingDynamicallyQuantizedLinearWeight] diff --git a/torchao/prototype/quantization/mixed_precision/scripts/BO_acc_modelsize.py b/torchao/prototype/quantization/mixed_precision/scripts/BO_acc_modelsize.py index 24c7ca8bf..1db980104 100644 --- a/torchao/prototype/quantization/mixed_precision/scripts/BO_acc_modelsize.py +++ b/torchao/prototype/quantization/mixed_precision/scripts/BO_acc_modelsize.py @@ -1,23 +1,19 @@ -import sys - -import torch -import torch.nn as nn -from torchao.quantization import quantize_ import random -from naive_intNwo import intN_weight_only - -import copy -from lm_eval.evaluator import evaluate -from lm_eval.models.huggingface import HFLM -from lm_eval.tasks import get_task_dict - -from transformers import AutoModelForCausalLM, AutoTokenizer -from ax.service.ax_client import AxClient, ObjectiveProperties +import torch import torch.multiprocessing as mp -from ax.modelbridge.cross_validation import cross_validate -from utils import write_history_to_csv, cal_wikitext_ppl, cal_model_size, load_model, quantize_by_fqn_to_config, load_parameters_from_json, load_initial_samples +from ax.service.ax_client import AxClient, ObjectiveProperties from BO_acc_throughput import define_parameter_list +from utils import ( + cal_model_size, + cal_wikitext_ppl, + load_initial_samples, + load_model, + load_parameters_from_json, + quantize_by_fqn_to_config, + write_history_to_csv, +) + # return evaluation results to complete BO trials def eval(model, tokenizer, num_PPL_eval_samples, fqn_to_config): @@ -26,6 +22,7 @@ def eval(model, tokenizer, num_PPL_eval_samples, fqn_to_config): "model_size": (cal_model_size(model, fqn_to_config), 0.0), } + # add initial search points based on the sensitivity score # TODO: add random initial samples if no sensitivity prior def get_initial_samples(num_BO_initial_samples=10): @@ -39,21 +36,37 @@ def get_initial_samples(num_BO_initial_samples=10): initial_points["groupsize." + str(i) + "."] = 32 for i in range(3, 18): - if i in [5,6,7,10,11,12,16]: - initial_points["bitwidth." + str(i) + "."] = random.choices([5, 4], [20, 80])[0] - initial_points["groupsize." + str(i) + "."] = random.choices([32, 64], [30, 70])[0] + if i in [5, 6, 7, 10, 11, 12, 16]: + initial_points["bitwidth." + str(i) + "."] = random.choices( + [5, 4], [20, 80] + )[0] + initial_points["groupsize." + str(i) + "."] = random.choices( + [32, 64], [30, 70] + )[0] else: - initial_points["bitwidth." + str(i) + "."] = random.choices([5, 4], [30, 70])[0] - initial_points["groupsize." + str(i) + "."] = random.choices([32, 64], [40, 60])[0] + initial_points["bitwidth." + str(i) + "."] = random.choices( + [5, 4], [30, 70] + )[0] + initial_points["groupsize." + str(i) + "."] = random.choices( + [32, 64], [40, 60] + )[0] for i in range(18, 30): - if i in [22,23,24]: - initial_points["bitwidth." + str(i) + "."] = random.choices([5, 4, 3, 2], [20, 55, 20, 5])[0] - initial_points["groupsize." + str(i) + "."] = random.choices([32, 64, 128, 256], [30, 40, 25, 5])[0] + if i in [22, 23, 24]: + initial_points["bitwidth." + str(i) + "."] = random.choices( + [5, 4, 3, 2], [20, 55, 20, 5] + )[0] + initial_points["groupsize." + str(i) + "."] = random.choices( + [32, 64, 128, 256], [30, 40, 25, 5] + )[0] else: - initial_points["bitwidth." + str(i) + "."] = random.choices([5, 4, 3, 2], [30, 55, 10, 5])[0] - initial_points["groupsize." + str(i) + "."] = random.choices([32, 64, 128, 256], [40, 40, 15, 5])[0] - + initial_points["bitwidth." + str(i) + "."] = random.choices( + [5, 4, 3, 2], [30, 55, 10, 5] + )[0] + initial_points["groupsize." + str(i) + "."] = random.choices( + [32, 64, 128, 256], [40, 40, 15, 5] + )[0] + for i in range(30, 32): initial_points["bitwidth." + str(i) + "."] = 5 initial_points["groupsize." + str(i) + "."] = 32 @@ -61,147 +74,186 @@ def get_initial_samples(num_BO_initial_samples=10): initial_points_set.append(initial_points) return initial_points_set -''' + +""" This function will run BO trials sequentially on a single GPU. Each time the BO gets one new trial, evaluates the trial on the GPU and return the evaluation results to update the BO. One trial, one BO update. TODO: refactor the sequential BO and parallel BO into a single function -''' -def run_sequential_BO(device, checkpoint, num_PPL_eval_samples, num_trials, model_size_constraint, history_output, parameters_list, initial_samples): - +""" + + +def run_sequential_BO( + device, + checkpoint, + num_PPL_eval_samples, + num_trials, + model_size_constraint, + history_output, + parameters_list, + initial_samples, +): # TODO: add default parameter list if not specified parameters_list = load_parameters_from_json(parameters_list) initial_points_set = load_initial_samples(initial_samples) - num_BO_initial_samples =len(initial_points_set) + num_BO_initial_samples = len(initial_points_set) - #initialize ax_client - constraint="model_size <= "+str(model_size_constraint) + # initialize ax_client + constraint = "model_size <= " + str(model_size_constraint) ax_client = AxClient() ax_client.create_experiment( - parameters = parameters_list, - name = "test_quantize_BO", - objectives = {"cal_PPL": ObjectiveProperties(minimize=True)}, - choose_generation_strategy_kwargs = { - "num_initialization_trials": num_BO_initial_samples, # the number of trials to build generation strategy + parameters=parameters_list, + name="test_quantize_BO", + objectives={"cal_PPL": ObjectiveProperties(minimize=True)}, + choose_generation_strategy_kwargs={ + "num_initialization_trials": num_BO_initial_samples, # the number of trials to build generation strategy }, - outcome_constraints = [constraint], + outcome_constraints=[constraint], ) - history=[] + history = [] trial_id = 0 # add initial points into the BO trials for i in range(num_BO_initial_samples): - ax_client.attach_trial(parameters=initial_points_set[i]) m, tokenizer = load_model(checkpoint, device) quantize_by_fqn_to_config(m, device, initial_points_set[i]) eval_results = eval(m, tokenizer, num_PPL_eval_samples, initial_points_set[i]) - + print("------------") print(trial_id, initial_points_set[i], eval_results) history.append((eval_results, initial_points_set[i])) ax_client.complete_trial( - trial_index = trial_id, - raw_data = eval_results, + trial_index=trial_id, + raw_data=eval_results, ) trial_id += 1 del m torch.cuda.empty_cache() - # run new BO trials for k_ in range(num_trials): parameters, trial_idx = ax_client.get_next_trial() - + m, tokenizer = load_model(checkpoint, device) quantize_by_fqn_to_config(m, device, parameters) eval_results = eval(m, tokenizer, num_PPL_eval_samples, parameters) - + print("------------") print(trial_idx, parameters, eval_results) history.append((eval_results, parameters)) - + ax_client.complete_trial( - trial_index=trial_idx, - raw_data=eval_results, + trial_index=trial_idx, + raw_data=eval_results, ) del m torch.cuda.empty_cache() - #write BO search trial history to csv file - write_history_to_csv(history, history_output, ["cal_PPL", "model_size", "quant_config"]) + # write BO search trial history to csv file + write_history_to_csv( + history, history_output, ["cal_PPL", "model_size", "quant_config"] + ) print("------Best config------") best_parameters, values = ax_client.get_best_parameters() print(values, best_parameters) -# Worker function to perform BO trials on a specific GPU -def eval_in_parallel(gpu_id, checkpoint, num_PPL_eval_samples, config, return_dict, proc_id, trial_id): - model, tokenizer = load_model(checkpoint, f'cuda:{gpu_id}') - parameters_list = define_parameter_list() +# Worker function to perform BO trials on a specific GPU +def eval_in_parallel( + gpu_id, checkpoint, num_PPL_eval_samples, config, return_dict, proc_id, trial_id +): + model, tokenizer = load_model(checkpoint, f"cuda:{gpu_id}") print(f"Process {proc_id} on GPU {gpu_id} starts!") - quantize_by_fqn_to_config(model=model, device=f'cuda:{gpu_id}', fqn_to_config=dict(config)) + quantize_by_fqn_to_config( + model=model, device=f"cuda:{gpu_id}", fqn_to_config=dict(config) + ) eval_results = eval(model, tokenizer, num_PPL_eval_samples, config) - + return_dict[proc_id] = (trial_id, config, eval_results) - + del model torch.cuda.empty_cache() -''' + +""" This function will run BO trials in parallel on multiple GPUs. Each time the BO gets multiple new trials, evaluates the trials on the GPUs and return the evaluation results to update the BO. Multiple trials, one BO update. -''' -def run_parallel_BO(device, checkpoint, num_PPL_eval_samples, num_trials, model_size_constraint, gpu_list, history_output, parameters_list, initial_samples): - +""" + + +def run_parallel_BO( + device, + checkpoint, + num_PPL_eval_samples, + num_trials, + model_size_constraint, + gpu_list, + history_output, + parameters_list, + initial_samples, +): # TODO: add default parameter list if not specified parameters_list = define_parameter_list() initial_points_set = load_initial_samples(initial_samples) - num_BO_initial_samples =len(initial_points_set) - - #initialize ax_client - constraint="model_size <= "+str(model_size_constraint) + num_BO_initial_samples = len(initial_points_set) + + # initialize ax_client + constraint = "model_size <= " + str(model_size_constraint) ax_client = AxClient() ax_client.create_experiment( - parameters = parameters_list, - name = "test_quantize_BO", - objectives = {"cal_PPL": ObjectiveProperties(minimize=True)}, - choose_generation_strategy_kwargs = { - "num_initialization_trials": num_BO_initial_samples, # the number of trials to build generation strategy + parameters=parameters_list, + name="test_quantize_BO", + objectives={"cal_PPL": ObjectiveProperties(minimize=True)}, + choose_generation_strategy_kwargs={ + "num_initialization_trials": num_BO_initial_samples, # the number of trials to build generation strategy }, outcome_constraints=[constraint], ) gpu_list = [int(i) for i in gpu_list.split(",")] - history=[] + history = [] trial_id = 0 # Set the multiprocessing start method to 'spawn' mp.set_start_method("spawn", force=True) # add initial points into the BO trials - for id in range(num_BO_initial_samples//len(gpu_list)): + for id in range(num_BO_initial_samples // len(gpu_list)): processes = [] manager = mp.Manager() return_dict = manager.dict() # Start the worker processes for i, gpu_id in enumerate(gpu_list): - ax_client.attach_trial(parameters=dict(initial_points_set[id*len(gpu_list)+i])) - p = mp.Process(target=eval_in_parallel, args=(gpu_id, checkpoint, num_PPL_eval_samples, initial_points_set[id*len(gpu_list)+i], return_dict, i, trial_id)) + ax_client.attach_trial( + parameters=dict(initial_points_set[id * len(gpu_list) + i]) + ) + p = mp.Process( + target=eval_in_parallel, + args=( + gpu_id, + checkpoint, + num_PPL_eval_samples, + initial_points_set[id * len(gpu_list) + i], + return_dict, + i, + trial_id, + ), + ) trial_id += 1 p.start() processes.append(p) @@ -215,10 +267,13 @@ def run_parallel_BO(device, checkpoint, num_PPL_eval_samples, num_trials, model_ for i in range(len(gpu_list)): current_trial_id, config, eval_results = return_dict[i] history.append((eval_results, config)) - ax_client.complete_trial(trial_index = current_trial_id, raw_data = eval_results,) + ax_client.complete_trial( + trial_index=current_trial_id, + raw_data=eval_results, + ) # run new BO trials - for id in range(num_trials//len(gpu_list)): + for id in range(num_trials // len(gpu_list)): processes = [] manager = mp.Manager() return_dict = manager.dict() @@ -228,8 +283,19 @@ def run_parallel_BO(device, checkpoint, num_PPL_eval_samples, num_trials, model_ parameters, trial_idx = ax_client.get_next_trial() parameter_tuple = [] for k, v in parameters.items(): - parameter_tuple.append((k, v)) - p = mp.Process(target = eval_in_parallel, args = (gpu_id, checkpoint, num_PPL_eval_samples, parameter_tuple, return_dict, i, trial_idx)) + parameter_tuple.append((k, v)) + p = mp.Process( + target=eval_in_parallel, + args=( + gpu_id, + checkpoint, + num_PPL_eval_samples, + parameter_tuple, + return_dict, + i, + trial_idx, + ), + ) p.start() processes.append(p) @@ -242,33 +308,98 @@ def run_parallel_BO(device, checkpoint, num_PPL_eval_samples, num_trials, model_ for i in range(len(gpu_list)): current_trial_id, config, eval_results = return_dict[i] history.append((eval_results, config)) - ax_client.complete_trial(trial_index = current_trial_id, raw_data = eval_results,) - - #write BO search trial history to csv file - write_history_to_csv(history, history_output, ["cal_PPL", "model_size", "quant_config"]) + ax_client.complete_trial( + trial_index=current_trial_id, + raw_data=eval_results, + ) + + # write BO search trial history to csv file + write_history_to_csv( + history, history_output, ["cal_PPL", "model_size", "quant_config"] + ) print("------Best config------") best_parameters, values = ax_client.get_best_parameters() print(values, best_parameters) -if __name__ == '__main__': - +if __name__ == "__main__": import argparse - parser = argparse.ArgumentParser(description='Bayesian optimization for mixed-precision quantization to optimize accuracy under model size constraint.') - parser.add_argument('--device', type=str, default="cuda", help='Device to use for evaluation') - parser.add_argument('--checkpoint', type=str, default="/tmp/Meta-Llama-3-8B", help='Path to load model') - parser.add_argument('--num_PPL_eval_samples', type=int, default=None, help='Number of samples to evaluate ppl') - parser.add_argument('--num_trials', type=int, default=200, help='Number of trials to run BO') - parser.add_argument('--model_size_constraint', type=float, default=6.0, help='The model size (GB) constraint for BO') - parser.add_argument('--gpu_list', type=str, default="", help="A list of gpus to run evaluation, separated by comma, e.g., --gpu_lists=0,1,2,3") - parser.add_argument('--history_output', type=str, default="BO_acc_modelsize_output.csv", help="The csv file path to save the BO search trials") - parser.add_argument('--parameters_list', type=str, default="Llama3-8B_parameters.json", help="The json file path to save the parameters list for BO") - parser.add_argument('--initial_samples', type=str, default="Llama3-8B_initial_samples.json", help="The json file path to save the user-defined initial samples for BO") + + parser = argparse.ArgumentParser( + description="Bayesian optimization for mixed-precision quantization to optimize accuracy under model size constraint." + ) + parser.add_argument( + "--device", type=str, default="cuda", help="Device to use for evaluation" + ) + parser.add_argument( + "--checkpoint", + type=str, + default="/tmp/Meta-Llama-3-8B", + help="Path to load model", + ) + parser.add_argument( + "--num_PPL_eval_samples", + type=int, + default=None, + help="Number of samples to evaluate ppl", + ) + parser.add_argument( + "--num_trials", type=int, default=200, help="Number of trials to run BO" + ) + parser.add_argument( + "--model_size_constraint", + type=float, + default=6.0, + help="The model size (GB) constraint for BO", + ) + parser.add_argument( + "--gpu_list", + type=str, + default="", + help="A list of gpus to run evaluation, separated by comma, e.g., --gpu_lists=0,1,2,3", + ) + parser.add_argument( + "--history_output", + type=str, + default="BO_acc_modelsize_output.csv", + help="The csv file path to save the BO search trials", + ) + parser.add_argument( + "--parameters_list", + type=str, + default="Llama3-8B_parameters.json", + help="The json file path to save the parameters list for BO", + ) + parser.add_argument( + "--initial_samples", + type=str, + default="Llama3-8B_initial_samples.json", + help="The json file path to save the user-defined initial samples for BO", + ) args = parser.parse_args() if args.gpu_list == "": - run_sequential_BO(device=args.device, checkpoint=args.checkpoint, num_PPL_eval_samples=args.num_PPL_eval_samples, num_trials=args.num_trials, model_size_constraint=args.model_size_constraint, history_output=args.history_output, parameters_list=args.parameters_list, initial_samples=args.initial_samples) + run_sequential_BO( + device=args.device, + checkpoint=args.checkpoint, + num_PPL_eval_samples=args.num_PPL_eval_samples, + num_trials=args.num_trials, + model_size_constraint=args.model_size_constraint, + history_output=args.history_output, + parameters_list=args.parameters_list, + initial_samples=args.initial_samples, + ) else: - run_parallel_BO(device=args.device, checkpoint=args.checkpoint, num_PPL_eval_samples=args.num_PPL_eval_samples, num_trials=args.num_trials, model_size_constraint=args.model_size_constraint, gpu_list=args.gpu_list, history_output=args.history_output, parameters_list=args.parameters_list, initial_samples=args.initial_samples) + run_parallel_BO( + device=args.device, + checkpoint=args.checkpoint, + num_PPL_eval_samples=args.num_PPL_eval_samples, + num_trials=args.num_trials, + model_size_constraint=args.model_size_constraint, + gpu_list=args.gpu_list, + history_output=args.history_output, + parameters_list=args.parameters_list, + initial_samples=args.initial_samples, + ) diff --git a/torchao/prototype/quantization/mixed_precision/scripts/BO_acc_throughput.py b/torchao/prototype/quantization/mixed_precision/scripts/BO_acc_throughput.py index a182ea0b2..12fc77bd9 100644 --- a/torchao/prototype/quantization/mixed_precision/scripts/BO_acc_throughput.py +++ b/torchao/prototype/quantization/mixed_precision/scripts/BO_acc_throughput.py @@ -1,58 +1,49 @@ -import sys - -import torch -import time -import torch.nn as nn -from torchao.quantization import quantize_ import random -from naive_intNwo import intN_weight_only - -import copy -from lm_eval.evaluator import evaluate -from lm_eval.models.huggingface import HFLM -from lm_eval.tasks import get_task_dict - -from transformers import AutoModelForCausalLM, AutoTokenizer -from ax.service.ax_client import AxClient, ObjectiveProperties -import torch.multiprocessing as mp - -import os -import sys +import time from pathlib import Path -from typing import Optional, Tuple -from datetime import datetime -import torchao +from typing import Optional + +import torch import torch._dynamo.config import torch._inductor.config -from torchao.utils import get_model_size_in_bytes -from torchao.utils import TORCH_VERSION_AT_LEAST_2_5 -from torchao.quantization.quant_api import int4_weight_only -from torchao._models.llama.model import Transformer, prepare_inputs_for_model -from torchao._models.llama.tokenizer import get_tokenizer -from torchao._models._eval import TransformerEvalWrapper, InputRecorder - -from torchao.dtypes import TensorCoreTiledLayout +from ax.service.ax_client import AxClient, ObjectiveProperties +from transformers import AutoTokenizer +from utils import ( + cal_wikitext_ppl, + load_initial_samples, + load_model, + load_parameters_from_json, + quantize_by_fqn_to_config, + write_history_to_csv, +) -from torchao._models.llama.generate import ( - device_sync, - multinomial_sample_one_no_sync, - logits_to_probs, - sample, - prefill, +import torchao +from torchao._models.llama.generate import ( + _load_model, decode_one_token, - model_forward, + device_sync, encode_tokens, - _load_model, + prefill, ) +from torchao._models.llama.model import Transformer, prepare_inputs_for_model +from torchao._models.llama.tokenizer import get_tokenizer -from utils import write_history_to_csv, cal_wikitext_ppl, load_model, quantize_by_fqn_to_config, load_parameters_from_json, load_initial_samples +default_device = "cuda" if torch.cuda.is_available() else "cpu" -default_device = 'cuda' if torch.cuda.is_available() else 'cpu' -def decode_n_tokens(model: Transformer, cur_token: torch.Tensor, input_pos: torch.Tensor, num_new_tokens: int, callback=lambda _: _, **sampling_kwargs): +def decode_n_tokens( + model: Transformer, + cur_token: torch.Tensor, + input_pos: torch.Tensor, + num_new_tokens: int, + callback=lambda _: _, + **sampling_kwargs, +): new_tokens, new_probs = [], [] for i in range(num_new_tokens): - with torch.backends.cuda.sdp_kernel(enable_flash=False, enable_mem_efficient=False, enable_math=True): # Actually better for Inductor to codegen attention here + with torch.backends.cuda.sdp_kernel( + enable_flash=False, enable_mem_efficient=False, enable_math=True + ): # Actually better for Inductor to codegen attention here next_token, next_prob = decode_one_token( model, cur_token, input_pos, **sampling_kwargs ) @@ -65,6 +56,7 @@ def decode_n_tokens(model: Transformer, cur_token: torch.Tensor, input_pos: torc return new_tokens, new_probs + @torch.no_grad() def generate( model: Transformer, @@ -72,9 +64,9 @@ def generate( max_new_tokens: int, *, interactive: bool, - callback = lambda x: x, + callback=lambda x: x, kv_cache_quantization: bool = False, - **sampling_kwargs + **sampling_kwargs, ) -> torch.Tensor: """ Takes a conditioning sequence (prompt) as input and continues to generate as many tokens as requested. @@ -85,7 +77,9 @@ def generate( T = prompt.numel() # calculate how many tokens to generate based on max_new_tokens and model's upper bound (block_size) - max_seq_length = min(T + max_new_tokens, model.config.block_size) if not interactive else 350 + max_seq_length = ( + min(T + max_new_tokens, model.config.block_size) if not interactive else 350 + ) new_tokens = max_seq_length - T # full prompt+output will be stored in seq @@ -97,14 +91,17 @@ def generate( model.setup_caches(max_batch_size=1, max_seq_length=max_seq_length) if kv_cache_quantization: from model import AffineQuantizedKVCache - from torchao.quantization.quant_api import _replace_with_custom_fn_if_matches_filter + + from torchao.quantization.quant_api import ( + _replace_with_custom_fn_if_matches_filter, + ) + _replace_with_custom_fn_if_matches_filter( model, AffineQuantizedKVCache.from_float, lambda x, y: isinstance(x, torchao._models.llama.model.KVCache), ) - # format model input x, input_pos = prepare_inputs_for_model(prompt, max_new_tokens) @@ -114,11 +111,19 @@ def generate( # execute token generation input_pos = torch.tensor([T], device=device, dtype=torch.int) - generated_tokens, _ = decode_n_tokens(model, next_token.view(1, -1), input_pos, new_tokens-1, callback=callback, **sampling_kwargs) - seq[T + 1:] = torch.cat(generated_tokens) + generated_tokens, _ = decode_n_tokens( + model, + next_token.view(1, -1), + input_pos, + new_tokens - 1, + callback=callback, + **sampling_kwargs, + ) + seq[T + 1 :] = torch.cat(generated_tokens) return seq + def cal_throughput( model, tokenizer, @@ -139,40 +144,39 @@ def cal_throughput( precision=torch.bfloat16, write_result: Optional[Path] = None, ) -> None: - """Generates text samples based on a pre-trained Transformer model and tokenizer. - """ + """Generates text samples based on a pre-trained Transformer model and tokenizer.""" B_INST, E_INST = "[INST]", "[/INST]" torchao.quantization.utils.recommended_inductor_config_setter() is_chat = "chat" in str(checkpoint_path) - device_sync(device=device) # MKG + device_sync(device=device) # MKG encoded = encode_tokens(tokenizer, prompt, bos=True, device=device) prompt_length = encoded.size(0) torch.manual_seed(1234) - if compile: print("Compiling Model") global decode_one_token, prefill - decode_one_token = torch.compile(decode_one_token, mode="reduce-overhead", fullgraph=True) + decode_one_token = torch.compile( + decode_one_token, mode="reduce-overhead", fullgraph=True + ) if compile_prefill: prefill = torch.compile(prefill, fullgraph=True, dynamic=True) - aggregate_metrics = { - 'tokens_per_sec': [], + "tokens_per_sec": [], } start = -1 if compile else 0 for i in range(start, num_samples): - if i==0: + if i == 0: torch.cuda.reset_peak_memory_stats() - device_sync(device=device) # MKG + device_sync(device=device) # MKG if i >= 0 and interactive: prompt = input("What is your prompt? ") if is_chat: @@ -181,8 +185,9 @@ def cal_throughput( if interactive and i >= 0: buffer = [] - period_id = tokenizer.encode('.')[0] + period_id = tokenizer.encode(".")[0] done_generating = False + def callback(x): nonlocal done_generating if done_generating: @@ -191,14 +196,15 @@ def callback(x): if x.item() == tokenizer.eos_id(): done_generating = True if len(buffer) == 4 or done_generating: - print(''.join(buffer), end='', flush=True) + print("".join(buffer), end="", flush=True) buffer.clear() # print(, end='', flush=True) else: - callback = lambda x : x + callback = lambda x: x t0 = time.perf_counter() import contextlib - if (i != num_samples - 1 or not profile): + + if i != num_samples - 1 or not profile: prof = contextlib.nullcontext() else: torch.profiler._utils._init_for_cuda_graphs() @@ -219,38 +225,37 @@ def callback(x): continue if hasattr(prof, "export_chrome_trace"): prof.export_chrome_trace(f"{profile}.json") - device_sync(device=device) # MKG + device_sync(device=device) # MKG t = time.perf_counter() - t0 - if not interactive: - tok_list = y.tolist() - # truncate text after end of string token - tokens = tok_list if not tokenizer.eos_id() in y else tok_list[:tok_list.index(tokenizer.eos_id())] - else: + if interactive: print() tokens_generated = y.size(0) - prompt_length tokens_sec = tokens_generated / t - aggregate_metrics['tokens_per_sec'].append(tokens_sec) + aggregate_metrics["tokens_per_sec"].append(tokens_sec) - tokpersec = torch.mean(torch.tensor(aggregate_metrics['tokens_per_sec'])).item() + tokpersec = torch.mean(torch.tensor(aggregate_metrics["tokens_per_sec"])).item() print("tokpersec", tokpersec) - return tokpersec + return tokpersec # return evaluation results to complete BO trials def eval(model4ppl, model4tp, tokenizer, device, num_PPL_eval_samples, fqn_to_config): return { "cal_PPL": (cal_wikitext_ppl(model4ppl, tokenizer, num_PPL_eval_samples), 0.0), - "cal_throughput": (cal_throughput(model=model4tp, tokenizer=tokenizer, device=device), 0.0), + "cal_throughput": ( + cal_throughput(model=model4tp, tokenizer=tokenizer, device=device), + 0.0, + ), } + # TODO: make it into a yaml or json file to enable users specify their custom model formats def define_parameter_list(): - # define the search space for all layers parameters_list = [] - for i in range(0, 3): + for i in range(0, 3): parameters_list.append( { "name": f"bitwidth.{i}.", @@ -273,13 +278,13 @@ def define_parameter_list(): } ) - for i in range(3, 30): + for i in range(3, 30): parameters_list.append( { "name": f"bitwidth.{i}.", "type": "choice", "value_type": "int", - "values": [2,3,4,5,6,8], + "values": [2, 3, 4, 5, 6, 8], "is_ordered": True, "sort_values": True, } @@ -296,7 +301,7 @@ def define_parameter_list(): } ) - for i in range(30, 32): + for i in range(30, 32): parameters_list.append( { "name": f"bitwidth.{i}.", @@ -320,10 +325,10 @@ def define_parameter_list(): return parameters_list + # add initial search points based on the sensitivity score # TODO: add default parameter list if not specified def get_initial_samples(num_BO_initial_samples=10): - initial_points_set = [] # auto sample the bit choices with random choice probability positive correlated to FIT score @@ -334,21 +339,37 @@ def get_initial_samples(num_BO_initial_samples=10): initial_points["groupsize." + str(i) + "."] = 32 for i in range(3, 18): - if i in [5,6,7,10,11,12,16]: - initial_points["bitwidth." + str(i) + "."] = random.choices([8, 6, 5, 4], [25, 2, 2, 71])[0] - initial_points["groupsize." + str(i) + "."] = random.choices([32, 64], [40, 60])[0] + if i in [5, 6, 7, 10, 11, 12, 16]: + initial_points["bitwidth." + str(i) + "."] = random.choices( + [8, 6, 5, 4], [25, 2, 2, 71] + )[0] + initial_points["groupsize." + str(i) + "."] = random.choices( + [32, 64], [40, 60] + )[0] else: - initial_points["bitwidth." + str(i) + "."] = random.choices([8, 6, 5, 4], [30, 2, 2,66])[0] - initial_points["groupsize." + str(i) + "."] = random.choices([32, 64], [50, 50])[0] + initial_points["bitwidth." + str(i) + "."] = random.choices( + [8, 6, 5, 4], [30, 2, 2, 66] + )[0] + initial_points["groupsize." + str(i) + "."] = random.choices( + [32, 64], [50, 50] + )[0] for i in range(18, 30): - if i in [22,23,24]: - initial_points["bitwidth." + str(i) + "."] = random.choices([8, 6, 5, 4], [10, 2, 2, 86])[0] - initial_points["groupsize." + str(i) + "."] = random.choices([32, 64, 128, 256], [35, 45, 10, 10])[0] + if i in [22, 23, 24]: + initial_points["bitwidth." + str(i) + "."] = random.choices( + [8, 6, 5, 4], [10, 2, 2, 86] + )[0] + initial_points["groupsize." + str(i) + "."] = random.choices( + [32, 64, 128, 256], [35, 45, 10, 10] + )[0] else: - initial_points["bitwidth." + str(i) + "."] = random.choices([8, 6, 5, 4], [20, 2, 2, 76])[0] - initial_points["groupsize." + str(i) + "."] = random.choices([32, 64, 128, 256], [30, 40, 25, 5])[0] - + initial_points["bitwidth." + str(i) + "."] = random.choices( + [8, 6, 5, 4], [20, 2, 2, 76] + )[0] + initial_points["groupsize." + str(i) + "."] = random.choices( + [32, 64, 128, 256], [30, 40, 25, 5] + )[0] + for i in range(30, 32): initial_points["bitwidth." + str(i) + "."] = 8 initial_points["groupsize." + str(i) + "."] = 32 @@ -357,28 +378,39 @@ def get_initial_samples(num_BO_initial_samples=10): return initial_points_set -''' + +""" This function will run BO trials sequentially on a single GPU. Each time the BO gets one new trial, evaluates the trial on the GPU and return the evaluation results to update the BO. One trial, one BO update. -''' -def run_sequential_BO(device, checkpoint_path, repo_id, num_PPL_eval_samples, num_trials, ppl_constraint, args): - ''' - currently use the loader and benchmark code from torchao/_models/llama/generate, +""" + + +def run_sequential_BO( + device, + checkpoint_path, + repo_id, + num_PPL_eval_samples, + num_trials, + ppl_constraint, + args, +): + """ + currently use the loader and benchmark code from torchao/_models/llama/generate, and use lm_eval for ppl evaluation - ''' + """ # load tokenizers assert checkpoint_path.is_file(), checkpoint_path tokenizer_path = checkpoint_path.parent / "tokenizer.model" assert tokenizer_path.is_file(), str(tokenizer_path) - device_sync(device=device) # MKG + device_sync(device=device) # MKG tokenizer4tp = get_tokenizer(tokenizer_path, checkpoint_path) tokenizer4ppl = AutoTokenizer.from_pretrained(repo_id) - + # initialize parameters # TODO: add default parameter list if not specified parameters_list = load_parameters_from_json(args.parameters_list) - + # sample initial points # TODO(future PR): fix me initial_samples = [] @@ -386,49 +418,55 @@ def run_sequential_BO(device, checkpoint_path, repo_id, num_PPL_eval_samples, nu num_BO_initial_samples = len(initial_points_set) # initialize BO experiment - constraint="cal_PPL <= "+str(ppl_constraint) + constraint = "cal_PPL <= " + str(ppl_constraint) ax_client = AxClient() ax_client.create_experiment( parameters=parameters_list, name="test_quantize_BO", objectives={"cal_throughput": ObjectiveProperties(minimize=False)}, choose_generation_strategy_kwargs={ - "num_initialization_trials": num_BO_initial_samples # the number of trials to build generation strategy + "num_initialization_trials": num_BO_initial_samples # the number of trials to build generation strategy }, outcome_constraints=[constraint], ) - history=[] + history = [] trial_id = 0 # add initial points into the BO trials for i in range(num_BO_initial_samples): - ax_client.attach_trial(parameters=initial_points_set[i]) - + # evaluate throuput of quantized model under torch.compile() model4tp = _load_model(checkpoint_path, device, torch.bfloat16) - quantize_by_fqn_to_config(model = model4tp, device=device, fqn_to_config = initial_points_set[i]) - tp=cal_throughput(model=model4tp, tokenizer=tokenizer4tp, device=device) + quantize_by_fqn_to_config( + model=model4tp, device=device, fqn_to_config=initial_points_set[i] + ) + tp = cal_throughput(model=model4tp, tokenizer=tokenizer4tp, device=device) del model4tp torch.cuda.empty_cache() # evaluate ppl of quantized model model4ppl = load_model(repo_id, device) - quantize_by_fqn_to_config(model = model4ppl, device=device, fqn_to_config = initial_points_set[i]) - ppl=cal_wikitext_ppl(model4ppl, tokenizer4ppl, num_PPL_eval_samples) + quantize_by_fqn_to_config( + model=model4ppl, device=device, fqn_to_config=initial_points_set[i] + ) + ppl = cal_wikitext_ppl(model4ppl, tokenizer4ppl, num_PPL_eval_samples) del model4ppl torch.cuda.empty_cache() - eval_results= {"cal_PPL": (ppl, 0.0), "cal_throughput": (tp, 0.0),} + eval_results = { + "cal_PPL": (ppl, 0.0), + "cal_throughput": (tp, 0.0), + } print("------------") print(trial_id, initial_points_set[i], eval_results) history.append((eval_results, initial_points_set[i])) ax_client.complete_trial( - trial_index=trial_id, - raw_data=eval_results, + trial_index=trial_id, + raw_data=eval_results, ) trial_id += 1 @@ -438,53 +476,118 @@ def run_sequential_BO(device, checkpoint_path, repo_id, num_PPL_eval_samples, nu # evaluate throuput of quantized model under torch.compile() model4tp = _load_model(checkpoint_path, device, torch.bfloat16) - quantize_by_fqn_to_config(model = model4tp, device=device, fqn_to_config = initial_points_set[i]) - tp=cal_throughput(model=model4tp, tokenizer=tokenizer4tp, device=device) + quantize_by_fqn_to_config( + model=model4tp, device=device, fqn_to_config=initial_points_set[i] + ) + tp = cal_throughput(model=model4tp, tokenizer=tokenizer4tp, device=device) del model4tp torch.cuda.empty_cache() # evaluate ppl of quantized model model4ppl = load_model(repo_id, device) - quantize_by_fqn_to_config(model = model4ppl, device=device, fqn_to_config = initial_points_set[i]) - ppl=cal_wikitext_ppl(model4ppl, tokenizer4ppl, num_PPL_eval_samples) + quantize_by_fqn_to_config( + model=model4ppl, device=device, fqn_to_config=initial_points_set[i] + ) + ppl = cal_wikitext_ppl(model4ppl, tokenizer4ppl, num_PPL_eval_samples) del model4ppl torch.cuda.empty_cache() - eval_results= {"cal_PPL": (ppl, 0.0), "cal_throughput": (tp, 0.0),} - + eval_results = { + "cal_PPL": (ppl, 0.0), + "cal_throughput": (tp, 0.0), + } + print("------------") print(trial_idx, parameters, eval_results) history.append((eval_results, parameters)) - + ax_client.complete_trial( - trial_index=trial_idx, - raw_data=eval_results, + trial_index=trial_idx, + raw_data=eval_results, ) - #write BO search trial history to csv file - write_history_to_csv(history, args.history_output, ["cal_PPL", "cal_throughput", "quant_config"]) + # write BO search trial history to csv file + write_history_to_csv( + history, args.history_output, ["cal_PPL", "cal_throughput", "quant_config"] + ) print("------Best config------") best_parameters, values = ax_client.get_best_parameters() print(values, best_parameters) -if __name__ == '__main__': +if __name__ == "__main__": import argparse - parser = argparse.ArgumentParser(description='Bayesian optimization for mixed-precision quantization to optimize inference speed under model accuracy constraint.') - - parser.add_argument('--device', type=str, default="cuda", help='Device to use for evaluation') - parser.add_argument('--checkpoint_path', type=Path, default=Path("/tmp/Meta-Llama-3-8B/model.pth"), help='Model checkpoint path for model.pth.') - parser.add_argument('--repo_id', type=str, default=Path("/tmp/Meta-Llama-3-8B"), help='Model repo id.') - parser.add_argument('--num_PPL_eval_samples', type=int, default=None, help='Number of samples to evaluate ppl') - parser.add_argument('--num_trials', type=int, default=150, help='Number of trials to run BO') - parser.add_argument('--ppl_constraint', type=float, default=7.5, help='The ppl constraint for BO') - parser.add_argument('--multi_gpus', action='store_true', help="Use multi-processing to run evaluation on multi-gpus") - parser.add_argument('--gpu_list', type=str, default="", help="A list of gpus to run evaluation, separated by comma, e.g., --gpu_lists=0,1,2,3") - parser.add_argument('--history_output', type=str, default="BO_acc_speed_output.csv", help="The csv file path to save the BO search trials") - parser.add_argument('--parameters_list', type=str, default="Llama3-8B_parameters.json", help="The json file path to save the parameters list for BO") - parser.add_argument('--initial_samples', type=str, default="Llama3-8B_initial_samples.json", help="The json file path to save the user-defined initial samples for BO") + + parser = argparse.ArgumentParser( + description="Bayesian optimization for mixed-precision quantization to optimize inference speed under model accuracy constraint." + ) + + parser.add_argument( + "--device", type=str, default="cuda", help="Device to use for evaluation" + ) + parser.add_argument( + "--checkpoint_path", + type=Path, + default=Path("/tmp/Meta-Llama-3-8B/model.pth"), + help="Model checkpoint path for model.pth.", + ) + parser.add_argument( + "--repo_id", + type=str, + default=Path("/tmp/Meta-Llama-3-8B"), + help="Model repo id.", + ) + parser.add_argument( + "--num_PPL_eval_samples", + type=int, + default=None, + help="Number of samples to evaluate ppl", + ) + parser.add_argument( + "--num_trials", type=int, default=150, help="Number of trials to run BO" + ) + parser.add_argument( + "--ppl_constraint", type=float, default=7.5, help="The ppl constraint for BO" + ) + parser.add_argument( + "--multi_gpus", + action="store_true", + help="Use multi-processing to run evaluation on multi-gpus", + ) + parser.add_argument( + "--gpu_list", + type=str, + default="", + help="A list of gpus to run evaluation, separated by comma, e.g., --gpu_lists=0,1,2,3", + ) + parser.add_argument( + "--history_output", + type=str, + default="BO_acc_speed_output.csv", + help="The csv file path to save the BO search trials", + ) + parser.add_argument( + "--parameters_list", + type=str, + default="Llama3-8B_parameters.json", + help="The json file path to save the parameters list for BO", + ) + parser.add_argument( + "--initial_samples", + type=str, + default="Llama3-8B_initial_samples.json", + help="The json file path to save the user-defined initial samples for BO", + ) args = parser.parse_args() - run_sequential_BO(device=args.device, checkpoint_path=args.checkpoint_path, repo_id=args.repo_id, num_PPL_eval_samples=args.num_PPL_eval_samples, num_trials=args.num_trials, ppl_constraint=args.ppl_constraint, args=args) + run_sequential_BO( + device=args.device, + checkpoint_path=args.checkpoint_path, + repo_id=args.repo_id, + num_PPL_eval_samples=args.num_PPL_eval_samples, + num_trials=args.num_trials, + ppl_constraint=args.ppl_constraint, + args=args, + ) diff --git a/torchao/prototype/quantization/mixed_precision/scripts/__init__.py b/torchao/prototype/quantization/mixed_precision/scripts/__init__.py index 1b0cae6ab..d4e7e5aca 100644 --- a/torchao/prototype/quantization/mixed_precision/scripts/__init__.py +++ b/torchao/prototype/quantization/mixed_precision/scripts/__init__.py @@ -1 +1,5 @@ from .naive_intNwo import intN_weight_only + +__all__ = [ + "intN_weight_only", +] diff --git a/torchao/prototype/quantization/mixed_precision/scripts/fit.py b/torchao/prototype/quantization/mixed_precision/scripts/fit.py index db77878a9..0765b9324 100644 --- a/torchao/prototype/quantization/mixed_precision/scripts/fit.py +++ b/torchao/prototype/quantization/mixed_precision/scripts/fit.py @@ -1,11 +1,11 @@ -import torch +import random + import numpy as np -import os -from tqdm import tqdm +import torch import transformers from datasets import load_dataset -import random -from torch.nn.attention import SDPBackend, sdpa_kernel +from tqdm import tqdm + def get_wikitext2(nsamples, seed, seqlen, tokenizer): traindata = load_dataset("Salesforce/wikitext", "wikitext-2-raw-v1", split="train") @@ -13,7 +13,7 @@ def get_wikitext2(nsamples, seed, seqlen, tokenizer): trainenc = tokenizer("\n\n".join(traindata["text"]), return_tensors="pt") testenc = tokenizer("\n\n".join(testdata["text"]), return_tensors="pt") - + random.seed(seed) trainloader = [] for _ in range(nsamples): @@ -25,19 +25,18 @@ def get_wikitext2(nsamples, seed, seqlen, tokenizer): trainloader.append((inp, tar)) return trainloader, testenc + def cal_FIT(device, data, nsamples, model, max_iter, max_seqlen, criterion, num_layers): - # store the history of trace for each layer - estimated_history=[] + estimated_history = [] # store the history of mean trace for each layer estimated_mean = [[] for _ in range(num_layers)] - trace = [0.] * num_layers - + trace = [0.0] * num_layers for iteration in range(max_iter): - print("iteration: ",iteration) - trace_tmp = [0.] * num_layers + print("iteration: ", iteration) + trace_tmp = [0.0] * num_layers for i in tqdm(range(nsamples)): inputs, targets = data[i] @@ -47,13 +46,15 @@ def cal_FIT(device, data, nsamples, model, max_iter, max_seqlen, criterion, num_ outputs = model(inputs) logits = outputs.logits loss = criterion(logits.view(-1, logits.size(-1)), targets.view(-1)) - + grads = torch.autograd.grad(loss, model.parameters()) - # Trace(Fisher Information Matrix) is calculated by the sum of the square of the gradient + # Trace(Fisher Information Matrix) is calculated by the sum of the square of the gradient for layerid in range(num_layers): for (name, _), grad in zip(model.named_parameters(), grads): - if "."+str(layerid)+"." in name and ("self_attn" in name or "mlp" in name): + if "." + str(layerid) + "." in name and ( + "self_attn" in name or "mlp" in name + ): trace_tmp[layerid] += torch.sum(grad * grad).item() # clean cache @@ -66,17 +67,20 @@ def cal_FIT(device, data, nsamples, model, max_iter, max_seqlen, criterion, num_ trace[t] = trace_tmp[t] / float(nsamples) estimated_mean[t].append(trace[t]) - print("trace:",trace) + print("trace:", trace) estimated_history.append(trace) F_average = np.array([np.mean(i) for i in estimated_mean]) return F_average, estimated_mean, estimated_history + def main(max_seqlen, checkpoint, nsamples, max_iter, num_layers): - device = 'cuda' if torch.cuda.is_available() else 'cpu' - + device = "cuda" if torch.cuda.is_available() else "cpu" + # have been tested models Llama-3-8B, Llama-2-7B, Mistral-7B, and stories110M - model = transformers.AutoModelForCausalLM.from_pretrained(checkpoint, torch_dtype=torch.bfloat16) + model = transformers.AutoModelForCausalLM.from_pretrained( + checkpoint, torch_dtype=torch.bfloat16 + ) tokenizer = transformers.AutoTokenizer.from_pretrained(checkpoint) model = model.to(device) model.eval() @@ -87,19 +91,56 @@ def main(max_seqlen, checkpoint, nsamples, max_iter, num_layers): seed = 0 trainloader, testloader = get_wikitext2(nsamples, seed, max_seqlen, tokenizer) - F_average, estimated_mean, estimated_history = cal_FIT(device=device, data=trainloader, nsamples=nsamples, model=model, max_iter=max_iter, max_seqlen=max_seqlen, criterion=criterion, num_layers=num_layers) + F_average, estimated_mean, estimated_history = cal_FIT( + device=device, + data=trainloader, + nsamples=nsamples, + model=model, + max_iter=max_iter, + max_seqlen=max_seqlen, + criterion=criterion, + num_layers=num_layers, + ) print("Iteration Done") - print("FIT scores for",num_layers,"layers:\n", F_average) + print("FIT scores for", num_layers, "layers:\n", F_average) print("estimated_mean:", estimated_mean) print("estimated_history:", estimated_history) -if __name__ == '__main__': + +if __name__ == "__main__": import argparse - parser = argparse.ArgumentParser(description='Calculate layer-wised fish information matrix trace.') - parser.add_argument('--checkpoint', type=str, default="/tmp/Meta-Llama-3-8B", help='Path to load model') - parser.add_argument('--max_seqlen', type=int, default=2048, help='Max sequence length') - parser.add_argument('--max_iter', type=int, default=100, help='The number of iterations to calculate FIT') - parser.add_argument('--num_layers', type=int, default=32, help='The number of layers to calculate FIT.') - parser.add_argument('--nsamples', type=int, default=128, help='The number of samples in calibration dataset') + + parser = argparse.ArgumentParser( + description="Calculate layer-wised fish information matrix trace." + ) + parser.add_argument( + "--checkpoint", + type=str, + default="/tmp/Meta-Llama-3-8B", + help="Path to load model", + ) + parser.add_argument( + "--max_seqlen", type=int, default=2048, help="Max sequence length" + ) + parser.add_argument( + "--max_iter", + type=int, + default=100, + help="The number of iterations to calculate FIT", + ) + parser.add_argument( + "--num_layers", + type=int, + default=32, + help="The number of layers to calculate FIT.", + ) + parser.add_argument( + "--nsamples", + type=int, + default=128, + help="The number of samples in calibration dataset", + ) args = parser.parse_args() - main(args.max_seqlen, args.checkpoint, args.nsamples, args.max_iter, args.num_layers) + main( + args.max_seqlen, args.checkpoint, args.nsamples, args.max_iter, args.num_layers + ) diff --git a/torchao/prototype/quantization/mixed_precision/scripts/hessian_grad.py b/torchao/prototype/quantization/mixed_precision/scripts/hessian_grad.py index 1a4998d78..750947eaf 100644 --- a/torchao/prototype/quantization/mixed_precision/scripts/hessian_grad.py +++ b/torchao/prototype/quantization/mixed_precision/scripts/hessian_grad.py @@ -1,16 +1,17 @@ -import torch +import random + import numpy as np -import os -from tqdm import tqdm +import torch import transformers from datasets import load_dataset -import random from torch.nn.attention import SDPBackend, sdpa_kernel -from torch.autograd.functional import hvp +from tqdm import tqdm + def group_product(xs, ys): return [torch.sum(x * y) for (x, y) in zip(xs, ys)] + def get_wikitext2(nsamples, seed, seqlen, tokenizer): traindata = load_dataset("Salesforce/wikitext", "wikitext-2-raw-v1", split="train") testdata = load_dataset("Salesforce/wikitext", "wikitext-2-raw-v1", split="test") @@ -29,10 +30,13 @@ def get_wikitext2(nsamples, seed, seqlen, tokenizer): trainloader.append((inp, tar)) return trainloader, testenc.input_ids -def dataloader_hv_product(layerid, params, device, v, data, nsamples, model, max_seqlen, criterion): + +def dataloader_hv_product( + layerid, params, device, v, data, nsamples, model, max_seqlen, criterion +): model.zero_grad() THv = [torch.zeros(p.size()).to(device) for p in params] # accumulate result - + # Freeze all the parameters in the model for param in model.parameters(): param.requires_grad = False @@ -43,7 +47,7 @@ def dataloader_hv_product(layerid, params, device, v, data, nsamples, model, max param.requires_grad = True for param in layer_.mlp.parameters(): param.requires_grad = True - + for i in tqdm(range(nsamples)): torch.cuda.empty_cache() inputs, labels = data[i] @@ -56,48 +60,52 @@ def dataloader_hv_product(layerid, params, device, v, data, nsamples, model, max outputs = model(inputs) logits = outputs.logits loss = criterion(logits.view(-1, logits.size(-1)), labels.view(-1)) - + # get the first order gradients grads = torch.autograd.grad(loss, params, create_graph=True, only_inputs=True) - + # calculate Hessian vector product via Jac-vector product - Hv = torch.autograd.grad(grads, params, grad_outputs=v, only_inputs=True, retain_graph=False) + Hv = torch.autograd.grad( + grads, params, grad_outputs=v, only_inputs=True, retain_graph=False + ) THv = [THv1 + Hv1 + 0.0 for THv1, Hv1 in zip(THv, Hv)] # clean cache - model.zero_grad() + model.zero_grad() del Hv - del grads + del grads torch.cuda.empty_cache() - + THv = [THv1 / float(nsamples) for THv1 in THv] return THv -def cal_trace(layerid, params, device, data, nsamples, model, max_iter, max_seqlen, criterion): + +def cal_trace( + layerid, params, device, data, nsamples, model, max_iter, max_seqlen, criterion +): vhv_c_history = [] trace_history = [] - trace = 0. + trace = 0.0 for i in range(max_iter): - print("iteration: ",i) + print("iteration: ", i) # generate Rademacher random variables - v = [ - torch.randint_like(p, high=2, device=device) - for p in params - ] - + v = [torch.randint_like(p, high=2, device=device) for p in params] + for v_i in v: v_i[v_i == 0] = -1 # calculate Hessian vector product - Hv = dataloader_hv_product(layerid, params, device, v, data, nsamples, model, max_seqlen, criterion) + Hv = dataloader_hv_product( + layerid, params, device, v, data, nsamples, model, max_seqlen, criterion + ) vHv = group_product(Hv, v) - + vHv_c = np.array([i.cpu().numpy() for i in vHv]) - + vhv_c_history.append(vHv_c) trace = np.sum(vHv_c) @@ -111,13 +119,14 @@ def cal_trace(layerid, params, device, data, nsamples, model, max_iter, max_seql def main(layer_id, checkpoint, max_seqlen, max_iter, nsamples): - device = 'cuda' if torch.cuda.is_available() else 'cpu' + device = "cuda" if torch.cuda.is_available() else "cpu" # to avoid aten::_scaled_dot_product_flash_attention_backward not implemented error with sdpa_kernel(SDPBackend.MATH): - # have been tested models Llama-3-8B, Llama-2-7B, Mistral-7B, and stories110M - model = transformers.AutoModelForCausalLM.from_pretrained(checkpoint, torch_dtype=torch.bfloat16) + model = transformers.AutoModelForCausalLM.from_pretrained( + checkpoint, torch_dtype=torch.bfloat16 + ) tokenizer = transformers.AutoTokenizer.from_pretrained(checkpoint) model = model.cuda() model.eval() @@ -129,23 +138,59 @@ def main(layer_id, checkpoint, max_seqlen, max_iter, nsamples): trainloader, testloader = get_wikitext2(128, seed, 2048, tokenizer) # calculate Hessian for only one layer each time - params=[] + params = [] layer_ = model.model.layers[layer_id] for param in layer_.self_attn.parameters(): params.append(param) for param in layer_.mlp.parameters(): params.append(param) - trace = cal_trace(layerid=layer_id, params=params, device=device, data=trainloader, nsamples=nsamples, model=model, max_iter=max_iter, max_seqlen=max_seqlen, criterion=criterion) + trace = cal_trace( + layerid=layer_id, + params=params, + device=device, + data=trainloader, + nsamples=nsamples, + model=model, + max_iter=max_iter, + max_seqlen=max_seqlen, + criterion=criterion, + ) print("The trace of layer " + str(layer_id) + " is", trace) -if __name__ == '__main__': + +if __name__ == "__main__": import argparse - parser = argparse.ArgumentParser(description='Calculate layer-wised Hessian trace leveraging autograd.') - parser.add_argument('--layer_id', type=int, default=0, help='Which layer to compute the trace and hessian') - parser.add_argument('--checkpoint', type=str, default="/tmp/Meta-Llama-3-8B", help='Path to load model') - parser.add_argument('--max_seqlen', type=int, default=2048, help='Max sequence length') - parser.add_argument('--max_iter', type=int, default=100, help='The number of iterations to calculate Hessian trace') - parser.add_argument('--nsamples', type=int, default=128, help='The number of samples in calibration dataset') + + parser = argparse.ArgumentParser( + description="Calculate layer-wised Hessian trace leveraging autograd." + ) + parser.add_argument( + "--layer_id", + type=int, + default=0, + help="Which layer to compute the trace and hessian", + ) + parser.add_argument( + "--checkpoint", + type=str, + default="/tmp/Meta-Llama-3-8B", + help="Path to load model", + ) + parser.add_argument( + "--max_seqlen", type=int, default=2048, help="Max sequence length" + ) + parser.add_argument( + "--max_iter", + type=int, + default=100, + help="The number of iterations to calculate Hessian trace", + ) + parser.add_argument( + "--nsamples", + type=int, + default=128, + help="The number of samples in calibration dataset", + ) args = parser.parse_args() main(args.layer_id, args.checkpoint, args.max_seqlen, args.max_iter, args.nsamples) diff --git a/torchao/prototype/quantization/mixed_precision/scripts/hessian_vhp.py b/torchao/prototype/quantization/mixed_precision/scripts/hessian_vhp.py index 9eef9cdad..cb4f202cf 100644 --- a/torchao/prototype/quantization/mixed_precision/scripts/hessian_vhp.py +++ b/torchao/prototype/quantization/mixed_precision/scripts/hessian_vhp.py @@ -1,18 +1,18 @@ -import torch -import torchvision.models as models +import random + import numpy as np -import os -from tqdm import tqdm +import torch import transformers from datasets import load_dataset -import random +from torch.autograd.functional import vhp from torch.nn.attention import SDPBackend, sdpa_kernel -from torch.autograd.functional import hvp, vhp +from tqdm import tqdm def group_product(xs, ys): return [torch.sum(x * y) for (x, y) in zip(xs, ys)] + def get_wikitext2(nsamples, seed, seqlen, tokenizer): traindata = load_dataset("Salesforce/wikitext", "wikitext-2-raw-v1", split="train") testdata = load_dataset("Salesforce/wikitext", "wikitext-2-raw-v1", split="test") @@ -31,6 +31,7 @@ def get_wikitext2(nsamples, seed, seqlen, tokenizer): trainloader.append((inp, tar)) return trainloader, testenc.input_ids + # utilities to make nn.Module functional def del_attr(obj, names): if len(names) == 1: @@ -38,21 +39,25 @@ def del_attr(obj, names): else: del_attr(getattr(obj, names[0]), names[1:]) + def set_attr(obj, names, val): if len(names) == 1: setattr(obj, names[0], val) else: set_attr(getattr(obj, names[0]), names[1:], val) + def make_functional(mod, layer_id): orig_params = tuple(mod.parameters()) # remove all the parameters in the model - selected_params=[] - selected_params_names=[] + selected_params = [] + selected_params_names = [] names = [] for name, p in list(mod.named_parameters()): - if name.startswith("model.layers."+str(layer_id)+".self_attn.") or name.startswith("model.layers."+str(layer_id)+".mlp."): + if name.startswith( + "model.layers." + str(layer_id) + ".self_attn." + ) or name.startswith("model.layers." + str(layer_id) + ".mlp."): selected_params.append(p) selected_params_names.append(name) del_attr(mod, name.split(".")) @@ -60,14 +65,14 @@ def make_functional(mod, layer_id): return orig_params, names, selected_params, selected_params_names - def main(layer_id, checkpoint, max_seqlen, max_iter, nsamples): - # use the functional model to load the weights back def load_weights(mod, names, params, selected_params, selected_params_names): for name, p in zip(names, params): - if name.startswith("model.layers."+str(layer_id)+".self_attn.") or name.startswith("model.layers."+str(layer_id)+".mlp."): - idx=selected_params_names.index(name) + if name.startswith( + "model.layers." + str(layer_id) + ".self_attn." + ) or name.startswith("model.layers." + str(layer_id) + ".mlp."): + idx = selected_params_names.index(name) set_attr(mod, name.split("."), selected_params[idx]) else: set_attr(mod, name.split("."), p) @@ -88,9 +93,10 @@ def f(*new_params): # to avoid aten::_scaled_dot_product_flash_attention_backward not implemented error with sdpa_kernel(SDPBackend.MATH): - # have been tested models Llama-3-8B, Llama-2-7B, Mistral-7B, and stories110M - model = transformers.AutoModelForCausalLM.from_pretrained(checkpoint, torch_dtype=torch.bfloat16) + model = transformers.AutoModelForCausalLM.from_pretrained( + checkpoint, torch_dtype=torch.bfloat16 + ) tokenizer = transformers.AutoTokenizer.from_pretrained(checkpoint) model = model.to(device) model.eval() @@ -98,24 +104,26 @@ def f(*new_params): criterion = torch.nn.CrossEntropyLoss() # load calibration dataset - seed = 0 - trainloader, testloader = get_wikitext2(128, 0, 2048, tokenizer) + trainloader, _ = get_wikitext2(128, 0, 2048, tokenizer) # make the model functional - params, names, selected_params, selected_params_names = make_functional(model, layer_id) + params, names, selected_params, selected_params_names = make_functional( + model, layer_id + ) # make params regular Tensors instead of nn.Parameter params = tuple(p.detach() for p in params) # set requires_grad to True for the selected parameters - selected_params_tuple = tuple(p.detach().requires_grad_() for p in selected_params) + selected_params_tuple = tuple( + p.detach().requires_grad_() for p in selected_params + ) trace_history = [] - vhv_c_history=[] + vhv_c_history = [] for iteration in range(max_iter): - - print("iteration: ",iteration) + print("iteration: ", iteration) # generate Rademacher random variables v = [torch.randint_like(p, high=2) for p in selected_params_tuple] @@ -133,11 +141,12 @@ def f(*new_params): # get vector-Hessian product _, vH = vhp(f, selected_params_tuple, tuple(v)) - if i==0: - TvH = [torch.zeros(p.size()).to(device) for p in selected_params_tuple] + if i == 0: + TvH = [ + torch.zeros(p.size()).to(device) for p in selected_params_tuple + ] TvH = [TvH1 + vH1 + 0.0 for TvH1, vH1 in zip(TvH, vH)] - TvH = [TvH1 / float(nsamples) for TvH1 in TvH] # get vHv vHv = group_product(TvH, v) @@ -152,14 +161,39 @@ def f(*new_params): print("trace_history,", trace_history) -if __name__ == '__main__': +if __name__ == "__main__": import argparse - parser = argparse.ArgumentParser(description="Calculate layer-wised Hessian trace leveraging torch's vhp function.") + + parser = argparse.ArgumentParser( + description="Calculate layer-wised Hessian trace leveraging torch's vhp function." + ) # TODO: make it a for loop for all the layer_ids to automatically calculate the Hessian trace for all the layers of a model - parser.add_argument('--layer_id', type=int, default=0, help='Which layer to compute the Hessian trace') - parser.add_argument('--checkpoint', type=str, default="/tmp/Meta-Llama-3-8B", help='Path to load model') - parser.add_argument('--max_seqlen', type=int, default=2048, help='Max sequence length') - parser.add_argument('--max_iter', type=int, default=100, help='The number of iterations to calculate Hessian trace') - parser.add_argument('--nsamples', type=int, default=128, help='The number of samples in calibration dataset') + parser.add_argument( + "--layer_id", + type=int, + default=0, + help="Which layer to compute the Hessian trace", + ) + parser.add_argument( + "--checkpoint", + type=str, + default="/tmp/Meta-Llama-3-8B", + help="Path to load model", + ) + parser.add_argument( + "--max_seqlen", type=int, default=2048, help="Max sequence length" + ) + parser.add_argument( + "--max_iter", + type=int, + default=100, + help="The number of iterations to calculate Hessian trace", + ) + parser.add_argument( + "--nsamples", + type=int, + default=128, + help="The number of samples in calibration dataset", + ) args = parser.parse_args() main(args.layer_id, args.checkpoint, args.max_seqlen, args.max_iter, args.nsamples) diff --git a/torchao/prototype/quantization/mixed_precision/scripts/mp_quant_eval.py b/torchao/prototype/quantization/mixed_precision/scripts/mp_quant_eval.py index 852fbd7e4..8d2f4f0b8 100644 --- a/torchao/prototype/quantization/mixed_precision/scripts/mp_quant_eval.py +++ b/torchao/prototype/quantization/mixed_precision/scripts/mp_quant_eval.py @@ -1,95 +1,209 @@ import torch import torch.nn as nn - -from naive_intNwo import intN_weight_only -from transformers import AutoModelForCausalLM, AutoTokenizer - -from lm_eval.models.huggingface import HFLM from lm_eval.evaluator import evaluate +from lm_eval.models.huggingface import HFLM from lm_eval.tasks import get_task_dict +from naive_intNwo import intN_weight_only +from transformers import AutoModelForCausalLM, AutoTokenizer -from torchao.quantization import quantize_, int8_weight_only, int4_weight_only, int8_dynamic_activation_int4_weight -from torchao._models._eval import TransformerEvalWrapper - -from torchao.quantization.quant_primitives import ( - MappingType, - ZeroPointDomain, +from torchao.quantization import ( + quantize_, ) - from torchao.quantization.quant_api import autoquant - torch._inductor.config.force_fuse_int_mm_with_mul = True torch._inductor.config.fx_graph_cache = True -def run_evaluation(repo_id, tasks, limit, device, precision, quantization, compile, batch_size, max_length, sensi_bit, non_sensi_bit, quant_sym, group_size): - +def run_evaluation( + repo_id, + tasks, + limit, + device, + precision, + quantization, + compile, + batch_size, + max_length, + sensi_bit, + non_sensi_bit, + quant_sym, + group_size, +): tokenizer = AutoTokenizer.from_pretrained(repo_id) - model = AutoModelForCausalLM.from_pretrained(repo_id).to(device="cpu", dtype=precision) + model = AutoModelForCausalLM.from_pretrained(repo_id).to( + device="cpu", dtype=precision + ) if quantization == "autoquant": model = autoquant(model.to(device=device)) - - # naive implementation of uniform precision quantization all layers - elif quantization in ["2","3","4","5","6","8"]: - quantize_(model.to(device=device), intN_weight_only(n=int(quantization), group_size=group_size, symmetric=quant_sym)) - - # mix precision quantization for Llama3 + + # naive implementation of uniform precision quantization all layers + elif quantization in ["2", "3", "4", "5", "6", "8"]: + quantize_( + model.to(device=device), + intN_weight_only( + n=int(quantization), group_size=group_size, symmetric=quant_sym + ), + ) + + # mix precision quantization for Llama3 elif quantization == "MP_llama3": - # filter for sensitive layers (the first 3 and last 2 layers for Llama3) - def filter_fn_sen(child: torch.nn.Module, cur_fqn:str) -> bool: - return isinstance(child, nn.Linear) and any(skiplayer in cur_fqn for skiplayer in ['.0.', '.1.', '.2.', '.30.', '.31.']) - + def filter_fn_sen(child: torch.nn.Module, cur_fqn: str) -> bool: + return isinstance(child, nn.Linear) and any( + skiplayer in cur_fqn + for skiplayer in [".0.", ".1.", ".2.", ".30.", ".31."] + ) + # filter for non-sensitive layers (other 27 layers for Llama3) - def filter_fn_nonsen(child: torch.nn.Module, cur_fqn:str) -> bool: - return isinstance(child, nn.Linear) and not(any(skiplayer in cur_fqn for skiplayer in ['.0.', '.1.', '.2.', '.30.', '.31.'])) - + def filter_fn_nonsen(child: torch.nn.Module, cur_fqn: str) -> bool: + return isinstance(child, nn.Linear) and not ( + any( + skiplayer in cur_fqn + for skiplayer in [".0.", ".1.", ".2.", ".30.", ".31."] + ) + ) + # quantize the sensitive layers if sensi_bit != 16: - quantize_(model.to(device=device), intN_weight_only(n=sensi_bit, group_size=group_size, symmetric=quant_sym), filter_fn_sen) + quantize_( + model.to(device=device), + intN_weight_only( + n=sensi_bit, group_size=group_size, symmetric=quant_sym + ), + filter_fn_sen, + ) # quantize the less-sensitive layers - if sensi_bit == 4: - quantize_(model, intN_weight_only(n=non_sensi_bit, group_size=group_size, symmetric=quant_sym), filter_fn_nonsen) + if sensi_bit == 4: + quantize_( + model, + intN_weight_only( + n=non_sensi_bit, group_size=group_size, symmetric=quant_sym + ), + filter_fn_nonsen, + ) else: - quantize_(model.to(device=device), intN_weight_only(n=non_sensi_bit, group_size=group_size, symmetric=quant_sym), filter_fn_nonsen) - + quantize_( + model.to(device=device), + intN_weight_only( + n=non_sensi_bit, group_size=group_size, symmetric=quant_sym + ), + filter_fn_nonsen, + ) + if compile: model = torch.compile(model, mode="max-autotune", fullgraph=True) with torch.no_grad(): - result = evaluate( HFLM( pretrained=model, - tokenizer=tokenizer, - batch_size=batch_size, - max_length=max_length), + tokenizer=tokenizer, + batch_size=batch_size, + max_length=max_length, + ), get_task_dict(tasks), - limit = limit, + limit=limit, ) for task, res in result["results"].items(): print(f"{task}: {res}") -if __name__ == '__main__': +if __name__ == "__main__": import argparse - parser = argparse.ArgumentParser(description='Run evaluation for uniform or mixed-precision quantization.') - parser.add_argument('--repo_id', type=str, default="checkpoints/meta-llama/Meta-Llama-3-8B", help='Repository ID to download from HF.') - parser.add_argument('--tasks', nargs='+', type=str, default=["wikitext"], help='List of lm-eluther tasks to evaluate usage: --tasks task1 task2') - parser.add_argument('--limit', type=int, default=None, help='Number of eval samples to evaluate') - parser.add_argument('--precision', type=lambda x: getattr(torch, x.split(".")[-1]), default=torch.bfloat16, help='dtype precision to use') - parser.add_argument('--device', type=str, default="cuda", help='Device to use for evaluation') - parser.add_argument('-q', '--quantization', default = "None", choices = ["2", "3", "4", "5", "6", "8", "MP_llama3", "None"], help='Which quantization technique to apply, choose from ["2", "3", "4", "5", "6", "8"] for uniform quantizatoin, choose "MP_llama3" for mixed-precision for Llama3 and need to set corresponding sensi_bit and non_sensi_bit, choose "None" for no quantization') - parser.add_argument('--compile', action='store_true', help='Whether to compile the model.') - parser.add_argument('--batch_size', type=int, default=1, help='Batch size to use for evaluation, note int8wo and int4wo work best with small batchsizes, int8dq works better with large batchsizes') - parser.add_argument('--max_length', type=int, default=None, help='Length of text to process at one time') - parser.add_argument('--sensi_bit', type=int, default=16, choices = [16, 8, 6, 5, 4, 3], help='Bit setting for sensitive layers') - parser.add_argument('--non_sensi_bit', type=int, default=8, choices = [8, 6, 5, 4, 3, 2], help='Bit setting for non-sensitive layers') - parser.add_argument('--quant_sym', type=bool, default=False, help='Symmetric or asymmetric quantization, asymmetric by default') - parser.add_argument('--group_size', type=int, default=32, help='Group size to perform quantization on') + + parser = argparse.ArgumentParser( + description="Run evaluation for uniform or mixed-precision quantization." + ) + parser.add_argument( + "--repo_id", + type=str, + default="checkpoints/meta-llama/Meta-Llama-3-8B", + help="Repository ID to download from HF.", + ) + parser.add_argument( + "--tasks", + nargs="+", + type=str, + default=["wikitext"], + help="List of lm-eluther tasks to evaluate usage: --tasks task1 task2", + ) + parser.add_argument( + "--limit", type=int, default=None, help="Number of eval samples to evaluate" + ) + parser.add_argument( + "--precision", + type=lambda x: getattr(torch, x.split(".")[-1]), + default=torch.bfloat16, + help="dtype precision to use", + ) + parser.add_argument( + "--device", type=str, default="cuda", help="Device to use for evaluation" + ) + parser.add_argument( + "-q", + "--quantization", + default="None", + choices=["2", "3", "4", "5", "6", "8", "MP_llama3", "None"], + help='Which quantization technique to apply, choose from ["2", "3", "4", "5", "6", "8"] for uniform quantizatoin, choose "MP_llama3" for mixed-precision for Llama3 and need to set corresponding sensi_bit and non_sensi_bit, choose "None" for no quantization', + ) + parser.add_argument( + "--compile", action="store_true", help="Whether to compile the model." + ) + parser.add_argument( + "--batch_size", + type=int, + default=1, + help="Batch size to use for evaluation, note int8wo and int4wo work best with small batchsizes, int8dq works better with large batchsizes", + ) + parser.add_argument( + "--max_length", + type=int, + default=None, + help="Length of text to process at one time", + ) + parser.add_argument( + "--sensi_bit", + type=int, + default=16, + choices=[16, 8, 6, 5, 4, 3], + help="Bit setting for sensitive layers", + ) + parser.add_argument( + "--non_sensi_bit", + type=int, + default=8, + choices=[8, 6, 5, 4, 3, 2], + help="Bit setting for non-sensitive layers", + ) + parser.add_argument( + "--quant_sym", + type=bool, + default=False, + help="Symmetric or asymmetric quantization, asymmetric by default", + ) + parser.add_argument( + "--group_size", + type=int, + default=32, + help="Group size to perform quantization on", + ) args = parser.parse_args() - run_evaluation(args.repo_id, args.tasks, args.limit, args.device, args.precision, args.quantization, args.compile, args.batch_size, args.max_length, args.sensi_bit, args.non_sensi_bit, args.quant_sym, args.group_size) + run_evaluation( + args.repo_id, + args.tasks, + args.limit, + args.device, + args.precision, + args.quantization, + args.compile, + args.batch_size, + args.max_length, + args.sensi_bit, + args.non_sensi_bit, + args.quant_sym, + args.group_size, + ) diff --git a/torchao/prototype/quantization/mixed_precision/scripts/naive_intNwo.py b/torchao/prototype/quantization/mixed_precision/scripts/naive_intNwo.py index 363bcb7b9..44680b0fb 100644 --- a/torchao/prototype/quantization/mixed_precision/scripts/naive_intNwo.py +++ b/torchao/prototype/quantization/mixed_precision/scripts/naive_intNwo.py @@ -1,50 +1,68 @@ import torch +from torchao.quantization import int4_weight_only, int8_weight_only +from torchao.quantization.quant_api import _get_linear_subclass_inserter from torchao.quantization.quant_primitives import ( MappingType, - ZeroPointDomain, ) -from torchao.quantization import int8_weight_only, int4_weight_only -from torchao.quantization.quant_api import _get_linear_subclass_inserter def intN_weight_only(group_size=32, n=8, symmetric=False): - ''' - Apply int N-bit weight only quantization to a linear layer. - Args: - `group_size`: parameter for quantization, controls the granularity of quantization, smaller size is more fine grained, choices are [512, 256, 128, 64, 32] - `n`: number of bits to quantize to, choices are [8, 6, 5, 4, 3, 2] - Usage: - from torchao.quantization import quantize_ - quantize_(model, intN_weight_only(n=your_bit_choice, group_size=group_size), optional_filter_func_for_desired_layers_to_quantize) - ''' + """ + Apply int N-bit weight only quantization to a linear layer. + Args: + `group_size`: parameter for quantization, controls the granularity of quantization, smaller size is more fine grained, choices are [512, 256, 128, 64, 32] + `n`: number of bits to quantize to, choices are [8, 6, 5, 4, 3, 2] + Usage: + from torchao.quantization import quantize_ + quantize_(model, intN_weight_only(n=your_bit_choice, group_size=group_size), optional_filter_func_for_desired_layers_to_quantize) + """ + # for asymmetric quantization def apply_intN_weight_only_quant_asym(weight): # avoid circular dependency from torchao.dtypes import to_affine_quantized_intx + mapping_type = MappingType.ASYMMETRIC block_size = (1, group_size) target_dtype = torch.uint8 quant_min = 0 - quant_max = 2**n-1 + quant_max = 2**n - 1 eps = 1e-6 - preserve_zero = True zero_point_dtype = torch.int64 - zero_point_domain = ZeroPointDomain.INT - return to_affine_quantized_intx(weight, mapping_type, block_size, target_dtype, quant_min, quant_max, eps, zero_point_dtype=zero_point_dtype)#, preserve_zero=preserve_zero,zero_point_domain=zero_point_domain) + return to_affine_quantized_intx( + weight, + mapping_type, + block_size, + target_dtype, + quant_min, + quant_max, + eps, + zero_point_dtype=zero_point_dtype, + ) # , preserve_zero=preserve_zero,zero_point_domain=zero_point_domain) # for symmetric quantization def apply_intN_weight_only_quant_sym(weight): # avoid circular dependency from torchao.dtypes import to_affine_quantized_intx + mapping_type = MappingType.SYMMETRIC block_size = (1, group_size) target_dtype = torch.int8 - quant_min = -2**(n-1) - quant_max = 2**(n-1)-1 + quant_min = -(2 ** (n - 1)) + quant_max = 2 ** (n - 1) - 1 eps = 1e-6 zero_point_dtype = torch.int64 - return to_affine_quantized_intx(weight, mapping_type, block_size, target_dtype, quant_min, quant_max, eps=eps, zero_point_dtype=zero_point_dtype) + return to_affine_quantized_intx( + weight, + mapping_type, + block_size, + target_dtype, + quant_min, + quant_max, + eps=eps, + zero_point_dtype=zero_point_dtype, + ) try: assert n in [8, 6, 5, 4, 3, 2], "n must be one of [8, 6, 5, 4, 3, 2]" @@ -57,6 +75,5 @@ def apply_intN_weight_only_quant_sym(weight): return _get_linear_subclass_inserter(apply_intN_weight_only_quant_sym) else: return _get_linear_subclass_inserter(apply_intN_weight_only_quant_asym) - except Exception as e: - raise - + except Exception: + raise diff --git a/torchao/prototype/quantization/mixed_precision/scripts/utils.py b/torchao/prototype/quantization/mixed_precision/scripts/utils.py index 108c2eaff..67ca8c023 100644 --- a/torchao/prototype/quantization/mixed_precision/scripts/utils.py +++ b/torchao/prototype/quantization/mixed_precision/scripts/utils.py @@ -1,36 +1,32 @@ import csv -import sys - -import torch -import torch.nn as nn -from torchao.quantization import quantize_ -import random - -from naive_intNwo import intN_weight_only +import json -import copy +import torch from lm_eval.evaluator import evaluate from lm_eval.models.huggingface import HFLM from lm_eval.tasks import get_task_dict - +from naive_intNwo import intN_weight_only from transformers import AutoModelForCausalLM, AutoTokenizer -import json + +from torchao.quantization import quantize_ + def write_history_to_csv(history, output_file, keyword): - #keyword example: ['cal_PPL', 'cal_throughput', 'config'] - - with open(output_file, mode='w', newline='') as file: + # keyword example: ['cal_PPL', 'cal_throughput', 'config'] + + with open(output_file, mode="w", newline="") as file: writer = csv.writer(file) - + # Write the header row writer.writerow(keyword) - + for eval_results, config in history: obj1 = eval_results[keyword[0]][0] obj2 = eval_results[keyword[1]][0] - + writer.writerow([obj1, obj2, config]) - + + # quantize a model based on a given quantization configuration def quantize_by_fqn_to_config(model, device, fqn_to_config): it = iter(fqn_to_config.items()) @@ -55,16 +51,16 @@ def filter_fn_sen(child: torch.nn.Module, cur_fqn: str) -> bool: # calculate perplexity on wikitext-document, need to support more tasks def cal_wikitext_ppl(model, tokenizer, limit=62): - with torch.no_grad(): result = evaluate( HFLM(pretrained=model, tokenizer=tokenizer, batch_size=1), get_task_dict("wikitext"), - limit=limit + limit=limit, ) return result["results"]["wikitext"]["word_perplexity,none"] + # TODO: make it generalize to more models def cal_model_size(model, fqn_to_config): _sum = 0 @@ -101,26 +97,32 @@ def cal_model_size(model, fqn_to_config): _sum_in_GB = _sum_in_byte / (1024**3) / 1.0 return _sum_in_GB + def load_model(repo_id, device): tokenizer = AutoTokenizer.from_pretrained(repo_id) - model = AutoModelForCausalLM.from_pretrained(repo_id, torch_dtype=torch.bfloat16).to( - device=device - ) + model = AutoModelForCausalLM.from_pretrained( + repo_id, torch_dtype=torch.bfloat16 + ).to(device=device) return model, tokenizer - def load_parameters_from_json(json_path): with open(json_path, "r") as f: config = json.load(f) - - bitwidth_config = next(param for param in config["parameters"] if param["name"] == "bitwidth") - groupsize_config = next(param for param in config["parameters"] if param["name"] == "groupsize") - + + bitwidth_config = next( + param for param in config["parameters"] if param["name"] == "bitwidth" + ) + groupsize_config = next( + param for param in config["parameters"] if param["name"] == "groupsize" + ) + parameters_list = [] - + # Ensure that we are interleaving bitwidth and groupsize for each layer - for bw_layer, gs_layer in zip(bitwidth_config["layers"], groupsize_config["layers"]): + for bw_layer, gs_layer in zip( + bitwidth_config["layers"], groupsize_config["layers"] + ): start, end = bw_layer["range"] for i in range(start, end): # Add bitwidth parameter @@ -136,7 +138,7 @@ def load_parameters_from_json(json_path): elif bw_layer["type"] == "choice": bitwidth_param["values"] = bw_layer["values"] parameters_list.append(bitwidth_param) - + # Add groupsize parameter groupsize_param = { "name": groupsize_config["name_format"].format(i=i), @@ -150,7 +152,7 @@ def load_parameters_from_json(json_path): elif gs_layer["type"] == "choice": groupsize_param["values"] = gs_layer["values"] parameters_list.append(groupsize_param) - + return parameters_list diff --git a/torchao/prototype/quantized_training/__init__.py b/torchao/prototype/quantized_training/__init__.py index f888c00aa..1a9577e21 100644 --- a/torchao/prototype/quantized_training/__init__.py +++ b/torchao/prototype/quantized_training/__init__.py @@ -1,4 +1,8 @@ -from .bitnet import BitNetTrainingLinearWeight, bitnet_training, precompute_bitnet_scale_for_fsdp +from .bitnet import ( + BitNetTrainingLinearWeight, + bitnet_training, + precompute_bitnet_scale_for_fsdp, +) from .int8 import ( Int8QuantizedTrainingLinearWeight, int8_weight_only_quantized_training, @@ -10,3 +14,16 @@ Int8MixedPrecisionTrainingLinearWeight, int8_mixed_precision_training, ) + +__all__ = [ + "BitNetTrainingLinearWeight", + "bitnet_training", + "precompute_bitnet_scale_for_fsdp", + "Int8MixedPrecisionTrainingConfig", + "Int8MixedPrecisionTrainingLinear", + "Int8MixedPrecisionTrainingLinearWeight", + "int8_mixed_precision_training", + "Int8QuantizedTrainingLinearWeight", + "int8_weight_only_quantized_training", + "quantize_int8_rowwise", +] diff --git a/torchao/prototype/quantized_training/bitnet.py b/torchao/prototype/quantized_training/bitnet.py index 6627db22f..10c030ded 100644 --- a/torchao/prototype/quantized_training/bitnet.py +++ b/torchao/prototype/quantized_training/bitnet.py @@ -9,8 +9,8 @@ import torch.nn.functional as F import torch.utils._pytree as pytree from torch import Tensor, nn -from torch.utils._triton import has_triton from torch.distributed._tensor import DTensor +from torch.utils._triton import has_triton from torchao.quantization.quant_api import _get_linear_subclass_inserter from torchao.utils import TorchAOBaseTensor @@ -21,11 +21,12 @@ from .int8_mm import scaled_int8_mm else: - # This is less performant than the explicit hand-written Triton kernel, though things might # change in the future. # Multiplying col_scale first is faster than the other way round. - def scaled_int8_mm(A: Tensor, B: Tensor, row_scale: Tensor, col_scale: Tensor) -> Tensor: + def scaled_int8_mm( + A: Tensor, B: Tensor, row_scale: Tensor, col_scale: Tensor + ) -> Tensor: return torch._int_mm(A, B) * col_scale.view(-1) * row_scale.view(-1, 1) @@ -55,8 +56,14 @@ def __tensor_flatten__(self): return ["_data"], [] @classmethod - def __tensor_unflatten__(cls, tensor_data_dict, tensor_attributes, outer_size=None, outer_stride=None): - return cls(tensor_data_dict["_data"], tensor_data_dict.get("_precomputed_scale", None), *tensor_attributes) + def __tensor_unflatten__( + cls, tensor_data_dict, tensor_attributes, outer_size=None, outer_stride=None + ): + return cls( + tensor_data_dict["_data"], + tensor_data_dict.get("_precomputed_scale", None), + *tensor_attributes, + ) def __repr__(self): return f"{self.__class__.__name__}(data={self._data})" @@ -153,7 +160,8 @@ def precompute_bitnet_scale_for_fsdp(module: nn.Module): bitnet_params = [ p for p in module.parameters() - if isinstance(p, DTensor) and isinstance(p._local_tensor, BitNetTrainingLinearWeight) + if isinstance(p, DTensor) + and isinstance(p._local_tensor, BitNetTrainingLinearWeight) ] if len(bitnet_params) == 0: return @@ -169,7 +177,12 @@ def precompute_bitnet_scale_for_fsdp(module: nn.Module): class _BitNetTrainingLinear(torch.autograd.Function): @staticmethod - def forward(ctx, input: Tensor, weight: BitNetTrainingLinearWeight, bias: Optional[Tensor] = None): + def forward( + ctx, + input: Tensor, + weight: BitNetTrainingLinearWeight, + bias: Optional[Tensor] = None, + ): batch_dims = input.shape[:-1] input = input.view(-1, weight.shape[1]) @@ -186,7 +199,9 @@ def forward(ctx, input: Tensor, weight: BitNetTrainingLinearWeight, bias: Option ctx.save_for_backward(input_i8, row_scale, weight_i8, tensor_scale) # use int8 tensor cores - out = scaled_int8_mm(input_i8.contiguous(), weight_i8.contiguous().T, row_scale, tensor_scale) + out = scaled_int8_mm( + input_i8.contiguous(), weight_i8.contiguous().T, row_scale, tensor_scale + ) out = out.view(*batch_dims, weight.shape[0]) out = out + bias if bias is not None else out @@ -218,7 +233,9 @@ def backward(ctx, grad_output): def bitnet_training(): - return _get_linear_subclass_inserter(BitNetTrainingLinearWeight, allow_requires_grad=True) + return _get_linear_subclass_inserter( + BitNetTrainingLinearWeight, allow_requires_grad=True + ) def _pack_i2_in_i8(x: Tensor): @@ -227,7 +244,9 @@ def _pack_i2_in_i8(x: Tensor): # thus, we have to mask out the 2 least significant bits (right-most) before bit-shift. # e.g. 1111 1111 (value=-1) -> 0000 0011 -> 0011 0000 - x0 = x[:, ::4] << 6 # don't need to mask this number because we shift it to the left-most + x0 = ( + x[:, ::4] << 6 + ) # don't need to mask this number because we shift it to the left-most x1 = (x[:, 1::4] & 0b11) << 4 x2 = (x[:, 2::4] & 0b11) << 2 x3 = x[:, 3::4] & 0b11 @@ -237,7 +256,9 @@ def _pack_i2_in_i8(x: Tensor): def _unpack_i2_in_i8(x: Tensor): # NOTE: this is signed integer, so left-shift then right-shift will perform sign extension correctly # e.g. aa10bbcc -> 10bbcc00 -> 11111110 - return torch.stack([x >> 6, x << 2 >> 6, x << 4 >> 6, x << 6 >> 6], dim=-1).view(x.shape[0], -1) + return torch.stack([x >> 6, x << 2 >> 6, x << 4 >> 6, x << 6 >> 6], dim=-1).view( + x.shape[0], -1 + ) # currently this class mainly serves as a container for quantized FSDP2 all-gather, @@ -266,8 +287,12 @@ def __tensor_flatten__(self): return ["int_data", "scale"], [] @classmethod - def __tensor_unflatten__(cls, tensor_data_dict, tensor_attributes, outer_size=None, outer_stride=None): - return cls(tensor_data_dict["int_data"], tensor_data_dict["scale"], *tensor_attributes) + def __tensor_unflatten__( + cls, tensor_data_dict, tensor_attributes, outer_size=None, outer_stride=None + ): + return cls( + tensor_data_dict["int_data"], tensor_data_dict["scale"], *tensor_attributes + ) def __repr__(self): return f"{self.__class__.__name__}(data={self.dequantize()})" @@ -306,7 +331,12 @@ def _(func, types, args, kwargs): class _BitNetPacked2bitLinear(torch.autograd.Function): @staticmethod - def forward(ctx, input: Tensor, weight: BitNetPacked2bitLinearWeight, bias: Optional[Tensor] = None): + def forward( + ctx, + input: Tensor, + weight: BitNetPacked2bitLinearWeight, + bias: Optional[Tensor] = None, + ): batch_dims = input.shape[:-1] input = input.view(-1, weight.shape[1]) @@ -320,7 +350,9 @@ def forward(ctx, input: Tensor, weight: BitNetPacked2bitLinearWeight, bias: Opti # use int8 tensor cores # NOTE: is doing dequant inside matmul faster when M is large? weight_i8 = _unpack_i2_in_i8(weight_i2) - out = scaled_int8_mm(input_i8.contiguous(), weight_i8.contiguous().T, row_scale, tensor_scale) + out = scaled_int8_mm( + input_i8.contiguous(), weight_i8.contiguous().T, row_scale, tensor_scale + ) out = out.view(*batch_dims, weight.shape[0]) out = out + bias if bias is not None else out diff --git a/torchao/prototype/quantized_training/int8.py b/torchao/prototype/quantized_training/int8.py index e0a07c047..94c5043da 100644 --- a/torchao/prototype/quantized_training/int8.py +++ b/torchao/prototype/quantized_training/int8.py @@ -4,9 +4,8 @@ from torch import Tensor from torch.utils._python_dispatch import return_and_correct_aliasing -from torchao.utils import TorchAOBaseTensor from torchao.quantization.quant_api import _get_linear_subclass_inserter - +from torchao.utils import TorchAOBaseTensor aten = torch.ops.aten c10d_functional = torch.ops.c10d_functional @@ -14,7 +13,9 @@ @torch.no_grad() -def quantize_int8_rowwise(tensor: Tensor, stochastic_rounding: bool = False, eps: float = 1e-12): +def quantize_int8_rowwise( + tensor: Tensor, stochastic_rounding: bool = False, eps: float = 1e-12 +): """Normal rounding will always round down small changes in weight update. To tackle this problem, stochastic rounding can be used, which has a low chance, but not zero, of rounding up. The probability of rounding up is equal to x - ⌊x⌋, which indicates how close the value is to the next @@ -30,7 +31,9 @@ def quantize_int8_rowwise(tensor: Tensor, stochastic_rounding: bool = False, eps # absmax symmetric quantization scale = tensor.abs().amax(1) / 127 # same dtype as tensor inv_scale = 1.0 / scale.float().clip(eps) - tensor = tensor.float() * inv_scale.view(-1, 1) # slightly faster than divide directly + tensor = tensor.float() * inv_scale.view( + -1, 1 + ) # slightly faster than divide directly if stochastic_rounding: tensor = (tensor + torch.rand_like(tensor)).floor() @@ -77,8 +80,12 @@ def __tensor_flatten__(self): return ["int_data", "scale"], [] @classmethod - def __tensor_unflatten__(cls, tensor_data_dict, tensor_attributes, outer_size=None, outer_stride=None): - return cls(tensor_data_dict["int_data"], tensor_data_dict["scale"], *tensor_attributes) + def __tensor_unflatten__( + cls, tensor_data_dict, tensor_attributes, outer_size=None, outer_stride=None + ): + return cls( + tensor_data_dict["int_data"], tensor_data_dict["scale"], *tensor_attributes + ) @classmethod def from_float(cls, tensor: Tensor): @@ -130,7 +137,12 @@ def fsdp_post_all_gather( class _Int8WeightOnlyLinear(torch.autograd.Function): @staticmethod - def forward(ctx, input: Tensor, weight: Int8QuantizedTrainingLinearWeight, bias: Optional[Tensor] = None): + def forward( + ctx, + input: Tensor, + weight: Int8QuantizedTrainingLinearWeight, + bias: Optional[Tensor] = None, + ): ctx.save_for_backward(input, weight) ctx.bias = bias is not None @@ -143,8 +155,12 @@ def forward(ctx, input: Tensor, weight: Int8QuantizedTrainingLinearWeight, bias: def backward(ctx, grad_output): input, weight = ctx.saved_tensors - grad_input = (grad_output * weight.scale) @ weight.int_data.to(grad_output.dtype) - grad_weight = grad_output.view(-1, weight.shape[0]).T @ input.view(-1, weight.shape[1]) + grad_input = (grad_output * weight.scale) @ weight.int_data.to( + grad_output.dtype + ) + grad_weight = grad_output.view(-1, weight.shape[0]).T @ input.view( + -1, weight.shape[1] + ) grad_bias = grad_output.view(-1, weight.shape[0]).sum(0) if ctx.bias else None return grad_input, grad_weight, grad_bias @@ -202,13 +218,18 @@ def _(func, types, args, kwargs): # out-of-place math ops always return plain tensor @implements([aten.sub.Tensor, aten.mul.Tensor]) def _(func, types, args, kwargs): - args = [x.dequantize() if isinstance(x, Int8QuantizedTrainingLinearWeight) else x for x in args] + args = [ + x.dequantize() if isinstance(x, Int8QuantizedTrainingLinearWeight) else x + for x in args + ] return func(*args, **kwargs) @implements(aten.copy_.default) def _(func, types, args, kwargs): - if isinstance(args[0], Int8QuantizedTrainingLinearWeight) and isinstance(args[1], Int8QuantizedTrainingLinearWeight): + if isinstance(args[0], Int8QuantizedTrainingLinearWeight) and isinstance( + args[1], Int8QuantizedTrainingLinearWeight + ): args[0].int_data.copy_(args[1].int_data, **kwargs) args[0].scale.copy_(args[1].scale, **kwargs) @@ -240,7 +261,10 @@ def _(func, types, args, kwargs): int_data_list = func(int8_weight.int_data, *args[1:], **kwargs) scale_list = func(int8_weight.scale, *args[1:], **kwargs) - out = [Int8QuantizedTrainingLinearWeight(int_data, scale) for int_data, scale in zip(int_data_list, scale_list)] + out = [ + Int8QuantizedTrainingLinearWeight(int_data, scale) + for int_data, scale in zip(int_data_list, scale_list) + ] return out @@ -270,4 +294,6 @@ def _(func, types, args, kwargs): def int8_weight_only_quantized_training(): - return _get_linear_subclass_inserter(Int8QuantizedTrainingLinearWeight.from_float, allow_requires_grad=True) + return _get_linear_subclass_inserter( + Int8QuantizedTrainingLinearWeight.from_float, allow_requires_grad=True + ) diff --git a/torchao/prototype/quantized_training/int8_mixed_precision.py b/torchao/prototype/quantized_training/int8_mixed_precision.py index 640057cb0..3e7b20a11 100644 --- a/torchao/prototype/quantized_training/int8_mixed_precision.py +++ b/torchao/prototype/quantized_training/int8_mixed_precision.py @@ -14,11 +14,12 @@ from .int8_mm import scaled_int8_mm else: - # This is less performant than the explicit hand-written Triton kernel, though things might # change in the future. # Multiplying col_scale first is faster than the other way round. - def scaled_int8_mm(A: Tensor, B: Tensor, row_scale: Tensor, col_scale: Tensor) -> Tensor: + def scaled_int8_mm( + A: Tensor, B: Tensor, row_scale: Tensor, col_scale: Tensor + ) -> Tensor: return torch._int_mm(A, B) * col_scale.view(-1) * row_scale.view(-1, 1) @@ -61,7 +62,9 @@ def __tensor_flatten__(self): return ["_data"], [self.config] @classmethod - def __tensor_unflatten__(cls, tensor_data_dict, tensor_attributes, outer_size=None, outer_stride=None): + def __tensor_unflatten__( + cls, tensor_data_dict, tensor_attributes, outer_size=None, outer_stride=None + ): return cls(tensor_data_dict["_data"], *tensor_attributes) def __repr__(self): @@ -155,12 +158,16 @@ def _(func, types, args, kwargs): class Int8MixedPrecisionTrainingLinear(nn.Linear): - def __init__(self, *args, config: Int8MixedPrecisionTrainingConfig, **kwargs) -> None: + def __init__( + self, *args, config: Int8MixedPrecisionTrainingConfig, **kwargs + ) -> None: super().__init__(*args, **kwargs) self.config = config def forward(self, input: Tensor) -> Tensor: - return _Int8MixedPrecisionTrainingLinearFunction.apply(input, self.weight, self.bias, self.config) + return _Int8MixedPrecisionTrainingLinearFunction.apply( + input, self.weight, self.bias, self.config + ) def _dynamic_int8_mm(A: Tensor, B: Tensor) -> Tensor: @@ -246,7 +253,9 @@ def backward(ctx, grad_output): input = input.view(-1, weight.shape[1]) if ctx.config.grad_weight: # grad_weight = _dynamic_int8_mm(grad_output.T, input) - grad_weight = _dynamic_int8_mm(input.T, grad_output).T # this is slightly faster + grad_weight = _dynamic_int8_mm( + input.T, grad_output + ).T # this is slightly faster else: grad_weight = grad_output.T @ input diff --git a/torchao/prototype/quantized_training/int8_mm.py b/torchao/prototype/quantized_training/int8_mm.py index 74d3027da..7de6620d6 100644 --- a/torchao/prototype/quantized_training/int8_mm.py +++ b/torchao/prototype/quantized_training/int8_mm.py @@ -44,7 +44,11 @@ ] configs = [ - triton.Config(dict(BLOCK_M=BLOCK_M, BLOCK_N=BLOCK_N, BLOCK_K=BLOCK_K), num_stages=num_stages, num_warps=num_warps) + triton.Config( + dict(BLOCK_M=BLOCK_M, BLOCK_N=BLOCK_N, BLOCK_K=BLOCK_K), + num_stages=num_stages, + num_warps=num_warps, + ) for BLOCK_M, BLOCK_N, BLOCK_K, num_stages, num_warps in configs ] @@ -125,10 +129,14 @@ def _scaled_int8_mm_kernel( tl.store(C_ptr + tl.broadcast_to(xindex, mask.shape), acc, mask) -lib.define("scaled_int8_mm(Tensor A, Tensor B, Tensor A_scale, Tensor B_scale) -> Tensor") +lib.define( + "scaled_int8_mm(Tensor A, Tensor B, Tensor A_scale, Tensor B_scale) -> Tensor" +) -def scaled_int8_mm(A: Tensor, B: Tensor, row_scale: Tensor, col_scale: Tensor) -> Tensor: +def scaled_int8_mm( + A: Tensor, B: Tensor, row_scale: Tensor, col_scale: Tensor +) -> Tensor: """Compute `(A @ B) * row_scale * col_scale`, where `A` and `B` are INT8 to utilize INT8 tensor cores. `col_scale` can be a scalar. """ @@ -152,7 +160,10 @@ def scaled_int8_mm_cuda(A: Tensor, B: Tensor, row_scale: Tensor, col_scale: Tens M, K = A.shape _, N = B.shape C = torch.empty(M, N, device=A.device, dtype=row_scale.dtype) - grid = lambda meta: (triton.cdiv(meta["M"], meta["BLOCK_M"]) * triton.cdiv(meta["N"], meta["BLOCK_N"]),) + grid = lambda meta: ( + triton.cdiv(meta["M"], meta["BLOCK_M"]) + * triton.cdiv(meta["N"], meta["BLOCK_N"]), + ) _scaled_int8_mm_kernel[grid]( A, B, diff --git a/torchao/prototype/smoothquant/__init__.py b/torchao/prototype/smoothquant/__init__.py index d1626638a..d31da9b5f 100644 --- a/torchao/prototype/smoothquant/__init__.py +++ b/torchao/prototype/smoothquant/__init__.py @@ -1,7 +1,15 @@ from .api import ( insert_smooth_quant_observer_, - smooth_quant, - save_smooth_quant_recipe, load_smooth_quant_recipe, + save_smooth_quant_recipe, + smooth_quant, ) from .core import SmoothQuantObservedLinear + +__all__ = [ + "insert_smooth_quant_observer_", + "load_smooth_quant_recipe", + "save_smooth_quant_recipe", + "smooth_quant", + "SmoothQuantObservedLinear", +] diff --git a/torchao/prototype/smoothquant/api.py b/torchao/prototype/smoothquant/api.py index 7876c90ff..1354a4be3 100644 --- a/torchao/prototype/smoothquant/api.py +++ b/torchao/prototype/smoothquant/api.py @@ -1,28 +1,29 @@ +from typing import Dict, Optional + import torch -from torchao.quantization.quant_api import _replace_with_custom_fn_if_matches_filter + from torchao.dtypes import to_affine_quantized_intx, to_affine_quantized_intx_static +from torchao.prototype.smoothquant.core import ( + SmoothQuantObservedLinear, + SmoothQuantObserver, +) from torchao.quantization.linear_activation_quantized_tensor import ( to_linear_activation_quantized, ) from torchao.quantization.linear_activation_scale import ( to_weight_tensor_with_linear_activation_scale_metadata, ) -from torchao.quantization.weight_tensor_linear_activation_quantization import ( - to_weight_tensor_with_linear_activation_quantization_metadata, -) +from torchao.quantization.quant_api import _replace_with_custom_fn_if_matches_filter from torchao.quantization.quant_primitives import MappingType from torchao.quantization.utils import _get_per_token_block_size -from torchao.prototype.smoothquant.core import( - SmoothQuantObserver, - SmoothQuantObservedLinear, +from torchao.quantization.weight_tensor_linear_activation_quantization import ( + to_weight_tensor_with_linear_activation_quantization_metadata, ) -from typing import Dict, Optional def insert_smooth_quant_observer_( - model: torch.nn.Module, - alpha: Optional[float] = 0.5, - quant_mode: str = "dynamic"): + model: torch.nn.Module, alpha: Optional[float] = 0.5, quant_mode: str = "dynamic" +): """ Inserts SmoothQuantObserver into Linear layers of a given model. @@ -45,7 +46,8 @@ def replace_with_observer(layer): quant_mode, quant_min=quant_min, quant_max=quant_max, - eps=eps) + eps=eps, + ) return SmoothQuantObservedLinear.from_float(layer, observer) _replace_with_custom_fn_if_matches_filter(model, replace_with_observer, _is_linear) @@ -58,6 +60,7 @@ def _observed_linear_subclass_inserter(constructor): Args: constructor: the function which applies quantization to the observed linear layer """ + def insert_subclass(observed_linear): # creates the new linear layer using constructor linear = torch.nn.Linear( @@ -65,25 +68,29 @@ def insert_subclass(observed_linear): observed_linear.out_features, observed_linear.bias is not None, device=observed_linear.weight.device, - dtype=observed_linear.weight.dtype + dtype=observed_linear.weight.dtype, + ) + linear.weight = torch.nn.Parameter( + constructor(observed_linear), requires_grad=False ) - linear.weight = torch.nn.Parameter(constructor(observed_linear), requires_grad=False) linear.bias = observed_linear.bias return linear return insert_subclass -def save_smooth_quant_recipe(model: torch.nn.Module, save_path: str) -> Dict[str, torch.Tensor]: +def save_smooth_quant_recipe( + model: torch.nn.Module, save_path: str +) -> Dict[str, torch.Tensor]: """ Save smoothing_factors, act_scales, and wei_scales for each SmoothQuantObservedLinear layer in the model. """ result = {} - def recurse(module: torch.nn.Module, name: str = ''): + def recurse(module: torch.nn.Module, name: str = ""): for child_name, child in module.named_children(): full_name = f"{name}.{child_name}" if name else child_name - + # Apply the analysis function to this layer if isinstance(child, SmoothQuantObservedLinear): smoothing_factor, act_scales, wei_scales = child.obs.calculate_qparams() @@ -99,10 +106,12 @@ def recurse(module: torch.nn.Module, name: str = ''): torch.save(result, save_path) -def load_smooth_quant_recipe(model: torch.nn.Module, recipe_path: str, device=None) -> torch.nn.Module: +def load_smooth_quant_recipe( + model: torch.nn.Module, recipe_path: str, device=None +) -> torch.nn.Module: recipe = torch.load(recipe_path, weights_only=True) - def recurse(module: torch.nn.Module, name: str = ''): + def recurse(module: torch.nn.Module, name: str = ""): if isinstance(module, SmoothQuantObservedLinear): smoothing_factor = recipe.get(name + ".smoothing_factor", None) act_scales = recipe.get(name + ".act_scales", None) @@ -131,20 +140,29 @@ def __init__(self, target_dtype, quant_min=-127): def dynamic_quantize(self, input): return to_affine_quantized_intx( - input, MappingType.SYMMETRIC, _get_per_token_block_size(input), self.target_dtype, self.quant_min + input, + MappingType.SYMMETRIC, + _get_per_token_block_size(input), + self.target_dtype, + self.quant_min, ) def static_quantize(self, input, scale, zero_point): return to_affine_quantized_intx_static( - input, scale, zero_point, list(input.shape), self.target_dtype, self.quant_min + input, + scale, + zero_point, + list(input.shape), + self.target_dtype, + self.quant_min, ) def smooth_quant( - smoothing_factor: Optional[torch.Tensor] = None, - act_scales: Optional[torch.Tensor] = None, - wei_scales: Optional[torch.Tensor] = None - ): + smoothing_factor: Optional[torch.Tensor] = None, + act_scales: Optional[torch.Tensor] = None, + wei_scales: Optional[torch.Tensor] = None, +): """ Quantizes linear layers when passed into quantize_() @@ -176,7 +194,9 @@ def quantize_weight(observed_linear): if x_scale is None: # dynamic quant - qw = to_linear_activation_quantized(qw, _ActQuantizer(target_dtype).dynamic_quantize) + qw = to_linear_activation_quantized( + qw, _ActQuantizer(target_dtype).dynamic_quantize + ) else: # static quant x_zero_point = torch.zeros_like(x_scale, dtype=torch.int64) @@ -184,6 +204,8 @@ def quantize_weight(observed_linear): qw, _ActQuantizer(target_dtype).static_quantize, x_scale, x_zero_point ) - return to_weight_tensor_with_linear_activation_scale_metadata(qw, factor.to(qw.dtype)) + return to_weight_tensor_with_linear_activation_scale_metadata( + qw, factor.to(qw.dtype) + ) return _observed_linear_subclass_inserter(quantize_weight) diff --git a/torchao/prototype/smoothquant/core.py b/torchao/prototype/smoothquant/core.py index cf1873a14..1d7d18aa0 100644 --- a/torchao/prototype/smoothquant/core.py +++ b/torchao/prototype/smoothquant/core.py @@ -1,19 +1,20 @@ from typing import Optional + import torch import torch.nn.functional as F + +from torchao.quantization.observer import AffineQuantizedMinMaxObserver, PerAxis from torchao.quantization.quant_primitives import ( MappingType, ) -from torchao.quantization.observer import ( - AffineQuantizedMinMaxObserver, PerAxis -) class SmoothQuantObserver(torch.nn.Module): - def __init__(self, + def __init__( + self, weight: torch.Tensor, alpha: Optional[float] = 0.5, - quant_mode: str = "static", # or dynamic + quant_mode: str = "static", # or dynamic quant_min: Optional[int] = None, quant_max: Optional[int] = None, eps: Optional[float] = None, @@ -87,7 +88,9 @@ def calculate_qparams(self): if self.alpha is None: # fall back to conventional quantization if alpha is None smoothing_factor = torch.ones_like( - x_abs_max_per_ic, dtype=x_abs_max_per_ic.dtype, device=x_abs_max_per_ic.device + x_abs_max_per_ic, + dtype=x_abs_max_per_ic.dtype, + device=x_abs_max_per_ic.device, ) else: smoothing_factor = torch.pow(x_abs_max_per_ic, self.alpha) / torch.pow( @@ -104,8 +107,12 @@ def calculate_qparams(self): ) min_val_per_tensor = torch.min(act_min_per_ic_new) max_val_per_tensor = torch.max(act_max_per_ic_new) - min_val_neg = torch.min(min_val_per_tensor, torch.zeros_like(min_val_per_tensor)) - max_val_pos = torch.max(max_val_per_tensor, torch.zeros_like(max_val_per_tensor)) + min_val_neg = torch.min( + min_val_per_tensor, torch.zeros_like(min_val_per_tensor) + ) + max_val_pos = torch.max( + max_val_per_tensor, torch.zeros_like(max_val_per_tensor) + ) max_val_pos = torch.max(-min_val_neg, max_val_pos) act_scale = max_val_pos / (float(self.quant_max - self.quant_min) / 2) act_scales = act_scale.to(self.device) @@ -118,13 +125,14 @@ def calculate_qparams(self): class SmoothQuantObservedLinear(torch.nn.Linear): def __init__( - self, - in_features: int, - out_features: int, - bias: bool, - obs: SmoothQuantObserver, - device=None, - dtype=None): + self, + in_features: int, + out_features: int, + bias: bool, + obs: SmoothQuantObserver, + device=None, + dtype=None, + ): super().__init__(in_features, out_features, bias, device, dtype) assert isinstance(obs, SmoothQuantObserver) self.obs = obs diff --git a/torchao/prototype/smoothquant/example.py b/torchao/prototype/smoothquant/example.py index 481acf2ac..007550259 100644 --- a/torchao/prototype/smoothquant/example.py +++ b/torchao/prototype/smoothquant/example.py @@ -1,21 +1,23 @@ -import torch import argparse import os +import time from typing import Optional -from transformers import AutoModelForCausalLM, AutoTokenizer + +import torch from datasets import load_dataset from tqdm import tqdm -import time +from transformers import AutoModelForCausalLM, AutoTokenizer + from torchao.prototype.smoothquant import ( - insert_smooth_quant_observer_, - SmoothQuantObservedLinear, - smooth_quant + SmoothQuantObservedLinear, + insert_smooth_quant_observer_, + smooth_quant, ) from torchao.quantization import quantize_ def get_calib_dataset(tokenizer=None, n_samples=100, block_size=512): - dataset = load_dataset('wikitext', 'wikitext-2-raw-v1', split='validation') + dataset = load_dataset("wikitext", "wikitext-2-raw-v1", split="validation") samples = [] n_tokens = n_samples * block_size n_run = n_tokens @@ -34,32 +36,38 @@ def get_calib_dataset(tokenizer=None, n_samples=100, block_size=512): break cat_samples = torch.cat(samples, dim=1) - return [cat_samples[:, i * block_size : (i + 1) * block_size] for i in range(n_samples)] + return [ + cat_samples[:, i * block_size : (i + 1) * block_size] for i in range(n_samples) + ] -def wiki2_eval(model, tokenizer, sequence_length, stride=512, verbose=True, device="cuda"): +def wiki2_eval( + model, tokenizer, sequence_length, stride=512, verbose=True, device="cuda" +): model.eval() - tokenizer.pad_token = tokenizer.eos_token - tokenizer.padding_side = "right" + tokenizer.pad_token = tokenizer.eos_token + tokenizer.padding_side = "right" tokenizer.add_eos_token = False print("Loading dataset") t0 = time.time() - dataset = load_dataset('wikitext', 'wikitext-2-raw-v1', split='test') - encodings = tokenizer('\n\n'.join(dataset['text']), return_tensors='pt') + dataset = load_dataset("wikitext", "wikitext-2-raw-v1", split="test") + encodings = tokenizer("\n\n".join(dataset["text"]), return_tensors="pt") print(f"Time to load dataset: {time.time() - t0:.02f} seconds") - encodings['input_ids'] = encodings['input_ids'].to(device) + encodings["input_ids"] = encodings["input_ids"].to(device) print("Running evaluation") lls, t = [], [] - for i in tqdm(range(0, encodings['input_ids'].size(1), stride), disable=not verbose): - begin_loc = max(i + stride - sequence_length, 0) - end_loc = min(i + stride, encodings['input_ids'].size(1)) - trg_len = end_loc - i - input_ids = encodings['input_ids'][:,begin_loc:end_loc] + for i in tqdm( + range(0, encodings["input_ids"].size(1), stride), disable=not verbose + ): + begin_loc = max(i + stride - sequence_length, 0) + end_loc = min(i + stride, encodings["input_ids"].size(1)) + trg_len = end_loc - i + input_ids = encodings["input_ids"][:, begin_loc:end_loc] target_ids = input_ids.clone() - target_ids[:,:-trg_len] = -100 # ignore context + target_ids[:, :-trg_len] = -100 # ignore context t1 = time.time() with torch.no_grad(): @@ -67,18 +75,18 @@ def wiki2_eval(model, tokenizer, sequence_length, stride=512, verbose=True, devi if device == "cuda": torch.cuda.synchronize() t2 = time.time() - t.append((t2-t1)) + t.append((t2 - t1)) lls.append(log_likelihood) del input_ids, target_ids - ppl = float(torch.exp(torch.stack(lls).sum() / end_loc)) - pred_time = sum(t)/len(t) - if(verbose): - print('perplexity', ppl) - print('time', str(pred_time) + ' sec/it') + ppl = float(torch.exp(torch.stack(lls).sum() / end_loc)) + pred_time = sum(t) / len(t) + if verbose: + print("perplexity", ppl) + print("time", str(pred_time) + " sec/it") - return {'perplexity':ppl, 'prediction_time':pred_time} + return {"perplexity": ppl, "prediction_time": pred_time} def benchmark(model, tokenizer, max_length, tasks=None, device="cuda"): @@ -88,21 +96,24 @@ def benchmark(model, tokenizer, max_length, tasks=None, device="cuda"): tasks = ["PPL"] results = {} if "PPL" in tasks: - results["perplexity"] = wiki2_eval(model, tokenizer, 512, verbose=True, device=device) + results["perplexity"] = wiki2_eval( + model, tokenizer, 512, verbose=True, device=device + ) return results def wikitext2_ppl( - model_id: str, - alpha: Optional[float], - quant_mode: str, - calibration_size: int, - device: str, - precision:torch.dtype, - sequence_length: int, - compile: bool, - model_load_path: str, - model_save_path: str): + model_id: str, + alpha: Optional[float], + quant_mode: str, + calibration_size: int, + device: str, + precision: torch.dtype, + sequence_length: int, + compile: bool, + model_load_path: str, + model_save_path: str, +): print(f"Loading model on {device}...") torch.manual_seed(34) t0 = time.time() @@ -113,13 +124,19 @@ def wikitext2_ppl( model = torch.load(model_load_path, weights_only=False).to(device) print(f"Time to load quantized model: {time.time() - t0:.02f} seconds") else: - model = AutoModelForCausalLM.from_pretrained(model_id, torch_dtype=precision).eval().to(device) + model = ( + AutoModelForCausalLM.from_pretrained(model_id, torch_dtype=precision) + .eval() + .to(device) + ) print(f"Time to load model: {time.time() - t0:.02f} seconds") - print(f"running calibration") + print("running calibration") t0 = time.time() # insert observers to find average magnitude and calculate scales insert_smooth_quant_observer_(model, alpha, quant_mode) - calibration_data = get_calib_dataset(tokenizer=tokenizer, n_samples=calibration_size, block_size=sequence_length) + calibration_data = get_calib_dataset( + tokenizer=tokenizer, n_samples=calibration_size, block_size=sequence_length + ) for batch in calibration_data: model(batch.to(device)) batch.to("cpu") @@ -142,25 +159,70 @@ def wikitext2_ppl( if __name__ == "__main__": - parser = argparse.ArgumentParser(description="Evaluate a model with the specified parameters.") + parser = argparse.ArgumentParser( + description="Evaluate a model with the specified parameters." + ) # Optional arguments with default values - parser.add_argument("--model-id", "-m", type=str, help="Repository ID of the model.") - parser.add_argument("--alpha", type=float, default=0.5, help="The alpha hyperparameter for SmoothQuant.") - parser.add_argument("--quant-mode", type=str, help="Quantization mode, either static or dynamic.") - parser.add_argument("--calibration-samples", type=int, default=10, - help="Number of samples to use for calibration. Default is 10.") - parser.add_argument("--device", type=str, default="cuda", help="Device to run the evaluation on. Default is 'cuda'.") - parser.add_argument("--precision", type=str, default="bfloat16", help="Precision type. Default is 'bfloat16'.") - parser.add_argument("--seq_len", type=int, default=512, - help="Length of examples to calibrate and evaluate model on. Default is 512") - parser.add_argument("--compile", action="store_true", help="Flag to indicate if compilation is required.") - parser.add_argument("--model-load-path", type=str, default=None, - help="Path to load quantized model. If this is provided, " - "the model will be loaded from this path instead of quantizing the model.") - parser.add_argument("--model-save-path", type=str, default=None, help="Path to store quantized model.") - parser.add_argument("--disable-smooth-quant", action="store_true", - help="Run conventional dynamic or static quantization for testing or debugging.") + parser.add_argument( + "--model-id", "-m", type=str, help="Repository ID of the model." + ) + parser.add_argument( + "--alpha", + type=float, + default=0.5, + help="The alpha hyperparameter for SmoothQuant.", + ) + parser.add_argument( + "--quant-mode", type=str, help="Quantization mode, either static or dynamic." + ) + parser.add_argument( + "--calibration-samples", + type=int, + default=10, + help="Number of samples to use for calibration. Default is 10.", + ) + parser.add_argument( + "--device", + type=str, + default="cuda", + help="Device to run the evaluation on. Default is 'cuda'.", + ) + parser.add_argument( + "--precision", + type=str, + default="bfloat16", + help="Precision type. Default is 'bfloat16'.", + ) + parser.add_argument( + "--seq_len", + type=int, + default=512, + help="Length of examples to calibrate and evaluate model on. Default is 512", + ) + parser.add_argument( + "--compile", + action="store_true", + help="Flag to indicate if compilation is required.", + ) + parser.add_argument( + "--model-load-path", + type=str, + default=None, + help="Path to load quantized model. If this is provided, " + "the model will be loaded from this path instead of quantizing the model.", + ) + parser.add_argument( + "--model-save-path", + type=str, + default=None, + help="Path to store quantized model.", + ) + parser.add_argument( + "--disable-smooth-quant", + action="store_true", + help="Run conventional dynamic or static quantization for testing or debugging.", + ) args = parser.parse_args() @@ -176,5 +238,5 @@ def wikitext2_ppl( args.seq_len, args.compile, args.model_load_path, - args.model_save_path + args.model_save_path, ) diff --git a/torchao/prototype/sparsity/__init__.py b/torchao/prototype/sparsity/__init__.py index 924b7f409..821e5049e 100644 --- a/torchao/prototype/sparsity/__init__.py +++ b/torchao/prototype/sparsity/__init__.py @@ -18,3 +18,16 @@ from torchao.prototype.sparsity.sparsifier.weight_norm_sparsifier import ( WeightNormSparsifier, ) + +__all__ = [ + "BaseScheduler", + "CubicSL", + "LambdaSL", + "BaseSparsifier", + "NearlyDiagonalSparsifier", + "FakeSparsity", + "fqn_to_module", + "get_arg_info_from_tensor_fqn", + "module_to_fqn", + "WeightNormSparsifier", +] diff --git a/torchao/prototype/sparsity/pruner/__init__.py b/torchao/prototype/sparsity/pruner/__init__.py index 6f017aa9e..9d7f77538 100644 --- a/torchao/prototype/sparsity/pruner/__init__.py +++ b/torchao/prototype/sparsity/pruner/__init__.py @@ -1,8 +1,17 @@ from .base_structured_sparsifier import BaseStructuredSparsifier +from .FPGM_pruner import FPGMPruner +from .lstm_saliency_pruner import LSTMSaliencyPruner from .parametrization import ( - FakeStructuredSparsity, BiasHook, + FakeStructuredSparsity, ) from .saliency_pruner import SaliencyPruner -from .lstm_saliency_pruner import LSTMSaliencyPruner -from .FPGM_pruner import FPGMPruner + +__all__ = [ + "BaseStructuredSparsifier", + "FPGMPruner", + "LSTMSaliencyPruner", + "BiasHook", + "FakeStructuredSparsity", + "SaliencyPruner", +] diff --git a/torchao/prototype/sparsity/pruner/base_structured_sparsifier.py b/torchao/prototype/sparsity/pruner/base_structured_sparsifier.py index fa0c3bad6..407052731 100644 --- a/torchao/prototype/sparsity/pruner/base_structured_sparsifier.py +++ b/torchao/prototype/sparsity/pruner/base_structured_sparsifier.py @@ -10,7 +10,7 @@ from torchao.prototype.sparsity import BaseSparsifier -from .match_utils import apply_match, MatchAllNode +from .match_utils import MatchAllNode, apply_match from .parametrization import BiasHook, FakeStructuredSparsity, module_contains_param from .prune_functions import ( prune_conv2d, @@ -92,10 +92,12 @@ def _get_supported_activation_modules(): return SUPPORTED_ACTIVATION_MODULES -def _get_default_structured_pruning_patterns() -> Dict[ - Tuple[Union[Type[nn.Module], Callable, MatchAllNode, str], ...], - Callable[..., None], -]: +def _get_default_structured_pruning_patterns() -> ( + Dict[ + Tuple[Union[Type[nn.Module], Callable, MatchAllNode, str], ...], + Callable[..., None], + ] +): """ Returns the patterns for conv2d / linear conversion for each element in the activation functions/modules defined above. """ diff --git a/torchao/prototype/sparsity/pruner/lstm_saliency_pruner.py b/torchao/prototype/sparsity/pruner/lstm_saliency_pruner.py index 4a0d74d6d..3d47116e9 100644 --- a/torchao/prototype/sparsity/pruner/lstm_saliency_pruner.py +++ b/torchao/prototype/sparsity/pruner/lstm_saliency_pruner.py @@ -1,8 +1,10 @@ from typing import cast import torch + from .base_structured_sparsifier import BaseStructuredSparsifier, FakeStructuredSparsity + class LSTMSaliencyPruner(BaseStructuredSparsifier): """ Prune packed LSTM weights based on saliency. @@ -31,7 +33,9 @@ def update_mask(self, module, tensor_name, **kwargs): # select weights based on magnitude if weights.dim() <= 1: - raise Exception("Structured pruning can only be applied to a 2+dim weight tensor!") + raise Exception( + "Structured pruning can only be applied to a 2+dim weight tensor!" + ) # take norm over all but first dim dims = tuple(range(1, weights.dim())) saliency = weights.norm(dim=dims, p=1) diff --git a/torchao/prototype/sparsity/pruner/match_utils.py b/torchao/prototype/sparsity/pruner/match_utils.py index d0f7a9f62..d7200c128 100644 --- a/torchao/prototype/sparsity/pruner/match_utils.py +++ b/torchao/prototype/sparsity/pruner/match_utils.py @@ -1,6 +1,9 @@ """ Contains utility functions to check if a pattern is in the graph and return the matching nodes """ + +from typing import Any, Dict, List, Optional, Tuple, Union + import torch from torch import nn from torch.ao.quantization.utils import ( @@ -8,9 +11,11 @@ ) from torch.fx import Node from torch.nn.utils import parametrize -from typing import Any, Dict, List, Optional, Tuple, Union -def _match(modules: Dict[str, nn.ModuleDict], node: Node, current: Union[nn.Module, Any]) -> bool: + +def _match( + modules: Dict[str, nn.ModuleDict], node: Node, current: Union[nn.Module, Any] +) -> bool: r""" checks to see if a single node of a pattern matches """ @@ -30,6 +35,7 @@ def _match(modules: Dict[str, nn.ModuleDict], node: Node, current: Union[nn.Modu return node.target == current return False + def apply_match( modules: Dict[str, nn.ModuleDict], pattern: Union[Tuple[Any], Any], diff --git a/torchao/prototype/sparsity/pruner/parametrization.py b/torchao/prototype/sparsity/pruner/parametrization.py index df94f7093..c3ac3dda3 100644 --- a/torchao/prototype/sparsity/pruner/parametrization.py +++ b/torchao/prototype/sparsity/pruner/parametrization.py @@ -44,7 +44,6 @@ def __init__(self, parametrization, prune_bias): self.prune_bias = prune_bias def __call__(self, module, input, output): - if getattr(module, "_bias", None) is not None: bias = module._bias.data if self.prune_bias: diff --git a/torchao/prototype/sparsity/pruner/prune_functions.py b/torchao/prototype/sparsity/pruner/prune_functions.py index a75c09cc3..bcf736cd6 100644 --- a/torchao/prototype/sparsity/pruner/prune_functions.py +++ b/torchao/prototype/sparsity/pruner/prune_functions.py @@ -2,13 +2,16 @@ Collection of conversion functions for linear / conv2d structured pruning Also contains utilities for bias propagation """ -from typing import cast, List, Optional, Callable, Tuple + +from typing import Callable, List, Optional, Tuple, cast import torch -from torch import nn, Tensor +from torch import Tensor, nn from torch.nn.utils import parametrize from torch.nn.utils.parametrize import ParametrizationList -from .parametrization import FakeStructuredSparsity, BiasHook + +from .parametrization import BiasHook, FakeStructuredSparsity + # BIAS PROPAGATION def _remove_bias_handles(module: nn.Module) -> None: diff --git a/torchao/prototype/sparsity/pruner/saliency_pruner.py b/torchao/prototype/sparsity/pruner/saliency_pruner.py index f965fa647..a29399c0b 100644 --- a/torchao/prototype/sparsity/pruner/saliency_pruner.py +++ b/torchao/prototype/sparsity/pruner/saliency_pruner.py @@ -18,7 +18,9 @@ def update_mask(self, module, tensor_name, **kwargs): # use negative weights so we can use topk (we prune out the smallest) if weights.dim() <= 1: - raise Exception("Structured pruning can only be applied to a 2+dim weight tensor!") + raise Exception( + "Structured pruning can only be applied to a 2+dim weight tensor!" + ) saliency = -weights.norm(dim=tuple(range(1, weights.dim())), p=1) assert saliency.shape == mask.shape diff --git a/torchao/prototype/sparsity/scheduler/base_scheduler.py b/torchao/prototype/sparsity/scheduler/base_scheduler.py index 5d91098c5..dc5713340 100644 --- a/torchao/prototype/sparsity/scheduler/base_scheduler.py +++ b/torchao/prototype/sparsity/scheduler/base_scheduler.py @@ -8,9 +8,7 @@ class BaseScheduler: - def __init__(self, sparsifier, last_epoch=-1, verbose=False): - # Attach sparsifier if not isinstance(sparsifier, BaseSparsifier): raise TypeError( @@ -136,7 +134,6 @@ def step(self, epoch=None): self._step_count += 1 class _enable_get_sl_call: - def __init__(self, o): self.o = o diff --git a/torchao/prototype/sparsity/scheduler/cubic_scheduler.py b/torchao/prototype/sparsity/scheduler/cubic_scheduler.py index 76fc61daa..805e5c3a1 100644 --- a/torchao/prototype/sparsity/scheduler/cubic_scheduler.py +++ b/torchao/prototype/sparsity/scheduler/cubic_scheduler.py @@ -4,6 +4,7 @@ __all__ = ["CubicSL"] + def _clamp(x, lo, hi): return max(lo, min(hi, x)) @@ -35,16 +36,18 @@ class CubicSL(BaseScheduler): verbose (bool): If ``True``, prints a message to stdout for each update. Default: ``False``. """ - def __init__(self, - sparsifier, - init_sl=0.0, - init_t=0, - delta_t=10, - total_t=100, - initially_zero=False, - last_epoch=-1, - verbose=False - ): + + def __init__( + self, + sparsifier, + init_sl=0.0, + init_t=0, + delta_t=10, + total_t=100, + initially_zero=False, + last_epoch=-1, + verbose=False, + ): self.sparsifier = sparsifier self.init_sl = self._make_sure_a_list(init_sl) @@ -58,7 +61,7 @@ def __init__(self, @staticmethod def sparsity_compute_fn(s_0, s_f, t, t_0, dt, n, initially_zero=False): - r""""Computes the current level of sparsity. + r""" "Computes the current level of sparsity. Based on https://arxiv.org/pdf/1710.01878.pdf @@ -85,7 +88,8 @@ def get_sl(self): if not self._get_sl_called_within_step: warnings.warn( "To get the last sparsity level computed by the scheduler, " - "please use `get_last_sl()`.") + "please use `get_last_sl()`." + ) return [ self.sparsity_compute_fn( s_0=initial_sparsity, @@ -94,14 +98,14 @@ def get_sl(self): t_0=initial_epoch, dt=delta_epoch, n=interval_epochs, - initially_zero=initially_zero - ) for initial_sparsity, final_sparsity, initial_epoch, delta_epoch, interval_epochs, initially_zero in - zip( + initially_zero=initially_zero, + ) + for initial_sparsity, final_sparsity, initial_epoch, delta_epoch, interval_epochs, initially_zero in zip( self.init_sl, self.base_sl, self.init_t, self.delta_t, self.total_t, - self.initially_zero + self.initially_zero, ) ] diff --git a/torchao/prototype/sparsity/scheduler/lambda_scheduler.py b/torchao/prototype/sparsity/scheduler/lambda_scheduler.py index a88d99a1f..01d0aee01 100644 --- a/torchao/prototype/sparsity/scheduler/lambda_scheduler.py +++ b/torchao/prototype/sparsity/scheduler/lambda_scheduler.py @@ -4,6 +4,7 @@ __all__ = ["LambdaSL"] + class LambdaSL(BaseScheduler): """Sets the sparsity level of each parameter group to the final sl times a given function. When last_epoch=-1, sets initial sl as zero. @@ -34,7 +35,9 @@ def __init__(self, sparsifier, sl_lambda, last_epoch=-1, verbose=False): self.sl_lambdas = [sl_lambda] * len(sparsifier.groups) else: if len(sl_lambda) != len(sparsifier.groups): - raise ValueError(f"Expected {len(sparsifier.groups)} lr_lambdas, but got {len(sl_lambda)}") + raise ValueError( + f"Expected {len(sparsifier.groups)} lr_lambdas, but got {len(sl_lambda)}" + ) self.sl_lambdas = list(sl_lambda) super().__init__(sparsifier, last_epoch, verbose) @@ -42,6 +45,9 @@ def get_sl(self): if not self._get_sl_called_within_step: warnings.warn( "To get the last sparsity level computed by the scheduler, " - "please use `get_last_sl()`.") - return [base_sl * lmbda(self.last_epoch) - for lmbda, base_sl in zip(self.sl_lambdas, self.base_sl)] + "please use `get_last_sl()`." + ) + return [ + base_sl * lmbda(self.last_epoch) + for lmbda, base_sl in zip(self.sl_lambdas, self.base_sl) + ] diff --git a/torchao/prototype/sparsity/sparsifier/base_sparsifier.py b/torchao/prototype/sparsity/sparsifier/base_sparsifier.py index 1c210ace3..2246ff48f 100644 --- a/torchao/prototype/sparsity/sparsifier/base_sparsifier.py +++ b/torchao/prototype/sparsity/sparsifier/base_sparsifier.py @@ -1,7 +1,7 @@ import abc import copy from collections import defaultdict -from typing import Any, Dict, Optional, Set, Tuple, List, Type +from typing import Any, Dict, List, Optional, Set, Tuple, Type import torch from torch import nn @@ -9,11 +9,11 @@ from torch.nn.utils.parametrize import type_before_parametrizations from .utils import ( - module_contains_param, - swap_module, FakeSparsity, get_arg_info_from_tensor_fqn, + module_contains_param, module_to_fqn, + swap_module, ) __all__ = ["BaseSparsifier"] @@ -200,9 +200,7 @@ def prepare(self, model, config): and "." + info_from_tensor_fqn[key] == local_args[key] ) # info_from_tensor_fqn will chop leading '.' from tensor_fqn so ignore that - ), ( - f"Given both `{key}` and `tensor_fqn` in the config, it is expected them to agree!" - ) + ), f"Given both `{key}` and `tensor_fqn` in the config, it is expected them to agree!" local_args.update(info_from_tensor_fqn) self.groups.append(local_args) self._prepare() diff --git a/torchao/prototype/sparsity/sparsifier/nearly_diagonal_sparsifier.py b/torchao/prototype/sparsity/sparsifier/nearly_diagonal_sparsifier.py index 4f44e8148..7b341f09d 100644 --- a/torchao/prototype/sparsity/sparsifier/nearly_diagonal_sparsifier.py +++ b/torchao/prototype/sparsity/sparsifier/nearly_diagonal_sparsifier.py @@ -27,12 +27,12 @@ class NearlyDiagonalSparsifier(base_sparsifier.BaseSparsifier): nearliness: The degree of nearliness (default = 1) """ + def __init__(self, nearliness: int = 1): - defaults = {'nearliness': nearliness} + defaults = {"nearliness": nearliness} super().__init__(defaults=defaults) - def update_mask(self, module, tensor_name, nearliness, - **kwargs): + def update_mask(self, module, tensor_name, nearliness, **kwargs): mask = getattr(module.parametrizations, tensor_name)[0].mask mask.data = torch.zeros_like(mask) if nearliness <= 0: @@ -46,7 +46,9 @@ def update_mask(self, module, tensor_name, nearliness, dist_to_diagonal = nearliness // 2 # check if dist_to_diagonal >= min(height, width): - raise ValueError("nearliness cannot be larger than the dimensions of tensor.") + raise ValueError( + "nearliness cannot be larger than the dimensions of tensor." + ) for row in range(0, height): # Bounds of entries that needs to be set to 1 diff --git a/torchao/prototype/sparsity/sparsifier/utils.py b/torchao/prototype/sparsity/sparsifier/utils.py index c52af8869..be0195510 100644 --- a/torchao/prototype/sparsity/sparsifier/utils.py +++ b/torchao/prototype/sparsity/sparsifier/utils.py @@ -1,8 +1,8 @@ -from typing import Any, Dict, Optional, Type -from torch.nn.utils.parametrize import type_before_parametrizations, is_parametrized from itertools import chain +from typing import Any, Dict, Optional, Type from torch import nn +from torch.nn.utils.parametrize import is_parametrized, type_before_parametrizations __all__ = [ "module_contains_param", @@ -50,9 +50,9 @@ def swap_module( # respect device affinity when swapping modules devices = {p.device for p in chain(mod.parameters(), mod.buffers())} - assert len(devices) <= 1, ( - f"swap_module only works with cpu or single-device CUDA modules, but got devices {devices}" - ) + assert ( + len(devices) <= 1 + ), f"swap_module only works with cpu or single-device CUDA modules, but got devices {devices}" device = next(iter(devices)) if len(devices) > 0 else None if device: new_mod.to(device) diff --git a/torchao/prototype/sparsity/sparsifier/weight_norm_sparsifier.py b/torchao/prototype/sparsity/sparsifier/weight_norm_sparsifier.py index 2b24ca3d8..398ed4d1a 100644 --- a/torchao/prototype/sparsity/sparsifier/weight_norm_sparsifier.py +++ b/torchao/prototype/sparsity/sparsifier/weight_norm_sparsifier.py @@ -1,3 +1,4 @@ +import operator from functools import reduce from typing import Callable, Optional, Tuple, Union @@ -5,15 +6,16 @@ import torch.nn.functional as F from .base_sparsifier import BaseSparsifier -import operator __all__ = ["WeightNormSparsifier"] + def _flat_idx_to_2d(idx, shape): rows = idx // shape[1] cols = idx % shape[1] return rows, cols + class WeightNormSparsifier(BaseSparsifier): r"""Weight-Norm Sparsifier @@ -51,11 +53,14 @@ class WeightNormSparsifier(BaseSparsifier): arguments and could be overriden by the configuration provided in the `prepare` step. """ - def __init__(self, - sparsity_level: float = 0.5, - sparse_block_shape: Tuple[int, int] = (1, 4), - zeros_per_block: Optional[int] = None, - norm: Optional[Union[Callable, int]] = None): + + def __init__( + self, + sparsity_level: float = 0.5, + sparse_block_shape: Tuple[int, int] = (1, 4), + zeros_per_block: Optional[int] = None, + norm: Optional[Union[Callable, int]] = None, + ): if zeros_per_block is None: zeros_per_block = reduce(operator.mul, sparse_block_shape) defaults = { @@ -75,17 +80,29 @@ def __init__(self, raise NotImplementedError(f"L-{norm} is not yet implemented.") super().__init__(defaults=defaults) - def _scatter_fold_block_mask(self, output_shape, dim, indices, block_shape, - mask=None, input_shape=None, device=None): + def _scatter_fold_block_mask( + self, + output_shape, + dim, + indices, + block_shape, + mask=None, + input_shape=None, + device=None, + ): r"""Creates patches of size `block_shape` after scattering the indices.""" if mask is None: assert input_shape is not None mask = torch.ones(input_shape, device=device) mask.scatter_(dim=dim, index=indices, value=0) - mask.data = F.fold(mask, output_size=output_shape, kernel_size=block_shape, stride=block_shape) + mask.data = F.fold( + mask, output_size=output_shape, kernel_size=block_shape, stride=block_shape + ) return mask - def _make_tensor_mask(self, data, input_shape, sparsity_level, sparse_block_shape, mask=None): + def _make_tensor_mask( + self, data, input_shape, sparsity_level, sparse_block_shape, mask=None + ): r"""Creates a tensor-level mask. Tensor-level mask is described as a mask, where the granularity of sparsification of the @@ -113,7 +130,10 @@ def _make_tensor_mask(self, data, input_shape, sparsity_level, sparse_block_shap if values_per_block > 1: # Reduce the data data = F.avg_pool2d( - data[None, None, :], kernel_size=sparse_block_shape, stride=sparse_block_shape, ceil_mode=True + data[None, None, :], + kernel_size=sparse_block_shape, + stride=sparse_block_shape, + ceil_mode=True, ) data = data.flatten() num_blocks = len(data) @@ -127,8 +147,11 @@ def _make_tensor_mask(self, data, input_shape, sparsity_level, sparse_block_shap # Temp reshape for mask mask_reshape = mask.reshape(data.shape) # data might be reshaped self._scatter_fold_block_mask( - dim=2, output_shape=(h + dh, w + dw), - indices=sorted_idx, block_shape=sparse_block_shape, mask=mask_reshape + dim=2, + output_shape=(h + dh, w + dw), + indices=sorted_idx, + block_shape=sparse_block_shape, + mask=mask_reshape, ) mask.data = mask_reshape.squeeze().reshape(mask.shape)[:h, :w].contiguous() return mask @@ -160,21 +183,38 @@ def _make_block_mask(self, data, sparse_block_shape, zeros_per_block, mask=None) padded_data = torch.ones(h + dh, w + dw, dtype=data.dtype, device=data.device) padded_data.fill_(torch.nan) padded_data[:h, :w] = data - unfolded_data = F.unfold(padded_data[None, None, :], kernel_size=sparse_block_shape, stride=sparse_block_shape) + unfolded_data = F.unfold( + padded_data[None, None, :], + kernel_size=sparse_block_shape, + stride=sparse_block_shape, + ) # Temp reshape for mask mask_reshape = mask.reshape(unfolded_data.shape) - _, sorted_idx = torch.topk(unfolded_data, k=zeros_per_block, dim=1, largest=False) + _, sorted_idx = torch.topk( + unfolded_data, k=zeros_per_block, dim=1, largest=False + ) self._scatter_fold_block_mask( - dim=1, indices=sorted_idx, output_shape=padded_data.shape, block_shape=sparse_block_shape, mask=mask_reshape + dim=1, + indices=sorted_idx, + output_shape=padded_data.shape, + block_shape=sparse_block_shape, + mask=mask_reshape, ) mask.data = mask_reshape.squeeze().reshape(mask.shape).contiguous() return mask - def update_mask(self, module, tensor_name, sparsity_level, sparse_block_shape, - zeros_per_block, **kwargs): + def update_mask( + self, + module, + tensor_name, + sparsity_level, + sparse_block_shape, + zeros_per_block, + **kwargs, + ): values_per_block = reduce(operator.mul, sparse_block_shape) if zeros_per_block > values_per_block: raise ValueError( @@ -191,10 +231,16 @@ def update_mask(self, module, tensor_name, sparsity_level, sparse_block_shape, else: ww = self.norm_fn(getattr(module, tensor_name)) tensor_mask = self._make_tensor_mask( - data=ww, input_shape=ww.shape, sparsity_level=sparsity_level, sparse_block_shape=sparse_block_shape + data=ww, + input_shape=ww.shape, + sparsity_level=sparsity_level, + sparse_block_shape=sparse_block_shape, ) if values_per_block != zeros_per_block: - block_mask = self._make_block_mask(data=ww, sparse_block_shape=sparse_block_shape, - zeros_per_block=zeros_per_block) + block_mask = self._make_block_mask( + data=ww, + sparse_block_shape=sparse_block_shape, + zeros_per_block=zeros_per_block, + ) tensor_mask = torch.logical_or(tensor_mask, block_mask) mask.data = tensor_mask diff --git a/torchao/prototype/sparsity/superblock/benchmark.py b/torchao/prototype/sparsity/superblock/benchmark.py index 253d29dbe..b87834afa 100644 --- a/torchao/prototype/sparsity/superblock/benchmark.py +++ b/torchao/prototype/sparsity/superblock/benchmark.py @@ -2,11 +2,10 @@ import torch import torchvision - from torch.sparse._triton_ops_meta import ( - dump as store_tuned_kernel_params, optimize_bsr_dense_addmm, ) + from torchao.prototype.sparsity.superblock.utils import ( accelerate_with_sparsity, get_args_parser, diff --git a/torchao/prototype/sparsity/superblock/blocksparse.py b/torchao/prototype/sparsity/superblock/blocksparse.py index 69c98f6af..b5e843294 100644 --- a/torchao/prototype/sparsity/superblock/blocksparse.py +++ b/torchao/prototype/sparsity/superblock/blocksparse.py @@ -1,9 +1,10 @@ from functools import partial -from typing import Any, Callable, Dict, List, Optional, Tuple +from typing import List, Optional, Tuple import torch -from torch.sparse._triton_ops import broadcast_batch_dims, bsr_dense_addmm, bsr_dense_mm +from torch.sparse._triton_ops import broadcast_batch_dims, bsr_dense_addmm from torch.utils._python_dispatch import return_and_correct_aliasing + from torchao.quantization.quant_api import _get_linear_subclass_inserter from torchao.utils import TorchAOBaseTensor diff --git a/torchao/prototype/sparsity/superblock/evaluate.py b/torchao/prototype/sparsity/superblock/evaluate.py index bd17a1379..04701e518 100644 --- a/torchao/prototype/sparsity/superblock/evaluate.py +++ b/torchao/prototype/sparsity/superblock/evaluate.py @@ -7,7 +7,6 @@ from torchao.prototype.sparsity.superblock.train import evaluate, load_data from torchao.prototype.sparsity.superblock.utils import ( accelerate_with_sparsity, - apply_sparsity, get_args_parser, init_distributed_mode, simulate_sparsity, diff --git a/torchao/prototype/sparsity/superblock/supermask.py b/torchao/prototype/sparsity/superblock/supermask.py index 0b2876344..abd23c566 100644 --- a/torchao/prototype/sparsity/superblock/supermask.py +++ b/torchao/prototype/sparsity/superblock/supermask.py @@ -1,15 +1,14 @@ # Copyright (c) Meta Platforms, Inc. and affiliates. -import torch.nn as nn import math + import torch -from torch.autograd import Variable +import torch.nn as nn import torch.nn.functional as F -import numpy as np # original supermask -scores_min=None -scores_max=9e9 +scores_min = None +scores_max = 9e9 uniform_init_01 = False # adjusted supermask, initialize scores with uniform distribution in [0,1], clamp scores in each step in [0,1] @@ -17,19 +16,24 @@ # scores_max=1. # uniform_init_01 = True + def percentile(t, q): """Return the value that is larger than q% of t""" - k = 1 + round(.01 * float(q) * (t.numel() - 1)) + k = 1 + round(0.01 * float(q) * (t.numel() - 1)) return t.view(-1).kthvalue(k).values class GetSubnet(torch.autograd.Function): """Supermask STE function""" + @staticmethod def forward(ctx, scores, zeros, ones, sparsity): - clamped_scores = scores.clamp(min=scores_min,max=scores_max) - k_val = percentile(clamped_scores, sparsity*100) - return torch.where(clamped_scores < k_val, zeros.to(scores.device), ones.to(scores.device)) + clamped_scores = scores.clamp(min=scores_min, max=scores_max) + k_val = percentile(clamped_scores, sparsity * 100) + return torch.where( + clamped_scores < k_val, zeros.to(scores.device), ones.to(scores.device) + ) + @staticmethod def backward(ctx, g): return g, None, None, None @@ -37,16 +41,29 @@ def backward(ctx, g): class SupermaskLinear(nn.Linear): """Supermask class for Linear layer""" - def __init__(self, sparsity, fixed_mask, fixed_weight, bitwidth, transform, fixed_transform, *args, **kwargs): + + def __init__( + self, + sparsity, + fixed_mask, + fixed_weight, + bitwidth, + transform, + fixed_transform, + *args, + **kwargs, + ): tile_size = kwargs.pop("tile_size", 1) super(SupermaskLinear, self).__init__(*args, **kwargs) # initialize the scores - max_sparsity = 1 - (1 / math.prod([math.ceil(k / tile_size) for k in self.weight.size()])) + max_sparsity = 1 - ( + 1 / math.prod([math.ceil(k / tile_size) for k in self.weight.size()]) + ) self.sparsity = sparsity if self.sparsity > max_sparsity: print( f"reducing sparsity from {self.sparsity} to {max_sparsity}", - f"(maximum sparsity for layer with shape {self.weight.size()} and tile size {tile_size})" + f"(maximum sparsity for layer with shape {self.weight.size()} and tile size {tile_size})", ) self.sparsity = max_sparsity self.tile_size = tile_size @@ -57,42 +74,60 @@ def __init__(self, sparsity, fixed_mask, fixed_weight, bitwidth, transform, fixe ), requires_grad=not fixed_mask, ) - nn.init.uniform_(self.scores) if uniform_init_01 else nn.init.kaiming_uniform_(self.scores, a=math.sqrt(5)) + nn.init.uniform_(self.scores) if uniform_init_01 else nn.init.kaiming_uniform_( + self.scores, a=math.sqrt(5) + ) - # the shift and the scale are transformation parameters + # the shift and the scale are transformation parameters # the actually used weights = self.weight*self.scale+self.shift # the transformation is activated only for quantized weights - self.shift=nn.Parameter(torch.Tensor(1).fill_(0.), requires_grad=False) - self.scale=nn.Parameter(torch.Tensor(1).fill_(1.), requires_grad=False) - + self.shift = nn.Parameter(torch.Tensor(1).fill_(0.0), requires_grad=False) + self.scale = nn.Parameter(torch.Tensor(1).fill_(1.0), requires_grad=False) + with torch.no_grad(): # if bitwidth is None, then use floating point values in self.weight # if bitwidth is not None, then quantize self.weight into k-bit (k=bitwidth) - # quantized values are -2^(k-1), -2^(k-1)+1, ..., 0, 1, ..., 2^(k-1)-1 + # quantized values are -2^(k-1), -2^(k-1)+1, ..., 0, 1, ..., 2^(k-1)-1 # these quantized values are uniformly distributed if bitwidth is not None: weights_max = torch.max(self.weight).item() weights_min = torch.min(self.weight).item() - least_step = (weights_max-weights_min)/pow(2,bitwidth) - left_bound = weights_min-1e-6 - right_bound = weights_min+least_step+1e-6 + least_step = (weights_max - weights_min) / pow(2, bitwidth) + left_bound = weights_min - 1e-6 + right_bound = weights_min + least_step + 1e-6 # self.shift=nn.Parameter(torch.Tensor(1).fill_( (weights_min+(pow(2,bitwidth-1)+0.5)*least_step) if transform[0] is None else transform[0] ), requires_grad=not fixed_transform[0]) # self.scale=nn.Parameter(torch.Tensor(1).fill_( least_step if transform[1] is None else transform[1] ), requires_grad=not fixed_transform[1]) # for example, if using binary weights (k=1) with -a, +a, set transform = [a,2a]; if using binary weights (k=1) with a, 0, set transform = [0,-a]; - self.shift=nn.Parameter(torch.Tensor(1).fill_( 0. if transform[0] is None else transform[0] ), requires_grad=not fixed_transform[0]) - self.scale=nn.Parameter(torch.Tensor(1).fill_( 1. if transform[1] is None else transform[1] ), requires_grad=not fixed_transform[1]) - for i in range(-int(pow(2,bitwidth-1)),int(pow(2,bitwidth-1))): - self.weight[torch.logical_and(self.weight>left_bound, self.weight<=right_bound)] = i + self.shift = nn.Parameter( + torch.Tensor(1).fill_( + 0.0 if transform[0] is None else transform[0] + ), + requires_grad=not fixed_transform[0], + ) + self.scale = nn.Parameter( + torch.Tensor(1).fill_( + 1.0 if transform[1] is None else transform[1] + ), + requires_grad=not fixed_transform[1], + ) + for i in range(-int(pow(2, bitwidth - 1)), int(pow(2, bitwidth - 1))): + self.weight[ + torch.logical_and( + self.weight > left_bound, self.weight <= right_bound + ) + ] = i left_bound = right_bound right_bound += least_step self.weight.requires_grad = not fixed_weight def get_mask(self): - subnet = GetSubnet.apply(self.scores, - torch.zeros_like(self.scores), - torch.ones_like(self.scores), - self.sparsity) + subnet = GetSubnet.apply( + self.scores, + torch.zeros_like(self.scores), + torch.ones_like(self.scores), + self.sparsity, + ) if self.tile_size != 1: for i, k in enumerate(self.weight.shape): @@ -100,33 +135,46 @@ def get_mask(self): subnet = torch.narrow(subnet, i, 0, k) return subnet - + def sparsify_offline(self): subnet = self.get_mask() - self.weight.data = (self.weight*self.scale+self.shift) * subnet + self.weight.data = (self.weight * self.scale + self.shift) * subnet self.sparsify_weights = True def forward(self, x): if not self.sparsify_weights: subnet = self.get_mask() - w = (self.weight*self.scale+self.shift) * subnet + w = (self.weight * self.scale + self.shift) * subnet else: w = self.weight return F.linear(x, w, self.bias) - + class SupermaskConv2d(nn.Conv2d): """Supermask class for Conv2d layer""" - def __init__(self, sparsity, fixed_mask, fixed_weight, bitwidth, transform, fixed_transform, *args, **kwargs): + + def __init__( + self, + sparsity, + fixed_mask, + fixed_weight, + bitwidth, + transform, + fixed_transform, + *args, + **kwargs, + ): tile_size = kwargs.pop("tile_size", 1) super(SupermaskConv2d, self).__init__(*args, **kwargs) # initialize the scores - max_sparsity = 1 - (1 / math.prod([math.ceil(k / tile_size) for k in self.weight.size()])) + max_sparsity = 1 - ( + 1 / math.prod([math.ceil(k / tile_size) for k in self.weight.size()]) + ) self.sparsity = sparsity if self.sparsity > max_sparsity: print( f"reducing sparsity from {self.sparsity} to {max_sparsity}", - f"(maximum sparsity for layer with shape {self.weight.size()} and tile size {tile_size})" + f"(maximum sparsity for layer with shape {self.weight.size()} and tile size {tile_size})", ) self.sparsity = max_sparsity self.tile_size = tile_size @@ -136,51 +184,72 @@ def __init__(self, sparsity, fixed_mask, fixed_weight, bitwidth, transform, fixe ), requires_grad=not fixed_mask, ) - nn.init.uniform_(self.scores) if uniform_init_01 else nn.init.kaiming_uniform_(self.scores, a=math.sqrt(5)) + nn.init.uniform_(self.scores) if uniform_init_01 else nn.init.kaiming_uniform_( + self.scores, a=math.sqrt(5) + ) - # the shift and the scale are transformation parameters + # the shift and the scale are transformation parameters # the actually used weights = self.weight*self.scale+self.shift # the transformation is activated only for quantized weights - self.shift=nn.Parameter(torch.Tensor(1).fill_(0.), requires_grad=False) - self.scale=nn.Parameter(torch.Tensor(1).fill_(1.), requires_grad=False) + self.shift = nn.Parameter(torch.Tensor(1).fill_(0.0), requires_grad=False) + self.scale = nn.Parameter(torch.Tensor(1).fill_(1.0), requires_grad=False) with torch.no_grad(): # if bitwidth is None, then use floating point values in self.weight # if bitwidth is not None, then quantize self.weight into k-bit (k=bitwidth) - # quantized values are -2^(k-1), -2^(k-1)+1, ..., 0, 1, ..., 2^(k-1)-1 + # quantized values are -2^(k-1), -2^(k-1)+1, ..., 0, 1, ..., 2^(k-1)-1 # these quantized values are uniformly distributed if bitwidth is not None: weights_max = torch.max(self.weight).item() weights_min = torch.min(self.weight).item() - least_step = (weights_max-weights_min)/pow(2,bitwidth) - left_bound = weights_min-1e-6 - right_bound = weights_min+least_step+1e-6 + least_step = (weights_max - weights_min) / pow(2, bitwidth) + left_bound = weights_min - 1e-6 + right_bound = weights_min + least_step + 1e-6 # self.shift=nn.Parameter(torch.Tensor(1).fill_( (weights_min+(pow(2,bitwidth-1)+0.5)*least_step) if transform[0] is None else transform[0] ), requires_grad=not fixed_transform[0]) # self.scale=nn.Parameter(torch.Tensor(1).fill_( least_step if transform[1] is None else transform[1]), requires_grad=not fixed_transform[1]) # for example, if using binary weights (k=1) with -a, +a, set transform = [a,2a]; if using binary weights (k=1) with a, 0, set transform = [0,-a]; - self.shift=nn.Parameter(torch.Tensor(1).fill_( 0. if transform[0] is None else transform[0] ), requires_grad=not fixed_transform[0]) - self.scale=nn.Parameter(torch.Tensor(1).fill_( 1. if transform[1] is None else transform[1] ), requires_grad=not fixed_transform[1]) - for i in range(-int(pow(2,bitwidth-1)),int(pow(2,bitwidth-1))): - self.weight[torch.logical_and(self.weight>left_bound, self.weight<=right_bound)] = i + self.shift = nn.Parameter( + torch.Tensor(1).fill_( + 0.0 if transform[0] is None else transform[0] + ), + requires_grad=not fixed_transform[0], + ) + self.scale = nn.Parameter( + torch.Tensor(1).fill_( + 1.0 if transform[1] is None else transform[1] + ), + requires_grad=not fixed_transform[1], + ) + for i in range(-int(pow(2, bitwidth - 1)), int(pow(2, bitwidth - 1))): + self.weight[ + torch.logical_and( + self.weight > left_bound, self.weight <= right_bound + ) + ] = i left_bound = right_bound right_bound += least_step self.weight.requires_grad = not fixed_weight def forward(self, x): - subnet = GetSubnet.apply(self.scores, - torch.zeros_like(self.scores), - torch.ones_like(self.scores), - self.sparsity) - + subnet = GetSubnet.apply( + self.scores, + torch.zeros_like(self.scores), + torch.ones_like(self.scores), + self.sparsity, + ) + if self.tile_size != 1: for i, k in enumerate(self.weight.shape): # if k == 1: continue subnet = subnet.repeat_interleave(self.tile_size, dim=i) subnet = torch.narrow(subnet, i, 0, k) - w = (self.weight*self.scale+self.shift) * subnet - return F.conv2d(x, w, self.bias, self.stride, self.padding, self.dilation, self.groups) + w = (self.weight * self.scale + self.shift) * subnet + return F.conv2d( + x, w, self.bias, self.stride, self.padding, self.dilation, self.groups + ) + def apply_supermask( model, @@ -203,14 +272,23 @@ def apply_supermask( continue if skip_first_transformer_sparsity and "encoder.layers.encoder_layer_0" in n: continue - + # convert 1x1 convolutions - if conv1x1_sparsity != 0.0 and isinstance(m, torch.nn.Conv2d) and m.kernel_size == (1, 1): + if ( + conv1x1_sparsity != 0.0 + and isinstance(m, torch.nn.Conv2d) + and m.kernel_size == (1, 1) + ): new_m = SupermaskConv2d( - conv1x1_sparsity, False, False, None, None, None, + conv1x1_sparsity, + False, + False, + None, + None, + None, m.in_channels, m.out_channels, - m.kernel_size, + m.kernel_size, stride=m.stride, padding=m.padding, dilation=m.dilation, @@ -229,10 +307,15 @@ def apply_supermask( # convert all other convolutions (not tested!) if conv_sparsity != 0.0 and isinstance(m, torch.nn.Conv2d): new_m = SupermaskConv2d( - conv_sparsity, False, False, None, None, None, + conv_sparsity, + False, + False, + None, + None, + None, m.in_channels, m.out_channels, - m.kernel_size, + m.kernel_size, stride=m.stride, padding=m.padding, dilation=m.dilation, @@ -250,7 +333,12 @@ def apply_supermask( if linear_sparsity != 0.0 and isinstance(m, torch.nn.Linear): new_m = SupermaskLinear( - linear_sparsity, False, False, None, None, None, + linear_sparsity, + False, + False, + None, + None, + None, m.in_features, m.out_features, bias=m.bias is not None, @@ -270,6 +358,8 @@ def apply_supermask( sm.add_module(ch_name, v) if verbose: - print(f'sparsified module "{k}" with sparsity={v.sparsity}, tile size={v.tile_size}') + print( + f'sparsified module "{k}" with sparsity={v.sparsity}, tile size={v.tile_size}' + ) return model diff --git a/torchao/prototype/sparsity/superblock/train.py b/torchao/prototype/sparsity/superblock/train.py index 355b5f33e..330dba4b6 100644 --- a/torchao/prototype/sparsity/superblock/train.py +++ b/torchao/prototype/sparsity/superblock/train.py @@ -3,7 +3,6 @@ import datetime import glob import os -import sys import time import warnings @@ -13,11 +12,11 @@ import utils from torch import nn from torch.utils.data.dataloader import default_collate - -from torchao.prototype.sparsity.superblock.utils import simulate_sparsity from torchvision.transforms.functional import InterpolationMode from utils import RASampler +from torchao.prototype.sparsity.superblock.utils import simulate_sparsity + def train_one_epoch( model, diff --git a/torchao/prototype/sparsity/superblock/utils.py b/torchao/prototype/sparsity/superblock/utils.py index e2b546db2..89a443bda 100644 --- a/torchao/prototype/sparsity/superblock/utils.py +++ b/torchao/prototype/sparsity/superblock/utils.py @@ -8,23 +8,24 @@ import math import os import time -from collections import defaultdict, deque, OrderedDict +from collections import OrderedDict, defaultdict, deque from typing import List, Optional, Tuple import torch +from torchvision.transforms import autoaugment, transforms +from torchvision.transforms import functional as F +from torchvision.transforms.functional import InterpolationMode + from torchao.prototype.sparsity.sparsifier.weight_norm_sparsifier import ( WeightNormSparsifier, ) from torchao.prototype.sparsity.superblock.blocksparse import block_sparse_weight from torchao.prototype.sparsity.superblock.supermask import ( - apply_supermask, SupermaskLinear, + apply_supermask, ) - from torchao.quantization import int8_dynamic_activation_int8_weight, quantize_ from torchao.sparsity import semi_sparse_weight, sparsify_ -from torchvision.transforms import autoaugment, functional as F, transforms -from torchvision.transforms.functional import InterpolationMode def get_args_parser(train=False, evaluate=False, benchmark=False): @@ -1009,7 +1010,6 @@ def __init__( std=(0.229, 0.224, 0.225), interpolation=InterpolationMode.BILINEAR, ): - self.transforms = transforms.Compose( [ transforms.Resize(resize_size, interpolation=interpolation), diff --git a/torchao/prototype/spinquant/__init__.py b/torchao/prototype/spinquant/__init__.py index ca74ce7d9..b20f7abc0 100644 --- a/torchao/prototype/spinquant/__init__.py +++ b/torchao/prototype/spinquant/__init__.py @@ -1 +1,5 @@ from .spinquant import apply_spinquant + +__all__ = [ + "apply_spinquant", +] diff --git a/torchao/prototype/spinquant/_hadamard_matrices.py b/torchao/prototype/spinquant/_hadamard_matrices.py index 58a28e2f4..8602a100d 100644 --- a/torchao/prototype/spinquant/_hadamard_matrices.py +++ b/torchao/prototype/spinquant/_hadamard_matrices.py @@ -4,15 +4,99313 @@ # hadamard matrices for had12, had36.pal2, had52,will, # # had60.pal, had108.pal, had140.pal, had156.will, had172.will: # http://www.neilsloane.com/hadamard/index.html -def get_had12():return torch.FloatTensor([[+1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[+1,+1,-1,+1,-1,-1,-1,+1,+1,+1,-1,+1],[+1,+1,+1,-1,+1,-1,-1,-1,+1,+1,+1,-1],[+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,+1,+1],[+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,+1],[+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1],[+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1],[+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1],[+1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1],[+1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1],[+1,+1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1],[+1,-1,+1,-1,-1,-1,+1,+1,+1,-1,+1,+1]]) -def get_had44():return torch.FloatTensor([[1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1],[1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1],[1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1],[1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1],[1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1],[1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1],[1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1],[1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1],[1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1],[1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1],[1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1],[1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1],[1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1],[1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1],[1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1],[1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1],[1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1],[1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1],[1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1],[1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1],[1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1],[1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1],[1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1],[1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1],[1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1],[1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1],[1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1],[1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1],[1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1],[1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1],[1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1],[1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,-1],[1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1],[1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1,-1],[1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1,1],[1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1,1],[1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,-1],[1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1],[1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1,-1],[1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1,1],[1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,1],[1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1,-1],[1,-1,1,1,-1,1,-1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,1,1,1,1,-1,1,1,1,-1,-1,1,-1,1,-1,-1,1,1]]) -def get_had40():return torch.FloatTensor([[+1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1],[+1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1],[+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1],[+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1],[+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1],[+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1],[+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1],[+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1],[+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1],[+1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1],[+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1],[+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1],[+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1],[+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1],[+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1],[+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1],[+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1],[+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1],[+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1],[+1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1],[+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1],[+1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1],[+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1],[+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1],[+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,-1],[+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1],[+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1],[+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1],[+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1],[+1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,+1,+1,+1,-1,+1],[+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,+1,+1,+1,-1],[+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,+1,+1,+1],[+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,+1,+1],[+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,+1],[+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1],[+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1],[+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1],[+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1],[+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1]]) -def get_had20():return torch.FloatTensor([[+1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1],[+1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1],[+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1],[+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1],[+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1],[+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1],[+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1],[+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1],[+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1],[+1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1],[+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1],[+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1],[+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1],[+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1],[+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1],[+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1],[+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1],[+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1],[+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1]]) -def get_had28():return torch.FloatTensor([[+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1],[+1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1],[+1,+1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1],[+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,-1,+1,+1],[+1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,-1,+1],[+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,-1],[+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,+1,+1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1],[+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,+1,-1,-1],[+1,-1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,+1,-1],[+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,+1],[+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1],[+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1],[+1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,-1,+1],[+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,-1],[-1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[+1,-1,+1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1],[+1,+1,-1,+1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1],[+1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1],[+1,+1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,+1,+1,+1,-1],[+1,+1,+1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,+1,+1,+1],[+1,-1,+1,+1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,+1,+1],[+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,+1],[+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1],[+1,-1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,-1,+1,-1,-1,-1,+1,-1,-1],[+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1,-1,-1,+1,-1],[+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1,-1,-1,+1],[+1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1,-1,-1],[+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1,-1]]) -def get_had36():return torch.FloatTensor([[+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1],[+1,+1,+1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,+1],[+1,+1,+1,+1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1],[+1,+1,+1,+1,+1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1],[+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1],[+1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1],[+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1],[+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,+1,-1],[+1,-1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,+1],[+1,+1,-1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1],[+1,+1,+1,-1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1],[+1,-1,+1,+1,-1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1],[+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1],[+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1],[+1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1],[+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1],[+1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,+1,-1,+1],[+1,+1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,+1,-1],[-1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,-1,-1,+1,+1,+1,-1,+1,-1,-1],[+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,+1,-1,-1,+1,+1,+1,-1,+1,-1],[+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,+1,-1,-1,+1,+1,+1,-1,+1],[+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,+1,-1,-1,+1,+1,+1,-1],[+1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,+1,-1,-1,+1,+1,+1],[+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,+1,-1,-1,+1,+1],[+1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,+1,-1,-1,+1],[+1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,+1,-1,-1],[+1,+1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,+1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,+1,-1],[+1,+1,+1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,+1],[+1,-1,+1,+1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,+1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1],[+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1],[+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,-1,+1,+1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1],[+1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,+1,+1,+1,-1,+1,-1,-1,-1,-1,-1,+1],[+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,-1,+1,+1,+1,-1,+1,-1,-1,-1,-1,-1],[+1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,+1,-1,+1,-1,-1,+1,-1,+1,+1,+1,-1,-1,+1,+1,+1,-1,+1,-1,-1,-1,-1],[+1,+1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,-1,-1,+1,+1,+1,-1,+1,-1,-1,-1]]) -def get_had60():return torch.FloatTensor([[+1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1],[+1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1],[+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1],[+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1],[+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1],[+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1],[+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1],[+1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1],[+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1],[+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1],[+1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1],[+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1],[+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1],[+1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1],[+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1],[+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1],[+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1],[+1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1],[+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1],[+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1],[+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1],[+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1],[+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1],[+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1],[+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1],[+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1],[+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1],[+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1],[+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1],[+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1],[+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1],[+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1],[+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1],[+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1],[+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1],[+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1],[+1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1],[+1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1],[+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1],[+1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1],[+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1],[+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1],[+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1],[+1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1],[+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1],[+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1],[+1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1],[+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1],[+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1],[+1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1],[+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1],[+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1],[+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1],[+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1],[+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1],[+1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1],[+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1],[+1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1],[+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1]]) -def get_had52():return torch.FloatTensor([[+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,-1],[-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1],[+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,-1],[-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1],[-1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1],[+1,-1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1],[+1,+1,-1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1],[+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1],[+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,-1,-1],[-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,-1],[-1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1],[+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1],[-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1],[-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,+1,-1,+1],[+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,+1,-1],[+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,+1],[+1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1],[-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1],[-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1],[-1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1],[-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1],[-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1],[-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1],[+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1],[+1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1],[+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1],[-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1],[-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,+1],[+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1],[-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1],[+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1],[+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1],[-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,-1],[-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1],[+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1],[+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,+1],[-1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1],[+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1],[-1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1],[-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1],[+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1],[+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1],[+1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1],[+1,+1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1],[-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1],[+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1],[+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,-1,-1,+1],[-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,-1,-1],[+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,-1],[+1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1],[+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1],[+1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1]]) -def get_had108():return torch.FloatTensor([[+1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1],[+1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1],[+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1],[+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1],[+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1],[+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1],[+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1],[+1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1],[+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1],[+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1],[+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1],[+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1],[+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1],[+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1],[+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1],[+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1],[+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1],[+1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1],[+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1],[+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1],[+1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1],[+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1],[+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1],[+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1],[+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1],[+1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1],[+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1],[+1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1],[+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1],[+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1],[+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1],[+1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1],[+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1],[+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1],[+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1],[+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1],[+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1],[+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1],[+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1],[+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1],[+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1],[+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1],[+1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1],[+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1],[+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1],[+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1],[+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1],[+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1],[+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1],[+1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1],[+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1],[+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1],[+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1],[+1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1],[+1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1],[+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1],[+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1],[+1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1],[+1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1],[+1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1],[+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1],[+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1],[+1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1],[+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1],[+1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1],[+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1],[+1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1],[+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1],[+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1],[+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1],[+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1],[+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1],[+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1],[+1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1],[+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1],[+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1],[+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1],[+1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1],[+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1],[+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1],[+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1],[+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1],[+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1],[+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1],[+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1],[+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1],[+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1],[+1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1],[+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1],[+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1],[+1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1],[+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1],[+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1],[+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1],[+1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1],[+1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1],[+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1],[+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1],[+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1],[+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1],[+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1],[+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1],[+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1],[+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1],[+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1],[+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1],[+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1]]) -def get_had140():return torch.FloatTensor([[+1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1],[+1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1],[+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1],[+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1],[+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1],[+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1],[+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1],[+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1],[+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1],[+1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1],[+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1],[+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1],[+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1],[+1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1],[+1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1],[+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1],[+1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1],[+1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1],[+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1],[+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1],[+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1],[+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1],[+1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1],[+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1],[+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1],[+1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1],[+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1],[+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1],[+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1],[+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1],[+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1],[+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1],[+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1],[+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1],[+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1],[+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1],[+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1],[+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1],[+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1],[+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1],[+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1],[+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1],[+1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1],[+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1],[+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1],[+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1],[+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1],[+1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1],[+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1],[+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1],[+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1],[+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1],[+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1],[+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1],[+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1],[+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1],[+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1],[+1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1],[+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1],[+1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1],[+1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1],[+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1],[+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1],[+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1],[+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1],[+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1],[+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1],[+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1],[+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1],[+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1],[+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1],[+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1],[+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1],[+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1],[+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1],[+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1],[+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1],[+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1],[+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1],[+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1],[+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1],[+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1],[+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1],[+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1],[+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1],[+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1],[+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1],[+1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1],[+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1],[+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1],[+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1],[+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1],[+1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1],[+1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1],[+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1],[+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1],[+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1],[+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1],[+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1],[+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1],[+1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1],[+1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1],[+1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1],[+1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1],[+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1],[+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1],[+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1],[+1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1],[+1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1],[+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1],[+1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1],[+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1],[+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1],[+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1],[+1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1],[+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1],[+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1],[+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1],[+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1],[+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1],[+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1],[+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1],[+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1],[+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1],[+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1],[+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1],[+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1],[+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1],[+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1],[+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1],[+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1],[+1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1],[+1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1],[+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1],[+1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1],[+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1],[+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1],[+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1],[+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1]]) -def get_had156():return torch.FloatTensor([[+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1],[+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1],[+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1],[-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1],[-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1],[+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1],[-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1],[+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1],[-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1],[-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1],[-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1],[-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1],[-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1],[+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1],[-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1],[-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1],[+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1],[+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1],[-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1],[-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1],[-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1],[-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1],[+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1],[+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1],[-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1],[-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1],[+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1],[-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1],[-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1],[-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1],[-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1],[-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1],[+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1],[-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1],[+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1],[-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1],[-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1],[+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1],[+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1],[-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1],[-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1],[-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1],[+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1],[+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1],[+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1],[-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1],[+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1],[+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1],[-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1],[-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1],[+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1],[+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1],[+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1],[+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1],[-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1],[+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1],[-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1],[+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1],[+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1],[-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1],[+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1],[-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1],[+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1],[+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1],[+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1],[+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1],[-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1],[-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1],[+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1],[+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1],[-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1],[+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1],[+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1],[+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1],[-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1],[-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1],[-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1],[-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1],[-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1],[-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1],[+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1],[+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1],[-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1],[-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1],[+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1],[-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1],[+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1],[+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1],[+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1],[-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1],[+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1],[-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1],[+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1],[+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1],[-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1],[+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1],[+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1],[+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1],[+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1],[-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1],[+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1],[+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1],[-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1],[+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1],[-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1],[+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1],[+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1],[+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1],[-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1],[+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1],[-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1],[-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,+1],[+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1],[+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1],[-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1],[-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,-1,-1],[-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1],[+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1],[+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1],[+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1],[-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1],[-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1],[+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1],[-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1],[+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1],[-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1],[+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1],[+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1],[+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1],[+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1],[+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1],[-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1],[-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1],[-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1],[+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1],[-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1],[-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1],[+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1],[-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1],[-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1],[-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1],[+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1],[+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1],[+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1],[+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1],[+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1],[-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1],[+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1],[-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1],[+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1,+1],[-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1,-1],[-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,-1],[+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1],[+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1],[+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1]]) -def get_had172():return torch.FloatTensor([[+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1],[-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1],[-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1],[-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1],[+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1],[+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1],[-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1],[-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1],[+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1],[+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1],[+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1],[+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1],[-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1],[+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1],[-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1],[+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1],[+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1],[+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1],[+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1],[+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1],[-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1],[-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1],[+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1],[+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1],[-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1],[+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1],[+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1],[+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1],[-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1],[+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1],[-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1],[+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1],[+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1],[+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1],[+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1],[-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1],[-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1],[+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1],[+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1],[-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1],[-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1],[-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1],[-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1],[-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1],[+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1],[-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1],[-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1],[-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1],[-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1],[-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1],[-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1],[+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1],[+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1],[+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1],[+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1],[-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1],[+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1],[-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1],[+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1],[+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1],[-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1],[-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1],[+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1],[-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1],[-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1],[+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1],[-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1],[-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1],[+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1],[+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1],[-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1],[+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1],[-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1],[+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1],[+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1],[+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1],[+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1],[-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1],[-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1],[-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1],[-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,+1],[-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1],[-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,+1],[+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1],[-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1],[-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1],[-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1],[-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1],[+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1],[-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1],[+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1],[-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1],[-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1],[+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1],[+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1],[-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1],[+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1],[-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1],[+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1],[-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1],[-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1],[-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1],[-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1],[+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1],[-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1],[+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1],[+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1],[+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1],[+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1],[-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1],[+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1],[-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1],[-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1],[-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1],[-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1],[+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1],[-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1],[+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1],[-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,+1],[+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1],[+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1],[-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1],[-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1],[+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1,-1],[-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1,-1],[+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1,+1],[-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1,-1],[-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,-1,-1,+1,-1,-1],[-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1],[-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1],[+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1],[+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1],[+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1],[-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1],[-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1],[-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1],[-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1],[+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1],[-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1],[+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1],[+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1],[-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1],[+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1],[+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1],[-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1],[-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1],[+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1],[+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1],[+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1],[+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1],[+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1],[+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1],[+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1],[+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1],[-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1],[-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1],[+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1],[+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1],[-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1],[+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1],[+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1],[-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1],[+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1,+1],[-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,+1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1,-1],[-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,+1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1,-1],[-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1,+1],[-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1,+1],[+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1,-1],[+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,+1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1,-1],[+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1,-1],[-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,+1,+1,+1,-1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,+1,-1,+1,+1,+1,+1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,-1,+1,+1,-1,+1,+1,-1,+1,+1,-1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,-1,+1,+1,-1,-1,-1,+1,+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,+1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,+1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1,+1,+1,-1,-1,-1,+1]]) +def get_had12(): + return torch.FloatTensor( + [ + [+1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], + [+1, +1, -1, +1, -1, -1, -1, +1, +1, +1, -1, +1], + [+1, +1, +1, -1, +1, -1, -1, -1, +1, +1, +1, -1], + [+1, -1, +1, +1, -1, +1, -1, -1, -1, +1, +1, +1], + [+1, +1, -1, +1, +1, -1, +1, -1, -1, -1, +1, +1], + [+1, +1, +1, -1, +1, +1, -1, +1, -1, -1, -1, +1], + [+1, +1, +1, +1, -1, +1, +1, -1, +1, -1, -1, -1], + [+1, -1, +1, +1, +1, -1, +1, +1, -1, +1, -1, -1], + [+1, -1, -1, +1, +1, +1, -1, +1, +1, -1, +1, -1], + [+1, -1, -1, -1, +1, +1, +1, -1, +1, +1, -1, +1], + [+1, +1, -1, -1, -1, +1, +1, +1, -1, +1, +1, -1], + [+1, -1, +1, -1, -1, -1, +1, +1, +1, -1, +1, +1], + ] + ) + + +def get_had44(): + return torch.FloatTensor( + [ + [ + 1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + ], + [ + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + ], + [ + 1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + ], + [ + 1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + ], + [ + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + ], + [ + 1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + ], + [ + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + ], + [ + 1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + ], + [ + 1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + ], + [ + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + ], + [ + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + ], + [ + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + ], + [ + 1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + ], + [ + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + ], + [ + 1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + ], + [ + 1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + ], + [ + 1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + ], + [ + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + ], + [ + 1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + ], + [ + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + ], + [ + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + ], + [ + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + ], + [ + 1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + ], + [ + 1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + ], + [ + 1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + ], + [ + 1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + ], + [ + 1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + ], + [ + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + ], + [ + 1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + ], + [ + 1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + ], + [ + 1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + ], + [ + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + ], + [ + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + ], + [ + 1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + -1, + ], + [ + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + 1, + ], + [ + 1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + -1, + ], + [ + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + 1, + ], + [ + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + 1, + ], + [ + 1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + -1, + ], + [ + 1, + -1, + 1, + 1, + -1, + 1, + -1, + 1, + 1, + -1, + -1, + -1, + 1, + -1, + -1, + -1, + -1, + -1, + 1, + 1, + 1, + -1, + 1, + -1, + -1, + -1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 1, + 1, + -1, + -1, + 1, + -1, + 1, + -1, + -1, + 1, + 1, + ], + ] + ) + + +def get_had40(): + return torch.FloatTensor( + [ + [ + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + ], + [ + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + ], + [ + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + ], + [ + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + ], + [ + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + ], + [ + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + ], + [ + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + ], + [ + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + ], + [ + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + ], + [ + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + ], + [ + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + ], + [ + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + ], + [ + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + ], + [ + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + ], + [ + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + ], + [ + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + ], + [ + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + ], + [ + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + ], + [ + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + ], + [ + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + ], + [ + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + ], + [ + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + ], + [ + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + ], + ] + ) + + +def get_had20(): + return torch.FloatTensor( + [ + [ + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + ], + [ + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + ], + [ + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + ], + [ + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + ], + ] + ) + + +def get_had28(): + return torch.FloatTensor( + [ + [ + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + ], + [ + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + ], + [ + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + ], + [ + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + ], + [ + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + ], + [ + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + ], + [ + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + ], + [ + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + ], + [ + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + ], + [ + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + ], + [ + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + ], + [ + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + ], + [ + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + ], + [ + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + ], + [ + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + ], + [ + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + ], + ] + ) + + +def get_had36(): + return torch.FloatTensor( + [ + [ + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + ], + [ + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + ], + [ + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + ], + [ + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + ], + [ + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + ], + [ + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + ], + [ + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + ], + [ + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + ], + [ + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + ], + [ + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + ], + [ + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + ], + [ + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + ], + [ + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + ], + [ + +1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + ], + [ + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + ], + [ + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + ], + [ + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + ], + [ + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + ], + [ + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + ], + [ + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + ], + [ + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + ], + [ + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + ], + [ + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + ], + [ + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + ], + ] + ) + + +def get_had60(): + return torch.FloatTensor( + [ + [ + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + ], + [ + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + ], + [ + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + ], + [ + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + ], + [ + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + ], + [ + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + ], + [ + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + ], + [ + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + ], + [ + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + ], + [ + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + ], + [ + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + ], + [ + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + ], + [ + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + ], + [ + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + ], + [ + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + ], + [ + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + ], + [ + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + ], + [ + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + ], + [ + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + ], + [ + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + ], + [ + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + ], + [ + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + ], + ] + ) + + +def get_had52(): + return torch.FloatTensor( + [ + [ + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + ], + [ + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + ], + [ + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + ], + [ + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + ], + [ + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + ], + [ + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + ], + [ + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + ], + [ + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + ], + [ + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + ], + [ + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + ], + [ + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + ], + [ + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + ], + [ + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + ], + [ + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + ], + [ + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + ], + [ + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + ], + [ + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + ], + [ + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + ], + [ + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + ], + [ + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + ], + [ + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + ], + [ + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + ], + [ + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + ], + [ + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + ], + [ + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + ], + [ + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + ], + [ + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + ], + [ + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + ], + [ + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + ], + [ + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + ], + [ + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + ], + [ + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + ], + [ + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + ], + [ + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + ], + [ + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + ], + [ + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + ], + [ + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + ], + [ + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + ], + [ + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + ], + [ + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + ], + [ + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + ], + [ + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + ], + [ + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + ], + ] + ) + + +def get_had108(): + return torch.FloatTensor( + [ + [ + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + ], + [ + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + ], + [ + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + ], + [ + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + ], + [ + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + ], + [ + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + ], + [ + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + ], + [ + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + ], + [ + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + ], + [ + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + ], + [ + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + ], + [ + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + ], + [ + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + ], + [ + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + ], + [ + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + ], + [ + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + ], + [ + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + ], + [ + +1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + ], + [ + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + ], + [ + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + ], + [ + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + ], + [ + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + ], + [ + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + ], + [ + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + ], + [ + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + ], + [ + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + ], + [ + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + ], + [ + +1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + ], + [ + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + ], + [ + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + ], + [ + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + ], + [ + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + ], + [ + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + ], + [ + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + ], + [ + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + ], + ] + ) + + +def get_had140(): + return torch.FloatTensor( + [ + [ + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + ], + [ + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + ], + [ + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + ], + [ + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + ], + [ + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + ], + [ + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + ], + [ + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + ], + [ + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + ], + [ + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + ], + [ + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + ], + [ + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + ], + [ + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + ], + [ + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + ], + [ + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + ], + [ + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + ], + [ + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + ], + [ + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + ], + [ + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + ], + [ + +1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + ], + [ + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + ], + [ + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + ], + [ + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + ], + [ + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + ], + [ + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + ], + [ + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + ], + [ + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + ], + [ + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + ], + [ + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + ], + [ + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + ], + [ + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + ], + [ + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + ], + [ + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + ], + [ + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + ], + [ + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + ], + [ + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + ], + [ + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + ], + [ + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + ], + [ + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + ], + [ + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + ], + ] + ) + + +def get_had156(): + return torch.FloatTensor( + [ + [ + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + ], + [ + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + ], + [ + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + ], + [ + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + ], + [ + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + ], + [ + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + ], + [ + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + ], + [ + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + ], + [ + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + ], + [ + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + ], + [ + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + ], + [ + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + ], + [ + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + ], + [ + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + ], + [ + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + ], + [ + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + ], + [ + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + ], + [ + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + ], + [ + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + ], + [ + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + ], + [ + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + ], + [ + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + ], + [ + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + ], + [ + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + ], + [ + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + ], + [ + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + ], + [ + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + ], + [ + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + ], + [ + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + ], + [ + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + ], + [ + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + ], + [ + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + ], + [ + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + ], + [ + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + ], + [ + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + ], + [ + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + ], + [ + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + ], + [ + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + ], + [ + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + ], + [ + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + ], + [ + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + ], + [ + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + ], + [ + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + ], + [ + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + ], + [ + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + ], + [ + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + ], + [ + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + ], + [ + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + ], + [ + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + ], + [ + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + ], + [ + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + ], + [ + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + ], + [ + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + ], + [ + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + ], + [ + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + ], + [ + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + ], + [ + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + ], + [ + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + ], + [ + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + ], + [ + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + ], + [ + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + ], + [ + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + ], + [ + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + ], + [ + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + ], + [ + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + ], + [ + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + ], + [ + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + ], + [ + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + ], + [ + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + ], + [ + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + ], + [ + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + ], + [ + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + ], + [ + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + ], + [ + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + ], + [ + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + ], + [ + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + ], + [ + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + ], + [ + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + ], + [ + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + ], + [ + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + ], + [ + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + ], + [ + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + ], + [ + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + ], + [ + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + ], + [ + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + ], + [ + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + ], + [ + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + ], + [ + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + ], + [ + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + ], + [ + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + ], + [ + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + ], + [ + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + ], + [ + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + ], + [ + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + ], + [ + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + ], + [ + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + ], + [ + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + ], + [ + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + ], + [ + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + ], + [ + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + ], + [ + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + ], + [ + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + ], + [ + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + ], + [ + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + ], + [ + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + ], + [ + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + ], + [ + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + ], + [ + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + ], + [ + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + ], + [ + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + ], + [ + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + ], + [ + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + ], + [ + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + ], + [ + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + ], + [ + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + ], + [ + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + ], + [ + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + ], + [ + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + ], + [ + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + ], + [ + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + ], + [ + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + ], + [ + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + ], + [ + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + ], + [ + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + ], + [ + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + ], + [ + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + ], + [ + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + ], + [ + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + ], + ] + ) + + +def get_had172(): + return torch.FloatTensor( + [ + [ + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + ], + [ + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + ], + [ + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + ], + [ + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + ], + [ + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + ], + [ + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + ], + [ + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + ], + [ + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + ], + [ + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + ], + [ + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + ], + [ + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + ], + [ + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + ], + [ + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + ], + [ + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + ], + [ + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + ], + [ + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + ], + [ + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + ], + [ + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + ], + [ + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + ], + [ + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + ], + [ + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + ], + [ + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + ], + [ + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + ], + [ + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + ], + [ + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + ], + [ + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + ], + [ + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + ], + [ + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + ], + [ + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + ], + [ + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + ], + [ + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + ], + [ + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + ], + [ + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + ], + [ + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + ], + [ + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + ], + [ + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + ], + [ + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + ], + [ + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + ], + [ + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + ], + [ + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + ], + [ + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + ], + [ + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + ], + [ + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + ], + [ + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + ], + [ + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + ], + [ + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + ], + [ + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + ], + [ + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + ], + [ + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + ], + [ + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + ], + [ + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + ], + [ + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + ], + [ + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + ], + [ + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + ], + [ + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + ], + [ + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + ], + [ + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + ], + [ + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + ], + [ + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + ], + [ + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + ], + [ + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + ], + [ + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + ], + [ + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + ], + [ + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + ], + [ + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + ], + [ + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + ], + [ + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + ], + [ + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + ], + [ + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + ], + [ + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + ], + [ + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + ], + [ + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + ], + [ + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + ], + [ + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + ], + [ + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + ], + [ + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + ], + [ + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + ], + [ + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + ], + [ + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + ], + [ + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + ], + [ + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + ], + [ + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + ], + [ + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + ], + [ + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + ], + [ + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + ], + [ + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + ], + [ + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + ], + [ + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + ], + [ + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + ], + [ + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + ], + [ + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + ], + [ + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + ], + [ + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + ], + [ + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + ], + [ + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + ], + [ + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + ], + [ + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + ], + [ + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + ], + [ + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + ], + [ + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + ], + [ + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + ], + [ + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + ], + [ + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + ], + [ + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + ], + [ + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + ], + [ + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + ], + [ + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + ], + [ + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + ], + [ + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + ], + [ + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + ], + [ + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + ], + [ + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + ], + [ + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + ], + [ + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + ], + [ + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + ], + [ + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + ], + [ + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + ], + [ + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + ], + [ + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + ], + [ + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + ], + [ + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + ], + [ + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + ], + [ + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + ], + [ + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + ], + [ + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + ], + [ + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + ], + [ + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + ], + [ + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + ], + [ + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + ], + [ + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + ], + [ + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + ], + [ + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + ], + [ + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + ], + [ + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + ], + [ + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + ], + [ + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + ], + [ + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + ], + [ + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + ], + [ + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + ], + [ + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + ], + [ + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + ], + [ + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + ], + [ + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + ], + [ + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + ], + [ + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + ], + [ + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + ], + [ + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + +1, + ], + [ + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + +1, + ], + [ + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + -1, + ], + [ + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + -1, + ], + [ + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + -1, + ], + [ + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + -1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + -1, + +1, + -1, + -1, + -1, + -1, + +1, + +1, + +1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + +1, + +1, + +1, + -1, + +1, + -1, + +1, + +1, + +1, + +1, + -1, + -1, + +1, + +1, + -1, + -1, + -1, + +1, + ], + ] + ) diff --git a/torchao/prototype/spinquant/hadamard_utils.py b/torchao/prototype/spinquant/hadamard_utils.py index 6e17a04de..e1c779c56 100644 --- a/torchao/prototype/spinquant/hadamard_utils.py +++ b/torchao/prototype/spinquant/hadamard_utils.py @@ -12,7 +12,20 @@ import torch from torchao.ops import lib -from torchao.prototype.spinquant._hadamard_matrices import get_had172, get_had156, get_had140, get_had108, get_had60, get_had52, get_had36, get_had28, get_had44, get_had40, get_had20, get_had12 +from torchao.prototype.spinquant._hadamard_matrices import ( + get_had12, + get_had20, + get_had28, + get_had36, + get_had40, + get_had44, + get_had52, + get_had60, + get_had108, + get_had140, + get_had156, + get_had172, +) from torchao.utils import TORCH_VERSION_AT_LEAST_2_4 try: @@ -25,10 +38,11 @@ def matmul_hadU(X, hadK, K): return matmul_hadU_slow(X, hadK, K) except ImportError: - - print("NOTE: Using slow Hadamard transform for SpinQuant. " - "For better performance on GPU, install `fast_hadamard_transform`: " - "`pip install git+https://github.com/Dao-AILab/fast-hadamard-transform.git`") + print( + "NOTE: Using slow Hadamard transform for SpinQuant. " + "For better performance on GPU, install `fast_hadamard_transform`: " + "`pip install git+https://github.com/Dao-AILab/fast-hadamard-transform.git`" + ) def matmul_hadU(X, hadK, K): return matmul_hadU_slow(X, hadK, K) @@ -41,6 +55,7 @@ def decorator(func): else: lib.define("hadamard_transform(Tensor x, float scale = 0.0) -> Tensor") return torch.library.impl(f"{name}", "cuda")(func) + return decorator @@ -50,6 +65,7 @@ def decorator(func): return torch.library.register_fake(f"{name}")(func) else: return torch.library.impl_abstract(f"{name}")(func) + return decorator @@ -73,7 +89,9 @@ def hadamard_transform(x: torch.Tensor, scale: float = 1.0) -> torch.Tensor: @register_custom_op_abstract("torchao::hadamard_transform") def _(x: torch.Tensor, scale: float = 1.0) -> torch.Tensor: - torch._check(x.dim() >= 1, lambda: f"input should be at least a 1D tensor, got {x.dim()}D") + torch._check( + x.dim() >= 1, lambda: f"input should be at least a 1D tensor, got {x.dim()}D" + ) return torch.empty_like(x) @@ -189,9 +207,15 @@ def matmul_hadU_slow(X, hadK, K): def matmul_hadU_fast(X, hadK, K): n = X.shape[-1] if K == 1: - return torch.ops.torchao.hadamard_transform.default(X.contiguous()) / torch.tensor(n).sqrt() + return ( + torch.ops.torchao.hadamard_transform.default(X.contiguous()) + / torch.tensor(n).sqrt() + ) input = X.view(-1, K, n // K) - input = torch.ops.torchao.hadamard_transform.default(input.contiguous()) / torch.tensor(n).sqrt() + input = ( + torch.ops.torchao.hadamard_transform.default(input.contiguous()) + / torch.tensor(n).sqrt() + ) input = hadK.to(input.device).to(input.dtype) @ input return input.reshape(X.shape) @@ -249,4 +273,4 @@ def apply_exact_had_to_linear(module, had_dim=-1, output=False, R2=None): if output: W = W.t() - module.weight.data = W.to(dtype=dtype_orig) \ No newline at end of file + module.weight.data = W.to(dtype=dtype_orig) diff --git a/torchao/prototype/spinquant/spinquant.py b/torchao/prototype/spinquant/spinquant.py index a8a791197..60ad1a8b4 100644 --- a/torchao/prototype/spinquant/spinquant.py +++ b/torchao/prototype/spinquant/spinquant.py @@ -4,14 +4,19 @@ Based on https://github.com/facebookresearch/SpinQuant """ -from pathlib import Path import typing +from pathlib import Path import torch from torch import nn -from torchao.prototype.spinquant.hadamard_utils import apply_exact_had_to_linear, random_hadamard_matrix, get_hadK, matmul_hadU from torchao._models.llama.model import RMSNorm, Transformer +from torchao.prototype.spinquant.hadamard_utils import ( + apply_exact_had_to_linear, + get_hadK, + matmul_hadU, + random_hadamard_matrix, +) class HadamardMultiplier(nn.Module): @@ -32,10 +37,16 @@ def forward(self, x): return x -def apply_spinquant(model: Transformer, use_r1=False, use_r2=False, use_r4=True, pretrained_rotation_path=None): +def apply_spinquant( + model: Transformer, + use_r1=False, + use_r2=False, + use_r4=True, + pretrained_rotation_path=None, +): """ Apply SpinQuant to a Transformer model: https://arxiv.org/abs/2405.16406 - + Currently, the R1, R2, and R4 rotation matrices are implemented, and can be used independently from each other. For R1 and R2, random Hadamard matrices are used. The default is to only use R4, which appears to show best results in many cases (see https://github.com/pytorch/ao/pull/983). @@ -53,7 +64,9 @@ def apply_spinquant(model: Transformer, use_r1=False, use_r2=False, use_r4=True, # pretrained_rotation_path = "7B_W4A16KV16_lr_1.5_seed_0/R.bin" if pretrained_rotation_path is not None: - assert Path(pretrained_rotation_path).is_file(), "Pretrained rotation path does not exist" + assert Path( + pretrained_rotation_path + ).is_file(), "Pretrained rotation path does not exist" assert Path(pretrained_rotation_path).suffix == ".bin", "Expected a .bin file." if use_r1: @@ -69,10 +82,13 @@ def apply_spinquant(model: Transformer, use_r1=False, use_r2=False, use_r4=True, def apply_spinquant_r1(model, device, pretrained_rotation_path=None): """Apply the SpinQuant R1 rotation matrix to the model.""" - + if pretrained_rotation_path is not None: R1 = torch.load(pretrained_rotation_path)["R1"].to(device).to(torch.float64) - assert R1.shape == (model.config.dim, model.config.dim), f"{R1.shape} vs {model.config.dim}" + assert R1.shape == ( + model.config.dim, + model.config.dim, + ), f"{R1.shape} vs {model.config.dim}" else: R1 = random_hadamard_matrix(model.config.dim, device) @@ -89,7 +105,10 @@ def apply_spinquant_r2(model, device, pretrained_rotation_path=None): key = f"model.layers.{i}.self_attn.R2" R2s_ = torch.load(pretrained_rotation_path) R2 = R2s_[key].to(device).to(torch.float64) - assert R2.shape == (head_dim, head_dim), f"{R2.shape} != ({head_dim}, {head_dim})" + assert R2.shape == ( + head_dim, + head_dim, + ), f"{R2.shape} != ({head_dim}, {head_dim})" else: R2 = random_hadamard_matrix(head_dim, device) R2s.append(R2) @@ -104,7 +123,9 @@ def apply_spinquant_r4(model, device): @torch.no_grad() -def _fuse_layernorm_into_linear(layernorm: RMSNorm, linear_layers: typing.Iterable[torch.nn.Linear]): +def _fuse_layernorm_into_linear( + layernorm: RMSNorm, linear_layers: typing.Iterable[torch.nn.Linear] +): """Fuse the linear operations in Layernorm into the adjacent linear blocks.""" for linear in linear_layers: linear_dtype = linear.weight.dtype @@ -150,16 +171,23 @@ def _rotate_model_r2(model, R2s): attn = layer.attention R2 = R2s[idx] - + # Rotate W_o apply_exact_had_to_linear(attn.wo, had_dim=head_dim, output=False, R2=R2) # Extract W_v kv_size = model.config.n_local_heads * head_dim - wq, wk, wv = attn.wqkv.weight.data.split([model.config.dim, kv_size, kv_size], dim=0) + wq, wk, wv = attn.wqkv.weight.data.split( + [model.config.dim, kv_size, kv_size], dim=0 + ) out_features, in_features = wv.shape - wv_mod = nn.Linear(in_features, out_features, bias=attn.wqkv.bias is not None, - device=wv.device, dtype=wv.dtype) + wv_mod = nn.Linear( + in_features, + out_features, + bias=attn.wqkv.bias is not None, + device=wv.device, + dtype=wv.dtype, + ) wv_mod.weight.data = wv # Rotate W_v @@ -188,16 +216,15 @@ def _add_activation_wrappers_r4(model): # print(f"K: {K}") for layer in model.layers: layer.feed_forward.w2 = nn.Sequential( - HadamardMultiplier(had_K, K, use_fp32=False), - layer.feed_forward.w2 + HadamardMultiplier(had_K, K, use_fp32=False), layer.feed_forward.w2 ) @torch.no_grad() def fuse_layernorm_into_linear(model): """ - Fuse RMSNorm weights into the subsequent linear layers. - + Fuse RMSNorm weights into the subsequent linear layers. + This is done in the paper specifically to make pre-norm LLMs like LLaMa rotation-invariant when quantization is not present. """ @@ -209,7 +236,9 @@ def fuse_layernorm_into_linear(model): W.weight.data = (W_ - W_.mean(dim=-1, keepdim=True)).to(W.weight.data.dtype) for layer in model.layers: - _fuse_layernorm_into_linear(layer.ffn_norm, [layer.feed_forward.w1, layer.feed_forward.w3]) + _fuse_layernorm_into_linear( + layer.ffn_norm, [layer.feed_forward.w1, layer.feed_forward.w3] + ) _fuse_layernorm_into_linear(layer.attention_norm, [layer.attention.wqkv]) _fuse_layernorm_into_linear(model.norm, [model.output]) @@ -258,4 +287,3 @@ def _rotate_mod_weight_left(mod, R): dtype = mod.weight.dtype W = mod.weight.data.to(dtype=torch.float64) mod.weight.data = torch.matmul(R.T, W).to(dtype=dtype) - diff --git a/torchao/prototype/splitk/__init__.py b/torchao/prototype/splitk/__init__.py index 44983dbf4..2e4cacaac 100644 --- a/torchao/prototype/splitk/__init__.py +++ b/torchao/prototype/splitk/__init__.py @@ -1 +1,6 @@ from .splitk_gemm import gemm_split_k, to_float8 + +__all__ = [ + "gemm_split_k", + "to_float8", +] diff --git a/torchao/prototype/splitk/splitk_gemm.py b/torchao/prototype/splitk/splitk_gemm.py index 1efaa731d..9f4027b8a 100644 --- a/torchao/prototype/splitk/splitk_gemm.py +++ b/torchao/prototype/splitk/splitk_gemm.py @@ -1,14 +1,16 @@ +import os + import torch import triton import triton.language as tl -import os -os.environ['ENABLE_TMA'] = '1' -@triton.jit -def grouped_launch(pid, - m, n, - block_m: tl.constexpr, block_n: tl.constexpr, group_m: tl.constexpr): +os.environ["ENABLE_TMA"] = "1" + +@triton.jit +def grouped_launch( + pid, m, n, block_m: tl.constexpr, block_n: tl.constexpr, group_m: tl.constexpr +): grid_m = tl.cdiv(m, block_m) grid_n = tl.cdiv(n, block_n) @@ -21,27 +23,38 @@ def grouped_launch(pid, return pid_m, pid_n -@triton.jit -def gemm_split_k_kernel(a_ptr, b_ptr, c_ptr, - stride_am, stride_ak, - stride_bk, stride_bn, - stride_cm, stride_cn, - scale_a, scale_b, - m, n, k, - block_m: tl.constexpr, block_n: tl.constexpr, block_k: tl.constexpr, - split_k: tl.constexpr, group_m: tl.constexpr): +@triton.jit +def gemm_split_k_kernel( + a_ptr, + b_ptr, + c_ptr, + stride_am, + stride_ak, + stride_bk, + stride_bn, + stride_cm, + stride_cn, + scale_a, + scale_b, + m, + n, + k, + block_m: tl.constexpr, + block_n: tl.constexpr, + block_k: tl.constexpr, + split_k: tl.constexpr, + group_m: tl.constexpr, +): pid = tl.program_id(0) pid_k = tl.program_id(1) - grid_k = tl.cdiv(k, block_k*split_k) + grid_k = tl.cdiv(k, block_k * split_k) - pid_m, pid_n = grouped_launch(pid, - m, n, - block_m, block_n, group_m) + pid_m, pid_n = grouped_launch(pid, m, n, block_m, block_n, group_m) - offs_m = pid_m*block_m + tl.arange(0, block_m) - offs_n = pid_n*block_n + tl.arange(0, block_n) - offs_k = pid_k*block_k + tl.arange(0, block_k) + offs_m = pid_m * block_m + tl.arange(0, block_m) + offs_n = pid_n * block_n + tl.arange(0, block_n) + offs_k = pid_k * block_k + tl.arange(0, block_k) offs_am = tl.max_contiguous(tl.multiple_of(offs_m, block_m), block_m) offs_bn = tl.max_contiguous(tl.multiple_of(offs_n, block_n), block_n) @@ -49,10 +62,8 @@ def gemm_split_k_kernel(a_ptr, b_ptr, c_ptr, a_ptrs = a_ptr + (offs_am[:, None] * stride_am + offs_k[None, :] * stride_ak) b_ptrs = b_ptr + (offs_k[:, None] * stride_bk + offs_bn[None, :] * stride_bn) - acc = tl.zeros((block_m, block_n), dtype=tl.float32) for k_ in range(0, grid_k): - k_remaining = k - k_ * (block_k * split_k) a = tl.load(a_ptrs, mask=offs_k[None, :] < k_remaining, other=0.0) @@ -66,15 +77,16 @@ def gemm_split_k_kernel(a_ptr, b_ptr, c_ptr, acc = scale_a * scale_b * acc acc.to(tl.float16) - offs_m = pid_m*block_m + tl.arange(0, block_m) - offs_n = pid_n*block_n + tl.arange(0, block_n) + offs_m = pid_m * block_m + tl.arange(0, block_m) + offs_n = pid_n * block_n + tl.arange(0, block_n) c_ptrs = c_ptr + (offs_m[:, None] * stride_cm + offs_n[None, :] * stride_cn) mask = (offs_m < m)[:, None] & (offs_n < n)[None, :] tl.atomic_add(c_ptrs, acc, mask=mask) -def gemm_split_k(a, b, scale_a:float=1.0, scale_b:float=1.0): + +def gemm_split_k(a, b, scale_a: float = 1.0, scale_b: float = 1.0): assert a.shape[1] == b.shape[0] m, k = a.shape _, n = b.shape @@ -95,14 +107,29 @@ def gemm_split_k(a, b, scale_a:float=1.0, scale_b:float=1.0): grid = (total_programs_mn, total_programs_k) c = torch.zeros((m, n), device=a.device, dtype=torch.float16) - k = gemm_split_k_kernel[grid](a, b, c, - a.stride(0), a.stride(1), - b.stride(0), b.stride(1), - c.stride(0), c.stride(1), - scale_a, scale_b, - m, n, k, - block_m, block_n, block_k, - split_k, group_m, num_stages=num_stages, num_warps=num_warps) + k = gemm_split_k_kernel[grid]( + a, + b, + c, + a.stride(0), + a.stride(1), + b.stride(0), + b.stride(1), + c.stride(0), + c.stride(1), + scale_a, + scale_b, + m, + n, + k, + block_m, + block_n, + block_k, + split_k, + group_m, + num_stages=num_stages, + num_warps=num_warps, + ) return c From e1d88997f8fd3f18a1026054f737e3dbcfee80bc Mon Sep 17 00:00:00 2001 From: Jerry Zhang Date: Tue, 7 Jan 2025 19:20:05 -0800 Subject: [PATCH 5/9] Add min_sqnr to torchao/_models (#1502) * Add min_sqnr to torchao/_models Summary: att, this allows us to run benchmarks with different min_sqnr to control the accuracy loss of the model Test Plan: ``` export CHECKPOINT_PATH=checkpoints export MODEL_REPO=meta-llama/Meta-Llama-3.1-8B python torchao/_models/llama/generate.py --checkpoint_path "${CHECKPOINT_PATH}/${MODEL_REPO}/model.pth" --compile --compile_prefill --quantization autoquant-all --output_json_path benchmark-results.json --outpu\t_json_local --min_sqnr 40 python torchao/_models/sam/eval_combo.py --coco_root_dir datasets/coco2017 --coco_slice_name val2017 --sam_checkpoint_base_path checkpoints --sam_model_type vit_h --point_sampling_cache_dir tmp/sam_coco_mask_ce\nter_cache --mask_debug_out_dir tmp/sam_eval_masks_out --batch_size 32 --num_workers 8 --use_compile max-autotune --use_half bfloat16 --device cuda --compress autoquant-all --output_json_path benchmark-results.json\ --output_json_local --min_sqnr 40 cd examples/sam2_amg_server python server.py ../../${CHECKPOINT_PATH}/sam2 large --port 4000 --host localhost --fast --use_autoquant --benchmark --dry --output_json_path ../../benchmark-results.json --output_json_local --min_sqnr 40 ``` Reviewers: Subscribers: Tasks: Tags: * change origins * add min_sqnr to result * add min_sqnr to result * cleanup --- .../sam2_amg_server/compile_export_utils.py | 308 +++++++---- examples/sam2_amg_server/server.py | 510 +++++++++++------- torchao/_models/llama/generate.py | 44 +- torchao/_models/sam/eval_combo.py | 33 +- torchao/_models/utils.py | 6 +- torchao/quantization/autoquant.py | 24 +- 6 files changed, 605 insertions(+), 320 deletions(-) diff --git a/examples/sam2_amg_server/compile_export_utils.py b/examples/sam2_amg_server/compile_export_utils.py index 9237a2dd5..27c4ee7b0 100644 --- a/examples/sam2_amg_server/compile_export_utils.py +++ b/examples/sam2_amg_server/compile_export_utils.py @@ -1,7 +1,9 @@ -import torch import time from pathlib import Path from typing import Optional + +import torch + from torchao._models.sam2.sam2_image_predictor import SAM2ImagePredictor # Tools used to avoid compilation cold start and dynamo cache lookups @@ -13,6 +15,7 @@ TASK_TYPES = ["amg", "sps", "mps"] + # NOTE: We have to declare a separate class, because torch.export demands it. # We build this explicitly for the sole purpose of exporting _predict_masks # We made sure _predict_masks is fullgraph=True compileable so it can be exported @@ -20,12 +23,14 @@ # any expected recompilations. We'll add in guards to prevent unexpectedly # large inputs. class SAM2ImagePredictor_predict_masks(torch.nn.Module): - def __init__(self, - predictor: Optional[SAM2ImagePredictor], - batch_size=1, - points_per_batch=1024, - aoti_compiled_model=None, - furious=False): + def __init__( + self, + predictor: Optional[SAM2ImagePredictor], + batch_size=1, + points_per_batch=1024, + aoti_compiled_model=None, + furious=False, + ): super().__init__() self.predictor = predictor self.batch_size = batch_size @@ -33,16 +38,18 @@ def __init__(self, self.aoti_compiled_model = aoti_compiled_model self.furious = furious - def forward(self, - high_res_feats, - image_embed, - image_pe, - point_coords, - point_labels, - boxes: Optional[torch.Tensor] = None, - mask_input: Optional[torch.Tensor] = None, - multimask_output: bool = True, - img_idx: int = -1): + def forward( + self, + high_res_feats, + image_embed, + image_pe, + point_coords, + point_labels, + boxes: Optional[torch.Tensor] = None, + mask_input: Optional[torch.Tensor] = None, + multimask_output: bool = True, + img_idx: int = -1, + ): assert high_res_feats[0].size() == (self.batch_size, 32, 256, 256) assert high_res_feats[1].size() == (self.batch_size, 64, 128, 128) if self.furious: @@ -69,33 +76,39 @@ def forward(self, assert img_idx == -1 if self.predictor is None: assert self.aoti_compiled_model is not None - return self.aoti_compiled_model(high_res_feats, - image_embed, - image_pe, - point_coords, - point_labels, - boxes=boxes, - mask_input=mask_input, - multimask_output=multimask_output, - img_idx=img_idx) - return self.predictor._predict_masks(high_res_feats, - image_embed, - image_pe, - point_coords, - point_labels, - boxes=boxes, - mask_input=mask_input, - multimask_output=multimask_output, - img_idx=img_idx) - - -def aot_compile(model_directory, - name, - fn, - sample_args, - sample_kwargs=None, - options=None, - overwrite=False): + return self.aoti_compiled_model( + high_res_feats, + image_embed, + image_pe, + point_coords, + point_labels, + boxes=boxes, + mask_input=mask_input, + multimask_output=multimask_output, + img_idx=img_idx, + ) + return self.predictor._predict_masks( + high_res_feats, + image_embed, + image_pe, + point_coords, + point_labels, + boxes=boxes, + mask_input=mask_input, + multimask_output=multimask_output, + img_idx=img_idx, + ) + + +def aot_compile( + model_directory, + name, + fn, + sample_args, + sample_kwargs=None, + options=None, + overwrite=False, +): path = Path(model_directory) / Path(f"{name}.pt2") if path.exists() and not overwrite: raise ValueError(f"{path} already exists and overwrite is {overwrite}") @@ -107,6 +120,7 @@ def aot_compile(model_directory, } from torch.export import export_for_inference + exported = export_for_inference(fn, sample_args, sample_kwargs) output_path = torch._inductor.aoti_compile_and_package( exported, @@ -121,7 +135,6 @@ def aot_load(path): class FunctionModel(torch.nn.Module): - def __init__(self, module, fn_name): super().__init__() self.module = module @@ -131,69 +144,123 @@ def forward(self, *args): return getattr(self.module, self.fn_name)(*args) -def export_model(mask_generator, - model_directory, - task_type, - furious=False, - batch_size=1, - points_per_batch=None, - overwrite=False): +def export_model( + mask_generator, + model_directory, + task_type, + furious=False, + batch_size=1, + points_per_batch=None, + overwrite=False, +): if furious: set_furious(mask_generator) assert task_type in TASK_TYPES, f"Expected {task_type} to be one of {TASK_TYPES}" if task_type in ["sps", "amg"]: - assert points_per_batch is not None, f"Specify points_per_batch for task {task_type}" + assert ( + points_per_batch is not None + ), f"Specify points_per_batch for task {task_type}" if task_type == "sps": - assert points_per_batch == 1, f"Expected points_per_batch set to 1 for {task_type} but got {points_per_batch}" - + assert ( + points_per_batch == 1 + ), f"Expected points_per_batch set to 1 for {task_type} but got {points_per_batch}" example_input = torch.empty(batch_size, 3, 1024, 1024) example_input = example_input.to(mask_generator.predictor._image_dtype) example_input = (example_input.to(mask_generator.predictor.device),) - aot_compile(model_directory, - "sam2_image_encoder", - mask_generator.predictor.model.image_encoder, - example_input, - overwrite=overwrite) + aot_compile( + model_directory, + "sam2_image_encoder", + mask_generator.predictor.model.image_encoder, + example_input, + overwrite=overwrite, + ) print(f"{task_type} cannot export _predict_masks") return if task_type in ["sps"]: - example_input_high_res_feats = [torch.randn(batch_size, 32, 256, 256, dtype=mask_generator.predictor._image_dtype, device=mask_generator.predictor.device), - torch.randn(batch_size, 64, 128, 128, dtype=mask_generator.predictor._image_dtype, device=mask_generator.predictor.device)] - example_input_image_embed = torch.randn(batch_size, 256, 64, 64, dtype=torch.float32, device=mask_generator.predictor.device) - example_input_image_pe = torch.randn(batch_size, 256, 64, 64, dtype=torch.float32, device=mask_generator.predictor.device) - example_input_point_coords = torch.randn(points_per_batch, 1, 2, dtype=torch.float32, device=mask_generator.predictor.device) - example_input_point_labels = torch.ones(points_per_batch, 1, dtype=torch.int32, device=mask_generator.predictor.device) - example_input_args = (example_input_high_res_feats, - example_input_image_embed, - example_input_image_pe, - example_input_point_coords, - example_input_point_labels) - - example_input_kwargs = {"boxes": None, - "mask_input": None, - "multimask_output": True, - "img_idx": -1, - } - - sam2_image_predict_masks = SAM2ImagePredictor_predict_masks(mask_generator.predictor, - batch_size=batch_size, - points_per_batch=points_per_batch, - furious=furious) - aot_compile(model_directory, - "sam2_image_predict_masks", - sam2_image_predict_masks, - example_input_args, - sample_kwargs=example_input_kwargs, - overwrite=overwrite) + example_input_high_res_feats = [ + torch.randn( + batch_size, + 32, + 256, + 256, + dtype=mask_generator.predictor._image_dtype, + device=mask_generator.predictor.device, + ), + torch.randn( + batch_size, + 64, + 128, + 128, + dtype=mask_generator.predictor._image_dtype, + device=mask_generator.predictor.device, + ), + ] + example_input_image_embed = torch.randn( + batch_size, + 256, + 64, + 64, + dtype=torch.float32, + device=mask_generator.predictor.device, + ) + example_input_image_pe = torch.randn( + batch_size, + 256, + 64, + 64, + dtype=torch.float32, + device=mask_generator.predictor.device, + ) + example_input_point_coords = torch.randn( + points_per_batch, + 1, + 2, + dtype=torch.float32, + device=mask_generator.predictor.device, + ) + example_input_point_labels = torch.ones( + points_per_batch, + 1, + dtype=torch.int32, + device=mask_generator.predictor.device, + ) + example_input_args = ( + example_input_high_res_feats, + example_input_image_embed, + example_input_image_pe, + example_input_point_coords, + example_input_point_labels, + ) + + example_input_kwargs = { + "boxes": None, + "mask_input": None, + "multimask_output": True, + "img_idx": -1, + } + + sam2_image_predict_masks = SAM2ImagePredictor_predict_masks( + mask_generator.predictor, + batch_size=batch_size, + points_per_batch=points_per_batch, + furious=furious, + ) + aot_compile( + model_directory, + "sam2_image_predict_masks", + sam2_image_predict_masks, + example_input_args, + sample_kwargs=example_input_kwargs, + overwrite=overwrite, + ) else: print(f"{task_type} cannot export _predict_masks") class LoadedModel(torch.nn.Module): - def __init__(self, aoti_compiled_model): super().__init__() self.aoti_compiled_model = aoti_compiled_model @@ -203,7 +270,6 @@ def forward(self, *args, **kwargs): class LoadedDecoder(torch.nn.Module): - def __init__(self, aoti_compiled_model, other): super().__init__() self.aoti_compiled_model = aoti_compiled_model @@ -216,12 +282,14 @@ def get_dense_pe(self, *args, **kwargs) -> torch.Tensor: return self.other.get_dense_pe(*args, **kwargs) -def load_exported_model(mask_generator, - model_directory, - task_type, - furious=False, - batch_size=1, - points_per_batch=1024): +def load_exported_model( + mask_generator, + model_directory, + task_type, + furious=False, + batch_size=1, + points_per_batch=1024, +): if furious: set_furious(mask_generator) assert task_type in TASK_TYPES, f"Expected {task_type} to be one of {TASK_TYPES}" @@ -239,7 +307,7 @@ def load_exported_model(mask_generator, if task_type in ["amg", "mps"]: return mask_generator - path = Path(model_directory) / Path(f"sam2_image_predict_masks.pt2") + path = Path(model_directory) / Path("sam2_image_predict_masks.pt2") assert path.exists(), f"Expected {path} to exist" print(f"Start load from {path}") pkg = torch._inductor.aoti_load_package(str(path)) @@ -249,17 +317,24 @@ def load_exported_model(mask_generator, assert points_per_batch == 1 if task_type == "mps": assert points_per_batch is None - pkg_m = SAM2ImagePredictor_predict_masks(None, - batch_size=batch_size, - points_per_batch=points_per_batch, - aoti_compiled_model=pkg, - furious=furious) + pkg_m = SAM2ImagePredictor_predict_masks( + None, + batch_size=batch_size, + points_per_batch=points_per_batch, + aoti_compiled_model=pkg, + furious=furious, + ) mask_generator.predictor._predict_masks = pkg_m.forward print(f"End load image encoder and predict masks. Took {time.time() - t0}s") -def set_fast(mask_generator, task_type, loaded_exported_model=False, allow_recompiles=True): +def set_fast( + mask_generator, task_type, loaded_exported_model=False, allow_recompiles=True +): + if task_type == "": + task_type = "amg" + assert task_type in TASK_TYPES, f"Expected {task_type} to be one of {TASK_TYPES}" if not loaded_exported_model: # TODO: Using CUDA graphs can cause numerical differences? @@ -296,22 +371,35 @@ def set_fast(mask_generator, task_type, loaded_exported_model=False, allow_recom ) import torchao + if allow_recompiles: # A bunch of extra compiles at module level # Note that this can cause recompilations! # We might want to guard on that - torchao._models.sam2.utils.amg._mask_to_rle_pytorch_2_0_0 = torch.compile(fullgraph=True, dynamic=True)(torchao._models.sam2.utils.amg._mask_to_rle_pytorch_2_0_0) - torchao._models.sam2.utils.amg._mask_to_rle_pytorch_2_0_1 = torch.compile(fullgraph=True, dynamic=True)(torchao._models.sam2.utils.amg._mask_to_rle_pytorch_2_0_1) - mask_generator.calculate_stability_score = torch.compile(fullgraph=True, dynamic=True)(mask_generator.calculate_stability_score) - mask_generator.batched_mask_to_box = torch.compile(fullgraph=True, dynamic=True)(mask_generator.batched_mask_to_box) + torchao._models.sam2.utils.amg._mask_to_rle_pytorch_2_0_0 = torch.compile( + fullgraph=True, dynamic=True + )(torchao._models.sam2.utils.amg._mask_to_rle_pytorch_2_0_0) + torchao._models.sam2.utils.amg._mask_to_rle_pytorch_2_0_1 = torch.compile( + fullgraph=True, dynamic=True + )(torchao._models.sam2.utils.amg._mask_to_rle_pytorch_2_0_1) + mask_generator.calculate_stability_score = torch.compile( + fullgraph=True, dynamic=True + )(mask_generator.calculate_stability_score) + mask_generator.batched_mask_to_box = torch.compile( + fullgraph=True, dynamic=True + )(mask_generator.batched_mask_to_box) def set_furious(mask_generator): - mask_generator.predictor.model.image_encoder = mask_generator.predictor.model.image_encoder.to(torch.float16) + mask_generator.predictor.model.image_encoder = ( + mask_generator.predictor.model.image_encoder.to(torch.float16) + ) # NOTE: Not baseline feature mask_generator.predictor._image_dtype = torch.float16 mask_generator.predictor._transforms_device = mask_generator.predictor.device - torch.set_float32_matmul_precision('high') - mask_generator.predictor.model.sam_mask_decoder = mask_generator.predictor.model.sam_mask_decoder.to(torch.float16) + torch.set_float32_matmul_precision("high") + mask_generator.predictor.model.sam_mask_decoder = ( + mask_generator.predictor.model.sam_mask_decoder.to(torch.float16) + ) # NOTE: Not baseline feature mask_generator.predictor.model.sam_mask_decoder._src_dtype = torch.float16 diff --git a/examples/sam2_amg_server/server.py b/examples/sam2_amg_server/server.py index 2fa216176..8d0f4c813 100644 --- a/examples/sam2_amg_server/server.py +++ b/examples/sam2_amg_server/server.py @@ -1,45 +1,37 @@ -import itertools -import requests -import uvicorn -import fire -import tempfile +import asyncio +import json import logging -import sys import time -import json +from contextlib import asynccontextmanager +from io import BytesIO from pathlib import Path -from typing import List, Optional +import cv2 +import fire +import matplotlib.pyplot as plt +import numpy as np +import requests import torch import torch._dynamo.config import torch._inductor.config -from fastapi.responses import Response +import uvicorn +from compile_export_utils import ( + export_model, + load_exported_model, + set_fast, + set_furious, +) from fastapi import FastAPI, File, UploadFile -from fastapi.responses import StreamingResponse from fastapi.middleware.cors import CORSMiddleware -from io import BytesIO -import shutil -from pydantic import BaseModel -import cv2 - -import matplotlib.pyplot as plt -import numpy as np +from fastapi.responses import StreamingResponse +from torch._inductor import config as inductorconfig -import asyncio -from contextlib import asynccontextmanager -import contextlib from torchao._models.utils import ( get_arch_name, - write_json_result_ossci, write_json_result_local, + write_json_result_ossci, ) -from compile_export_utils import set_fast -from compile_export_utils import set_furious -from compile_export_utils import load_exported_model -from compile_export_utils import export_model - -from torch._inductor import config as inductorconfig inductorconfig.triton.unique_kernel_names = True inductorconfig.coordinate_descent_tuning = True inductorconfig.coordinate_descent_check_all_directions = True @@ -48,12 +40,13 @@ # torch._dynamo.config.capture_dynamic_output_shape_ops = True torch._dynamo.config.capture_dynamic_output_shape_ops = True + def download_file(url, download_dir): # Create the directory if it doesn't exist download_dir = Path(download_dir) download_dir.mkdir(parents=True, exist_ok=True) # Extract the file name from the URL - file_name = url.split('/')[-1] + file_name = url.split("/")[-1] # Define the full path for the downloaded file file_path = download_dir / file_name # Download the file @@ -61,110 +54,123 @@ def download_file(url, download_dir): response.raise_for_status() # Raise an error for bad responses # Write the file to the specified directory print(f"Downloading '{file_name}' to '{download_dir}'") - with open(file_path, 'wb') as file: + with open(file_path, "wb") as file: for chunk in response.iter_content(chunk_size=8192): file.write(chunk) print(f"Downloaded '{file_name}' to '{download_dir}'") + def example_shapes(): - return [(848, 480, 3), - (720, 1280, 3), - (848, 480, 3), - (1280, 720, 3), - (480, 848, 3), - (1080, 1920, 3), - (1280, 720, 3), - (1280, 720, 3), - (720, 1280, 3), - (848, 480, 3), - (480, 848, 3), - (864, 480, 3), - (1920, 1080, 3), - (1920, 1080, 3), - (1280, 720, 3), - (1232, 672, 3), - (848, 480, 3), - (848, 480, 3), - (1920, 1080, 3), - (1080, 1920, 3), - (480, 848, 3), - (848, 480, 3), - (480, 848, 3), - (480, 848, 3), - (720, 1280, 3), - (720, 1280, 3), - (900, 720, 3), - (848, 480, 3), - (864, 480, 3), - (360, 640, 3), - (360, 640, 3), - (864, 480, 3)] + return [ + (848, 480, 3), + (720, 1280, 3), + (848, 480, 3), + (1280, 720, 3), + (480, 848, 3), + (1080, 1920, 3), + (1280, 720, 3), + (1280, 720, 3), + (720, 1280, 3), + (848, 480, 3), + (480, 848, 3), + (864, 480, 3), + (1920, 1080, 3), + (1920, 1080, 3), + (1280, 720, 3), + (1232, 672, 3), + (848, 480, 3), + (848, 480, 3), + (1920, 1080, 3), + (1080, 1920, 3), + (480, 848, 3), + (848, 480, 3), + (480, 848, 3), + (480, 848, 3), + (720, 1280, 3), + (720, 1280, 3), + (900, 720, 3), + (848, 480, 3), + (864, 480, 3), + (360, 640, 3), + (360, 640, 3), + (864, 480, 3), + ] def example_shapes_2(): - return [(1080, 1920, 3), - (1920, 1080, 3), - (1920, 1080, 3), - (1080, 1920, 3), - (848, 480, 3), - (864, 480, 3), - (720, 1280, 3), - (864, 480, 3), - (848, 480, 3), - (848, 480, 3), - (848, 480, 3), - (848, 480, 3), - (720, 1280, 3), - (864, 480, 3), - (480, 848, 3), - (1280, 720, 3), - (720, 1280, 3), - (1080, 1920, 3), - (1080, 1920, 3), - (1280, 720, 3), - (1080, 1920, 3), - (1080, 1920, 3), - (720, 1280, 3), - (720, 1280, 3), - (1280, 720, 3), - (360, 640, 3), - (864, 480, 3), - (1920, 1080, 3), - (1080, 1920, 3), - (1920, 1080, 3), - (1920, 1080, 3), - (1080, 1920, 3)] + return [ + (1080, 1920, 3), + (1920, 1080, 3), + (1920, 1080, 3), + (1080, 1920, 3), + (848, 480, 3), + (864, 480, 3), + (720, 1280, 3), + (864, 480, 3), + (848, 480, 3), + (848, 480, 3), + (848, 480, 3), + (848, 480, 3), + (720, 1280, 3), + (864, 480, 3), + (480, 848, 3), + (1280, 720, 3), + (720, 1280, 3), + (1080, 1920, 3), + (1080, 1920, 3), + (1280, 720, 3), + (1080, 1920, 3), + (1080, 1920, 3), + (720, 1280, 3), + (720, 1280, 3), + (1280, 720, 3), + (360, 640, 3), + (864, 480, 3), + (1920, 1080, 3), + (1080, 1920, 3), + (1920, 1080, 3), + (1920, 1080, 3), + (1080, 1920, 3), + ] + # torch.set_float32_matmul_precision('high') + def iou(mask1, mask2): assert mask1.dim() == 2 assert mask2.dim() == 2 intersection = torch.logical_and(mask1, mask2) union = torch.logical_or(mask1, mask2) - return (intersection.sum(dim=(-1, -2)) / union.sum(dim=(-1, -2))) + return intersection.sum(dim=(-1, -2)) / union.sum(dim=(-1, -2)) def show_anns(anns, rle_to_mask, sort_by_area=True, seed=None): if len(anns) == 0: return if sort_by_area: - sorted_anns = sorted(anns, key=(lambda x: x['area']), reverse=True) + sorted_anns = sorted(anns, key=(lambda x: x["area"]), reverse=True) else: sorted_anns = anns ax = plt.gca() ax.set_autoscale_on(False) for ann in sorted_anns: - ann['segmentation'] = rle_to_mask(ann['segmentation']) - - img = np.ones((sorted_anns[0]['segmentation'].shape[0], sorted_anns[0]['segmentation'].shape[1], 4)) - img[:,:,3] = 0 + ann["segmentation"] = rle_to_mask(ann["segmentation"]) + + img = np.ones( + ( + sorted_anns[0]["segmentation"].shape[0], + sorted_anns[0]["segmentation"].shape[1], + 4, + ) + ) + img[:, :, 3] = 0 np.random.seed(seed) ms = [] for ann in sorted_anns: - m = ann['segmentation'] + m = ann["segmentation"] ms.append(torch.as_tensor(m)) color_mask = np.concatenate([np.random.random(3), [0.35]]) img[m] = color_mask @@ -174,9 +180,12 @@ def show_anns(anns, rle_to_mask, sort_by_area=True, seed=None): def profiler_runner(path, fn, *args, **kwargs): with torch.profiler.profile( - activities=[torch.profiler.ProfilerActivity.CPU, - torch.profiler.ProfilerActivity.CUDA], - record_shapes=True) as prof: + activities=[ + torch.profiler.ProfilerActivity.CPU, + torch.profiler.ProfilerActivity.CUDA, + ], + record_shapes=True, + ) as prof: result = fn(*args, **kwargs) prof.export_chrome_trace(path) return result @@ -186,16 +195,15 @@ def memory_runner(path, fn, *args, **kwargs): print("Start memory recording") torch.cuda.synchronize() torch.cuda.memory._record_memory_history( - True, - trace_alloc_max_entries=100000, - trace_alloc_record_context=True + True, trace_alloc_max_entries=100000, trace_alloc_record_context=True ) result = fn(*args, **kwargs) torch.cuda.synchronize() snapshot = torch.cuda.memory._snapshot() print("Finish memory recording") import pickle - with open(path, 'wb') as f: + + with open(path, "wb") as f: pickle.dump(snapshot, f) # Use to convert pickle file into html # python torch/cuda/_memory_viz.py trace_plot .pickle -o .html @@ -218,9 +226,11 @@ def file_bytes_to_image_tensor(file_bytes, output_format="numpy"): if output_format == "numpy": return example_image if output_format not in ["torch"]: - raise ValueError("Expected output_format to be numpy or torch," - f" but got {output_format}") + raise ValueError( + "Expected output_format to be numpy or torch," f" but got {output_format}" + ) from torchvision.transforms import ToTensor + return ToTensor()(example_image) @@ -257,7 +267,6 @@ async def batch_worker(mask_generator, batch_size, *, pad_batch=True, furious=Fa batch.append(await request_queue.get()) if batch: - padded_batch = batch if pad_batch: padded_batch = batch + ([batch[-1]] * (batch_size - len(batch))) @@ -274,7 +283,9 @@ async def lifespan(app: FastAPI): mask_generator = app.state.mask_generator batch_size = app.state.batch_size furious = app.state.furious - task = asyncio.create_task(batch_worker(mask_generator, batch_size, furious=furious)) + task = asyncio.create_task( + batch_worker(mask_generator, batch_size, furious=furious) + ) yield # Shutdown logic (if needed) task.cancel() @@ -290,7 +301,7 @@ def benchmark_fn(func, inp, mask_generator, warmup=3, runs=10): t = time.time() for _ in range(runs): func(inp, mask_generator) - avg_time_per_run = (time.time() - t)/runs + avg_time_per_run = (time.time() - t) / runs print(f"Benchmark took {avg_time_per_run}s per iteration.") max_memory_allocated_bytes, max_memory_allocated_percentage = max_memory_allocated() return avg_time_per_run, max_memory_allocated_bytes, max_memory_allocated_percentage @@ -299,9 +310,13 @@ def benchmark_fn(func, inp, mask_generator, warmup=3, runs=10): def max_memory_allocated_stats(): max_memory_allocated_bytes = torch.cuda.max_memory_allocated() _, total_memory = torch.cuda.mem_get_info() - max_memory_allocated_percentage = int(100 * (max_memory_allocated_bytes / total_memory)) - return {"bytes": max_memory_allocated_bytes, - "percentage": max_memory_allocated_percentage} + max_memory_allocated_percentage = int( + 100 * (max_memory_allocated_bytes / total_memory) + ) + return { + "bytes": max_memory_allocated_bytes, + "percentage": max_memory_allocated_percentage, + } def max_memory_allocated(): @@ -309,11 +324,15 @@ def max_memory_allocated(): mib = stats["bytes"] >> 20 print(f"max_memory_allocated_bytes: {mib}MiB") print(f"max_memory_allocated_percentage: {stats['percentage']}%") + return mib, stats["percentage"] def unittest_fn(masks, ref_masks, order_by_area=False, verbose=False): from compare_rle_lists import compare_masks - miou, equal_count = compare_masks(masks, ref_masks, order_by_area=order_by_area, verbose=verbose) + + miou, equal_count = compare_masks( + masks, ref_masks, order_by_area=order_by_area, verbose=verbose + ) if equal_count == len(masks): print("Masks exactly match reference.") else: @@ -321,26 +340,26 @@ def unittest_fn(masks, ref_masks, order_by_area=False, verbose=False): MODEL_TYPES_TO_CONFIG = { - "tiny": "sam2.1_hiera_t.yaml", - "small": "sam2.1_hiera_s.yaml", - "plus": "sam2.1_hiera_b+.yaml", - "large": "sam2.1_hiera_l.yaml", - } + "tiny": "sam2.1_hiera_t.yaml", + "small": "sam2.1_hiera_s.yaml", + "plus": "sam2.1_hiera_b+.yaml", + "large": "sam2.1_hiera_l.yaml", +} MODEL_TYPES_TO_MODEL = { - "tiny": "sam2.1_hiera_tiny.pt", - "small": "sam2.1_hiera_small.pt", - "plus": "sam2.1_hiera_base_plus.pt", - "large": "sam2.1_hiera_large.pt", - } + "tiny": "sam2.1_hiera_tiny.pt", + "small": "sam2.1_hiera_small.pt", + "plus": "sam2.1_hiera_base_plus.pt", + "large": "sam2.1_hiera_large.pt", +} MODEL_TYPES_TO_URL = { - "tiny": "https://dl.fbaipublicfiles.com/segment_anything_2/092824/sam2.1_hiera_tiny.pt", - "small": "https://dl.fbaipublicfiles.com/segment_anything_2/092824/sam2.1_hiera_small.pt", - "plus": "https://dl.fbaipublicfiles.com/segment_anything_2/092824/sam2.1_hiera_base_plus.pt", - "large": "https://dl.fbaipublicfiles.com/segment_anything_2/092824/sam2.1_hiera_large.pt", - } + "tiny": "https://dl.fbaipublicfiles.com/segment_anything_2/092824/sam2.1_hiera_tiny.pt", + "small": "https://dl.fbaipublicfiles.com/segment_anything_2/092824/sam2.1_hiera_small.pt", + "plus": "https://dl.fbaipublicfiles.com/segment_anything_2/092824/sam2.1_hiera_base_plus.pt", + "large": "https://dl.fbaipublicfiles.com/segment_anything_2/092824/sam2.1_hiera_large.pt", +} def main_docstring(): @@ -353,107 +372,150 @@ def main_docstring(): def model_type_to_paths(checkpoint_path, model_type): if model_type not in MODEL_TYPES_TO_CONFIG.keys(): - raise ValueError(f"Expected model_type to be one of {', '.join(MODEL_TYPES_TO_MODEL.keys())} but got {model_type}") + raise ValueError( + f"Expected model_type to be one of {', '.join(MODEL_TYPES_TO_MODEL.keys())} but got {model_type}" + ) sam2_checkpoint = Path(checkpoint_path) / Path(MODEL_TYPES_TO_MODEL[model_type]) if not sam2_checkpoint.exists(): - print(f"Can't find checkpoint {sam2_checkpoint} in folder {checkpoint_path}. Downloading.") + print( + f"Can't find checkpoint {sam2_checkpoint} in folder {checkpoint_path}. Downloading." + ) download_file(MODEL_TYPES_TO_URL[model_type], checkpoint_path) assert sam2_checkpoint.exists(), "Can't find downloaded file. Please open an issue." model_cfg = f"configs/sam2.1/{MODEL_TYPES_TO_CONFIG[model_type]}" return sam2_checkpoint, model_cfg -def set_autoquant(mask_generator): +def set_autoquant(mask_generator, autoquant_type, min_sqnr): import torchao from torchao import autoquant + # NOTE: Not baseline feature - mask_generator.predictor.model.image_encoder = autoquant(mask_generator.predictor.model.image_encoder, qtensor_class_list=torchao.quantization.DEFAULT_FLOAT_AUTOQUANT_CLASS_LIST, min_sqnr=40) + if autoquant_type == "autoquant": + mask_generator.predictor.model.image_encoder = autoquant( + mask_generator.predictor.model.image_encoder, min_sqnr=min_sqnr + ) + elif autoquant_type == "autoquant-fp": + mask_generator.predictor.model.image_encoder = autoquant( + mask_generator.predictor.model.image_encoder, + qtensor_class_list=torchao.quantization.DEFAULT_FLOAT_AUTOQUANT_CLASS_LIST, + min_sqnr=min_sqnr, + ) + elif autoquant_type == "autoquant-all": + mask_generator.predictor.model.image_encoder = autoquant( + mask_generator.predictor.model.image_encoder, + qtensor_class_list=torchao.quantization.ALL_AUTOQUANT_CLASS_LIST, + min_sqnr=min_sqnr, + ) + else: + raise ValueError(f"Unexpected autoquant type: {autoquant_type}") + mask_generator.predictor._transforms_device = mask_generator.predictor.device - torch.set_float32_matmul_precision('high') + torch.set_float32_matmul_precision("high") # NOTE: this fails when we run # python server.py ~/checkpoints/sam2 large --port 8000 --host localhost --fast --use_autoquant --unittest # https://gist.github.com/jerryzh168/d337cb5de0a1dec306069fe48ac8225e # mask_generator.predictor.model.sam_mask_decoder = autoquant(mask_generator.predictor.model.sam_mask_decoder, qtensor_class_list=DEFAULT_FLOAT_AUTOQUANT_CLASS_LIST, min_sqnr=40) -def main(checkpoint_path, - model_type, - baseline=False, - fast=False, - furious=False, - use_autoquant=False, - unittest=False, - benchmark=False, - profile=None, - memory_profile=None, - verbose=False, - points_per_batch=64, - port=5000, - host="127.0.0.1", - dry=False, - batch_size=1, - load_fast="", - save_fast="", - output_json_path=None, - output_json_local=False): +def main( + checkpoint_path, + model_type, + baseline=False, + fast=False, + furious=False, + autoquant_type=None, + min_sqnr=None, + unittest=False, + benchmark=False, + profile=None, + memory_profile=None, + verbose=False, + points_per_batch=64, + port=5000, + host="127.0.0.1", + dry=False, + batch_size=1, + load_fast="", + save_fast="", + output_json_path=None, + output_json_local=False, +): if verbose: - logging.basicConfig(level=logging.INFO, - format='%(asctime)s - %(levelname)s - %(message)s', - datefmt='%Y-%m-%d %H:%M:%S') + logging.basicConfig( + level=logging.INFO, + format="%(asctime)s - %(levelname)s - %(message)s", + datefmt="%Y-%m-%d %H:%M:%S", + ) logging.info(f"Running with fast set to {fast} and furious set to {furious}") logging.info(f"Running with port {port} and host {host}") logging.info(f"Running with batch size {batch_size}") if baseline: assert batch_size == 1, "baseline only supports batch size 1." - logging.info(f"Importing sam2 from outside of torchao. If this errors, install https://github.com/facebookresearch/sam2") - from sam2.build_sam import build_sam2 + logging.info( + "Importing sam2 from outside of torchao. If this errors, install https://github.com/facebookresearch/sam2" + ) from sam2.automatic_mask_generator import SAM2AutomaticMaskGenerator + from sam2.build_sam import build_sam2 from sam2.utils.amg import rle_to_mask else: + from torchao._models.sam2.automatic_mask_generator import ( + SAM2AutomaticMaskGenerator, + ) from torchao._models.sam2.build_sam import build_sam2 - from torchao._models.sam2.automatic_mask_generator import SAM2AutomaticMaskGenerator from torchao._models.sam2.utils.amg import rle_to_mask device = "cuda" sam2_checkpoint, model_cfg = model_type_to_paths(checkpoint_path, model_type) logging.info(f"Loading model {sam2_checkpoint} with config {model_cfg}") - sam2 = build_sam2(model_cfg, sam2_checkpoint, device=device, apply_postprocessing=False) + sam2 = build_sam2( + model_cfg, sam2_checkpoint, device=device, apply_postprocessing=False + ) logging.info(f"Using {points_per_batch} points_per_batch") - mask_generator = SAM2AutomaticMaskGenerator(sam2, points_per_batch=points_per_batch, output_mode="uncompressed_rle") + mask_generator = SAM2AutomaticMaskGenerator( + sam2, points_per_batch=points_per_batch, output_mode="uncompressed_rle" + ) if load_fast != "": - load_exported_model(mask_generator, load_fast, "amg", furious, batch_size, points_per_batch) + load_exported_model( + mask_generator, load_fast, "amg", furious, batch_size, points_per_batch + ) if furious: set_furious(mask_generator) if save_fast != "": - assert load_fast == "", "Can't save compiled models while loading them with --load-fast." + assert ( + load_fast == "" + ), "Can't save compiled models while loading them with --load-fast." assert not baseline, "--fast cannot be combined with baseline. code to be torch.compile(fullgraph=True) compatible." print(f"Saving compiled models under directory {save_fast}") - export_model(mask_generator, - save_fast, - "amg", - furious=furious, - batch_size=batch_size, - points_per_batch=points_per_batch) + export_model( + mask_generator, + save_fast, + "amg", + furious=furious, + batch_size=batch_size, + points_per_batch=points_per_batch, + ) if fast: assert not baseline, "--fast cannot be combined with baseline. code to be torch.compile(fullgraph=True) compatible." set_fast(mask_generator, load_fast) # since autoquant is replicating what furious mode is doing, don't use these two together - if use_autoquant: + if autoquant_type is not None: assert not furious, "use autoquant can't be used together with furious" - set_autoquant(mask_generator) + set_autoquant(mask_generator, autoquant_type, min_sqnr) - with open('dog.jpg', 'rb') as f: + with open("dog.jpg", "rb") as f: output_format = "numpy" if baseline else "torch" - image_tensor = file_bytes_to_image_tensor(bytearray(f.read()), - output_format=output_format) + image_tensor = file_bytes_to_image_tensor( + bytearray(f.read()), output_format=output_format + ) # from torchvision import io as tio # img_bytes_tensor = tio.read_file('dog.jpg') @@ -469,7 +531,9 @@ def main(checkpoint_path, else: # TODO: Transpose dog image to create diversity in input image shape logging.info(f"batch size {batch_size} unittest") - all_masks = image_tensors_to_masks([image_tensor] * batch_size, mask_generator) + all_masks = image_tensors_to_masks( + [image_tensor] * batch_size, mask_generator + ) all_masks = [masks_to_rle_dict(masks) for masks in all_masks] ref_masks = json.loads(open("dog_rle.json").read()) for masks in all_masks: @@ -480,17 +544,24 @@ def main(checkpoint_path, if batch_size == 1: result = benchmark_fn(image_tensor_to_masks, image_tensor, mask_generator) else: - result = benchmark_fn(image_tensors_to_masks, [image_tensor] * batch_size, mask_generator) + result = benchmark_fn( + image_tensors_to_masks, [image_tensor] * batch_size, mask_generator + ) for i, shapes in enumerate([example_shapes(), example_shapes_2()]): print(f"batch size {batch_size} example shapes {i} benchmark") - random_images = [np.random.randint(0, 256, size=size, dtype=np.uint8) for size in shapes] + random_images = [ + np.random.randint(0, 256, size=size, dtype=np.uint8) for size in shapes + ] if batch_size > len(random_images): num_repeat = (len(random_images) + batch_size) // batch_size random_images = num_repeat * random_images if batch_size == 1: - [benchmark_fn(image_tensor_to_masks, r, mask_generator) for r in random_images] + [ + benchmark_fn(image_tensor_to_masks, r, mask_generator) + for r in random_images + ] else: random_images = random_images[:batch_size] print("len(random_images): ", len(random_images)) @@ -500,12 +571,44 @@ def main(checkpoint_path, headers = ["name", "dtype", "device", "arch", "metric", "actual", "target"] name = "sam2-" + model_type arch = get_arch_name() - dtype = "autoquant" if use_autoquant else "noquant" - avg_time_per_run, max_memory_allocated_bytes, max_memory_allocated_percentage = result - memory_result = [name, dtype, device, arch, "memory(MiB)", max_memory_allocated_bytes, None] - memory_percent_result = [name, dtype, device, arch, "memory(%)", max_memory_allocated_percentage, None] - performance_result = [name, dtype, device, arch, "time_s(avg)", avg_time_per_run, None] - write_json_result = write_json_result_local if output_json_local else write_json_result_ossci + dtype = autoquant_type or "noquant" + ( + avg_time_per_run, + max_memory_allocated_bytes, + max_memory_allocated_percentage, + ) = result + memory_result = [ + name, + dtype, + device, + arch, + "memory(MiB)", + max_memory_allocated_bytes, + None, + ] + memory_percent_result = [ + name, + dtype, + device, + arch, + "memory(%)", + max_memory_allocated_percentage, + None, + ] + performance_result = [ + name, + dtype, + device, + arch, + "time_s(avg)", + avg_time_per_run, + None, + ] + write_json_result = ( + write_json_result_local + if output_json_local + else write_json_result_ossci + ) write_json_result(output_json_path, headers, memory_result) write_json_result(output_json_path, headers, memory_percent_result) write_json_result(output_json_path, headers, performance_result) @@ -513,16 +616,30 @@ def main(checkpoint_path, if profile is not None: print(f"Saving profile under {profile}") if batch_size == 1: - profiler_runner(profile, image_tensor_to_masks, image_tensor, mask_generator) + profiler_runner( + profile, image_tensor_to_masks, image_tensor, mask_generator + ) else: - profiler_runner(profile, image_tensors_to_masks, [image_tensor] * batch_size, mask_generator) + profiler_runner( + profile, + image_tensors_to_masks, + [image_tensor] * batch_size, + mask_generator, + ) if memory_profile is not None: print(f"Saving memory profile under {memory_profile}") if batch_size == 1: - memory_runner(memory_profile, image_tensor_to_masks, image_tensor, mask_generator) + memory_runner( + memory_profile, image_tensor_to_masks, image_tensor, mask_generator + ) else: - memory_runner(memory_profile, image_tensors_to_masks, [image_tensor] * batch_size, mask_generator) + memory_runner( + memory_profile, + image_tensors_to_masks, + [image_tensor] * batch_size, + mask_generator, + ) if dry: return @@ -555,24 +672,25 @@ async def upload_image(image: UploadFile = File(...)): response_future = asyncio.Future() await request_queue.put((image_tensor, response_future)) masks = await response_future - + # Create figure and ensure it's closed after generating response fig = plt.figure(figsize=(image_tensor.shape[1]/100., image_tensor.shape[0]/100.), dpi=100) plt.imshow(image_tensor) show_anns(masks, rle_to_mask) - plt.axis('off') + plt.axis("off") plt.tight_layout() - + buf = BytesIO() - plt.savefig(buf, format='png') + plt.savefig(buf, format="png") buf.seek(0) plt.close(fig) # Close figure after we're done with it - + return StreamingResponse(buf, media_type="image/png") # uvicorn.run(app, host=host, port=port, log_level="info") uvicorn.run(app, host=host, port=port) + main.__doc__ = main_docstring() if __name__ == "__main__": fire.Fire(main) diff --git a/torchao/_models/llama/generate.py b/torchao/_models/llama/generate.py index a111e3e7c..3e466a5d1 100644 --- a/torchao/_models/llama/generate.py +++ b/torchao/_models/llama/generate.py @@ -266,6 +266,7 @@ def main( "checkpoints/meta-Transformer/Transformer-2-7b-chat-hf/model.pth" ), quantization: Optional[str] = None, + min_sqnr: Optional[float] = None, sparsity: Optional[str] = None, kv_cache_quantization: bool = False, cache_size: Optional[int] = None, @@ -706,6 +707,7 @@ def ffn_or_attn_only(mod, fqn): manual=True, qtensor_class_list=torchao.quantization.DEFAULT_INT4_AUTOQUANT_CLASS_LIST, example_input=inputs, + min_sqnr=min_sqnr, ) elif "autoquant-float8" == quantization: model = autoquant( @@ -713,6 +715,7 @@ def ffn_or_attn_only(mod, fqn): manual=True, qtensor_class_list=torchao.quantization.OTHER_AUTOQUANT_CLASS_LIST, example_input=inputs, + min_sqnr=min_sqnr, ) elif "autoquant-fp" == quantization: model = autoquant( @@ -720,6 +723,7 @@ def ffn_or_attn_only(mod, fqn): manual=True, qtensor_class_list=torchao.quantization.DEFAULT_FLOAT_AUTOQUANT_CLASS_LIST, example_input=inputs, + min_sqnr=min_sqnr, ) elif "autoquant-sparse" == quantization: model = autoquant( @@ -727,6 +731,7 @@ def ffn_or_attn_only(mod, fqn): manual=True, qtensor_class_list=torchao.quantization.DEFAULT_SPARSE_AUTOQUANT_CLASS_LIST, example_input=inputs, + min_sqnr=min_sqnr, ) elif "autoquant-gemlite-int4" == quantization: import os @@ -742,6 +747,7 @@ def ffn_or_attn_only(mod, fqn): manual=True, qtensor_class_list=torchao.quantization.GEMLITE_INT4_AUTOQUANT_CLASS_LIST, example_input=inputs, + min_sqnr=min_sqnr, ) elif "autoquant-all" == quantization: try: @@ -761,9 +767,12 @@ def ffn_or_attn_only(mod, fqn): manual=True, qtensor_class_list=torchao.quantization.ALL_AUTOQUANT_CLASS_LIST, example_input=inputs, + min_sqnr=min_sqnr, ) else: - model = autoquant(model, manual=True, example_input=inputs) + model = autoquant( + model, manual=True, example_input=inputs, min_sqnr=min_sqnr + ) generate( model, @@ -1015,12 +1024,30 @@ def callback(x): f.close() if output_json_path: - headers = ["name", "dtype", "device", "arch", "metric", "actual", "target"] + headers = [ + "name", + "dtype", + "min_sqnr", + "device", + "arch", + "metric", + "actual", + "target", + ] name = checkpoint_path.parent.name arch = get_arch_name() dtype = quantization or "noquant" - memory_result = [name, dtype, device, arch, "mem/s", bandwidth, None] - performance_result = [name, dtype, device, arch, "tok/s", tokpersec, None] + memory_result = [name, dtype, min_sqnr, device, arch, "mem/s", bandwidth, None] + performance_result = [ + name, + dtype, + min_sqnr, + device, + arch, + "tok/s", + tokpersec, + None, + ] write_json_result = ( write_json_result_local if output_json_local else write_json_result_ossci ) @@ -1073,6 +1100,14 @@ def callback(x): + "embed-int8wo, marlin_qqq, gemlite---, int8adq-int4w-symm" ), ) + parser.add_argument( + "--min_sqnr", + type=float, + default=None, + help=( + "min sqnr for quantizing v.s. not quantizing a layer, used in autoquant options", + ), + ) parser.add_argument( "-s", "--sparsity", @@ -1148,6 +1183,7 @@ def callback(x): args.temperature, args.checkpoint_path, args.quantization, + args.min_sqnr, args.sparsity, args.kv_cache_quantization, args.cache_size, diff --git a/torchao/_models/sam/eval_combo.py b/torchao/_models/sam/eval_combo.py index 4dd976bee..1a082d47b 100644 --- a/torchao/_models/sam/eval_combo.py +++ b/torchao/_models/sam/eval_combo.py @@ -284,6 +284,7 @@ def run( use_compile="False", use_compile_decoder=False, compress=None, + min_sqnr=None, num_workers=0, use_rel_pos=True, pad_input_image_batch=True, @@ -457,6 +458,7 @@ def mlp_only(mod, name): example_input=example_input, manual=True, qtensor_class_list=torchao.quantization.DEFAULT_INT4_AUTOQUANT_CLASS_LIST, + min_sqnr=min_sqnr, ) elif "autoquant-float8" == compress: autoquant( @@ -464,6 +466,7 @@ def mlp_only(mod, name): example_input=example_input, manual=True, qtensor_class_list=torchao.quantization.OTHER_AUTOQUANT_CLASS_LIST, + min_sqnr=min_sqnr, ) elif "autoquant-sparse" == compress: autoquant( @@ -471,6 +474,7 @@ def mlp_only(mod, name): example_input=example_input, manual=True, qtensor_class_list=torchao.quantization.DEFAULT_SPARSE_AUTOQUANT_CLASS_LIST, + min_sqnr=min_sqnr, ) elif "autoquant-all" == compress: autoquant( @@ -478,10 +482,14 @@ def mlp_only(mod, name): example_input=example_input, manual=True, qtensor_class_list=torchao.quantization.ALL_AUTOQUANT_CLASS_LIST, + min_sqnr=min_sqnr, ) else: autoquant( - predictor.model.image_encoder, example_input=example_input, manual=True + predictor.model.image_encoder, + example_input=example_input, + manual=True, + min_sqnr=min_sqnr, ) predictor.model.image_encoder(example_input) predictor.model.image_encoder.finalize_autoquant() @@ -630,20 +638,39 @@ def mlp_only(mod, name): f.write(vals + "\n") if output_json_path: - headers = ["name", "dtype", "device", "arch", "metric", "actual", "target"] + headers = [ + "name", + "dtype", + "min_sqnr", + "device", + "arch", + "metric", + "actual", + "target", + ] name = sam_model_type arch = get_arch_name() dtype = compress or "noquant" memory_result = [ name, dtype, + min_sqnr, device, arch, "memory(MiB)", max_memory_allocated_bytes, None, ] - performance_result = [name, dtype, device, arch, "img_s(avg)", img_s, None] + performance_result = [ + name, + dtype, + min_sqnr, + device, + arch, + "img_s(avg)", + img_s, + None, + ] write_json_result = ( write_json_result_local if output_json_local else write_json_result_ossci ) diff --git a/torchao/_models/utils.py b/torchao/_models/utils.py index a5fa1576d..bdbb43903 100644 --- a/torchao/_models/utils.py +++ b/torchao/_models/utils.py @@ -30,6 +30,7 @@ def write_json_result_ossci(output_json_path, headers, row): "name": "TorchAO benchmark", "mode": "inference", "dtype": mapping_headers["dtype"], + "min_sqnr": mapping_headers["min_sqnr"], "extra_info": { "device": mapping_headers["device"], "arch": mapping_headers["arch"], @@ -38,7 +39,7 @@ def write_json_result_ossci(output_json_path, headers, row): "model": { "name": mapping_headers["name"], "type": "model", - "origins": ["torchao/_models"], + "origins": ["torchao"], }, "metric": { "name": mapping_headers["metric"], @@ -79,6 +80,7 @@ def write_json_result_local(output_json_path, headers, row): "name": "TorchAO benchmark", "mode": "inference", "dtype": mapping_headers["dtype"], + "min_sqnr": mapping_headers["min_sqnr"], "extra_info": { "device": mapping_headers["device"], "arch": mapping_headers["arch"], @@ -87,7 +89,7 @@ def write_json_result_local(output_json_path, headers, row): "model": { "name": mapping_headers["name"], "type": "model", - "origins": ["torchao/_models"], + "origins": ["torchao"], }, "metric": { "name": mapping_headers["metric"], diff --git a/torchao/quantization/autoquant.py b/torchao/quantization/autoquant.py index e7806f07a..4b6a1d1d7 100644 --- a/torchao/quantization/autoquant.py +++ b/torchao/quantization/autoquant.py @@ -415,14 +415,14 @@ class AQInt8DynamicallyQuantizedLinearWeight(AQMixin, LinearActivationQuantizedT @classmethod def from_float(cls, weight): + if weight.dim() != 2: + return weight + # TODO test if this is valid # in_features = weight.shape[1] # int8 dynamic quantization only has benefit when in_feature > 16 # if in_features <= 16: - # return weight - - if weight.dim() != 2: - return weight + # return weight # avoid circular dep from torchao.dtypes import to_affine_quantized_intx @@ -522,7 +522,7 @@ def _autoquant_test(cls, act_mat, weight, bias, best_time, mode=["relu", None]): class AQInt8DynamicallyQuantizedSemiSparseLinearWeight( AQInt8DynamicallyQuantizedLinearWeight ): - layout: Layout = SemiSparseLayout() + aq_layout: Layout = SemiSparseLayout() @classmethod def _autoquant_test(cls, act_mat, weight, bias, best_time, mode=["relu", None]): @@ -627,6 +627,15 @@ def from_float(cls, weight): if weight.shape[-1] % group_size != 0: return weight + if ( + isinstance(_layout, TensorCoreTiledLayout) + and weight.dtype != torch.bfloat16 + ): + return weight + + if isinstance(_layout, MarlinSparseLayout) and weight.dtype != torch.float16: + return weight + use_hqq = True mapping_type = MappingType.ASYMMETRIC block_size = (1, group_size) @@ -690,6 +699,9 @@ class AQGemliteInt4G32WeightOnlyQuantizedLinearWeight(AffineQuantizedTensor, AQM @classmethod def from_float(cls, weight): + if weight.dtype != torch.float16: + return weight + from torchao.dtypes.uintx.gemlite_layout import get_gemlite_aqt_kwargs bit_width = 4 @@ -1022,7 +1034,9 @@ def get_weight_block_size(x): DEFAULT_SPARSE_AUTOQUANT_CLASS_LIST = [ AQDefaultLinearWeight, + # TODO: investigate why there are some problems when adding sparse kernels for sam2 AQInt4G128WeightOnlyQuantizedMarlinSparseLinearWeight, + # some errors when calling cusparse kernels when running on sam2 AQInt8DynamicallyQuantizedSemiSparseLinearWeight, ] From e4827f27f25542a46d8a5c08e3f3de66e0df04e5 Mon Sep 17 00:00:00 2001 From: Apurva Jain Date: Tue, 7 Jan 2025 19:20:34 -0800 Subject: [PATCH 6/9] Lint benchmark folder (#1519) * Torchao folder linted * Torchao/prototype folder linted * Benchmarks folder linted * Lint fixes --- benchmarks/bench_galore_fused_kernels.py | 2 - benchmarks/benchmark_aq.py | 118 +++++++---- benchmarks/benchmark_fp6.py | 39 +++- benchmarks/benchmark_gpu_sparsity.py | 100 +++++---- benchmarks/benchmark_hqq.py | 16 +- benchmarks/benchmark_low_bit_adam.py | 4 +- benchmarks/benchmark_marlin_qqq.py | 7 +- benchmarks/benchmark_s8s4_cutlass.py | 9 +- benchmarks/benchmark_semi_sparse_training.py | 138 ++++++++----- benchmarks/benchmark_uintx.py | 74 +++---- benchmarks/dora/bench_utils.py | 1 - benchmarks/dora/dora_bench.py | 2 +- benchmarks/float8/bench_linear_float8.py | 33 ++- benchmarks/float8/bench_matmul.py | 37 ++-- benchmarks/float8/bench_multi_gpu.py | 5 +- benchmarks/float8/bench_padding.py | 10 +- benchmarks/float8/float8_roofline.py | 194 +++++++++++------- benchmarks/float8/profile_linear_float8.py | 101 +++++---- benchmarks/float8/utils.py | 126 ++++++------ benchmarks/fused_benchmark_utils.py | 1 - benchmarks/intmm.py | 12 +- benchmarks/print_config_shapes.py | 2 - .../quantized_training/benchmark_int8mm.py | 4 +- .../quantized_training/pretrain_llama2.py | 44 +++- ruff.toml | 1 + .../float8nocompile_scaling_utils.py | 5 +- 26 files changed, 656 insertions(+), 429 deletions(-) diff --git a/benchmarks/bench_galore_fused_kernels.py b/benchmarks/bench_galore_fused_kernels.py index c05f31e92..261c98acb 100644 --- a/benchmarks/bench_galore_fused_kernels.py +++ b/benchmarks/bench_galore_fused_kernels.py @@ -8,9 +8,7 @@ def run(args): dtype = getattr(torch, args.dtype) allow_tf32 = args.allow_tf32 - fp8_fast_accum = False torch.backends.cuda.matmul.allow_tf32 = allow_tf32 - kernel = args.kernel M, N = args.M, args.N rank = args.rank diff --git a/benchmarks/benchmark_aq.py b/benchmarks/benchmark_aq.py index ebf9e1e73..e0ab170bd 100644 --- a/benchmarks/benchmark_aq.py +++ b/benchmarks/benchmark_aq.py @@ -1,23 +1,26 @@ -"""Benchmarks for affine quantized tensor, this includes int8 dynamic quant, int8 weight only quant and int4 weight only quant APIs -""" +"""Benchmarks for affine quantized tensor, this includes int8 dynamic quant, int8 weight only quant and int4 weight only quant APIs""" + +import copy + import torch + +from torchao.quantization.quant_api import ( + _replace_with_custom_fn_if_matches_filter, + int4_weight_only, + int8_dynamic_activation_int8_weight, + int8_weight_only, + quantize_, +) from torchao.quantization.subclass import ( - Int8WeightOnlyQuantizedLinearWeight, Int4WeightOnlyQuantizedLinearWeight, + Int8WeightOnlyQuantizedLinearWeight, ) from torchao.utils import ( TORCH_VERSION_AT_LEAST_2_4, TORCH_VERSION_AT_LEAST_2_5, + unwrap_tensor_subclass, ) -from torchao.quantization.quant_api import ( - int4_weight_only, - int8_weight_only, - int8_dynamic_activation_int8_weight, - quantize_, - _replace_with_custom_fn_if_matches_filter, -) -import copy -from torchao.utils import unwrap_tensor_subclass + def _int8wo_api(mod, **kwargs): if TORCH_VERSION_AT_LEAST_2_4: @@ -27,14 +30,20 @@ def _int8wo_api(mod, **kwargs): else: change_linear_weights_to_int8_woqtensors(mod, **kwargs) + def _int8da_int8w_api(mod, **kwargs): if TORCH_VERSION_AT_LEAST_2_4: - quantize_(mod, int8_dynamic_activation_int8_weight(**kwargs), set_inductor_config=False) + quantize_( + mod, + int8_dynamic_activation_int8_weight(**kwargs), + set_inductor_config=False, + ) if not TORCH_VERSION_AT_LEAST_2_5: unwrap_tensor_subclass(mod) else: change_linear_weights_to_int8_dqtensors(mod, **kwargs) + def _int4wo_api(mod, **kwargs): if TORCH_VERSION_AT_LEAST_2_4: kwargs_copy = kwargs.copy() @@ -47,31 +56,43 @@ def _int4wo_api(mod, **kwargs): else: change_linear_weights_to_int4_woqtensors(mod, **kwargs) + class ToyLinearModel(torch.nn.Module): - """Single linear for m * k * n problem size - """ - def __init__(self, m=64, n=32, k=64, has_bias=False, dtype=torch.float, device="cuda"): + """Single linear for m * k * n problem size""" + + def __init__( + self, m=64, n=32, k=64, has_bias=False, dtype=torch.float, device="cuda" + ): super().__init__() self.m = m self.dtype = dtype self.device = device - self.linear = torch.nn.Linear(k, n, bias=has_bias).to(dtype=self.dtype, device=self.device) + self.linear = torch.nn.Linear(k, n, bias=has_bias).to( + dtype=self.dtype, device=self.device + ) def example_inputs(self): - return (torch.randn(self.m, self.linear.in_features, dtype=self.dtype, device=self.device),) + return ( + torch.randn( + self.m, self.linear.in_features, dtype=self.dtype, device=self.device + ), + ) def forward(self, x): x = self.linear(x) return x + def _ref_change_linear_weights_to_int8_dqtensors(model, filter_fn=None, **kwargs): """ The deprecated implementation for int8 dynamic quant API, used as a reference for numerics and performance """ - from torchao.quantization.quant_api import _in_features_greater_than_16 - from torchao.quantization.quant_api import _is_linear - from torchao.quantization.quant_api import _get_subclass_inserter + from torchao.quantization.quant_api import ( + _get_subclass_inserter, + _in_features_greater_than_16, + _is_linear, + ) from torchao.quantization.subclass import Int8DynamicallyQuantizedLinearWeight if filter_fn is None: @@ -80,40 +101,54 @@ def _ref_change_linear_weights_to_int8_dqtensors(model, filter_fn=None, **kwargs ) _replace_with_custom_fn_if_matches_filter( - model, _get_subclass_inserter(Int8DynamicallyQuantizedLinearWeight, enable_parametrization=False, **kwargs), filter_fn + model, + _get_subclass_inserter( + Int8DynamicallyQuantizedLinearWeight, enable_parametrization=False, **kwargs + ), + filter_fn, ) + def _get_ref_change_linear_weights_to_woqtensors(deprecated_tenosr_subclass): def _ref_change_linear_weights_to_woqtensors(model, filter_fn=None, **kwargs): """ The deprecated implementation for weight only quant API, used as a reference for numerics and performance """ - from torchao.quantization.quant_api import _is_linear - from torchao.quantization.quant_api import _get_subclass_inserter + from torchao.quantization.quant_api import _get_subclass_inserter, _is_linear filter_fn = kwargs.pop("filter_fn", _is_linear) _replace_with_custom_fn_if_matches_filter( model, - _get_subclass_inserter(deprecated_tenosr_subclass, enable_parametrization=True, **kwargs), + _get_subclass_inserter( + deprecated_tenosr_subclass, enable_parametrization=True, **kwargs + ), filter_fn, ) return _ref_change_linear_weights_to_woqtensors -_ref_change_linear_weights_to_int8_woqtensors = _get_ref_change_linear_weights_to_woqtensors(Int8WeightOnlyQuantizedLinearWeight) -_ref_change_linear_weights_to_int4_woqtensors = _get_ref_change_linear_weights_to_woqtensors(Int4WeightOnlyQuantizedLinearWeight) + +_ref_change_linear_weights_to_int8_woqtensors = ( + _get_ref_change_linear_weights_to_woqtensors(Int8WeightOnlyQuantizedLinearWeight) +) +_ref_change_linear_weights_to_int4_woqtensors = ( + _get_ref_change_linear_weights_to_woqtensors(Int4WeightOnlyQuantizedLinearWeight) +) torch._dynamo.config.cache_size_limit = 50000 + @torch.no_grad def _bench_quantized_tensor_subclass_perf(api, ref_api, M, N, K, kwargs=None): if kwargs is None: kwargs = {} - m = ToyLinearModel(M, N, K, has_bias=True, dtype=torch.bfloat16, device="cuda").eval() + m = ToyLinearModel( + M, N, K, has_bias=True, dtype=torch.bfloat16, device="cuda" + ).eval() m_bf16 = copy.deepcopy(m) m_ref = copy.deepcopy(m) example_inputs = m.example_inputs() @@ -130,26 +165,30 @@ def _bench_quantized_tensor_subclass_perf(api, ref_api, M, N, K, kwargs=None): # perf comparison from torchao.utils import benchmark_model + # warmup WARMUP = 20 RUNS = 100 torch._dynamo.reset() - m_ref = torch.compile(m_ref, mode='max-autotune', fullgraph=True) + m_ref = torch.compile(m_ref, mode="max-autotune", fullgraph=True) benchmark_model(m_ref, WARMUP, example_inputs) ref_elapsed_time = benchmark_model(m_ref, RUNS, example_inputs) torch._dynamo.reset() - m = torch.compile(m, mode='max-autotune', fullgraph=True) + m = torch.compile(m, mode="max-autotune", fullgraph=True) benchmark_model(m, WARMUP, example_inputs) elapsed_time = benchmark_model(m, RUNS, example_inputs) torch._dynamo.reset() - m_bf16 = torch.compile(m_bf16, mode='max-autotune', fullgraph=True) + m_bf16 = torch.compile(m_bf16, mode="max-autotune", fullgraph=True) benchmark_model(m_bf16, WARMUP, example_inputs) bf16_elapsed_time = benchmark_model(m_bf16, RUNS, example_inputs) - print(f"{(M, N, K)}: elapsed time: {elapsed_time}, ref elapsed time: {ref_elapsed_time}, bf16 elapsed time: {bf16_elapsed_time}") + print( + f"{(M, N, K)}: elapsed time: {elapsed_time}, ref elapsed time: {ref_elapsed_time}, bf16 elapsed time: {bf16_elapsed_time}" + ) + if __name__ == "__main__" and TORCH_VERSION_AT_LEAST_2_4 and torch.cuda.is_available(): all_shapes = [ @@ -158,16 +197,25 @@ def _bench_quantized_tensor_subclass_perf(api, ref_api, M, N, K, kwargs=None): print("_int8da_int8w_api") from torchao.quantization.quant_api import change_linear_weights_to_int8_dqtensors + for M, N, K in all_shapes: - _bench_quantized_tensor_subclass_perf(_int8da_int8w_api, _ref_change_linear_weights_to_int8_dqtensors, M, N, K) + _bench_quantized_tensor_subclass_perf( + _int8da_int8w_api, _ref_change_linear_weights_to_int8_dqtensors, M, N, K + ) print("_int8wo_api") from torchao.quantization.quant_api import change_linear_weights_to_int8_woqtensors + for M, N, K in all_shapes: - _bench_quantized_tensor_subclass_perf(_int8wo_api, _ref_change_linear_weights_to_int8_woqtensors, M, N, K) + _bench_quantized_tensor_subclass_perf( + _int8wo_api, _ref_change_linear_weights_to_int8_woqtensors, M, N, K + ) print("_int4wo_api") kwargs = {"groupsize": 32} from torchao.quantization.quant_api import change_linear_weights_to_int4_woqtensors + for M, N, K in all_shapes: - _bench_quantized_tensor_subclass_perf(_int4wo_api, _ref_change_linear_weights_to_int4_woqtensors, M, N, K, kwargs) + _bench_quantized_tensor_subclass_perf( + _int4wo_api, _ref_change_linear_weights_to_int4_woqtensors, M, N, K, kwargs + ) diff --git a/benchmarks/benchmark_fp6.py b/benchmarks/benchmark_fp6.py index 25967baa2..c20599532 100644 --- a/benchmarks/benchmark_fp6.py +++ b/benchmarks/benchmark_fp6.py @@ -1,17 +1,22 @@ -import torch import pandas as pd +import torch import torch.nn.functional as F +from tqdm import tqdm + from torchao.dtypes import to_affine_quantized_fpx -from torchao.dtypes.floatx import FloatxTensorCoreAQTTensorImpl, FloatxTensorCoreLayout +from torchao.dtypes.floatx import FloatxTensorCoreLayout from torchao.utils import benchmark_torch_function_in_microseconds -from tqdm import tqdm def benchmark(m: int, k: int, n: int): float_data_fp16 = torch.randn(n, k, dtype=torch.float16, device="cuda") float_data_bf16 = torch.randn(n, k, dtype=torch.bfloat16, device="cuda") - fp6_weight_fp16 = to_affine_quantized_fpx(float_data_fp16, FloatxTensorCoreLayout(3, 2)) - fp6_weight_bf16 = to_affine_quantized_fpx(float_data_bf16, FloatxTensorCoreLayout(3, 2)) + fp6_weight_fp16 = to_affine_quantized_fpx( + float_data_fp16, FloatxTensorCoreLayout(3, 2) + ) + fp6_weight_bf16 = to_affine_quantized_fpx( + float_data_bf16, FloatxTensorCoreLayout(3, 2) + ) fp16_weight = fp6_weight_fp16.dequantize(torch.float16) bf16_weight = fp6_weight_bf16.dequantize(torch.bfloat16) @@ -22,15 +27,27 @@ def benchmark(m: int, k: int, n: int): fp16_output = F.linear(fp16_act, fp16_weight) bf16_output = F.linear(bf16_act, bf16_weight) - fp16_time = benchmark_torch_function_in_microseconds(F.linear, fp16_act, fp16_weight) - bf16_time = benchmark_torch_function_in_microseconds(F.linear, bf16_act, bf16_weight) - fp6_time_fp16 = benchmark_torch_function_in_microseconds(F.linear, fp16_act, fp6_weight_fp16) - fp6_time_bf16 = benchmark_torch_function_in_microseconds(F.linear, bf16_act, fp6_weight_bf16) + fp16_time = benchmark_torch_function_in_microseconds( + F.linear, fp16_act, fp16_weight + ) + bf16_time = benchmark_torch_function_in_microseconds( + F.linear, bf16_act, bf16_weight + ) + fp6_time_fp16 = benchmark_torch_function_in_microseconds( + F.linear, fp16_act, fp6_weight_fp16 + ) + fp6_time_bf16 = benchmark_torch_function_in_microseconds( + F.linear, bf16_act, fp6_weight_bf16 + ) # follow https://github.com/usyd-fsalab/fp6_llm/blob/ce76774bcfc26b325c1b558abcf1935026d9abbc/tests/python/kernel_test.py # doesn't seem to be the right way to check for correctness - correct_fp16 = (fp6_output_fp16 - fp16_output).abs().mean() / fp16_output.abs().mean() < 1e-3 - correct_bf16 = (fp6_output_bf16 - bf16_output).abs().mean() / bf16_output.abs().mean() < 1e-2 + correct_fp16 = ( + fp6_output_fp16 - fp16_output + ).abs().mean() / fp16_output.abs().mean() < 1e-3 + correct_bf16 = ( + fp6_output_bf16 - bf16_output + ).abs().mean() / bf16_output.abs().mean() < 1e-2 return { "m": m, diff --git a/benchmarks/benchmark_gpu_sparsity.py b/benchmarks/benchmark_gpu_sparsity.py index 5a579ed1a..9e22f6d43 100644 --- a/benchmarks/benchmark_gpu_sparsity.py +++ b/benchmarks/benchmark_gpu_sparsity.py @@ -1,19 +1,18 @@ import argparse -import random import pandas as pd import torch -import torch.utils.benchmark as benchmark import torch.nn.functional as F -from torch import nn from torch.sparse import SparseSemiStructuredTensor, to_sparse_semi_structured - from torch.sparse._triton_ops_meta import optimize_bsr_dense_addmm -from torchao.utils import benchmark_model, profiler_runner -from torchao.sparsity.utils import create_semi_structured_tensor, create_block_sparse_tensor - from tqdm import tqdm +from torchao.sparsity.utils import ( + create_block_sparse_tensor, + create_semi_structured_tensor, +) +from torchao.utils import benchmark_model + torch.set_printoptions( precision=2, threshold=None, @@ -23,10 +22,11 @@ sci_mode=False, ) + def benchmark_model_with_warmup(func, x, N_WARMUP=3): benchmark_model(func, N_WARMUP, device_type="cuda") return benchmark_model(func, 10, device_type="cuda") - + def run_gpu_sparse_benchmark(m, k, n, args): with torch.no_grad(): @@ -40,21 +40,33 @@ def run_gpu_sparse_benchmark(m, k, n, args): A = create_semi_structured_tensor(m, k, dtype) A_sparse = to_sparse_semi_structured(A) elif args.sparsity == "block-sparse": - A = create_block_sparse_tensor(m, k, args.block_size, args.sparsity_level, dtype) + A = create_block_sparse_tensor( + m, k, args.block_size, args.sparsity_level, dtype + ) A_sparse = A.to_sparse_bsr(blocksize=args.block_size) # BSR kernel tuning if args.bsr_autotune: print("Tuning kernel params") - optimize_bsr_dense_addmm(m, k, n, args.block_size, args.block_size, - dtype=dtype, sparsity=args.sparsity_level, verbose=True) + optimize_bsr_dense_addmm( + m, + k, + n, + args.block_size, + args.block_size, + dtype=dtype, + sparsity=args.sparsity_level, + verbose=True, + ) else: raise ValueError(f"Unknown sparsity: {args.sparsity}") if args.eval_fn == "linear": b = torch.randn(m, dtype=dtype).cuda() + # can't use lambda def dense_func(): return F.linear(x, A, b) + def sparse_func(): return F.linear(x, A_sparse, b) @@ -66,26 +78,41 @@ def sparse_func(): scale_b = torch.tensor([1.0], device="cuda") def dense_func(): - return torch._scaled_mm(A, x, scale_a=scale_a, scale_b=scale_b, out_dtype=torch.bfloat16) + return torch._scaled_mm( + A, x, scale_a=scale_a, scale_b=scale_b, out_dtype=torch.bfloat16 + ) + def sparse_func(): - return torch._scaled_mm(A_sparse, x, scale_a=scale_a, scale_b=scale_b, out_dtype=torch.bfloat16) + return torch._scaled_mm( + A_sparse, + x, + scale_a=scale_a, + scale_b=scale_b, + out_dtype=torch.bfloat16, + ) else: x = x.t() + def dense_func(): return torch.mm(A, x) + def sparse_func(): return torch.mm(A_sparse, x) else: raise ValueError(f"Unknown eval_fn: {args.eval_fn}") - dense_time = benchmark_model_with_warmup(dense_func, 'dense.json.gz') - sparse_time = benchmark_model_with_warmup(sparse_func, 'sparse.json.gz') + dense_time = benchmark_model_with_warmup(dense_func, "dense.json.gz") + sparse_time = benchmark_model_with_warmup(sparse_func, "sparse.json.gz") dense_func_c = torch.compile(dense_func, mode="max-autotune") - dense_time_c = benchmark_model_with_warmup(dense_func_c, 'dense_compile.json.gz') + dense_time_c = benchmark_model_with_warmup( + dense_func_c, "dense_compile.json.gz" + ) sparse_func_c = torch.compile(sparse_func, mode="max-autotune") - sparse_time_c = benchmark_model_with_warmup(sparse_func_c, 'sparse_compile.json.gz') + sparse_time_c = benchmark_model_with_warmup( + sparse_func_c, "sparse_compile.json.gz" + ) torch._dynamo.reset() @@ -99,7 +126,8 @@ def sparse_func(): "dense": dense_time, "dense_c": dense_time_c, "sparse_c": sparse_time_c, - "speedup (d/s)": min(dense_time, dense_time_c) / min(sparse_time, sparse_time_c), + "speedup (d/s)": min(dense_time, dense_time_c) + / min(sparse_time, sparse_time_c), } @@ -135,27 +163,25 @@ def sparse_func(): 16, 32, 64, - ] + ], ) parser.add_argument( "--dtype", type=str, - choices=[ - "int8", - "float16", - "bfloat16", - "float32", - "float8_e4m3fn" - ], + choices=["int8", "float16", "bfloat16", "float32", "float8_e4m3fn"], default="bfloat16", ) parser.add_argument( "--backend", type=str, choices=["cutlass", "cusparselt"], default="cusparselt" ) - parser.add_argument("--eval-fn", type=str, choices=["linear", "mm"], default="linear") + parser.add_argument( + "--eval-fn", type=str, choices=["linear", "mm"], default="linear" + ) parser.add_argument("-contiguous", action="store_true") parser.add_argument("-save", action="store_true") - parser.add_argument("-bsr-autotune", action="store_true", help="Tune BSR kernel parameters") + parser.add_argument( + "-bsr-autotune", action="store_true", help="Tune BSR kernel parameters" + ) args = parser.parse_args() print(f"Started benchmark: {args}") @@ -170,8 +196,7 @@ def sparse_func(): (4096, 16384, 2816), ] results = ( - run_gpu_sparse_benchmark(m, k, n, args) - for (m, n, k) in tqdm(mm_shapes) + run_gpu_sparse_benchmark(m, k, n, args) for (m, n, k) in tqdm(mm_shapes) ) elif args.mode == "llama3-8b-w": mm_shapes = [ @@ -186,11 +211,10 @@ def sparse_func(): (8192, 11008, 4096), ] results = ( - run_gpu_sparse_benchmark(m, k, n, args) - for (m, k, n) in tqdm(mm_shapes) + run_gpu_sparse_benchmark(m, k, n, args) for (m, k, n) in tqdm(mm_shapes) ) elif args.mode == "vit-mlp": - vit_shapes= [ + vit_shapes = [ # vit-base (768, 3072, 50432), (3072, 3072, 50432), @@ -199,8 +223,7 @@ def sparse_func(): (5120, 1280, 65792), ] results = ( - run_gpu_sparse_benchmark(m, k, n, args) - for (m, k, n) in tqdm(vit_shapes) + run_gpu_sparse_benchmark(m, k, n, args) for (m, k, n) in tqdm(vit_shapes) ) elif args.mode == "nvidia-fixed-k": mn_vals = [ @@ -224,8 +247,7 @@ def sparse_func(): 20480, ] results = ( - run_gpu_sparse_benchmark(mn, 10240, mn, args) - for mn in tqdm(mn_vals) + run_gpu_sparse_benchmark(mn, 10240, mn, args) for mn in tqdm(mn_vals) ) elif args.mode == "nvidia-fixed-mn": k_vals = [ @@ -246,14 +268,12 @@ def sparse_func(): 20480, ] results = ( - run_gpu_sparse_benchmark(10240, k, 10240, args) - for k in tqdm(k_vals) + run_gpu_sparse_benchmark(10240, k, 10240, args) for k in tqdm(k_vals) ) else: raise ValueError(f"Unknown mode: {args.mode}") - df = pd.DataFrame.from_records(results) if args.save: save_file = f"{args.mode}_{args.dtype}_{args.backend}.csv" diff --git a/benchmarks/benchmark_hqq.py b/benchmarks/benchmark_hqq.py index 123e2e5f5..d86f16cb5 100644 --- a/benchmarks/benchmark_hqq.py +++ b/benchmarks/benchmark_hqq.py @@ -1,5 +1,5 @@ try: - import hqq + import hqq # noqa: F401 import triton if int(triton.__version__.split(".")[0]) < 3: @@ -54,10 +54,16 @@ def fn(): return t -def bench_hqq(x, hqq_linear: HQQLinear | HQQLinearTorchWeightOnlyInt4, transposed=False, tinygemm=False): +def bench_hqq( + x, + hqq_linear: HQQLinear | HQQLinearTorchWeightOnlyInt4, + transposed=False, + tinygemm=False, +): def reference_fn(): W_dq = hqq_linear.dequantize() _ = x @ W_dq.T if not transposed else x @ W_dq + fn = reference_fn if not tinygemm else lambda: hqq_linear(x) t = do_bench(fn) @@ -138,9 +144,9 @@ def run_benchmark( [1024, 4096, 4096], ] -DTYPES = [torch.bfloat16] #[torch.float16, torch.bfloat16] +DTYPES = [torch.bfloat16] # [torch.float16, torch.bfloat16] GROUP_SIZES = [128] -TRANSPOSED = [True] #[False, True] +TRANSPOSED = [True] # [False, True] HEADERS = [ "M", @@ -171,4 +177,4 @@ def run_benchmark( df = pd.DataFrame(data, columns=HEADERS) df.to_csv(output, index=False) print(output.getvalue()) - # df.to_csv("benchmark_hqq_tinygemm.csv", index=False) \ No newline at end of file + # df.to_csv("benchmark_hqq_tinygemm.csv", index=False) diff --git a/benchmarks/benchmark_low_bit_adam.py b/benchmarks/benchmark_low_bit_adam.py index 986cc58b4..ba5f109c0 100644 --- a/benchmarks/benchmark_low_bit_adam.py +++ b/benchmarks/benchmark_low_bit_adam.py @@ -31,11 +31,11 @@ import torch.nn.functional as F import wandb from torch.utils.data import DataLoader -from torchao.utils import get_available_devices from torchvision.transforms import v2 from tqdm import tqdm from torchao.prototype import low_bit_optim +from torchao.utils import get_available_devices _DEVICE = get_available_devices()[-1] assert _DEVICE in ["cuda", "xpu"], "Benchmark currently only supports CUDA & XPU(BF16)" @@ -157,7 +157,7 @@ def evaluate_model(model, args): all_labels = [] all_preds = [] - for batch in tqdm(val_dloader, dynamic_ncols=True, desc=f"Evaluating"): + for batch in tqdm(val_dloader, dynamic_ncols=True, desc="Evaluating"): all_labels.append(batch["label"].clone()) if args.full_bf16: batch["image"] = batch["image"].bfloat16() diff --git a/benchmarks/benchmark_marlin_qqq.py b/benchmarks/benchmark_marlin_qqq.py index 295d08968..51df84abe 100644 --- a/benchmarks/benchmark_marlin_qqq.py +++ b/benchmarks/benchmark_marlin_qqq.py @@ -1,9 +1,10 @@ -import torch import pandas as pd -from torchao.utils import benchmark_torch_function_in_microseconds +import torch +from tqdm import tqdm + from torchao.ops import marlin_qqq_gemm from torchao.quantization.marlin_qqq import marlin_qqq_workspace, pack_to_marlin_qqq -from tqdm import tqdm +from torchao.utils import benchmark_torch_function_in_microseconds def get_problem(m, n, k, groupsize=-1): diff --git a/benchmarks/benchmark_s8s4_cutlass.py b/benchmarks/benchmark_s8s4_cutlass.py index 397544b65..fbf07ebb3 100644 --- a/benchmarks/benchmark_s8s4_cutlass.py +++ b/benchmarks/benchmark_s8s4_cutlass.py @@ -1,13 +1,12 @@ -import torch import pandas as pd -from torchao.utils import benchmark_torch_function_in_microseconds -from torchao.ops import s8s4_linear_cutlass +import torch from tqdm import tqdm +from torchao.ops import s8s4_linear_cutlass +from torchao.utils import benchmark_torch_function_in_microseconds -def get_problem(m, n, k): - groupsize = k +def get_problem(m, n, k): dev = torch.device("cuda") A_ref = torch.randn((m, k), dtype=torch.half, device=dev) B_ref = torch.randn((k, n), dtype=torch.half, device=dev) diff --git a/benchmarks/benchmark_semi_sparse_training.py b/benchmarks/benchmark_semi_sparse_training.py index 35796157b..bf075c0e5 100644 --- a/benchmarks/benchmark_semi_sparse_training.py +++ b/benchmarks/benchmark_semi_sparse_training.py @@ -7,21 +7,21 @@ # This source code is licensed under the BSD license found in the # LICENSE file in the root directory of this source tree. import argparse -import itertools import gc +import itertools -from typing import Tuple - +import pandas as pd import torch -import torch.nn.functional as F +from segment_anything_fast import sam_model_registry +from torch.sparse import to_sparse_semi_structured from torch.utils import benchmark -from torch.sparse import to_sparse_semi_structured -from torchao.sparsity.training import SemiSparseLinear, swap_linear_with_semi_sparse_linear +from torchao.sparsity.training import ( + SemiSparseLinear, + swap_linear_with_semi_sparse_linear, +) from torchao.sparsity.training.autograd import semi_structured_sparsify -from segment_anything_fast import sam_model_registry -import pandas as pd def product_dict(**kwargs): keys = kwargs.keys() @@ -29,20 +29,24 @@ def product_dict(**kwargs): for instance in itertools.product(*vals): yield dict(zip(keys, instance)) + def benchmark_helper( - functions, - cases, + functions, + cases, fw: bool = False, bw: bool = False, cuda_graph: bool = False, compile: bool = False, - blocked_autorange = False, + blocked_autorange=False, ): assert fw or bw assert not (cuda_graph and compile) - print(f"Running benchmarks with: fw={fw}, bw={bw}, cuda_graph={cuda_graph}, compile={compile}: ") + print( + f"Running benchmarks with: fw={fw}, bw={bw}, cuda_graph={cuda_graph}, compile={compile}: " + ) results = [] + def handle_case(**case): for sparsity_config, benchmark_cls in functions.items(): result = { @@ -69,9 +73,11 @@ def run_one(): g.replay() if compile: - benchmark_object.model = torch.compile(benchmark_object.model, mode="max-autotune") + benchmark_object.model = torch.compile( + benchmark_object.model, mode="max-autotune" + ) - #benchmark + # benchmark torch.cuda.reset_peak_memory_stats() t0 = benchmark.Timer( stmt="fn()", @@ -83,18 +89,23 @@ def run_one(): if blocked_autorange: res = t0.blocked_autorange() else: - res = t0.adaptive_autorange(.03, min_run_time=.2, max_run_time=20) - result.update({'time':res.median * 1e3, 'memory': torch.cuda.max_memory_allocated()/1e9}) + res = t0.adaptive_autorange(0.03, min_run_time=0.2, max_run_time=20) + result.update( + { + "time": res.median * 1e3, + "memory": torch.cuda.max_memory_allocated() / 1e9, + } + ) except Exception as e: if "CUDA out of memory" not in str(e): raise else: - result.update({'time': 'OOM', 'memory': 'OOM'}) + result.update({"time": "OOM", "memory": "OOM"}) finally: # clean up - if 'benchmark_object' in locals(): + if "benchmark_object" in locals(): del benchmark_object - if 'g' in locals(): + if "g" in locals(): del g gc.collect() torch.cuda.empty_cache() @@ -104,13 +115,16 @@ def run_one(): handle_case(**case) return pd.DataFrame(results) + # test classes for Linear class LinearTest(torch.nn.Module): def __init__(self, mkn): super().__init__() m, k, n = mkn self.model = torch.nn.Linear(k, n).cuda().half() - self.input = torch.randn([m, k], device='cuda', dtype=torch.half, requires_grad=True) + self.input = torch.randn( + [m, k], device="cuda", dtype=torch.half, requires_grad=True + ) self.grad = torch.randn([m, n], device="cuda", dtype=torch.half) def fw(self): @@ -119,23 +133,30 @@ def fw(self): def bw(self): self.out.backward(self.grad, retain_graph=True) + class SemiSparseLinearOfflineCompressionTest(torch.nn.Module): def __init__(self, mkn): super().__init__() m, k, n = mkn self.model = torch.nn.Linear(k, n).cuda().half() - self.model.weight = torch.nn.Parameter(to_sparse_semi_structured(self.model.weight)) - self.input = torch.randn([m, k], device='cuda', dtype=torch.half, requires_grad=True) + self.model.weight = torch.nn.Parameter( + to_sparse_semi_structured(self.model.weight) + ) + self.input = torch.randn( + [m, k], device="cuda", dtype=torch.half, requires_grad=True + ) self.grad = torch.randn([m, n], device="cuda", dtype=torch.half) def fw(self): self.out = self.model(self.input) + class SemiSparseLinearTest(LinearTest): def __init__(self, mkn): super().__init__(mkn) self.model = SemiSparseLinear.from_dense(self.model) + class SemiSparseKernelTest(LinearTest): def __init__(self, mkn): super().__init__(mkn) @@ -145,15 +166,27 @@ def fw(self): def bw(self): pass - + + # test class for ViT (SAM image encoder) class SAMTest(torch.nn.Module): - def __init__(self, model_type, batch_size): super().__init__() - self.model = sam_model_registry[model_type]().image_encoder.cuda().half().train() - self.input = torch.randn(batch_size, 3, 1024, 1024, device='cuda', dtype=torch.half, requires_grad=True) - self.grad = torch.randn([batch_size, 256, 64, 64], device="cuda", dtype=torch.half) + self.model = ( + sam_model_registry[model_type]().image_encoder.cuda().half().train() + ) + self.input = torch.randn( + batch_size, + 3, + 1024, + 1024, + device="cuda", + dtype=torch.half, + requires_grad=True, + ) + self.grad = torch.randn( + [batch_size, 256, 64, 64], device="cuda", dtype=torch.half + ) def fw(self): self.out = self.model(self.input) @@ -161,16 +194,18 @@ def fw(self): def bw(self): self.out.backward(self.grad, retain_graph=True) + class SAM_W24_MLP_ONLY(SAMTest): def __init__(self, model_type, batch_size): super().__init__(model_type, batch_size) # Apply to just MLP linear layers of SAM image encoder (ViT) sparse_config = {} for name, mod in self.model.named_modules(): - if isinstance(mod, torch.nn.Linear) and 'mlp' in name: + if isinstance(mod, torch.nn.Linear) and "mlp" in name: sparse_config[name] = SemiSparseLinear swap_linear_with_semi_sparse_linear(self.model, sparse_config) + class SAM_W24_ALL(SAMTest): def __init__(self, model_type, batch_size): super().__init__(model_type, batch_size) @@ -181,17 +216,26 @@ def __init__(self, model_type, batch_size): sparse_config[name] = SemiSparseLinear swap_linear_with_semi_sparse_linear(self.model, sparse_config) + if __name__ == "__main__": print("BENCHMARKING") - parser = argparse.ArgumentParser(description='run semi-structured sparse training benchmarks') - parser.add_argument('--mode', type=str, choices=["linear", "llama3-8b", "vit"], help='nn.Linear/ViT-e2e benchmarking', default="vit") - parser.add_argument('--save', action="store_true", help="save benchmarking results") + parser = argparse.ArgumentParser( + description="run semi-structured sparse training benchmarks" + ) + parser.add_argument( + "--mode", + type=str, + choices=["linear", "llama3-8b", "vit"], + help="nn.Linear/ViT-e2e benchmarking", + default="vit", + ) + parser.add_argument("--save", action="store_true", help="save benchmarking results") args = parser.parse_args() if args.mode == "linear": functions = { "dense_linear": LinearTest, "semi_sparse_linear": SemiSparseLinearTest, - "semi_sparse_prune+compress_time_only": SemiSparseKernelTest, + "semi_sparse_prune+compress_time_only": SemiSparseKernelTest, } cases = list( product_dict( @@ -205,12 +249,8 @@ def __init__(self, model_type, batch_size): ) df = benchmark_helper( - functions, - cases, - fw=True, - bw=True, - cuda_graph=True, - blocked_autorange=True) + functions, cases, fw=True, bw=True, cuda_graph=True, blocked_autorange=True + ) elif args.mode == "llama3-8b": functions = { "dense_linear": LinearTest, @@ -233,12 +273,8 @@ def __init__(self, model_type, batch_size): ) df = benchmark_helper( - functions, - cases, - fw=True, - bw=False, - cuda_graph=True, - blocked_autorange=True) + functions, cases, fw=True, bw=False, cuda_graph=True, blocked_autorange=True + ) elif args.mode == "vit": functions = { @@ -246,19 +282,9 @@ def __init__(self, model_type, batch_size): "ViT MLP weight 2:4 sparse": SAM_W24_MLP_ONLY, # "ViT all(MLP+ATN) Linear weight 2:4 sparse": SAM_W24_ALL } - cases = list( - product_dict( - model_type=['vit_l'], - batch_size=[8] - ) - ) + cases = list(product_dict(model_type=["vit_l"], batch_size=[8])) - df = benchmark_helper( - functions, - cases, - fw=True, - bw=True, - compile=True) + df = benchmark_helper(functions, cases, fw=True, bw=True, compile=True) print(df) if args.save: diff --git a/benchmarks/benchmark_uintx.py b/benchmarks/benchmark_uintx.py index 9887fb8b4..78debbca8 100644 --- a/benchmarks/benchmark_uintx.py +++ b/benchmarks/benchmark_uintx.py @@ -1,24 +1,27 @@ -from math import log from copy import deepcopy import torch -from torchao.utils import unwrap_tensor_subclass -from torchao.prototype.uintx import uintx_affine_weight_only, pack, unpack, pack_cpu, unpack_cpu + +from torchao.prototype.uintx import ( + uintx_affine_weight_only, + unpack_cpu, +) from torchao.quantization.quant_api import quantize_ - + + class Linear16(torch.nn.Module): def __init__(self, scale): super().__init__() self.net = torch.nn.Sequential( - torch.nn.Linear(scale*2, scale, bias=True, dtype=torch.float16).cuda(), + torch.nn.Linear(scale * 2, scale, bias=True, dtype=torch.float16).cuda(), torch.nn.Linear(scale, scale, bias=True, dtype=torch.float16).cuda(), - torch.nn.Linear(scale, scale//2, bias=True, dtype=torch.float16).cuda(), + torch.nn.Linear(scale, scale // 2, bias=True, dtype=torch.float16).cuda(), ) def forward(self, x): return self.net(x) - + def benchmark(function, args, num_runs): # warmup torch._dynamo.reset() @@ -38,25 +41,26 @@ def benchmark(function, args, num_runs): def profile_bitpack(): - from torch.profiler import profile, record_function, ProfilerActivity - fake_tensor = [torch.randint(2**8, (512,512), dtype=torch.uint8).cuda()] + from torch.profiler import ProfilerActivity, profile + + fake_tensor = [torch.randint(2**8, (512, 512), dtype=torch.uint8).cuda()] func = torch.compile(unpack_cpu, fullgraph=True) - with profile(activities=[ - ProfilerActivity.CPU, - ProfilerActivity.CUDA], + with profile( + activities=[ProfilerActivity.CPU, ProfilerActivity.CUDA], record_shapes=True, - with_stack=True - ) as prof: - + with_stack=True, + ) as prof: for _ in range(1000): - unpacked = func(fake_tensor, 4) - + func(fake_tensor, 4) + # Print a summary with open("profile-bitpack.txt", "a") as f: - print(f'{func}',file=f) - print(prof.key_averages().table(sort_by="cuda_time_total", row_limit=10), file=f) + print(f"{func}", file=f) + print( + prof.key_averages().table(sort_by="cuda_time_total", row_limit=10), file=f + ) prof.export_chrome_trace("trace.json") - ''' + """ CPU perf: unpack_gpu Self CPU time total: 602.501ms @@ -71,39 +75,37 @@ def profile_bitpack(): unpack_cpu: Self CPU time total: 96.947ms Self CUDA time total: 5.253ms - ''' - -def uintx_vs_fp16(nbits= [1,2,3,4,5,6,7], scales=[256, 512, 1024], repeats=30): - results = [] + """ + + +def uintx_vs_fp16(nbits=[1, 2, 3, 4, 5, 6, 7], scales=[256, 512, 1024], repeats=30): + results = [] nbits.sort() scales.sort() for scale in scales: - test_input = torch.randn(scale*2, dtype=torch.float16).cuda() + test_input = torch.randn(scale * 2, dtype=torch.float16).cuda() forward_args = [test_input] times = [scale] - + fp16 = Linear16(scale) fp16c = torch.compile(fp16, fullgraph=True) fp16_time = benchmark(fp16c.forward, forward_args, repeats) times.append(fp16_time) for bit_size in nbits: m = deepcopy(fp16) - quantize_(m, uintx_affine_weight_only(bit_size)) + quantize_(m, uintx_affine_weight_only(bit_size)) m = torch.compile(m, fullgraph=True) uintx_time = benchmark(m.forward, forward_args, repeats) times.append(uintx_time) - print(f'scale={scale} done') - + print(f"scale={scale} done") + results.append(times) print("----------- benchmark results -----------") for result in results: print(f"scale: {result[0]} fp16 time:{result[1]: .2f}ms speedups:") for i in range(2, len(result)): print(f"int{nbits[i-2]}: {result[1]/result[i]: .2f}x") - - - -if __name__ == "__main__": - uintx_vs_fp16(nbits=[4,7]) - - \ No newline at end of file + + +if __name__ == "__main__": + uintx_vs_fp16(nbits=[4, 7]) diff --git a/benchmarks/dora/bench_utils.py b/benchmarks/dora/bench_utils.py index 2de4fa637..9e3aed0e5 100644 --- a/benchmarks/dora/bench_utils.py +++ b/benchmarks/dora/bench_utils.py @@ -1,7 +1,6 @@ import torch from bitsandbytes.nn import Linear4bit from hqq.core.quantize import BaseQuantizeConfig, HQQLinear - from prototypes.dora.dora_layer import BNBDoRALinear, HQQDoRALinear from prototypes.dora.kernels.matmul import triton_mm from prototypes.dora.kernels.smallk import triton_mm_small_k diff --git a/benchmarks/dora/dora_bench.py b/benchmarks/dora/dora_bench.py index 305cfbdb1..217f0b187 100644 --- a/benchmarks/dora/dora_bench.py +++ b/benchmarks/dora/dora_bench.py @@ -17,9 +17,9 @@ ) from triton.testing import do_bench +from torchao.prototype.common.profiling_tools import pivot_df from torchao.prototype.dora.kernels.matmul import triton_mm from torchao.prototype.dora.kernels.smallk import triton_mm_small_k -from torchao.prototype.common.profiling_tools import pivot_df def run_colnorm_bench(args): diff --git a/benchmarks/float8/bench_linear_float8.py b/benchmarks/float8/bench_linear_float8.py index f92303c62..d160d7241 100644 --- a/benchmarks/float8/bench_linear_float8.py +++ b/benchmarks/float8/bench_linear_float8.py @@ -11,14 +11,16 @@ from typing import Callable, List, Optional, Tuple import pandas as pd - import torch import torch.utils.benchmark as benchmark +from tqdm import tqdm +from utils import get_name_to_shapes_iter + from torchao.float8.config import ( - CastConfig, - Float8LinearConfig, - ScalingType, + CastConfig, + Float8LinearConfig, ScalingGranularity, + ScalingType, ) from torchao.float8.float8_linear import Float8Linear from torchao.float8.float8_linear_utils import ( @@ -26,8 +28,6 @@ sync_float8_amax_and_scale_history, ) from torchao.float8.float8_tensor import ScaledMMConfig -from utils import get_name_to_shapes_iter -from tqdm import tqdm # estimating TOPs for matmuls in fp32, fp16, fp8 # assuming A * B = C, with A being M * K, B being K * N, C being M * N @@ -105,7 +105,7 @@ def main( fast_accum_filter: Optional[bool] = None, shape_name_filter: Optional[str] = None, *, - shape_gen_name: str = 'llama', + shape_gen_name: str = "llama", M: Optional[int] = None, K: Optional[int] = None, N: Optional[int] = None, @@ -123,35 +123,35 @@ def main( scaling_granularity = ScalingGranularity(scaling_granularity) if scaling_type_input is ScalingType.STATIC: - cast_config_input=CastConfig( + cast_config_input = CastConfig( scaling_type=scaling_type_input, static_scale=torch.tensor([1.0], device="cuda"), scaling_granularity=scaling_granularity, ) else: - cast_config_input=CastConfig( + cast_config_input = CastConfig( scaling_type=scaling_type_input, scaling_granularity=scaling_granularity, ) if scaling_type_weight is ScalingType.STATIC: - cast_config_weight=CastConfig( + cast_config_weight = CastConfig( scaling_type=scaling_type_weight, static_scale=torch.tensor([1.0], device="cuda"), scaling_granularity=scaling_granularity, ) else: - cast_config_weight=CastConfig( + cast_config_weight = CastConfig( scaling_type=scaling_type_weight, scaling_granularity=scaling_granularity, ) if scaling_type_grad_output is ScalingType.STATIC: - cast_config_grad_output=CastConfig( + cast_config_grad_output = CastConfig( scaling_type=scaling_type_grad_output, static_scale=torch.tensor([1.0], device="cuda"), scaling_granularity=scaling_granularity, ) else: - cast_config_grad_output=CastConfig( + cast_config_grad_output = CastConfig( scaling_type=scaling_type_grad_output, scaling_granularity=scaling_granularity, ) @@ -169,7 +169,6 @@ def main( else: use_fast_accum = [True, False] if shape_name_filter is not None: - k = shape_name_filter name_to_shapes = ((k, v) for (k, v) in name_to_shapes if k == shape_name_filter) experiment_list: List[Experiment] = [] dtype = torch.bfloat16 @@ -336,11 +335,11 @@ def invoke_main() -> None: if args.shape_gen_name is not None: kwargs["shape_gen_name"] = args.shape_gen_name if args.M is not None: - kwargs["M"] = args.M, + kwargs["M"] = (args.M,) if args.K is not None: - kwargs["K"] = args.K, + kwargs["K"] = (args.K,) if args.N is not None: - kwargs["N"] = args.N, + kwargs["N"] = (args.N,) if args.scaling_type_input is not None: kwargs["scaling_type_input"] = args.scaling_type_input if args.scaling_type_weight is not None: diff --git a/benchmarks/float8/bench_matmul.py b/benchmarks/float8/bench_matmul.py index e969846b2..3d4885375 100644 --- a/benchmarks/float8/bench_matmul.py +++ b/benchmarks/float8/bench_matmul.py @@ -8,19 +8,16 @@ import fire import pandas as pd - import torch import torch.nn as nn import torch.utils.benchmark as benchmark - -from torchao.float8.config import ScalingGranularity - from utils import ( - get_name_to_shapes_iter, - profiler_output_to_filtered_time_by_kernel_name, get_gpu_kernel_gemm_time_s, + get_name_to_shapes_iter, ) +from torchao.float8.config import ScalingGranularity + # estimating TOPs for matmuls in fp32, fp16, fp8 # assuming A * B = C, with A being M * K, B being K * N, C being M * N @@ -50,11 +47,11 @@ def benchmark_fn_in_sec(f, *args, **kwargs): def do_benchmarks( - tops, - peak_tops, - use_gpu_kernel_time, - f, - *args, + tops, + peak_tops, + use_gpu_kernel_time, + f, + *args, **kwargs, ): if use_gpu_kernel_time: @@ -71,7 +68,7 @@ def do_benchmarks( @torch.inference_mode() def run( n_limit: Optional[int] = None, - shape_gen_name: str = 'llama', + shape_gen_name: str = "llama", out_filename: Optional[str] = None, M: Optional[int] = None, K: Optional[int] = None, @@ -81,7 +78,16 @@ def run( ): device = "cuda" - headers = ("fast_accum", "name", "M", "K", "N", "ref_time_s", "fp8_time_s", "fp8_speedup") + headers = ( + "fast_accum", + "name", + "M", + "K", + "N", + "ref_time_s", + "fp8_time_s", + "fp8_speedup", + ) results = [] dtype = torch.bfloat16 @@ -89,7 +95,9 @@ def run( fast_accum_vals = [True, False] scaling_granularity = ScalingGranularity(scaling_granularity) - for idx, (fast_accum, (name, (M, K, N))) in enumerate(itertools.product(fast_accum_vals, name_to_shapes)): + for idx, (fast_accum, (name, (M, K, N))) in enumerate( + itertools.product(fast_accum_vals, name_to_shapes) + ): if n_limit is not None and idx >= n_limit: break @@ -156,6 +164,7 @@ def do_matmul(A, B): if out_filename is not None: data_df.to_csv(out_filename) + def main() -> None: fire.Fire(run) diff --git a/benchmarks/float8/bench_multi_gpu.py b/benchmarks/float8/bench_multi_gpu.py index 44c758d1b..34a690edb 100644 --- a/benchmarks/float8/bench_multi_gpu.py +++ b/benchmarks/float8/bench_multi_gpu.py @@ -8,19 +8,18 @@ from typing import Callable import fire - import torch import torch.distributed as dist import torch.multiprocessing as mp import torch.nn as nn import torch.utils.benchmark as benchmark +from torch.distributed.fsdp import FullyShardedDataParallel as FSDP + from torchao.float8.config import CastConfig, Float8LinearConfig, ScalingType from torchao.float8.float8_linear_utils import ( convert_to_float8_training, sync_float8_amax_and_scale_history, ) -from torch.distributed.fsdp import FullyShardedDataParallel as FSDP - torch.manual_seed(0) diff --git a/benchmarks/float8/bench_padding.py b/benchmarks/float8/bench_padding.py index 977755343..7fc451641 100644 --- a/benchmarks/float8/bench_padding.py +++ b/benchmarks/float8/bench_padding.py @@ -2,18 +2,18 @@ from typing import Optional import fire - import torch +from tabulate import tabulate +from torch._inductor.utils import do_bench_using_profiling +from tqdm import tqdm + from torchao.float8.float8_tensor import ( GemmInputRole, - hp_tensor_and_scale_to_float8, LinearMMConfig, ScaledMMConfig, + hp_tensor_and_scale_to_float8, ) from torchao.float8.float8_utils import pad_tensor_for_matmul -from tabulate import tabulate -from torch._inductor.utils import do_bench_using_profiling -from tqdm import tqdm # estimating TOPs for matmuls in fp32, fp16, fp8 # assuming A * B = C, with A being M * K, B being K * N, C being M * N diff --git a/benchmarks/float8/float8_roofline.py b/benchmarks/float8/float8_roofline.py index 19c6cc21b..2b3f631d8 100644 --- a/benchmarks/float8/float8_roofline.py +++ b/benchmarks/float8/float8_roofline.py @@ -7,11 +7,11 @@ """ This is a script to estimate the benefit from converting a `torch.nn.Linear` layer to float8, by estimating the difference in e2e GPU kernel time between: -1. bf16 gemms in fwd and bwd, and +1. bf16 gemms in fwd and bwd, and 2. float8 gemms in fwd and bwd, and float8 overhead The gemm times are estimated either from direct measurements via benchmarks, -or with a roofline estimation based on TOPS and peak compute bandwidth of an +or with a roofline estimation based on TOPS and peak compute bandwidth of an NVIDIA H100. The float8 overhead times are estimated by counting memory reads and writes @@ -39,38 +39,35 @@ 5. assume no float8 all-gather (TODO model it) """ -import csv import copy import json import os -import time from typing import Optional import fire import pandas as pd import sympy -import tqdm - import torch import torch.utils.benchmark as benchmark -from torch.profiler import profile, ProfilerActivity, record_function - +import tqdm +from torch.profiler import ProfilerActivity, profile from utils import ( - get_name_to_shapes_iter, - get_gpu_kernel_gemm_time_s, + get_gpu_kernel_gemm_time_s, + get_name_to_shapes_iter, profiler_output_to_filtered_time_by_kernel_name, ) -from torchao.float8.roofline_utils import ( - get_gemm_time_sympy, - get_float8_mem_sympy, -) + from torchao.float8 import ( - convert_to_float8_training, - Float8LinearConfig, - ScalingType, CastConfig, + Float8LinearConfig, + ScalingType, + convert_to_float8_training, +) +from torchao.float8.config import Float8LinearRecipeName, recipe_name_to_linear_config +from torchao.float8.roofline_utils import ( + get_float8_mem_sympy, + get_gemm_time_sympy, ) -from torchao.float8.config import recipe_name_to_linear_config, Float8LinearRecipeName class LNLinearSigmoid(torch.nn.Module): @@ -85,6 +82,8 @@ def forward(self, x): x = self.fc(x) x = self.sigmoid(x) return x + + # TODO(next): hook this up @@ -103,7 +102,7 @@ def get_gpu_kernel_time(m, x): # warm up for _ in range(2): m(x).sum().backward() - + # capture a profiling run activities = [ProfilerActivity.CPU, ProfilerActivity.CUDA] n_iter = 5 @@ -114,18 +113,19 @@ def get_gpu_kernel_time(m, x): # get the gpu kernel time and aggregate it num_leaf_tensors = 1 + len(list(m.parameters())) ref_times = profiler_output_to_filtered_time_by_kernel_name( - prof, n_iter, num_leaf_tensors) + prof, n_iter, num_leaf_tensors + ) total_time_s = sum(v for v in ref_times.values()) / 1e6 / n_iter return total_time_s -def get_gemm_times(M, K, N, fast_accum, cache_filename=None): +def get_gemm_times(M, K, N, fast_accum, cache_filename=None): # Note: this is definitely not the best way to build a cache, # but it will do for now. if cache_filename is not None: if os.path.isfile(cache_filename): # cache already exists, use it - with open(cache_filename, 'r') as f: + with open(cache_filename, "r") as f: cache = json.load(f) else: # cache does not exist yet, create it @@ -136,7 +136,7 @@ def get_gemm_times(M, K, N, fast_accum, cache_filename=None): if key in cache: return cache[key] - device = torch.device('cuda') + device = torch.device("cuda") # bf16 time x_bf16 = torch.randn(M, K, dtype=torch.bfloat16, device=device) @@ -154,6 +154,7 @@ def do_matmul(A, B): return torch._scaled_mm( A, B, scale_a, scale_b, out_dtype=d3, use_fast_accum=fast_accum ) + f8_time_s = get_gpu_kernel_gemm_time_s(do_matmul, A, B) scale_a = torch.ones(M, 1, device=device) @@ -164,11 +165,12 @@ def do_matmul(A, B): # save to cache if needed if cache_filename is not None: cache[key] = [bf16_time_s, f8_time_s, f8_axs_time_s] - with open(cache_filename, 'w') as f: + with open(cache_filename, "w") as f: json.dump(cache, f) return bf16_time_s, f8_time_s, f8_axs_time_s + def run( outfile: str, gemm_time_strategy: str = "benchmarks", @@ -190,37 +192,47 @@ def run( * `n_limit (optional)`: if specified, only runs `n_limit` iterations """ - print(f'gemm_time_strategy: {gemm_time_strategy}') - print(f'shape_gen_name: {shape_gen_name}') + print(f"gemm_time_strategy: {gemm_time_strategy}") + print(f"shape_gen_name: {shape_gen_name}") - assert gemm_time_strategy in ("benchmarks", "roofline"), \ - "`gemm_time_strategy` must be 'benchmarks' or 'roofline'" + assert gemm_time_strategy in ( + "benchmarks", + "roofline", + ), "`gemm_time_strategy` must be 'benchmarks' or 'roofline'" - M, K, N = sympy.symbols('M K N') + M, K, N = sympy.symbols("M K N") fp8_mem_time_sympy_dyn_limit = get_float8_mem_sympy( - M, K, N, + M, + K, + N, model_torch_compile_limitations=True, scaling_type_input="dynamic", scaling_type_weight="dynamic", scaling_type_grad_output="dynamic", ) fp8_mem_time_sympy_dyn_nolimit = get_float8_mem_sympy( - M, K, N, + M, + K, + N, model_torch_compile_limitations=False, scaling_type_input="dynamic", scaling_type_weight="dynamic", scaling_type_grad_output="dynamic", ) fp8_mem_time_sympy_del_limit = get_float8_mem_sympy( - M, K, N, + M, + K, + N, model_torch_compile_limitations=True, scaling_type_input="delayed", scaling_type_weight="delayed", scaling_type_grad_output="delayed", ) fp8_mem_time_sympy_del_nolimit = get_float8_mem_sympy( - M, K, N, + M, + K, + N, model_torch_compile_limitations=False, scaling_type_input="delayed", scaling_type_weight="delayed", @@ -229,28 +241,39 @@ def run( if gemm_time_strategy == "roofline": bf16_gemm_time_sympy = get_gemm_time_sympy(M, K, N, torch.bfloat16) - print('bf16_gemm_time_sympy', bf16_gemm_time_sympy) + print("bf16_gemm_time_sympy", bf16_gemm_time_sympy) fp8_gemm_time_sympy = get_gemm_time_sympy(M, K, N, torch.float8_e4m3fn) - print('fp8_gemm_time_sympy', fp8_gemm_time_sympy) + print("fp8_gemm_time_sympy", fp8_gemm_time_sympy) print() else: print() headers = [ - 'fwd_M', 'fwd_K', 'fwd_N', + "fwd_M", + "fwd_K", + "fwd_N", # gemm microbenchmarks - 'bf16_gemm_s', 'fp8_gemm_s', 'fp8_axs_gemm_time_s', + "bf16_gemm_s", + "fp8_gemm_s", + "fp8_axs_gemm_time_s", # roofline memory overhead estimates - 'fp8_oh_dyn_limit', 'fp8_oh_dyn_nolimit', - 'fp8_oh_del_limit', 'fp8_oh_del_nolimit', + "fp8_oh_dyn_limit", + "fp8_oh_dyn_nolimit", + "fp8_oh_del_limit", + "fp8_oh_del_nolimit", # actual e2e measurements - 'bf16_s', 'fp8_dyn_s', 'fp8_del_s', 'fp8_dyn_axs_s', + "bf16_s", + "fp8_dyn_s", + "fp8_del_s", + "fp8_dyn_axs_s", # 'fp8_lw_s', - 'fp8_dyn_sp', 'fp8_del_sp', 'fp8_dyn_axs_sp', + "fp8_dyn_sp", + "fp8_del_sp", + "fp8_dyn_axs_sp", # 'fp8_lw_sp', ] results = [] - + name_to_shapes = get_name_to_shapes_iter(shape_gen_name, None, None, None) for idx, (name, (M_val, K_val, N_val)) in enumerate(tqdm.tqdm(name_to_shapes)): @@ -258,31 +281,47 @@ def run( break if gemm_time_strategy == "benchmarks": - bf16_g1, f8_g1, f8_g1_axs = get_gemm_times(M_val, K_val, N_val, True, gemm_cache_filename) - bf16_g2, f8_g2, f8_g2_axs = get_gemm_times(M_val, N_val, K_val, False, gemm_cache_filename) - bf16_g3, f8_g3, f8_g3_axs = get_gemm_times(K_val, M_val, N_val, False, gemm_cache_filename) + bf16_g1, f8_g1, f8_g1_axs = get_gemm_times( + M_val, K_val, N_val, True, gemm_cache_filename + ) + bf16_g2, f8_g2, f8_g2_axs = get_gemm_times( + M_val, N_val, K_val, False, gemm_cache_filename + ) + bf16_g3, f8_g3, f8_g3_axs = get_gemm_times( + K_val, M_val, N_val, False, gemm_cache_filename + ) bf16_time_val = bf16_g1 + bf16_g2 + bf16_g3 fp8_gemm_time_s = f8_g1 + f8_g2 + f8_g3 fp8_axs_gemm_time_s = f8_g1_axs + f8_g2_axs + f8_g3_axs else: assert gemm_time_strategy == "roofline", "unsupported" - bf16_time_val = bf16_gemm_time_sympy.subs(M, M_val).subs(K, K_val).subs(N, N_val) - fp8_gemm_time_s = fp8_gemm_time_sympy.subs(M, M_val).subs(K, K_val).subs(N, N_val) + bf16_time_val = ( + bf16_gemm_time_sympy.subs(M, M_val).subs(K, K_val).subs(N, N_val) + ) + fp8_gemm_time_s = ( + fp8_gemm_time_sympy.subs(M, M_val).subs(K, K_val).subs(N, N_val) + ) # for now, assume axiswise gemm is similar to tensorwise - fp8_axs_gemm_time_s = fp8_gemm_time_s + fp8_axs_gemm_time_s = fp8_gemm_time_s - fp8_mem_time_dyn_limit_s = \ + fp8_mem_time_dyn_limit_s = ( fp8_mem_time_sympy_dyn_limit.subs(M, M_val).subs(K, K_val).subs(N, N_val) - fp8_mem_time_dyn_nolimit_s = \ + ) + fp8_mem_time_dyn_nolimit_s = ( fp8_mem_time_sympy_dyn_nolimit.subs(M, M_val).subs(K, K_val).subs(N, N_val) - fp8_mem_time_del_limit_s = \ + ) + fp8_mem_time_del_limit_s = ( fp8_mem_time_sympy_del_limit.subs(M, M_val).subs(K, K_val).subs(N, N_val) - fp8_mem_time_del_nolimit_s = \ + ) + fp8_mem_time_del_nolimit_s = ( fp8_mem_time_sympy_del_nolimit.subs(M, M_val).subs(K, K_val).subs(N, N_val) + ) # create the model m_orig = LNLinearSigmoid(K_val, N_val).cuda().bfloat16() - x = torch.randn(M_val, K_val, dtype=torch.bfloat16, device="cuda").requires_grad_() + x = torch.randn( + M_val, K_val, dtype=torch.bfloat16, device="cuda" + ).requires_grad_() # get the bf16 gpu kernel time torch._dynamo.reset() @@ -324,29 +363,38 @@ def run( # m_fp8_lw = torch.compile(m_fp8_lw) # fp8_lw_time_actual_s = get_gpu_kernel_time(m_fp8_lw, x) - results.append([ - M_val, K_val, N_val, - # gemm microbenchmarks - bf16_time_val, fp8_gemm_time_s, fp8_axs_gemm_time_s, - # roofline overhead estimates - fp8_mem_time_dyn_limit_s, - fp8_mem_time_dyn_nolimit_s, - fp8_mem_time_del_limit_s, - fp8_mem_time_del_nolimit_s, - # e2e numbers - bf16_time_actual_s, fp8_dyn_time_actual_s, fp8_del_time_actual_s, - fp8_dyn_axs_time_actual_s, - # fp8_lw_time_actual_s, - bf16_time_actual_s / fp8_dyn_time_actual_s, - bf16_time_actual_s / fp8_del_time_actual_s, - bf16_time_actual_s / fp8_dyn_axs_time_actual_s, - # bf16_time_actual_s / fp8_lw_time_actual_s, - ]) + results.append( + [ + M_val, + K_val, + N_val, + # gemm microbenchmarks + bf16_time_val, + fp8_gemm_time_s, + fp8_axs_gemm_time_s, + # roofline overhead estimates + fp8_mem_time_dyn_limit_s, + fp8_mem_time_dyn_nolimit_s, + fp8_mem_time_del_limit_s, + fp8_mem_time_del_nolimit_s, + # e2e numbers + bf16_time_actual_s, + fp8_dyn_time_actual_s, + fp8_del_time_actual_s, + fp8_dyn_axs_time_actual_s, + # fp8_lw_time_actual_s, + bf16_time_actual_s / fp8_dyn_time_actual_s, + bf16_time_actual_s / fp8_del_time_actual_s, + bf16_time_actual_s / fp8_dyn_axs_time_actual_s, + # bf16_time_actual_s / fp8_lw_time_actual_s, + ] + ) df = pd.DataFrame(results, columns=headers) print(df) df.to_csv(outfile) - print('done') + print("done") + -if __name__ == '__main__': +if __name__ == "__main__": fire.Fire(run) diff --git a/benchmarks/float8/profile_linear_float8.py b/benchmarks/float8/profile_linear_float8.py index e545ea466..38a8c5e87 100644 --- a/benchmarks/float8/profile_linear_float8.py +++ b/benchmarks/float8/profile_linear_float8.py @@ -5,35 +5,41 @@ # LICENSE file in the root directory of this source tree. import copy -import io import functools +import io import os +import pathlib import random from contextlib import nullcontext, redirect_stdout from dataclasses import dataclass, field -import pathlib from typing import Callable, Optional import fire import pandas as pd # disable inductor FX cache, so we can can always study the inductor output logs -os.environ['TORCHINDUCTOR_FORCE_DISABLE_CACHES'] = '1' +os.environ["TORCHINDUCTOR_FORCE_DISABLE_CACHES"] = "1" import torch import torch.nn as nn import torch.nn.functional as F +from torch.profiler import ProfilerActivity, profile, record_function from torch.utils.checkpoint import ( - checkpoint, - create_selective_checkpoint_contexts, CheckpointPolicy, + checkpoint, + create_selective_checkpoint_contexts, +) +from utils import ( + kernel_name_to_category, + parse_bw_and_kernel_name, + profiler_output_to_filtered_time_by_kernel_name, + profiler_output_to_gpu_time_for_key, + update_triton_kernels_in_prof_chome_trace_with_torch_logs, ) + from torchao.float8.config import ( - CastConfig, - Float8LinearConfig, - ScalingType, - ScalingGranularity, Float8LinearRecipeName, + ScalingType, recipe_name_to_linear_config, ) from torchao.float8.float8_linear_utils import ( @@ -42,14 +48,6 @@ sync_float8_amax_and_scale_history, ) from torchao.testing.float8.test_utils import get_test_float8_linear_config -from torch.profiler import profile, ProfilerActivity, record_function -from utils import ( - kernel_name_to_category, - parse_bw_and_kernel_name, - profiler_output_to_gpu_time_for_key, - profiler_output_to_filtered_time_by_kernel_name, - update_triton_kernels_in_prof_chome_trace_with_torch_logs, -) # don't truncate long kernel names pd.options.display.max_colwidth = 100 @@ -57,7 +55,6 @@ pd.set_option("display.float_format", "{:.3f}".format) - class LNLinear(torch.nn.Module): def __init__(self, fc_dim1, fc_dim2): super().__init__() @@ -184,10 +181,10 @@ class ProfileConfig: def profile_function( - config: ProfileConfig, - func: Callable, + config: ProfileConfig, + func: Callable, add_inductor_metadata_to_trace: bool, - *args, + *args, **kwargs, ) -> torch.profiler.profile: """Profile a torch function and save the result to a file""" @@ -197,8 +194,10 @@ def profile_function( if add_inductor_metadata_to_trace: # ensure we aren't interfering with other torch_log settings - if os.environ.get('TORCH_LOGS', '') != '': - raise AssertionError('using TORCH_LOGS together with add_inductor_metadata_to_trace is not supported yet') + if os.environ.get("TORCH_LOGS", "") != "": + raise AssertionError( + "using TORCH_LOGS together with add_inductor_metadata_to_trace is not supported yet" + ) # save torch.compile logs to a file specific to this benchmark run # TODO(future): can we hack torch.compile to print to file only and not stdout? @@ -209,7 +208,6 @@ def profile_function( if os.path.isfile(config.logs_file_path): pathlib.Path.unlink(config.logs_file_path) torch._logging._init_logs(log_file_name=config.logs_file_path) - activities = [ProfilerActivity.CPU] if config.cuda: @@ -267,12 +265,14 @@ def profile_function( torch.ops.aten.max.default, ] + def policy_fn(ctx, op, *args, **kwargs): if op in ops_to_save: return CheckpointPolicy.MUST_SAVE else: return CheckpointPolicy.PREFER_RECOMPUTE + context_fn = functools.partial(create_selective_checkpoint_contexts, policy_fn) @@ -289,7 +289,12 @@ def main( enable_sync_amax_history: bool = True, enable_activation_checkpointing: bool = False, ): - assert model_type in ("linear", "ln_linear", "norm_ffn_norm", "norm_ffn_norm_small"), "unsupported" + assert model_type in ( + "linear", + "ln_linear", + "norm_ffn_norm", + "norm_ffn_norm_small", + ), "unsupported" assert dtype_filter in ("both", "float8", "bfloat16") scaling_type_input = ScalingType(scaling_type_input) @@ -317,7 +322,9 @@ def main( print(f"Compile is set to | {compile}") print(f"model_type is set to | {model_type}") print(f"scaling_repr is set to | {scaling_repr}") - print(f"enable_activation_checkpointing is set to {enable_activation_checkpointing}") + print( + f"enable_activation_checkpointing is set to {enable_activation_checkpointing}" + ) device = "cuda" ref_dtype = torch.bfloat16 @@ -406,7 +413,7 @@ def float8_forw_backward_wrapper(x): # to populate triton kernel bandwidth further down in the script if os.environ.get("TORCHINDUCTOR_PROFILE", "") == "": context = nullcontext() - f = None + f = None else: f = io.StringIO() context = redirect_stdout(f) @@ -425,16 +432,31 @@ def float8_forw_backward_wrapper(x): ref_logs_suffix = f"_{model_type}_ref_compile_{compile}.txt" trace_ref_path = profile_path_prefix + ref_trace_suffix log_ref_path = profile_path_prefix + ref_logs_suffix - trace_ref_modified_path = trace_ref_path.replace(".json", "_modified.json") + trace_ref_modified_path = trace_ref_path.replace( + ".json", "_modified.json" + ) profile_config = ProfileConfig( - trace_ref_path, log_ref_path, trace_ref_modified_path, ref_trace_suffix, iters=profile_iters, warmup_iters=2, sync=True + trace_ref_path, + log_ref_path, + trace_ref_modified_path, + ref_trace_suffix, + iters=profile_iters, + warmup_iters=2, + sync=True, + ) + p = profile_function( + profile_config, + ref_forw_backward, + add_inductor_metadata_to_trace, + input_tensor, ) - p = profile_function(profile_config, ref_forw_backward, add_inductor_metadata_to_trace, input_tensor) print(f"saved profiling trace to {trace_ref_path}") if add_inductor_metadata_to_trace: print(f"saved torch logs to {log_ref_path}") print(f"saved modified trace to {trace_ref_modified_path}") - ref_times = profiler_output_to_filtered_time_by_kernel_name(p, profile_iters, num_leaf_tensors) + ref_times = profiler_output_to_filtered_time_by_kernel_name( + p, profile_iters, num_leaf_tensors + ) total_time_ms = sum(v for v in ref_times.values()) / 1e3 / profile_iters for k, v in ref_times.items(): v_ms = v / 1e3 / profile_iters @@ -460,7 +482,9 @@ def float8_forw_backward_wrapper(x): ) trace_float8_path = profile_path_prefix + float8_trace_suffix log_float8_path = profile_path_prefix + float8_log_suffix - trace_float8_modified_path = trace_float8_path.replace(".json", "_modified.json") + trace_float8_modified_path = trace_float8_path.replace( + ".json", "_modified.json" + ) profile_config = ProfileConfig( trace_float8_path, log_float8_path, @@ -471,14 +495,21 @@ def float8_forw_backward_wrapper(x): sync=True, ) p = profile_function( - profile_config, float8_forw_backward_wrapper, add_inductor_metadata_to_trace, input_tensor + profile_config, + float8_forw_backward_wrapper, + add_inductor_metadata_to_trace, + input_tensor, ) print(f"saved profiling trace to {trace_float8_path}") if add_inductor_metadata_to_trace: print(f"saved torch logs to {log_float8_path}") print(f"saved modified trace to {trace_float8_modified_path}") - float8_times = profiler_output_to_filtered_time_by_kernel_name(p, profile_iters, num_leaf_tensors) - total_time_ms = sum(v for v in float8_times.values()) / 1e3 / profile_iters + float8_times = profiler_output_to_filtered_time_by_kernel_name( + p, profile_iters, num_leaf_tensors + ) + total_time_ms = ( + sum(v for v in float8_times.values()) / 1e3 / profile_iters + ) for k, v in float8_times.items(): v_ms = v / 1e3 / profile_iters data.append( diff --git a/benchmarks/float8/utils.py b/benchmarks/float8/utils.py index 6567f6949..60e402e60 100644 --- a/benchmarks/float8/utils.py +++ b/benchmarks/float8/utils.py @@ -9,15 +9,16 @@ import re from typing import Optional -from torch.profiler import profile, ProfilerActivity, record_function +from torch.profiler import ProfilerActivity, profile + def profiler_output_to_filtered_time_by_kernel_name( - prof, + prof, num_iter: int, num_leaf_tensors: int, ): """ - Input: + Input: * `prof`: a profiler with captured events * `num_iter`: number of iterations used to capture `prof` * `num_leaf_tensors`: number of leaf tensors to accumulate gradients to @@ -28,7 +29,7 @@ def profiler_output_to_filtered_time_by_kernel_name( set up as follows: # - # Forward pass + # Forward pass # # Expected GPU kernel overhead: none @@ -59,7 +60,6 @@ def profiler_output_to_filtered_time_by_kernel_name( thresh = 1e-10 kernel_name_to_gpu_time_us = collections.defaultdict(float) for e in key_averages: - # manually filter top-level CPU events with attributed CUDA time # example CPU event row from printing `key_averages`: # aten::addmm 0.83% 76.554us 0.98% 90.846us 90.846us 1.022ms 31.82% 1.022ms 1.022ms 1 @@ -69,23 +69,25 @@ def profiler_output_to_filtered_time_by_kernel_name( continue # manually filter expected microbenchmarking overhead, in order of execution - if e.key == 'aten::sum': + if e.key == "aten::sum": # forward pass sum - assert e.count == num_iter, f'unexpected number of iter for {e.key}' + assert e.count == num_iter, f"unexpected number of iter for {e.key}" continue - elif e.key == 'aten::fill_': + elif e.key == "aten::fill_": # filling the forward pass sum with 1.0 - assert e.count == num_iter, f'unexpected number of iter for {e.key}' + assert e.count == num_iter, f"unexpected number of iter for {e.key}" continue - elif e.key == 'aten::copy_': + elif e.key == "aten::copy_": # copying 1.0 from grad_out of `sum` to grad_out of next op - assert e.count == num_iter, f'unexpected number of iter for {e.key}' + assert e.count == num_iter, f"unexpected number of iter for {e.key}" continue - elif e.key == 'aten::add_': + elif e.key == "aten::add_": # accumulating gradients into leaf tensors - assert e.count == (num_iter * num_leaf_tensors), f'unexpected number of iter for {e.key}' + assert e.count == ( + num_iter * num_leaf_tensors + ), f"unexpected number of iter for {e.key}" continue - elif e.key == 'cudaDeviceSynchronize': + elif e.key == "cudaDeviceSynchronize": continue kernel_name_to_gpu_time_us[e.key] = e.self_device_time_total @@ -148,9 +150,10 @@ def get_name_to_shapes_iter( K: Optional[int], N: Optional[int], ): - if shape_gen_name == 'llama': - assert M == K == N == None, \ - f'M, K, N arguments not supported for shape_gen_name {shape_gen_name}' + if shape_gen_name == "llama": + assert ( + M == K == N == None + ), f"M, K, N arguments not supported for shape_gen_name {shape_gen_name}" bsz, seq_len = 4, 4096 M = bsz * seq_len # LLaMa 2 70B single-node weight shapes @@ -164,43 +167,47 @@ def get_name_to_shapes_iter( } return name_to_shapes_70b.items() - elif shape_gen_name == 'square': - assert M == K == N == None, \ - f'M, K, N arguments not supported for shape_gen_name {shape_gen_name}' + elif shape_gen_name == "square": + assert ( + M == K == N == None + ), f"M, K, N arguments not supported for shape_gen_name {shape_gen_name}" name_to_shapes = {} min_power_of_2 = 8 # 256 max_power_of_2 = 15 # 32,768 for idx, power_of_2 in enumerate(range(min_power_of_2, max_power_of_2 + 1)): - val = 2 ** power_of_2 + val = 2**power_of_2 name_to_shapes[idx] = val, val, val return name_to_shapes.items() - elif shape_gen_name == 'sweep': - assert M == K == N == None, \ - f'M, K, N arguments not supported for shape_gen_name {shape_gen_name}' + elif shape_gen_name == "sweep": + assert ( + M == K == N == None + ), f"M, K, N arguments not supported for shape_gen_name {shape_gen_name}" name_to_shapes = {} min_p2 = 8 # 256 max_p2 = 15 # 32,768 counter = 0 for M_p2 in range(min_p2, max_p2 + 1): - M = 2 ** M_p2 + M = 2**M_p2 for K_p2 in range(min_p2, max_p2 + 1): - K = 2 ** K_p2 + K = 2**K_p2 for N_p2 in range(min_p2, max_p2 + 1): - N = 2 ** N_p2 + N = 2**N_p2 name_to_shapes[counter] = M, K, N counter += 1 return name_to_shapes.items() - elif shape_gen_name == 'custom': - assert M is not None and K is not None and N is not None, \ - 'M, K, N must be specified for custom shape_gen' + elif shape_gen_name == "custom": + assert ( + M is not None and K is not None and N is not None + ), "M, K, N must be specified for custom shape_gen" name_to_shapes = { 1: (M, K, N), } return name_to_shapes.items() - raise AssertionError(f'unknown shape_gen_name {shape_gen_name}') + raise AssertionError(f"unknown shape_gen_name {shape_gen_name}") + # copy-pasta from https://github.com/vkuzo/pytorch_scripts/blob/main/add_inductor_metadata_to_perf_trace.py def update_triton_kernels_in_prof_chome_trace_with_torch_logs( @@ -209,34 +216,31 @@ def update_triton_kernels_in_prof_chome_trace_with_torch_logs( modified_perf_trace_file: str, ): """ - Input 1: a perf trace generated by using `torch.profiler.profile` inside of + Input 1: a perf trace generated by using `torch.profiler.profile` inside of some_program.py, and containing torch.compile + inductor kernels - Input 2: a text file with the output of + Input 2: a text file with the output of TORCH_LOGS="output_code" python some_program.py Input 3: filename for the modified perf trace This script does the following for each triton kernel in input 1: - navigate to the kernel information in the logs from input 2 - - copy over the kernel metadata (aten graph, triton code, etc) to the JSON + - copy over the kernel metadata (aten graph, triton code, etc) to the JSON in input 1 - The end result is that Input 1 is modified so that the kernel metadata is + The end result is that Input 1 is modified so that the kernel metadata is directly visible in tools like chrome://tracing and perfetto. """ - external_id_to_cpu_ops = dict() - external_id_to_kernels = dict() - # open the torch logs file torch_logs_str = None - with open(torch_logs_file, 'r') as f: + with open(torch_logs_file, "r") as f: torch_logs_str = f.readlines() # strip away the torch_logs prefix torch_logs_only = [] for line in torch_logs_str: - line = line.replace('\n', '') - match = re.match('.* \[__output_code\] (.*)', line) + line = line.replace("\n", "") + match = re.match(".* \[__output_code\] (.*)", line) if match: torch_logs_only.append(match.group(1)) @@ -253,7 +257,7 @@ def update_triton_kernels_in_prof_chome_trace_with_torch_logs( name_to_start_end = {} cur_start, cur_end, cur_name = None, None, None for line_num, line in enumerate(torch_logs_only): - match_start = re.match('\# kernel path: .*', line) + match_start = re.match("\# kernel path: .*", line) if match_start: cur_start = line_num @@ -279,14 +283,14 @@ def update_triton_kernels_in_prof_chome_trace_with_torch_logs( # ... # // CPU ops, with names matchable to triton kernels from inductor output code # { - # # "cat": "cpu_op", + # # "cat": "cpu_op", # # "name": "triton_red_fused_LayerNorm_abs_max_0", # # "args": {"External id": 1030, ...}, # # ... # }, # // Inductor kernels, with wall time # { - # # "cat": "kernel", + # # "cat": "kernel", # # "name": "triton_", // we don't depend on this name, including for context # # "args": {"External id": 1030, ...}, # # "ts": 4275686082015.124, // start time @@ -300,35 +304,37 @@ def update_triton_kernels_in_prof_chome_trace_with_torch_logs( # 2. Using 1, add the metadata to triton kernels # open the perf trace json - with open(perf_trace_file, 'r') as f: + with open(perf_trace_file, "r") as f: perf_trace = json.load(f) # find mapping of cpu_op to external_id external_id_to_cpu_op = dict() - for record in perf_trace['traceEvents']: + for record in perf_trace["traceEvents"]: # print(record) - is_cpu_op = record.get('cat') == 'cpu_op' + is_cpu_op = record.get("cat") == "cpu_op" if is_cpu_op: - external_id_to_cpu_op[record['args']['External id']] = record['name'] + external_id_to_cpu_op[record["args"]["External id"]] = record["name"] # add the metadata to triton kernels - for record in perf_trace['traceEvents']: - is_triton_kernel = record.get('cat') == 'kernel' and 'triton' in record.get('name', '') + for record in perf_trace["traceEvents"]: + is_triton_kernel = record.get("cat") == "kernel" and "triton" in record.get( + "name", "" + ) if not is_triton_kernel: continue - op_name = external_id_to_cpu_op.get(record['args']['External id']) + op_name = external_id_to_cpu_op.get(record["args"]["External id"]) if op_name is None: continue start, end = name_to_start_end[op_name] - triton_code = torch_logs_only[start:end+1] - s = '' + triton_code = torch_logs_only[start : end + 1] + s = "" for line in triton_code: - s += f'{line}\n' - record['args']['triton_code'] = s + s += f"{line}\n" + record["args"]["triton_code"] = s # write the modified file # out_file = perf_trace_file.replace('.json', '') + '_with_metadata.json' - with open(modified_perf_trace_file, 'w') as f: + with open(modified_perf_trace_file, "w") as f: json.dump(perf_trace, f) @@ -338,8 +344,10 @@ def get_gpu_kernel_gemm_time_s(f, *args, **kwargs): n_iter = 5 with profile(activities=[ProfilerActivity.CPU, ProfilerActivity.CUDA]) as prof: for idx in range(n_iter): - f(*args, **kwargs) - data = profiler_output_to_filtered_time_by_kernel_name(prof, n_iter, num_leaf_tensors=0) + f(*args, **kwargs) + data = profiler_output_to_filtered_time_by_kernel_name( + prof, n_iter, num_leaf_tensors=0 + ) # there is only 1 key, aten::mm or aten::_scaled_mm, with unit nanoseconds assert len(data) == 1 if "aten::mm" in data: @@ -348,5 +356,3 @@ def get_gpu_kernel_gemm_time_s(f, *args, **kwargs): return data["aten::_scaled_mm"] / 1e6 / n_iter else: raise AssertionError("unexpected format of data") - - diff --git a/benchmarks/fused_benchmark_utils.py b/benchmarks/fused_benchmark_utils.py index 5456154c3..da0cf99ec 100644 --- a/benchmarks/fused_benchmark_utils.py +++ b/benchmarks/fused_benchmark_utils.py @@ -47,7 +47,6 @@ def _ref_op( step_size=STEP_SIZE, **kwargs, ): - # Step 1: Down proj grad M, N = grad.shape if M >= N: diff --git a/benchmarks/intmm.py b/benchmarks/intmm.py index 5879f1405..ffad3cc27 100644 --- a/benchmarks/intmm.py +++ b/benchmarks/intmm.py @@ -1,21 +1,16 @@ import argparse import csv import itertools -import math -import sys import pathlib +import sys import torch -from torchao.utils import TORCH_VERSION_AT_LEAST_2_4, TORCH_VERSION_AT_LEAST_2_2 - # Check if CUDA is available, if not, exit the script if not torch.cuda.is_available(): print("CUDA is not available. Exiting the script.") sys.exit(0) -import torch.nn.functional as F -import torch.utils.benchmark as benchmark from torchao.kernel.intmm import int_matmul, int_scaled_matmul torch._dynamo.config.cache_size_limit = 128 @@ -72,7 +67,6 @@ def run_int_scaled_mm_benchmark(x, w, b): def run_benchmarks(shapes): print("fn,m,k,n,fp_time,int_mm_time,ratio") - positives = [] dtype = torch.bfloat16 device = "cuda" for fn, (m, k, n) in itertools.product( @@ -90,7 +84,9 @@ def run_benchmarks(shapes): if __name__ == "__main__": parser = argparse.ArgumentParser(description="integer matmul benchmarks") - parser.add_argument("--file_path", type=str, required=True, help="Path to csv file with shapes") + parser.add_argument( + "--file_path", type=str, required=True, help="Path to csv file with shapes" + ) args = parser.parse_args() # Access the file path provided as an argument file_path = args.file_path diff --git a/benchmarks/print_config_shapes.py b/benchmarks/print_config_shapes.py index 7c2737835..4cf232c86 100644 --- a/benchmarks/print_config_shapes.py +++ b/benchmarks/print_config_shapes.py @@ -1,5 +1,3 @@ -import torchao - from torchao.kernel import autotuner configs = autotuner._load_best_configs() diff --git a/benchmarks/quantized_training/benchmark_int8mm.py b/benchmarks/quantized_training/benchmark_int8mm.py index 0e85cd831..cc2d5cf0d 100644 --- a/benchmarks/quantized_training/benchmark_int8mm.py +++ b/benchmarks/quantized_training/benchmark_int8mm.py @@ -41,5 +41,7 @@ def bench_f(f, *args): sample = [M, N, K, bf16_time / i8_time, bf16_time / i8_dequant_time] data.append(sample) -df = pd.DataFrame(data, columns=["M", "N", "K", "CuBLAS INT8 speedup", "Triton INT8 dequant speedup"]) +df = pd.DataFrame( + data, columns=["M", "N", "K", "CuBLAS INT8 speedup", "Triton INT8 dequant speedup"] +) print(df.to_markdown()) diff --git a/benchmarks/quantized_training/pretrain_llama2.py b/benchmarks/quantized_training/pretrain_llama2.py index 0e6b79f60..25b37921b 100644 --- a/benchmarks/quantized_training/pretrain_llama2.py +++ b/benchmarks/quantized_training/pretrain_llama2.py @@ -23,7 +23,12 @@ from tqdm import tqdm from torchao import quantize_ -from torchao._models.llama.model import ModelArgs, Transformer, transformer_configs, RMSNorm +from torchao._models.llama.model import ( + ModelArgs, + RMSNorm, + Transformer, + transformer_configs, +) from torchao.prototype import low_bit_optim from torchao.prototype.quantized_training import ( bitnet_training, @@ -75,9 +80,13 @@ def get_tinystories(): tokens_list = [] chunk_size = 10_000 - for i in tqdm(range(0, len(stories), chunk_size), desc="Tokenizing TinyStories"): + for i in tqdm( + range(0, len(stories), chunk_size), desc="Tokenizing TinyStories" + ): chunk = stories[i : min(i + chunk_size, len(stories))] - tokens_list.extend(tokenizer.Encode(chunk, add_bos=True, add_eos=True, num_threads=4)) + tokens_list.extend( + tokenizer.Encode(chunk, add_bos=True, add_eos=True, num_threads=4) + ) total_size = sum(len(x) for x in tokens_list) mmap_tokens = np.memmap(save_path, dtype=np.uint16, mode="w+", shape=total_size) @@ -155,13 +164,21 @@ def insert_rmsnorm(module: torch.nn.Module): # don't apply int8_mixed_precision to LM head, since it can cause convergence issue. # TODO: might want to do the same for int8_weight_only to standardize. if args.quantize == "int8_weight_only": - quantize_(model, int8_weight_only_quantized_training(), set_inductor_config=False) + quantize_( + model, int8_weight_only_quantized_training(), set_inductor_config=False + ) elif args.quantize == "int8_mixed_precision": - quantize_(model.layers, int8_mixed_precision_training(), set_inductor_config=False) + quantize_( + model.layers, int8_mixed_precision_training(), set_inductor_config=False + ) elif args.quantize == "int8_mixed_precision_module_swap": - quantize_(model.layers, int8_mixed_precision_training(module_swap=True), set_inductor_config=False) + quantize_( + model.layers, + int8_mixed_precision_training(module_swap=True), + set_inductor_config=False, + ) elif args.quantize == "bitnet": quantize_(model.layers, bitnet_training(), set_inductor_config=False) @@ -195,8 +212,14 @@ def insert_rmsnorm(module: torch.nn.Module): while step < args.n_steps: # randomly select a continuous chunk, then reshape it - idx = torch.randint(0, data.shape[0] - args.batch_size * args.seq_len, (1,)).item() - batch = data[idx : idx + args.batch_size * args.seq_len].view(args.batch_size, args.seq_len).long() + idx = torch.randint( + 0, data.shape[0] - args.batch_size * args.seq_len, (1,) + ).item() + batch = ( + data[idx : idx + args.batch_size * args.seq_len] + .view(args.batch_size, args.seq_len) + .long() + ) with torch.autocast("cuda", torch.bfloat16, enabled=args.bf16_amp): loss = _get_loss(model, batch) @@ -220,7 +243,10 @@ def insert_rmsnorm(module: torch.nn.Module): if step % args.log_interval == 0: time1 = time.time() - log_dict = dict(tokens_per_second=(args.log_interval * args.batch_size * args.seq_len) / (time1 - time0)) + log_dict = dict( + tokens_per_second=(args.log_interval * args.batch_size * args.seq_len) + / (time1 - time0) + ) time0 = time1 run.log(log_dict, step=step) diff --git a/ruff.toml b/ruff.toml index 3df55e96e..a044e95b3 100644 --- a/ruff.toml +++ b/ruff.toml @@ -5,6 +5,7 @@ include = [ "torchao/**/*.py", "test/**/*.py", + "benchmarks/**/*.py", ] exclude = [ diff --git a/torchao/prototype/float8nocompile/float8nocompile_scaling_utils.py b/torchao/prototype/float8nocompile/float8nocompile_scaling_utils.py index df86b8642..bade82c61 100644 --- a/torchao/prototype/float8nocompile/float8nocompile_scaling_utils.py +++ b/torchao/prototype/float8nocompile/float8nocompile_scaling_utils.py @@ -11,19 +11,16 @@ import torch from torchao.float8.float8_tensor import ( - Float8Tensor, GemmInputRole, LinearMMConfig, - _ToFloat8ConstrFunc, ) - from torchao.prototype.float8nocompile.kernels.fp8_dynamic_tensorwise import ( + KernelAlgorithm, hp_to_fp8_col_major, hp_to_fp8_col_major_t, hp_to_fp8_row_and_col_major, hp_to_fp8_row_major, hp_to_fp8_row_major_t, - KernelAlgorithm, ) From eb4933331c425c2e9e47c8e03b0cb4e6565c05f9 Mon Sep 17 00:00:00 2001 From: Daniel Vega-Myhre Date: Tue, 7 Jan 2025 19:47:33 -0800 Subject: [PATCH 7/9] integrate new differentiable fp8 conversion funcs into Float8NoCompileLinear (#1496) --- .../float8nocompile/float8nocompile_linear.py | 120 +++++++++++------- .../test/{test.py => train_test.py} | 0 2 files changed, 74 insertions(+), 46 deletions(-) rename torchao/prototype/float8nocompile/test/{test.py => train_test.py} (100%) diff --git a/torchao/prototype/float8nocompile/float8nocompile_linear.py b/torchao/prototype/float8nocompile/float8nocompile_linear.py index 50ef59ca2..1e50fe0bd 100644 --- a/torchao/prototype/float8nocompile/float8nocompile_linear.py +++ b/torchao/prototype/float8nocompile/float8nocompile_linear.py @@ -11,11 +11,13 @@ import torch from torchao.float8.config import Float8LinearConfig -from torchao.float8.float8_linear import manual_float8_matmul_with_args_in_float8 from torchao.float8.float8_tensor import GemmInputRole, LinearMMConfig, ScaledMMConfig from torchao.prototype.float8nocompile.float8nocompile_scaling_utils import ( - Float8NoCompileConversionFunc, - NoopFwToFloat8NoCompileBwDynamic, + ToFP8ColumnMajor, + ToFP8ColumnMajorT, + ToFP8RowAndColumnMajor, + ToFP8RowMajor, + ToFP8RowMajorT, ) from torchao.prototype.float8nocompile.kernels.fp8_dynamic_tensorwise import ( KernelAlgorithm, @@ -69,53 +71,14 @@ def __init__(self, *args, **kwargs): def forward(self, input: torch.Tensor) -> torch.Tensor: # TODO(danielvegamyhre): support for FSDP once dependencies are implemented - input_fp8 = self.cast_input_to_float8(input) - weight_fp8_t = self.cast_weight_to_float8_t(self.weight) - - # compute fp8 matmul - output = manual_float8_matmul_with_args_in_float8.apply(input_fp8, weight_fp8_t) - - # cast grad_output to float8_e5m2 during backward - return self.cast_output_to_float8_in_bw(output) - - def cast_input_to_float8(self, input: torch.Tensor) -> torch.Tensor: - # Duplicate the autocast logic for F.linear, so that the output - # of our module has the right original precision - if torch.is_autocast_enabled(): - # For now, hardcode to GPU's autocast dtype - # if we need CPU support in the future, we can add it - autocast_dtype = torch.get_autocast_gpu_dtype() - input = input.to(autocast_dtype) - - return Float8NoCompileConversionFunc.apply( + output = matmul_with_args_in_hp.apply( input, - self.config.cast_config_input.target_dtype, - self.linear_mm_config, - GemmInputRole.INPUT, - self.kernel_algo, - ) - - def cast_weight_to_float8_t( - self, - weight: torch.Tensor, - ) -> torch.Tensor: - weight_fp8 = Float8NoCompileConversionFunc.apply( - weight, - self.config.cast_config_weight.target_dtype, - self.linear_mm_config, - GemmInputRole.WEIGHT, - self.kernel_algo, - ) - return weight_fp8.t() - - def cast_output_to_float8_in_bw(self, output: torch.Tensor) -> torch.Tensor: - # casts grad_output to float8_e5m2 for backward - return NoopFwToFloat8NoCompileBwDynamic.apply( - output, - self.config.cast_config_grad_output.target_dtype, + self.weight, + self.config, self.linear_mm_config, self.kernel_algo, ) + return output @classmethod def from_float(cls, mod, kernel_algo: KernelAlgorithm = KernelAlgorithm.ATOMIC_MAX): @@ -140,3 +103,68 @@ def from_float(cls, mod, kernel_algo: KernelAlgorithm = KernelAlgorithm.ATOMIC_M # TODO(danielvegamyhre): support for FSDP once dependencies are implemented return new_mod + + +class matmul_with_args_in_hp(torch.autograd.Function): + @staticmethod + def forward(ctx, input_hp, weight_hp, config, linear_mm_config, kernel_algo): + # output = input @ weight_t + input_fp8_row_major, input_fp8_col_major = ToFP8RowAndColumnMajor.apply( + input_hp, + config.cast_config_input.target_dtype, + linear_mm_config, + GemmInputRole.INPUT, + kernel_algo, + ) + weight_t_fp8_col_major = ToFP8ColumnMajorT.apply( + weight_hp, + config.cast_config_weight.target_dtype, + linear_mm_config, + GemmInputRole.WEIGHT, + kernel_algo, + ) + output = torch.mm(input_fp8_row_major, weight_t_fp8_col_major) + + # save data for backward before returning + ctx.save_for_backward(input_fp8_col_major, weight_hp) + ctx.config = config + ctx.linear_mm_config = linear_mm_config + ctx.kernel_algo = kernel_algo + + return output + + @staticmethod + def backward(ctx, grad_output): + input_fp8_col_major, weight_hp = ctx.saved_tensors + + # cast grad output to float8_e5m2 for backward + grad_output_fp8_row_major = ToFP8RowMajor.apply( + grad_output, + ctx.config.cast_config_grad_output.target_dtype, + ctx.linear_mm_config, + GemmInputRole.GRAD_OUTPUT, + ctx.kernel_algo, + ) + + # grad_input = grad_output @ weight + weight_fp8_col_major = ToFP8ColumnMajor.apply( + weight_hp, + ctx.config.cast_config_weight.target_dtype, + ctx.linear_mm_config, + GemmInputRole.WEIGHT, + ctx.kernel_algo, + ) + grad_input = torch.mm(grad_output_fp8_row_major, weight_fp8_col_major) + + # grad_weight = grad_output_t @ input + # apparently this variant is slightly faster than `grad_weight_t = input_t @ grad_output` + # source: https://github.com/pytorch/ao/blob/fe5f11b2c58b452e01ba9ec7359629928b143619/torchao/float8/float8_linear.py#L84-L85 + grad_output_t_row_major = ToFP8RowMajorT.apply( + grad_output, + ctx.config.cast_config_grad_output.target_dtype, + ctx.linear_mm_config, + GemmInputRole.GRAD_OUTPUT, + ctx.kernel_algo, + ) + grad_weight = torch.mm(grad_output_t_row_major, input_fp8_col_major) + return grad_input, grad_weight, None, None, None diff --git a/torchao/prototype/float8nocompile/test/test.py b/torchao/prototype/float8nocompile/test/train_test.py similarity index 100% rename from torchao/prototype/float8nocompile/test/test.py rename to torchao/prototype/float8nocompile/test/train_test.py From 49961013b2abc0c500c3cb516b00866d64938043 Mon Sep 17 00:00:00 2001 From: Driss Guessous <32754868+drisspg@users.noreply.github.com> Date: Tue, 7 Jan 2025 21:26:57 -0800 Subject: [PATCH 8/9] Fix gcc warning (#1527) --- torchao/csrc/cuda/sparse_marlin/marlin_kernel_nm.cu | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/torchao/csrc/cuda/sparse_marlin/marlin_kernel_nm.cu b/torchao/csrc/cuda/sparse_marlin/marlin_kernel_nm.cu index 380d69130..9f4c44f74 100644 --- a/torchao/csrc/cuda/sparse_marlin/marlin_kernel_nm.cu +++ b/torchao/csrc/cuda/sparse_marlin/marlin_kernel_nm.cu @@ -401,10 +401,13 @@ __global__ void Marlin_24( meta_ptr[i] += m_gl_rd_delta_o; } // Only fetch scales if this tile starts a new group - if (group_blocks != -1 && pipe % (group_blocks / thread_k_blocks) == 0) { - int4* sh_s_stage = sh_s + s_sh_stage * pipe; - if (s_sh_wr_pred) cp_async4(&sh_s_stage[s_sh_wr], &s[s_gl_rd]); - s_gl_rd += s_gl_rd_delta; + if constexpr (group_blocks != -1) { + if (pipe % (group_blocks / thread_k_blocks) == 0) { + int4 *sh_s_stage = sh_s + s_sh_stage * pipe; + if (s_sh_wr_pred) + cp_async4(&sh_s_stage[s_sh_wr], &s[s_gl_rd]); + s_gl_rd += s_gl_rd_delta; + } } } // Insert a fence even when we are winding down the pipeline to ensure that @@ -429,7 +432,7 @@ __global__ void Marlin_24( // however, this does not seem to be a significant bottleneck, while some // theoretically better attempts have lead to bad instruction ordering by // the compiler and correspondingly a noticeable drop in performance. - if (group_blocks != -1) { + if constexpr (group_blocks != -1) { int4* sh_s_stage = sh_s + s_sh_stage * ((group_blocks / thread_k_blocks) * (pipe / (group_blocks / thread_k_blocks))); From 070345d9676f3dd6cdd325e987764fc3c71ccaf5 Mon Sep 17 00:00:00 2001 From: Daniel Vega-Myhre Date: Wed, 8 Jan 2025 06:39:20 -0800 Subject: [PATCH 9/9] add fused transpose and non-transpose kernel and use it for grad output (#1497) --- torchao/prototype/float8nocompile/__init__.py | 0 .../float8nocompile/float8nocompile_linear.py | 25 ++- .../float8nocompile_scaling_utils.py | 36 +++- .../float8nocompile/kernels/__init__.py | 0 .../kernels/fp8_dynamic_tensorwise.py | 158 ++++++++++++++++++ .../kernels/fp8_dynamic_tensorwise_test.py | 75 +++++++++ 6 files changed, 275 insertions(+), 19 deletions(-) create mode 100644 torchao/prototype/float8nocompile/__init__.py create mode 100644 torchao/prototype/float8nocompile/kernels/__init__.py diff --git a/torchao/prototype/float8nocompile/__init__.py b/torchao/prototype/float8nocompile/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/torchao/prototype/float8nocompile/float8nocompile_linear.py b/torchao/prototype/float8nocompile/float8nocompile_linear.py index 1e50fe0bd..37de7b852 100644 --- a/torchao/prototype/float8nocompile/float8nocompile_linear.py +++ b/torchao/prototype/float8nocompile/float8nocompile_linear.py @@ -16,8 +16,7 @@ ToFP8ColumnMajor, ToFP8ColumnMajorT, ToFP8RowAndColumnMajor, - ToFP8RowMajor, - ToFP8RowMajorT, + ToFP8RowMajorTAndNonT, ) from torchao.prototype.float8nocompile.kernels.fp8_dynamic_tensorwise import ( KernelAlgorithm, @@ -138,12 +137,14 @@ def backward(ctx, grad_output): input_fp8_col_major, weight_hp = ctx.saved_tensors # cast grad output to float8_e5m2 for backward - grad_output_fp8_row_major = ToFP8RowMajor.apply( - grad_output, - ctx.config.cast_config_grad_output.target_dtype, - ctx.linear_mm_config, - GemmInputRole.GRAD_OUTPUT, - ctx.kernel_algo, + grad_output_fp8_row_major, grad_output_t_row_major = ( + ToFP8RowMajorTAndNonT.apply( + grad_output, + ctx.config.cast_config_grad_output.target_dtype, + ctx.linear_mm_config, + GemmInputRole.GRAD_OUTPUT, + ctx.kernel_algo, + ) ) # grad_input = grad_output @ weight @@ -159,12 +160,6 @@ def backward(ctx, grad_output): # grad_weight = grad_output_t @ input # apparently this variant is slightly faster than `grad_weight_t = input_t @ grad_output` # source: https://github.com/pytorch/ao/blob/fe5f11b2c58b452e01ba9ec7359629928b143619/torchao/float8/float8_linear.py#L84-L85 - grad_output_t_row_major = ToFP8RowMajorT.apply( - grad_output, - ctx.config.cast_config_grad_output.target_dtype, - ctx.linear_mm_config, - GemmInputRole.GRAD_OUTPUT, - ctx.kernel_algo, - ) grad_weight = torch.mm(grad_output_t_row_major, input_fp8_col_major) + return grad_input, grad_weight, None, None, None diff --git a/torchao/prototype/float8nocompile/float8nocompile_scaling_utils.py b/torchao/prototype/float8nocompile/float8nocompile_scaling_utils.py index bade82c61..7b6a25e3f 100644 --- a/torchao/prototype/float8nocompile/float8nocompile_scaling_utils.py +++ b/torchao/prototype/float8nocompile/float8nocompile_scaling_utils.py @@ -10,10 +10,7 @@ import torch -from torchao.float8.float8_tensor import ( - GemmInputRole, - LinearMMConfig, -) +from torchao.float8.float8_tensor import GemmInputRole, LinearMMConfig from torchao.prototype.float8nocompile.kernels.fp8_dynamic_tensorwise import ( KernelAlgorithm, hp_to_fp8_col_major, @@ -21,6 +18,7 @@ hp_to_fp8_row_and_col_major, hp_to_fp8_row_major, hp_to_fp8_row_major_t, + hp_to_fp8_row_major_t_and_non_t, ) @@ -172,3 +170,33 @@ def forward( @staticmethod def backward(ctx, g): return g, None, None, None, None + + +class ToFP8RowMajorTAndNonT(torch.autograd.Function): + """ + A differentiable conversion to fp8. + * forward: convert from high precision to float8 and produces both row-major (transposed) and row-major (non-transposed) outputs + * backward: pass the gradient without changes + """ + + @staticmethod + def forward( + ctx, + tensor: torch.Tensor, + float8_dtype: torch.dtype, + linear_mm_config: LinearMMConfig, + gemm_input_role: GemmInputRole, + kernel_algo: KernelAlgorithm = KernelAlgorithm.ATOMIC_MAX, + ): + fp8_row_major, fp8_row_major_t = hp_to_fp8_row_major_t_and_non_t( + tensor, + float8_dtype, + linear_mm_config, + gemm_input_role, + algo=kernel_algo, + ) + return fp8_row_major, fp8_row_major_t + + @staticmethod + def backward(ctx, g): + return g, None, None, None, None diff --git a/torchao/prototype/float8nocompile/kernels/__init__.py b/torchao/prototype/float8nocompile/kernels/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/torchao/prototype/float8nocompile/kernels/fp8_dynamic_tensorwise.py b/torchao/prototype/float8nocompile/kernels/fp8_dynamic_tensorwise.py index 7da49e20d..4400a587c 100644 --- a/torchao/prototype/float8nocompile/kernels/fp8_dynamic_tensorwise.py +++ b/torchao/prototype/float8nocompile/kernels/fp8_dynamic_tensorwise.py @@ -305,6 +305,82 @@ def _to_fp8_row_and_col_major( tl.store(col_major_out_ptr + col_major_offs, fp8_vals, mask=mask) +@triton.autotune( + configs=kernel_configs_2D, + key=["num_elements"], +) +@triton.jit +def _to_fp8_row_major_t_and_non_t( + input_ptr, + row_major_out_ptr, + row_major_t_out_ptr, + scale_ptr, + num_elements: int, + fp8_dtype_min: float, + fp8_dtype_max: float, + input_num_rows: int, + input_num_cols: int, + input_stride_row: int, + input_stride_col: int, + row_major_out_stride_row: int, + row_major_out_stride_col: int, + row_major_t_out_stride_row: int, + row_major_t_out_stride_col: int, + input_dtype: tl.constexpr, + output_dtype: tl.constexpr, + BLOCK_SIZE_ROWS: tl.constexpr, + BLOCK_SIZE_COLS: tl.constexpr, + EPS: tl.constexpr, +): + """ + Reads a row-major, high precision input tensor and writes 2 output tensors: + 1) fp8 row major tensor (transposed) + 2) fp8 row major tensor + """ + block_row_id = tl.program_id(axis=0) + block_col_id = tl.program_id(axis=1) + + # load scaling factor + scale = tl.load(scale_ptr).to(tl.float32) + + # load block of input tensor + block_row_start = block_row_id * BLOCK_SIZE_ROWS + block_col_start = block_col_id * BLOCK_SIZE_COLS + block_row_offs = block_row_start + tl.arange(0, BLOCK_SIZE_ROWS) + block_col_offs = block_col_start + tl.arange(0, BLOCK_SIZE_COLS) + input_offs = ( + block_row_offs[:, None] * input_stride_row + + block_col_offs[None, :] * input_stride_col + ) + mask = (block_row_offs[:, None] < input_num_rows) & ( + block_col_offs[None, :] < input_num_cols + ) + vals = tl.load(input_ptr + input_offs, mask=mask).to(input_dtype) + + # perform conversion + vals = vals * scale + fp8_vals = tl.clamp(vals, min=fp8_dtype_min, max=fp8_dtype_max).to(output_dtype) + + # write row-major output + row_major_offs = ( + block_row_offs[:, None] * row_major_out_stride_row + + block_col_offs[None, :] * row_major_out_stride_col + ) + tl.store(row_major_out_ptr + row_major_offs, fp8_vals, mask=mask) + + # write tranposed row-major output + row_major_t_num_rows = input_num_cols + row_major_t_num_cols = input_num_rows + row_major_t_offs = ( + block_col_offs[:, None] * row_major_t_out_stride_row + + block_row_offs[None, :] * row_major_t_out_stride_col + ) + mask = (block_row_offs[:, None] < row_major_t_num_rows) & ( + block_col_offs[None, :] < row_major_t_num_cols + ) + tl.store(row_major_t_out_ptr + row_major_t_offs, fp8_vals.trans(1, 0), mask=mask) + + @triton.autotune(configs=kernel_configs_1D, key=["num_elements"]) @triton.jit def _amax_atomic( @@ -701,6 +777,88 @@ def hp_to_fp8_row_and_col_major( return fp8_tensor_row_major, fp8_tensor_col_major +def hp_to_fp8_row_major_t_and_non_t( + hp_tensor: torch.Tensor, + fp8_dtype: torch.dtype, + linear_mm_config: LinearMMConfig, + gemm_input_role: GemmInputRole = GemmInputRole.INPUT, + algo: KernelAlgorithm = KernelAlgorithm.ATOMIC_MAX, +) -> Float8Tensor: + assert hp_tensor.is_contiguous(), "input tensor must be contiguous" + + tl_input_dtype = FP8_DTYPE_MAP[hp_tensor.dtype] + tl_output_dtype = FP8_DTYPE_MAP[fp8_dtype] + + fp8_dtype_min = torch.finfo(fp8_dtype).min + fp8_dtype_max = torch.finfo(fp8_dtype).max + + # compute scaling factor for tensor + scale = _hp_tensor_to_scale( + hp_tensor, + tl_input_dtype, + fp8_dtype_max, + algo, + ) + + # perform fp8 conversion + input_num_rows, input_num_cols = hp_tensor.shape + transposed_num_rows, transposed_num_cols = input_num_cols, input_num_rows + num_elements = hp_tensor.numel() + + # preallocate necessary output tensors + fp8_output_row_major = torch.empty( + (input_num_rows, input_num_cols), dtype=fp8_dtype, device=hp_tensor.device + ) + fp8_output_row_major_t = torch.empty( + (transposed_num_rows, transposed_num_cols), + dtype=fp8_dtype, + device=hp_tensor.device, + ) + + # launch triton kernel to perform conversion + grid = lambda meta: ( + triton.cdiv(input_num_rows, meta["BLOCK_SIZE_ROWS"]), + triton.cdiv(input_num_cols, meta["BLOCK_SIZE_COLS"]), + ) + _to_fp8_row_major_t_and_non_t[grid]( + hp_tensor, + fp8_output_row_major, + fp8_output_row_major_t, + scale, + num_elements, + fp8_dtype_min, + fp8_dtype_max, + input_num_rows, + input_num_cols, + hp_tensor.stride(0), + hp_tensor.stride(1), + fp8_output_row_major.stride(0), + fp8_output_row_major.stride(1), + fp8_output_row_major_t.stride(0), + fp8_output_row_major_t.stride(1), + input_dtype=tl_input_dtype, + output_dtype=tl_output_dtype, + EPS=EPS, + ) + + # wrap outputs in Float8Tensors + fp8_tensor_row_major = Float8Tensor( + fp8_output_row_major, + scale, + orig_dtype=hp_tensor.dtype, + linear_mm_config=linear_mm_config, + gemm_input_role=gemm_input_role, + ) + fp8_tensor_row_major_t = Float8Tensor( + fp8_output_row_major_t, + scale, + orig_dtype=hp_tensor.dtype, + linear_mm_config=linear_mm_config, + gemm_input_role=gemm_input_role, + ) + return fp8_tensor_row_major, fp8_tensor_row_major_t + + def _hp_tensor_to_scale( hp_tensor: torch.Tensor, tl_input_dtype: tl.core.dtype, diff --git a/torchao/prototype/float8nocompile/kernels/fp8_dynamic_tensorwise_test.py b/torchao/prototype/float8nocompile/kernels/fp8_dynamic_tensorwise_test.py index df09728ab..f0dd78bc0 100644 --- a/torchao/prototype/float8nocompile/kernels/fp8_dynamic_tensorwise_test.py +++ b/torchao/prototype/float8nocompile/kernels/fp8_dynamic_tensorwise_test.py @@ -11,6 +11,7 @@ hp_to_fp8_row_and_col_major, hp_to_fp8_row_major, hp_to_fp8_row_major_t, + hp_to_fp8_row_major_t_and_non_t, ) @@ -335,3 +336,77 @@ def test_fp8_hp_to_fp8_row_and_col_major( torch.float8_e4m3fn, LinearMMConfig(), ) + + +@pytest.mark.parametrize( + "algo", + [KernelAlgorithm.REDUCTION, KernelAlgorithm.ATOMIC_MAX], +) +@pytest.mark.parametrize( + "input_shape", + [(2, 4), (32, 16), (512, 512)], +) +def test_fp8_hp_to_fp8_row_major_t_and_non_t( + input_shape: tuple[int, int], algo: KernelAlgorithm +): + assert torch.cuda.is_available() + device = "cuda" + input_bf16 = torch.randn(input_shape, dtype=torch.bfloat16, device=device) + x_bf16 = input_bf16.clone().detach().to(device) + y_bf16 = input_bf16.clone().detach().to(device) + + # production implementation + x_fp8_row_major = hp_tensor_to_float8_dynamic( + x_bf16, + torch.float8_e4m3fn, + LinearMMConfig(), + ) + x_fp8_row_major_t = x_fp8_row_major.t().contiguous() + + # float8nocompile triton implementation + y_fp8_row_major, y_fp8_row_major_t = hp_to_fp8_row_major_t_and_non_t( + y_bf16, + torch.float8_e4m3fn, + LinearMMConfig(), + algo=algo, + ) + + # check scales + assert torch.eq(x_fp8_row_major._scale, y_fp8_row_major._scale) + assert torch.eq(x_fp8_row_major_t._scale, y_fp8_row_major_t._scale) + + # check data + assert torch.all(torch.eq(x_fp8_row_major._data, y_fp8_row_major._data)) + assert torch.all(torch.eq(x_fp8_row_major_t._data, y_fp8_row_major_t._data)) + + # check shapes + assert x_fp8_row_major.shape == y_fp8_row_major.shape + assert x_fp8_row_major_t.shape == y_fp8_row_major_t.shape + + # check strides + assert x_fp8_row_major.stride() == y_fp8_row_major.stride() + assert x_fp8_row_major_t.stride() == y_fp8_row_major_t.stride() + + # check memory layout + assert is_row_major(x_fp8_row_major.stride()) + assert is_row_major(y_fp8_row_major.stride()) + assert is_row_major(x_fp8_row_major_t.stride()) + assert is_row_major(y_fp8_row_major_t.stride()) + + # check underlying memory layout + assert ( + x_fp8_row_major._data.storage().tolist() + == y_fp8_row_major._data.storage().tolist() + ) + assert ( + x_fp8_row_major_t._data.storage().tolist() + == y_fp8_row_major_t._data.storage().tolist() + ) + + # assert that error is raised when input tensor is not contiguous + with pytest.raises(AssertionError, match="tensor must be contiguous"): + hp_to_fp8_row_major_t_and_non_t( + y_bf16.t(), # transpose so tensor memory layout is no longer contiguous + torch.float8_e4m3fn, + LinearMMConfig(), + )