Problem 270

C(30) mod 10^8 for square cuttings.

Answer82282080
Output82282080
StatusPASS
Native helperno
Runtime70 ms
Peak memory3648 KB
Time complexityO(n log n) (estimated)
Space complexityO(n^2) (estimated)

Performance comparison

MetricOur solutionBest known
Time complexityO(n log n)O(n^2)
Space complexityO(n^2)O(n^2)
ApproachFlow solutionCombinatorial counting
VerdictOptimal

Flow source

# Project Euler 270
# C(30) mod 10^8 for square cuttings.

extern {
    function calloc(n: i64, size: i64) -> ptr<void>
    function free(p: ptr<void>) -> void
}

let mut G_i: i64 = 0
let mut G_j: i64 = 0
let mut G_dp: ptr<i64> = null
let mut G_n: i64 = 0
let mut G_types: ptr<i32> = null
let mut G_masks: ptr<i32> = null
let mut G_allowed: ptr<i8> = null
let mut G_compat: ptr<i32> = null
let mut G_memo_v: ptr<i64> = null
let mut G_memo_k: ptr<i32> = null
let mut G_mod: i64 = 100000000

function f(p: i64, R: i64) -> i64 {
    let key: i32 = ((p as i32) << 8) | (R as i32)
    let mut h: i64 = (key as i64) % 200003
    if h < 0 { h = -h }
    while G_memo_k[h] != 0 {
        if G_memo_k[h] == key + 1 {
            return G_memo_v[h]
        }
        h = h + 1
        if h == 200003 { h = 0 }
    }
    let mut total: i64 = 0
    let mut q: i64 = p + 1
    while q <= G_j {
        if !(p == G_i && q == G_j) {
            let tq: i64 = G_types[q] as i64
            if ((R >> tq) & 1) != 0 {
                let ok_edge: bool = (q == p + 1) || (G_allowed[p * G_n + q] != 0)
                if ok_edge {
                    let mut ok: bool = true
                    if p != G_i && q != G_j && (G_masks[q] & G_masks[G_i]) == 0 {
                        ok = false
                    }
                    if ok && q != G_j && p != G_i && (G_masks[p] & G_masks[G_j]) == 0 {
                        ok = false
                    }
                    if ok {
                        let w: i64 = G_dp[p * G_n + q]
                        if w != 0 {
                            if q == G_j {
                                total = total + w
                            } else {
                                let mut Rn: i64 = R
                                if p != G_i {
                                    Rn = R & (G_compat[G_types[p] as i64] as i64)
                                }
                                total = total + w * f(q, Rn)
                            }
                        }
                    }
                }
            }
        }
        q = q + 1
    }
    total = total % G_mod
    G_memo_k[h] = key + 1
    G_memo_v[h] = total
    return total
}

function main() -> i32 {
    let N: i64 = 30
    let MOD: i64 = 100000000
    G_mod = MOD
    let n: i64 = 4 * N
    G_n = n
    let pts_x: ptr<i64> = calloc(n, 8)
    let pts_y: ptr<i64> = calloc(n, 8)
    let mut k: i64 = 0
    let mut x: i64 = 0
    while x <= N {
        pts_x[k] = x; pts_y[k] = 0; k = k + 1
        x = x + 1
    }
    let mut y: i64 = 1
    while y <= N {
        pts_x[k] = N; pts_y[k] = y; k = k + 1
        y = y + 1
    }
    x = N - 1
    while x >= 0 {
        pts_x[k] = x; pts_y[k] = N; k = k + 1
        x = x - 1
    }
    y = N - 1
    while y >= 1 {
        pts_x[k] = 0; pts_y[k] = y; k = k + 1
        y = y - 1
    }
    G_masks = calloc(n, 4)
    G_types = calloc(n, 4)
    let mut i: i64 = 0
    while i < n {
        let xx: i64 = pts_x[i]
        let yy: i64 = pts_y[i]
        let mut mask: i32 = 0
        if yy == 0 { mask = mask | 1 }
        if xx == N { mask = mask | 2 }
        if yy == N { mask = mask | 4 }
        if xx == 0 { mask = mask | 8 }
        G_masks[i] = mask
        let mut t: i32 = 0
        match mask {
            1 => { t = 0 }
            2 => { t = 1 }
            4 => { t = 2 }
            8 => { t = 3 }
            3 => { t = 4 }
            6 => { t = 5 }
            12 => { t = 6 }
            9 => { t = 7 }
            _ => { }
        }
        G_types[i] = t
        i = i + 1
    }
    let masks_by_type: ptr<i32> = calloc(8, 4)
    masks_by_type[0] = 1; masks_by_type[1] = 2; masks_by_type[2] = 4; masks_by_type[3] = 8
    masks_by_type[4] = 3; masks_by_type[5] = 6; masks_by_type[6] = 12; masks_by_type[7] = 9
    G_compat = calloc(8, 4)
    let mut t: i64 = 0
    while t < 8 {
        let mut bit: i32 = 0
        let mut u: i64 = 0
        while u < 8 {
            if (masks_by_type[t] & masks_by_type[u]) != 0 {
                bit = bit | (1 << u)
            }
            u = u + 1
        }
        G_compat[t] = bit
        t = t + 1
    }
    G_allowed = calloc(n * n, 1)
    i = 0
    while i < n {
        let mut j: i64 = i + 2
        while j < n {
            if (G_masks[i] & G_masks[j]) == 0 {
                G_allowed[i * n + j] = 1
            }
            j = j + 1
        }
        i = i + 1
    }
    G_dp = calloc(n * n, 8)
    i = 0
    while i < n - 1 {
        G_dp[i * n + (i + 1)] = 1
        i = i + 1
    }
    G_memo_v = calloc(200003, 8)
    G_memo_k = calloc(200003, 4)
    let mut length: i64 = 2
    while length < n {
        i = 0
        while i + length < n {
            let j: i64 = i + length
            G_i = i
            G_j = j
            # clear memo
            let mut h: i64 = 0
            while h < 200003 {
                G_memo_k[h] = 0
                h = h + 1
            }
            G_dp[i * n + j] = f(i, 255) % MOD
            i = i + 1
        }
        length = length + 1
    }
    printf("%lld\n", G_dp[0 * n + (n - 1)] % MOD)
    return 0
}

Generated C

#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* Flow runtime helpers */
typedef struct flow_temp_node { struct flow_temp_node* next; } flow_temp_node;
static flow_temp_node* flow_temp_head = NULL;
static int flow_temp_atexit_set = 0;
__attribute__((unused)) static void flow_temp_free_all(void) {
    while (flow_temp_head) {
        flow_temp_node* n = flow_temp_head;
        flow_temp_head = n->next;
        free(n);
    }
}
__attribute__((unused)) static void* flow_temp_alloc(size_t nbytes) {
    flow_temp_node* node = (flow_temp_node*)malloc(sizeof(flow_temp_node) + nbytes);
    if (!node) return NULL;
    node->next = flow_temp_head;
    flow_temp_head = node;
    if (!flow_temp_atexit_set) {
        flow_temp_atexit_set = 1;
        atexit(flow_temp_free_all);
    }
    return (void*)(node + 1);
}
#ifndef FLOW_DIAG
#define FLOW_DIAG(msg) fprintf(stderr, "%s", (msg))
#endif
#ifndef FLOW_LOG
#define FLOW_LOG(fmt, ...) printf(fmt, __VA_ARGS__)
#endif
#ifndef FLOW_LOG_EMPTY
#define FLOW_LOG_EMPTY(fmt) printf(fmt)
#endif
static char* flow_strcat(const char* a, const char* b) {
    size_t la = strlen(a ? a : ""), lb = strlen(b ? b : "");
    char* r = (char*)flow_temp_alloc(la + lb + 1);
    if (!r) return NULL;
    if (la) memcpy(r, a, la);
    if (lb) memcpy(r + la, b, lb);
    r[la + lb] = '\0';
    return r;
}

#define __flow_in_arr(arr, val) __extension__ ({ \
    int _found = 0; \
    size_t _n = sizeof(arr)/sizeof((arr)[0]); \
    for (size_t _i = 0; _i < _n; _i++) { \
        if ((arr)[_i] == (val)) { _found = 1; break; } \
    } _found; })

/* Unified fault handler (MISRA #279) — override with -DFLOW_FAULT_HANDLER=fn */
#ifndef FLOW_FAULT_HANDLER
__attribute__((unused)) static inline void flow_fault_handler(const char* msg) {
    fprintf(stderr, "flow: %s\n", msg ? msg : "fault");
    abort();
#if defined(__GNUC__) || defined(__clang__)
    __builtin_unreachable();
#endif
}
#else
#define flow_fault_handler FLOW_FAULT_HANDLER
#endif
#define flow_div_by_zero_handler() flow_fault_handler("division by zero")
#define flow_shift_ub_handler() flow_fault_handler("invalid shift (amount out of range or left-shift of negative)")

#ifndef FLOW_CHECKED_DIV
#define FLOW_CHECKED_DIV(L, R) (((R) != 0) ? ((L) / (R)) : (flow_div_by_zero_handler(), (L) * 0))
#endif
#ifndef FLOW_CHECKED_MOD
#define FLOW_CHECKED_MOD(L, R) (((R) != 0) ? ((L) % (R)) : (flow_div_by_zero_handler(), (L) * 0))
#endif
#ifndef FLOW_CHECKED_SHL
#define FLOW_CHECKED_SHL(L, R) ((((R) >= 0) && ((unsigned long long)(R) < (sizeof(L) * 8ull)) && ((L) >= 0)) ? ((L) << (R)) : (flow_shift_ub_handler(), (L) * 0))
#endif
#ifndef FLOW_CHECKED_SHR
#define FLOW_CHECKED_SHR(L, R) ((((R) >= 0) && ((unsigned long long)(R) < (sizeof(L) * 8ull))) ? ((L) >> (R)) : (flow_shift_ub_handler(), (L) * 0))
#endif

#include <math.h>

void* _ui_state = NULL;

static inline float i32_to_f32(int32_t v) { return (float)v; }

/* Host stub for @gpu kernels (device codegen replaces this). */
static inline int32_t gpu_thread_id(void) { return 0; }

int64_t f_i64_i64(int64_t p, int64_t R);
int32_t main(void);

/* Module statics */
static int64_t G_i = 0;
static int64_t G_j = 0;
static int64_t* G_dp = NULL;
static int64_t G_n = 0;
static int32_t* G_types = NULL;
static int32_t* G_masks = NULL;
static int8_t* G_allowed = NULL;
static int32_t* G_compat = NULL;
static int64_t* G_memo_v = NULL;
static int32_t* G_memo_k = NULL;
static int64_t G_mod = 100000000;



int64_t f_i64_i64(int64_t p, int64_t R) {
    int32_t key = (FLOW_CHECKED_SHL((((int32_t)(p))), (8)) | ((int32_t)(R)));
    int64_t h = FLOW_CHECKED_MOD((((int64_t)(key))), (200003));
    if (h < 0) {
        h = (-h);
    }
    while (G_memo_k[h] != 0) {
        if (G_memo_k[h] == (key + 1)) {
            return G_memo_v[h];
        }
        h = (h + 1);
        if (h == 200003) {
            h = 0;
        }
    }
    int64_t total = 0;
    int64_t q = (p + 1);
    while (q <= G_j) {
        if ((!((p == G_i && q == G_j)))) {
            int64_t tq = ((int64_t)(G_types[q]));
            if ((FLOW_CHECKED_SHR((R), (tq)) & 1) != 0) {
                bool ok_edge = (q == (p + 1) || G_allowed[((p * G_n) + q)] != 0);
                if (ok_edge) {
                    bool ok = 1;
                    if (((p != G_i && q != G_j) && (G_masks[q] & G_masks[G_i]) == 0)) {
                        ok = 0;
                    }
                    if ((((ok && q != G_j) && p != G_i) && (G_masks[p] & G_masks[G_j]) == 0)) {
                        ok = 0;
                    }
                    if (ok) {
                        int64_t w = G_dp[((p * G_n) + q)];
                        if (w != 0) {
                            if (q == G_j) {
                                total = (total + w);
                            } else {
                                int64_t Rn = R;
                                if (p != G_i) {
                                    Rn = (R & ((int64_t)(G_compat[((int64_t)(G_types[p]))])));
                                }
                                total = (total + (w * f_i64_i64(q, Rn)));
                            }
                        }
                    }
                }
            }
        }
        q = (q + 1);
    }
    total = FLOW_CHECKED_MOD((total), (G_mod));
    G_memo_k[h] = (key + 1);
    G_memo_v[h] = total;
    return total;
}

int32_t main(void) {
    int64_t N = 30;
    int64_t MOD = 100000000;
    G_mod = MOD;
    int64_t n = (4 * N);
    G_n = n;
    int64_t* pts_x = (int64_t*)(calloc(n, 8));
    int64_t* pts_y = (int64_t*)(calloc(n, 8));
    int64_t k = 0;
    int64_t x = 0;
    while (x <= N) {
        pts_x[k] = x;
        pts_y[k] = 0;
        k = (k + 1);
        x = (x + 1);
    }
    int64_t y = 1;
    while (y <= N) {
        pts_x[k] = N;
        pts_y[k] = y;
        k = (k + 1);
        y = (y + 1);
    }
    x = (N - 1);
    while (x >= 0) {
        pts_x[k] = x;
        pts_y[k] = N;
        k = (k + 1);
        x = (x - 1);
    }
    y = (N - 1);
    while (y >= 1) {
        pts_x[k] = 0;
        pts_y[k] = y;
        k = (k + 1);
        y = (y - 1);
    }
    G_masks = calloc(n, 4);
    G_types = calloc(n, 4);
    int64_t i = 0;
    while (i < n) {
        int64_t xx = pts_x[i];
        int64_t yy = pts_y[i];
        int32_t mask = 0;
        if (yy == 0) {
            mask = (mask | 1);
        }
        if (xx == N) {
            mask = (mask | 2);
        }
        if (yy == N) {
            mask = (mask | 4);
        }
        if (xx == 0) {
            mask = (mask | 8);
        }
        G_masks[i] = mask;
        int32_t t = 0;
        { // match block
            if ((mask) == 1) {
                t = 0;
            } else if ((mask) == 2) {
                t = 1;
            } else if ((mask) == 4) {
                t = 2;
            } else if ((mask) == 8) {
                t = 3;
            } else if ((mask) == 3) {
                t = 4;
            } else if ((mask) == 6) {
                t = 5;
            } else if ((mask) == 12) {
                t = 6;
            } else if ((mask) == 9) {
                t = 7;
            } else { // exhaustive
            }
        } // end match
        G_types[i] = t;
        i = (i + 1);
    }
    int32_t* masks_by_type = (int32_t*)(calloc(8, 4));
    masks_by_type[0] = 1;
    masks_by_type[1] = 2;
    masks_by_type[2] = 4;
    masks_by_type[3] = 8;
    masks_by_type[4] = 3;
    masks_by_type[5] = 6;
    masks_by_type[6] = 12;
    masks_by_type[7] = 9;
    G_compat = calloc(8, 4);
    int64_t t = 0;
    while (t < 8) {
        int32_t bit = 0;
        int64_t u = 0;
        while (u < 8) {
            if ((masks_by_type[t] & masks_by_type[u]) != 0) {
                bit = (bit | FLOW_CHECKED_SHL((1), (u)));
            }
            u = (u + 1);
        }
        G_compat[t] = bit;
        t = (t + 1);
    }
    G_allowed = calloc((n * n), 1);
    i = 0;
    while (i < n) {
        int64_t j = (i + 2);
        while (j < n) {
            if ((G_masks[i] & G_masks[j]) == 0) {
                G_allowed[((i * n) + j)] = 1;
            }
            j = (j + 1);
        }
        i = (i + 1);
    }
    G_dp = calloc((n * n), 8);
    i = 0;
    while (i < (n - 1)) {
        G_dp[((i * n) + (i + 1))] = 1;
        i = (i + 1);
    }
    G_memo_v = calloc(200003, 8);
    G_memo_k = calloc(200003, 4);
    int64_t length = 2;
    while (length < n) {
        i = 0;
        while ((i + length) < n) {
            int64_t j = (i + length);
            G_i = i;
            G_j = j;
            int64_t h = 0;
            while (h < 200003) {
                G_memo_k[h] = 0;
                h = (h + 1);
            }
            G_dp[((i * n) + j)] = FLOW_CHECKED_MOD((f_i64_i64(i, 255)), (MOD));
            i = (i + 1);
        }
        length = (length + 1);
    }
    printf("%lld\n", FLOW_CHECKED_MOD((G_dp[((0 * n) + (n - 1))]), (MOD)));
    return 0;
}

Generated MLIR

module {
  llvm.func @printf(!llvm.ptr, ...) -> i32
  llvm.mlir.global internal constant @str_0("%lld\n\00") {addr_space = 0 : i32} : !llvm.array<6 x i8>
  func.func private @calloc(i64, i64) -> !llvm.ptr
  func.func private @free(!llvm.ptr) -> ()
  // Module static: G_i
  llvm.mlir.global internal @G_i(0 : i64) : i64
  // Module static: G_j
  llvm.mlir.global internal @G_j(0 : i64) : i64
  // Module static: G_dp
  llvm.mlir.global internal @G_dp() {addr_space = 0 : i32} : !llvm.ptr {
    %0 = llvm.mlir.zero : !llvm.ptr
    llvm.return %0 : !llvm.ptr
  }
  // Module static: G_n
  llvm.mlir.global internal @G_n(0 : i64) : i64
  // Module static: G_types
  llvm.mlir.global internal @G_types() {addr_space = 0 : i32} : !llvm.ptr {
    %1 = llvm.mlir.zero : !llvm.ptr
    llvm.return %1 : !llvm.ptr
  }
  // Module static: G_masks
  llvm.mlir.global internal @G_masks() {addr_space = 0 : i32} : !llvm.ptr {
    %2 = llvm.mlir.zero : !llvm.ptr
    llvm.return %2 : !llvm.ptr
  }
  // Module static: G_allowed
  llvm.mlir.global internal @G_allowed() {addr_space = 0 : i32} : !llvm.ptr {
    %3 = llvm.mlir.zero : !llvm.ptr
    llvm.return %3 : !llvm.ptr
  }
  // Module static: G_compat
  llvm.mlir.global internal @G_compat() {addr_space = 0 : i32} : !llvm.ptr {
    %4 = llvm.mlir.zero : !llvm.ptr
    llvm.return %4 : !llvm.ptr
  }
  // Module static: G_memo_v
  llvm.mlir.global internal @G_memo_v() {addr_space = 0 : i32} : !llvm.ptr {
    %5 = llvm.mlir.zero : !llvm.ptr
    llvm.return %5 : !llvm.ptr
  }
  // Module static: G_memo_k
  llvm.mlir.global internal @G_memo_k() {addr_space = 0 : i32} : !llvm.ptr {
    %6 = llvm.mlir.zero : !llvm.ptr
    llvm.return %6 : !llvm.ptr
  }
  // Module static: G_mod
  llvm.mlir.global internal @G_mod(100000000 : i64) : i64
  func.func @f(%arg0: i64, %arg1: i64) -> i64 {
    %7 = arith.trunci %arg0 : i64 to i32
    %8 = arith.constant 8 : i32
    %9 = arith.shli %7, %8 : i32
    %10 = arith.trunci %arg1 : i64 to i32
    %11 = arith.ori %9, %10 : i32
    %12 = arith.extsi %11 : i32 to i64
    %13 = arith.constant 200003 : i32
    %15 = arith.extsi %13 : i32 to i64
    %14 = arith.remsi %12, %15 : i64
    %16 = llvm.mlir.constant(1 : i64) : i64
    %17 = llvm.alloca %16 x i64 : (i64) -> !llvm.ptr
    llvm.store %14, %17 : i64, !llvm.ptr
    %18 = llvm.load %17 : !llvm.ptr -> i64
    %19 = arith.constant 0 : i32
    %21 = arith.extsi %19 : i32 to i64
    %20 = arith.cmpi slt, %18, %21 : i64
    cf.cond_br %20, ^bb0, ^bb1
    ^bb0:
      %22 = llvm.load %17 : !llvm.ptr -> i64
      %24 = arith.constant 0 : i64
      %23 = arith.subi %24, %22 : i64
      llvm.store %23, %17 : i64, !llvm.ptr
      cf.br ^bb2
    ^bb1:
      cf.br ^bb2
    ^bb2:
    cf.br ^bb3
    ^bb3:
    %26 = llvm.mlir.addressof @G_memo_k : !llvm.ptr
    %27 = llvm.load %26 : !llvm.ptr -> !llvm.ptr
    %28 = llvm.load %17 : !llvm.ptr -> i64
    %29 = llvm.getelementptr %27[%28] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %25 = llvm.load %29 : !llvm.ptr -> i32
    %30 = arith.constant 0 : i32
    %31 = arith.cmpi ne, %25, %30 : i32
    cf.cond_br %31, ^bb4, ^bb5
    ^bb4:
      %33 = llvm.mlir.addressof @G_memo_k : !llvm.ptr
      %34 = llvm.load %33 : !llvm.ptr -> !llvm.ptr
      %35 = llvm.load %17 : !llvm.ptr -> i64
      %36 = llvm.getelementptr %34[%35] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %32 = llvm.load %36 : !llvm.ptr -> i32
      %37 = arith.constant 1 : i32
      %38 = arith.addi %11, %37 : i32
      %39 = arith.cmpi eq, %32, %38 : i32
      cf.cond_br %39, ^bb6, ^bb7
      ^bb6:
        %41 = llvm.mlir.addressof @G_memo_v : !llvm.ptr
        %42 = llvm.load %41 : !llvm.ptr -> !llvm.ptr
        %43 = llvm.load %17 : !llvm.ptr -> i64
        %44 = llvm.getelementptr %42[%43] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %40 = llvm.load %44 : !llvm.ptr -> i64
        func.return %40 : i64
      ^bb7:
        cf.br ^bb8
      ^bb8:
      %45 = llvm.load %17 : !llvm.ptr -> i64
      %46 = arith.constant 1 : i32
      %48 = arith.extsi %46 : i32 to i64
      %47 = arith.addi %45, %48 : i64
      llvm.store %47, %17 : i64, !llvm.ptr
      %49 = llvm.load %17 : !llvm.ptr -> i64
      %50 = arith.constant 200003 : i32
      %52 = arith.extsi %50 : i32 to i64
      %51 = arith.cmpi eq, %49, %52 : i64
      cf.cond_br %51, ^bb9, ^bb10
      ^bb9:
        %53 = arith.constant 0 : i32
        %54 = arith.extsi %53 : i32 to i64
        llvm.store %54, %17 : i64, !llvm.ptr
        cf.br ^bb11
      ^bb10:
        cf.br ^bb11
      ^bb11:
      cf.br ^bb3
    ^bb5:
    %55 = arith.constant 0 : i32
    %56 = arith.extsi %55 : i32 to i64
    %57 = llvm.mlir.constant(1 : i64) : i64
    %58 = llvm.alloca %57 x i64 : (i64) -> !llvm.ptr
    llvm.store %56, %58 : i64, !llvm.ptr
    %59 = arith.constant 1 : i32
    %61 = arith.extsi %59 : i32 to i64
    %60 = arith.addi %arg0, %61 : i64
    %62 = llvm.mlir.constant(1 : i64) : i64
    %63 = llvm.alloca %62 x i64 : (i64) -> !llvm.ptr
    llvm.store %60, %63 : i64, !llvm.ptr
    cf.br ^bb12
    ^bb12:
    %64 = llvm.load %63 : !llvm.ptr -> i64
    %65 = llvm.mlir.addressof @G_j : !llvm.ptr
    %66 = llvm.load %65 : !llvm.ptr -> i64
    %67 = arith.cmpi sle, %64, %66 : i64
    cf.cond_br %67, ^bb13, ^bb14
    ^bb13:
      %68 = llvm.mlir.addressof @G_i : !llvm.ptr
      %69 = llvm.load %68 : !llvm.ptr -> i64
      %70 = arith.cmpi eq, %arg0, %69 : i64
      %71 = scf.if %70 -> (i1) {
        %72 = llvm.load %63 : !llvm.ptr -> i64
        %73 = llvm.mlir.addressof @G_j : !llvm.ptr
        %74 = llvm.load %73 : !llvm.ptr -> i64
        %75 = arith.cmpi eq, %72, %74 : i64
        scf.yield %75 : i1
      } else {
        %76 = arith.constant false
        scf.yield %76 : i1
      }
      %78 = arith.constant 1 : i1
      %77 = arith.xori %71, %78 : i1
      cf.cond_br %77, ^bb15, ^bb16
      ^bb15:
        %81 = llvm.mlir.addressof @G_types : !llvm.ptr
        %82 = llvm.load %81 : !llvm.ptr -> !llvm.ptr
        %83 = llvm.load %63 : !llvm.ptr -> i64
        %84 = llvm.getelementptr %82[%83] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %80 = llvm.load %84 : !llvm.ptr -> i32
        %85 = arith.extsi %80 : i32 to i64
        %86 = arith.shrsi %arg1, %85 : i64
        %87 = arith.constant 1 : i32
        %89 = arith.extsi %87 : i32 to i64
        %88 = arith.andi %86, %89 : i64
        %90 = arith.constant 0 : i32
        %92 = arith.extsi %90 : i32 to i64
        %91 = arith.cmpi ne, %88, %92 : i64
        cf.cond_br %91, ^bb18, ^bb19
        ^bb18:
          %93 = llvm.load %63 : !llvm.ptr -> i64
          %94 = arith.constant 1 : i32
          %96 = arith.extsi %94 : i32 to i64
          %95 = arith.addi %arg0, %96 : i64
          %97 = arith.cmpi eq, %93, %95 : i64
          %98 = scf.if %97 -> (i1) {
            %99 = arith.constant true
            scf.yield %99 : i1
          } else {
            %101 = llvm.mlir.addressof @G_allowed : !llvm.ptr
            %102 = llvm.load %101 : !llvm.ptr -> !llvm.ptr
            %103 = llvm.mlir.addressof @G_n : !llvm.ptr
            %104 = llvm.load %103 : !llvm.ptr -> i64
            %105 = arith.muli %arg0, %104 : i64
            %106 = llvm.load %63 : !llvm.ptr -> i64
            %107 = arith.addi %105, %106 : i64
            %108 = llvm.getelementptr %102[%107] : (!llvm.ptr, i64) -> !llvm.ptr, i8
            %100 = llvm.load %108 : !llvm.ptr -> i8
            %109 = arith.constant 0 : i32
            %111 = arith.extsi %100 : i8 to i32
            %110 = arith.cmpi ne, %111, %109 : i32
            scf.yield %110 : i1
          }
          cf.cond_br %98, ^bb21, ^bb22
          ^bb21:
            %112 = arith.constant 1 : i1
            %113 = llvm.mlir.constant(1 : i64) : i64
            %114 = llvm.alloca %113 x i1 : (i64) -> !llvm.ptr
            llvm.store %112, %114 : i1, !llvm.ptr
            %115 = llvm.mlir.addressof @G_i : !llvm.ptr
            %116 = llvm.load %115 : !llvm.ptr -> i64
            %117 = arith.cmpi ne, %arg0, %116 : i64
            %118 = scf.if %117 -> (i1) {
              %119 = llvm.load %63 : !llvm.ptr -> i64
              %120 = llvm.mlir.addressof @G_j : !llvm.ptr
              %121 = llvm.load %120 : !llvm.ptr -> i64
              %122 = arith.cmpi ne, %119, %121 : i64
              scf.yield %122 : i1
            } else {
              %123 = arith.constant false
              scf.yield %123 : i1
            }
            %124 = scf.if %118 -> (i1) {
              %126 = llvm.mlir.addressof @G_masks : !llvm.ptr
              %127 = llvm.load %126 : !llvm.ptr -> !llvm.ptr
              %128 = llvm.load %63 : !llvm.ptr -> i64
              %129 = llvm.getelementptr %127[%128] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              %125 = llvm.load %129 : !llvm.ptr -> i32
              %131 = llvm.mlir.addressof @G_masks : !llvm.ptr
              %132 = llvm.load %131 : !llvm.ptr -> !llvm.ptr
              %133 = llvm.mlir.addressof @G_i : !llvm.ptr
              %134 = llvm.load %133 : !llvm.ptr -> i64
              %135 = llvm.getelementptr %132[%134] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              %130 = llvm.load %135 : !llvm.ptr -> i32
              %136 = arith.andi %125, %130 : i32
              %137 = arith.constant 0 : i32
              %138 = arith.cmpi eq, %136, %137 : i32
              scf.yield %138 : i1
            } else {
              %139 = arith.constant false
              scf.yield %139 : i1
            }
            cf.cond_br %124, ^bb24, ^bb25
            ^bb24:
              %140 = arith.constant 0 : i1
              llvm.store %140, %114 : i1, !llvm.ptr
              cf.br ^bb26
            ^bb25:
              cf.br ^bb26
            ^bb26:
            %141 = llvm.load %114 : !llvm.ptr -> i1
            %142 = scf.if %141 -> (i1) {
              %143 = llvm.load %63 : !llvm.ptr -> i64
              %144 = llvm.mlir.addressof @G_j : !llvm.ptr
              %145 = llvm.load %144 : !llvm.ptr -> i64
              %146 = arith.cmpi ne, %143, %145 : i64
              scf.yield %146 : i1
            } else {
              %147 = arith.constant false
              scf.yield %147 : i1
            }
            %148 = scf.if %142 -> (i1) {
              %149 = llvm.mlir.addressof @G_i : !llvm.ptr
              %150 = llvm.load %149 : !llvm.ptr -> i64
              %151 = arith.cmpi ne, %arg0, %150 : i64
              scf.yield %151 : i1
            } else {
              %152 = arith.constant false
              scf.yield %152 : i1
            }
            %153 = scf.if %148 -> (i1) {
              %155 = llvm.mlir.addressof @G_masks : !llvm.ptr
              %156 = llvm.load %155 : !llvm.ptr -> !llvm.ptr
              %157 = llvm.getelementptr %156[%arg0] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              %154 = llvm.load %157 : !llvm.ptr -> i32
              %159 = llvm.mlir.addressof @G_masks : !llvm.ptr
              %160 = llvm.load %159 : !llvm.ptr -> !llvm.ptr
              %161 = llvm.mlir.addressof @G_j : !llvm.ptr
              %162 = llvm.load %161 : !llvm.ptr -> i64
              %163 = llvm.getelementptr %160[%162] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              %158 = llvm.load %163 : !llvm.ptr -> i32
              %164 = arith.andi %154, %158 : i32
              %165 = arith.constant 0 : i32
              %166 = arith.cmpi eq, %164, %165 : i32
              scf.yield %166 : i1
            } else {
              %167 = arith.constant false
              scf.yield %167 : i1
            }
            cf.cond_br %153, ^bb27, ^bb28
            ^bb27:
              %168 = arith.constant 0 : i1
              llvm.store %168, %114 : i1, !llvm.ptr
              cf.br ^bb29
            ^bb28:
              cf.br ^bb29
            ^bb29:
            %169 = llvm.load %114 : !llvm.ptr -> i1
            cf.cond_br %169, ^bb30, ^bb31
            ^bb30:
              %171 = llvm.mlir.addressof @G_dp : !llvm.ptr
              %172 = llvm.load %171 : !llvm.ptr -> !llvm.ptr
              %173 = llvm.mlir.addressof @G_n : !llvm.ptr
              %174 = llvm.load %173 : !llvm.ptr -> i64
              %175 = arith.muli %arg0, %174 : i64
              %176 = llvm.load %63 : !llvm.ptr -> i64
              %177 = arith.addi %175, %176 : i64
              %178 = llvm.getelementptr %172[%177] : (!llvm.ptr, i64) -> !llvm.ptr, i64
              %170 = llvm.load %178 : !llvm.ptr -> i64
              %179 = arith.constant 0 : i32
              %181 = arith.extsi %179 : i32 to i64
              %180 = arith.cmpi ne, %170, %181 : i64
              cf.cond_br %180, ^bb33, ^bb34
              ^bb33:
                %182 = llvm.load %63 : !llvm.ptr -> i64
                %183 = llvm.mlir.addressof @G_j : !llvm.ptr
                %184 = llvm.load %183 : !llvm.ptr -> i64
                %185 = arith.cmpi eq, %182, %184 : i64
                cf.cond_br %185, ^bb36, ^bb37
                ^bb36:
                  %186 = llvm.load %58 : !llvm.ptr -> i64
                  %187 = arith.addi %186, %170 : i64
                  llvm.store %187, %58 : i64, !llvm.ptr
                  cf.br ^bb38
                ^bb37:
                  %188 = llvm.mlir.constant(1 : i64) : i64
                  %189 = llvm.alloca %188 x i64 : (i64) -> !llvm.ptr
                  llvm.store %arg1, %189 : i64, !llvm.ptr
                  %190 = llvm.mlir.addressof @G_i : !llvm.ptr
                  %191 = llvm.load %190 : !llvm.ptr -> i64
                  %192 = arith.cmpi ne, %arg0, %191 : i64
                  cf.cond_br %192, ^bb39, ^bb40
                  ^bb39:
                    %194 = llvm.mlir.addressof @G_compat : !llvm.ptr
                    %195 = llvm.load %194 : !llvm.ptr -> !llvm.ptr
                    %197 = llvm.mlir.addressof @G_types : !llvm.ptr
                    %198 = llvm.load %197 : !llvm.ptr -> !llvm.ptr
                    %199 = llvm.getelementptr %198[%arg0] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                    %196 = llvm.load %199 : !llvm.ptr -> i32
                    %200 = arith.extsi %196 : i32 to i64
                    %201 = llvm.getelementptr %195[%200] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                    %193 = llvm.load %201 : !llvm.ptr -> i32
                    %202 = arith.extsi %193 : i32 to i64
                    %203 = arith.andi %arg1, %202 : i64
                    llvm.store %203, %189 : i64, !llvm.ptr
                    cf.br ^bb41
                  ^bb40:
                    cf.br ^bb41
                  ^bb41:
                  %204 = llvm.load %58 : !llvm.ptr -> i64
                  %206 = llvm.load %63 : !llvm.ptr -> i64
                  %207 = llvm.load %189 : !llvm.ptr -> i64
                  %205 = func.call @f(%206, %207) : (i64, i64) -> i64
                  %208 = arith.muli %170, %205 : i64
                  %209 = arith.addi %204, %208 : i64
                  llvm.store %209, %58 : i64, !llvm.ptr
                  cf.br ^bb38
                ^bb38:
                cf.br ^bb35
              ^bb34:
                cf.br ^bb35
              ^bb35:
              cf.br ^bb32
            ^bb31:
              cf.br ^bb32
            ^bb32:
            cf.br ^bb23
          ^bb22:
            cf.br ^bb23
          ^bb23:
          cf.br ^bb20
        ^bb19:
          cf.br ^bb20
        ^bb20:
        cf.br ^bb17
      ^bb16:
        cf.br ^bb17
      ^bb17:
      %210 = llvm.load %63 : !llvm.ptr -> i64
      %211 = arith.constant 1 : i32
      %213 = arith.extsi %211 : i32 to i64
      %212 = arith.addi %210, %213 : i64
      llvm.store %212, %63 : i64, !llvm.ptr
      cf.br ^bb12
    ^bb14:
    %214 = llvm.load %58 : !llvm.ptr -> i64
    %215 = llvm.mlir.addressof @G_mod : !llvm.ptr
    %216 = llvm.load %215 : !llvm.ptr -> i64
    %217 = arith.remsi %214, %216 : i64
    llvm.store %217, %58 : i64, !llvm.ptr
    %218 = arith.constant 1 : i32
    %219 = arith.addi %11, %218 : i32
    %220 = llvm.mlir.addressof @G_memo_k : !llvm.ptr
    %221 = llvm.load %220 : !llvm.ptr -> !llvm.ptr
    %222 = llvm.load %17 : !llvm.ptr -> i64
    %223 = llvm.getelementptr %221[%222] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %219, %223 : i32, !llvm.ptr
    %224 = llvm.load %58 : !llvm.ptr -> i64
    %225 = llvm.mlir.addressof @G_memo_v : !llvm.ptr
    %226 = llvm.load %225 : !llvm.ptr -> !llvm.ptr
    %227 = llvm.load %17 : !llvm.ptr -> i64
    %228 = llvm.getelementptr %226[%227] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %224, %228 : i64, !llvm.ptr
    %229 = llvm.load %58 : !llvm.ptr -> i64
    func.return %229 : i64
  }
  func.func @main() -> i32 {
    %230 = arith.constant 30 : i32
    %231 = arith.extsi %230 : i32 to i64
    %232 = arith.constant 100000000 : i32
    %233 = arith.extsi %232 : i32 to i64
    %234 = llvm.mlir.addressof @G_mod : !llvm.ptr
    llvm.store %233, %234 : i64, !llvm.ptr
    %235 = arith.constant 4 : i32
    %237 = arith.extsi %235 : i32 to i64
    %236 = arith.muli %237, %231 : i64
    %238 = llvm.mlir.addressof @G_n : !llvm.ptr
    llvm.store %236, %238 : i64, !llvm.ptr
    %240 = arith.constant 8 : i32
    %241 = arith.extsi %240 : i32 to i64
    %239 = func.call @calloc(%236, %241) : (i64, i64) -> !llvm.ptr
    %243 = arith.constant 8 : i32
    %244 = arith.extsi %243 : i32 to i64
    %242 = func.call @calloc(%236, %244) : (i64, i64) -> !llvm.ptr
    %245 = arith.constant 0 : i32
    %246 = arith.extsi %245 : i32 to i64
    %247 = llvm.mlir.constant(1 : i64) : i64
    %248 = llvm.alloca %247 x i64 : (i64) -> !llvm.ptr
    llvm.store %246, %248 : i64, !llvm.ptr
    %249 = arith.constant 0 : i32
    %250 = arith.extsi %249 : i32 to i64
    %251 = llvm.mlir.constant(1 : i64) : i64
    %252 = llvm.alloca %251 x i64 : (i64) -> !llvm.ptr
    llvm.store %250, %252 : i64, !llvm.ptr
    cf.br ^bb42
    ^bb42:
    %253 = llvm.load %252 : !llvm.ptr -> i64
    %254 = arith.cmpi sle, %253, %231 : i64
    cf.cond_br %254, ^bb43, ^bb44
    ^bb43:
      %255 = llvm.load %252 : !llvm.ptr -> i64
      %256 = llvm.load %248 : !llvm.ptr -> i64
      %257 = llvm.getelementptr %239[%256] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %255, %257 : i64, !llvm.ptr
      %258 = arith.constant 0 : i32
      %259 = llvm.load %248 : !llvm.ptr -> i64
      %260 = arith.extsi %258 : i32 to i64
      %261 = llvm.getelementptr %242[%259] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %260, %261 : i64, !llvm.ptr
      %262 = llvm.load %248 : !llvm.ptr -> i64
      %263 = arith.constant 1 : i32
      %265 = arith.extsi %263 : i32 to i64
      %264 = arith.addi %262, %265 : i64
      llvm.store %264, %248 : i64, !llvm.ptr
      %266 = llvm.load %252 : !llvm.ptr -> i64
      %267 = arith.constant 1 : i32
      %269 = arith.extsi %267 : i32 to i64
      %268 = arith.addi %266, %269 : i64
      llvm.store %268, %252 : i64, !llvm.ptr
      cf.br ^bb42
    ^bb44:
    %270 = arith.constant 1 : i32
    %271 = arith.extsi %270 : i32 to i64
    %272 = llvm.mlir.constant(1 : i64) : i64
    %273 = llvm.alloca %272 x i64 : (i64) -> !llvm.ptr
    llvm.store %271, %273 : i64, !llvm.ptr
    cf.br ^bb45
    ^bb45:
    %274 = llvm.load %273 : !llvm.ptr -> i64
    %275 = arith.cmpi sle, %274, %231 : i64
    cf.cond_br %275, ^bb46, ^bb47
    ^bb46:
      %276 = llvm.load %248 : !llvm.ptr -> i64
      %277 = llvm.getelementptr %239[%276] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %231, %277 : i64, !llvm.ptr
      %278 = llvm.load %273 : !llvm.ptr -> i64
      %279 = llvm.load %248 : !llvm.ptr -> i64
      %280 = llvm.getelementptr %242[%279] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %278, %280 : i64, !llvm.ptr
      %281 = llvm.load %248 : !llvm.ptr -> i64
      %282 = arith.constant 1 : i32
      %284 = arith.extsi %282 : i32 to i64
      %283 = arith.addi %281, %284 : i64
      llvm.store %283, %248 : i64, !llvm.ptr
      %285 = llvm.load %273 : !llvm.ptr -> i64
      %286 = arith.constant 1 : i32
      %288 = arith.extsi %286 : i32 to i64
      %287 = arith.addi %285, %288 : i64
      llvm.store %287, %273 : i64, !llvm.ptr
      cf.br ^bb45
    ^bb47:
    %289 = arith.constant 1 : i32
    %291 = arith.extsi %289 : i32 to i64
    %290 = arith.subi %231, %291 : i64
    llvm.store %290, %252 : i64, !llvm.ptr
    cf.br ^bb48
    ^bb48:
    %292 = llvm.load %252 : !llvm.ptr -> i64
    %293 = arith.constant 0 : i32
    %295 = arith.extsi %293 : i32 to i64
    %294 = arith.cmpi sge, %292, %295 : i64
    cf.cond_br %294, ^bb49, ^bb50
    ^bb49:
      %296 = llvm.load %252 : !llvm.ptr -> i64
      %297 = llvm.load %248 : !llvm.ptr -> i64
      %298 = llvm.getelementptr %239[%297] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %296, %298 : i64, !llvm.ptr
      %299 = llvm.load %248 : !llvm.ptr -> i64
      %300 = llvm.getelementptr %242[%299] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %231, %300 : i64, !llvm.ptr
      %301 = llvm.load %248 : !llvm.ptr -> i64
      %302 = arith.constant 1 : i32
      %304 = arith.extsi %302 : i32 to i64
      %303 = arith.addi %301, %304 : i64
      llvm.store %303, %248 : i64, !llvm.ptr
      %305 = llvm.load %252 : !llvm.ptr -> i64
      %306 = arith.constant 1 : i32
      %308 = arith.extsi %306 : i32 to i64
      %307 = arith.subi %305, %308 : i64
      llvm.store %307, %252 : i64, !llvm.ptr
      cf.br ^bb48
    ^bb50:
    %309 = arith.constant 1 : i32
    %311 = arith.extsi %309 : i32 to i64
    %310 = arith.subi %231, %311 : i64
    llvm.store %310, %273 : i64, !llvm.ptr
    cf.br ^bb51
    ^bb51:
    %312 = llvm.load %273 : !llvm.ptr -> i64
    %313 = arith.constant 1 : i32
    %315 = arith.extsi %313 : i32 to i64
    %314 = arith.cmpi sge, %312, %315 : i64
    cf.cond_br %314, ^bb52, ^bb53
    ^bb52:
      %316 = arith.constant 0 : i32
      %317 = llvm.load %248 : !llvm.ptr -> i64
      %318 = arith.extsi %316 : i32 to i64
      %319 = llvm.getelementptr %239[%317] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %318, %319 : i64, !llvm.ptr
      %320 = llvm.load %273 : !llvm.ptr -> i64
      %321 = llvm.load %248 : !llvm.ptr -> i64
      %322 = llvm.getelementptr %242[%321] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %320, %322 : i64, !llvm.ptr
      %323 = llvm.load %248 : !llvm.ptr -> i64
      %324 = arith.constant 1 : i32
      %326 = arith.extsi %324 : i32 to i64
      %325 = arith.addi %323, %326 : i64
      llvm.store %325, %248 : i64, !llvm.ptr
      %327 = llvm.load %273 : !llvm.ptr -> i64
      %328 = arith.constant 1 : i32
      %330 = arith.extsi %328 : i32 to i64
      %329 = arith.subi %327, %330 : i64
      llvm.store %329, %273 : i64, !llvm.ptr
      cf.br ^bb51
    ^bb53:
    %332 = arith.constant 4 : i32
    %333 = arith.extsi %332 : i32 to i64
    %331 = func.call @calloc(%236, %333) : (i64, i64) -> !llvm.ptr
    %334 = llvm.mlir.addressof @G_masks : !llvm.ptr
    llvm.store %331, %334 : !llvm.ptr, !llvm.ptr
    %336 = arith.constant 4 : i32
    %337 = arith.extsi %336 : i32 to i64
    %335 = func.call @calloc(%236, %337) : (i64, i64) -> !llvm.ptr
    %338 = llvm.mlir.addressof @G_types : !llvm.ptr
    llvm.store %335, %338 : !llvm.ptr, !llvm.ptr
    %339 = arith.constant 0 : i32
    %340 = arith.extsi %339 : i32 to i64
    %341 = llvm.mlir.constant(1 : i64) : i64
    %342 = llvm.alloca %341 x i64 : (i64) -> !llvm.ptr
    llvm.store %340, %342 : i64, !llvm.ptr
    cf.br ^bb54
    ^bb54:
    %343 = llvm.load %342 : !llvm.ptr -> i64
    %344 = arith.cmpi slt, %343, %236 : i64
    cf.cond_br %344, ^bb55, ^bb56
    ^bb55:
      %346 = llvm.load %342 : !llvm.ptr -> i64
      %347 = llvm.getelementptr %239[%346] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %345 = llvm.load %347 : !llvm.ptr -> i64
      %349 = llvm.load %342 : !llvm.ptr -> i64
      %350 = llvm.getelementptr %242[%349] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %348 = llvm.load %350 : !llvm.ptr -> i64
      %351 = arith.constant 0 : i32
      %352 = llvm.mlir.constant(1 : i64) : i64
      %353 = llvm.alloca %352 x i32 : (i64) -> !llvm.ptr
      llvm.store %351, %353 : i32, !llvm.ptr
      %354 = arith.constant 0 : i32
      %356 = arith.extsi %354 : i32 to i64
      %355 = arith.cmpi eq, %348, %356 : i64
      cf.cond_br %355, ^bb57, ^bb58
      ^bb57:
        %357 = llvm.load %353 : !llvm.ptr -> i32
        %358 = arith.constant 1 : i32
        %359 = arith.ori %357, %358 : i32
        llvm.store %359, %353 : i32, !llvm.ptr
        cf.br ^bb59
      ^bb58:
        cf.br ^bb59
      ^bb59:
      %360 = arith.cmpi eq, %345, %231 : i64
      cf.cond_br %360, ^bb60, ^bb61
      ^bb60:
        %361 = llvm.load %353 : !llvm.ptr -> i32
        %362 = arith.constant 2 : i32
        %363 = arith.ori %361, %362 : i32
        llvm.store %363, %353 : i32, !llvm.ptr
        cf.br ^bb62
      ^bb61:
        cf.br ^bb62
      ^bb62:
      %364 = arith.cmpi eq, %348, %231 : i64
      cf.cond_br %364, ^bb63, ^bb64
      ^bb63:
        %365 = llvm.load %353 : !llvm.ptr -> i32
        %366 = arith.constant 4 : i32
        %367 = arith.ori %365, %366 : i32
        llvm.store %367, %353 : i32, !llvm.ptr
        cf.br ^bb65
      ^bb64:
        cf.br ^bb65
      ^bb65:
      %368 = arith.constant 0 : i32
      %370 = arith.extsi %368 : i32 to i64
      %369 = arith.cmpi eq, %345, %370 : i64
      cf.cond_br %369, ^bb66, ^bb67
      ^bb66:
        %371 = llvm.load %353 : !llvm.ptr -> i32
        %372 = arith.constant 8 : i32
        %373 = arith.ori %371, %372 : i32
        llvm.store %373, %353 : i32, !llvm.ptr
        cf.br ^bb68
      ^bb67:
        cf.br ^bb68
      ^bb68:
      %374 = llvm.load %353 : !llvm.ptr -> i32
      %375 = llvm.mlir.addressof @G_masks : !llvm.ptr
      %376 = llvm.load %375 : !llvm.ptr -> !llvm.ptr
      %377 = llvm.load %342 : !llvm.ptr -> i64
      %378 = llvm.getelementptr %376[%377] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %374, %378 : i32, !llvm.ptr
      %379 = arith.constant 0 : i32
      %380 = llvm.mlir.constant(1 : i64) : i64
      %381 = llvm.alloca %380 x i32 : (i64) -> !llvm.ptr
      llvm.store %379, %381 : i32, !llvm.ptr
      %382 = llvm.load %353 : !llvm.ptr -> i32
      %383 = arith.constant 1 : i32
      %384 = arith.cmpi eq, %382, %383 : i32
      cf.cond_br %384, ^bb69, ^bb70
^bb69:
        %385 = arith.constant 0 : i32
        llvm.store %385, %381 : i32, !llvm.ptr
        cf.br ^bb87
^bb70:
      %386 = arith.constant 2 : i32
      %387 = arith.cmpi eq, %382, %386 : i32
      cf.cond_br %387, ^bb71, ^bb72
^bb71:
        %388 = arith.constant 1 : i32
        llvm.store %388, %381 : i32, !llvm.ptr
        cf.br ^bb87
^bb72:
      %389 = arith.constant 4 : i32
      %390 = arith.cmpi eq, %382, %389 : i32
      cf.cond_br %390, ^bb73, ^bb74
^bb73:
        %391 = arith.constant 2 : i32
        llvm.store %391, %381 : i32, !llvm.ptr
        cf.br ^bb87
^bb74:
      %392 = arith.constant 8 : i32
      %393 = arith.cmpi eq, %382, %392 : i32
      cf.cond_br %393, ^bb75, ^bb76
^bb75:
        %394 = arith.constant 3 : i32
        llvm.store %394, %381 : i32, !llvm.ptr
        cf.br ^bb87
^bb76:
      %395 = arith.constant 3 : i32
      %396 = arith.cmpi eq, %382, %395 : i32
      cf.cond_br %396, ^bb77, ^bb78
^bb77:
        %397 = arith.constant 4 : i32
        llvm.store %397, %381 : i32, !llvm.ptr
        cf.br ^bb87
^bb78:
      %398 = arith.constant 6 : i32
      %399 = arith.cmpi eq, %382, %398 : i32
      cf.cond_br %399, ^bb79, ^bb80
^bb79:
        %400 = arith.constant 5 : i32
        llvm.store %400, %381 : i32, !llvm.ptr
        cf.br ^bb87
^bb80:
      %401 = arith.constant 12 : i32
      %402 = arith.cmpi eq, %382, %401 : i32
      cf.cond_br %402, ^bb81, ^bb82
^bb81:
        %403 = arith.constant 6 : i32
        llvm.store %403, %381 : i32, !llvm.ptr
        cf.br ^bb87
^bb82:
      %404 = arith.constant 9 : i32
      %405 = arith.cmpi eq, %382, %404 : i32
      cf.cond_br %405, ^bb83, ^bb84
^bb83:
        %406 = arith.constant 7 : i32
        llvm.store %406, %381 : i32, !llvm.ptr
        cf.br ^bb87
^bb84:
      %407 = arith.constant 1 : i1
      cf.cond_br %407, ^bb85, ^bb86
^bb85:
        cf.br ^bb87
^bb86:
      cf.br ^bb87
^bb87:
      %408 = llvm.load %381 : !llvm.ptr -> i32
      %409 = llvm.mlir.addressof @G_types : !llvm.ptr
      %410 = llvm.load %409 : !llvm.ptr -> !llvm.ptr
      %411 = llvm.load %342 : !llvm.ptr -> i64
      %412 = llvm.getelementptr %410[%411] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %408, %412 : i32, !llvm.ptr
      %413 = llvm.load %342 : !llvm.ptr -> i64
      %414 = arith.constant 1 : i32
      %416 = arith.extsi %414 : i32 to i64
      %415 = arith.addi %413, %416 : i64
      llvm.store %415, %342 : i64, !llvm.ptr
      cf.br ^bb54
    ^bb56:
    %418 = arith.constant 8 : i32
    %419 = arith.constant 4 : i32
    %420 = arith.extsi %418 : i32 to i64
    %421 = arith.extsi %419 : i32 to i64
    %417 = func.call @calloc(%420, %421) : (i64, i64) -> !llvm.ptr
    %422 = arith.constant 1 : i32
    %423 = arith.constant 0 : i32
    %424 = arith.extsi %423 : i32 to i64
    %425 = llvm.getelementptr %417[%424] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %422, %425 : i32, !llvm.ptr
    %426 = arith.constant 2 : i32
    %427 = arith.constant 1 : i32
    %428 = arith.extsi %427 : i32 to i64
    %429 = llvm.getelementptr %417[%428] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %426, %429 : i32, !llvm.ptr
    %430 = arith.constant 4 : i32
    %431 = arith.constant 2 : i32
    %432 = arith.extsi %431 : i32 to i64
    %433 = llvm.getelementptr %417[%432] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %430, %433 : i32, !llvm.ptr
    %434 = arith.constant 8 : i32
    %435 = arith.constant 3 : i32
    %436 = arith.extsi %435 : i32 to i64
    %437 = llvm.getelementptr %417[%436] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %434, %437 : i32, !llvm.ptr
    %438 = arith.constant 3 : i32
    %439 = arith.constant 4 : i32
    %440 = arith.extsi %439 : i32 to i64
    %441 = llvm.getelementptr %417[%440] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %438, %441 : i32, !llvm.ptr
    %442 = arith.constant 6 : i32
    %443 = arith.constant 5 : i32
    %444 = arith.extsi %443 : i32 to i64
    %445 = llvm.getelementptr %417[%444] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %442, %445 : i32, !llvm.ptr
    %446 = arith.constant 12 : i32
    %447 = arith.constant 6 : i32
    %448 = arith.extsi %447 : i32 to i64
    %449 = llvm.getelementptr %417[%448] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %446, %449 : i32, !llvm.ptr
    %450 = arith.constant 9 : i32
    %451 = arith.constant 7 : i32
    %452 = arith.extsi %451 : i32 to i64
    %453 = llvm.getelementptr %417[%452] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %450, %453 : i32, !llvm.ptr
    %455 = arith.constant 8 : i32
    %456 = arith.constant 4 : i32
    %457 = arith.extsi %455 : i32 to i64
    %458 = arith.extsi %456 : i32 to i64
    %454 = func.call @calloc(%457, %458) : (i64, i64) -> !llvm.ptr
    %459 = llvm.mlir.addressof @G_compat : !llvm.ptr
    llvm.store %454, %459 : !llvm.ptr, !llvm.ptr
    %460 = arith.constant 0 : i32
    %461 = arith.extsi %460 : i32 to i64
    %462 = llvm.mlir.constant(1 : i64) : i64
    %463 = llvm.alloca %462 x i64 : (i64) -> !llvm.ptr
    llvm.store %461, %463 : i64, !llvm.ptr
    cf.br ^bb88
    ^bb88:
    %464 = llvm.load %463 : !llvm.ptr -> i64
    %465 = arith.constant 8 : i32
    %467 = arith.extsi %465 : i32 to i64
    %466 = arith.cmpi slt, %464, %467 : i64
    cf.cond_br %466, ^bb89, ^bb90
    ^bb89:
      %468 = arith.constant 0 : i32
      %469 = llvm.mlir.constant(1 : i64) : i64
      %470 = llvm.alloca %469 x i32 : (i64) -> !llvm.ptr
      llvm.store %468, %470 : i32, !llvm.ptr
      %471 = arith.constant 0 : i32
      %472 = arith.extsi %471 : i32 to i64
      %473 = llvm.mlir.constant(1 : i64) : i64
      %474 = llvm.alloca %473 x i64 : (i64) -> !llvm.ptr
      llvm.store %472, %474 : i64, !llvm.ptr
      cf.br ^bb91
      ^bb91:
      %475 = llvm.load %474 : !llvm.ptr -> i64
      %476 = arith.constant 8 : i32
      %478 = arith.extsi %476 : i32 to i64
      %477 = arith.cmpi slt, %475, %478 : i64
      cf.cond_br %477, ^bb92, ^bb93
      ^bb92:
        %480 = llvm.load %463 : !llvm.ptr -> i64
        %481 = llvm.getelementptr %417[%480] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %479 = llvm.load %481 : !llvm.ptr -> i32
        %483 = llvm.load %474 : !llvm.ptr -> i64
        %484 = llvm.getelementptr %417[%483] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %482 = llvm.load %484 : !llvm.ptr -> i32
        %485 = arith.andi %479, %482 : i32
        %486 = arith.constant 0 : i32
        %487 = arith.cmpi ne, %485, %486 : i32
        cf.cond_br %487, ^bb94, ^bb95
        ^bb94:
          %488 = llvm.load %470 : !llvm.ptr -> i32
          %489 = arith.constant 1 : i32
          %490 = llvm.load %474 : !llvm.ptr -> i64
          %492 = arith.extsi %489 : i32 to i64
          %491 = arith.shli %492, %490 : i64
          %494 = arith.extsi %488 : i32 to i64
          %493 = arith.ori %494, %491 : i64
          %495 = arith.trunci %493 : i64 to i32
          llvm.store %495, %470 : i32, !llvm.ptr
          cf.br ^bb96
        ^bb95:
          cf.br ^bb96
        ^bb96:
        %496 = llvm.load %474 : !llvm.ptr -> i64
        %497 = arith.constant 1 : i32
        %499 = arith.extsi %497 : i32 to i64
        %498 = arith.addi %496, %499 : i64
        llvm.store %498, %474 : i64, !llvm.ptr
        cf.br ^bb91
      ^bb93:
      %500 = llvm.load %470 : !llvm.ptr -> i32
      %501 = llvm.mlir.addressof @G_compat : !llvm.ptr
      %502 = llvm.load %501 : !llvm.ptr -> !llvm.ptr
      %503 = llvm.load %463 : !llvm.ptr -> i64
      %504 = llvm.getelementptr %502[%503] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %500, %504 : i32, !llvm.ptr
      %505 = llvm.load %463 : !llvm.ptr -> i64
      %506 = arith.constant 1 : i32
      %508 = arith.extsi %506 : i32 to i64
      %507 = arith.addi %505, %508 : i64
      llvm.store %507, %463 : i64, !llvm.ptr
      cf.br ^bb88
    ^bb90:
    %510 = arith.muli %236, %236 : i64
    %511 = arith.constant 1 : i32
    %512 = arith.extsi %511 : i32 to i64
    %509 = func.call @calloc(%510, %512) : (i64, i64) -> !llvm.ptr
    %513 = llvm.mlir.addressof @G_allowed : !llvm.ptr
    llvm.store %509, %513 : !llvm.ptr, !llvm.ptr
    %514 = arith.constant 0 : i32
    %515 = arith.extsi %514 : i32 to i64
    llvm.store %515, %342 : i64, !llvm.ptr
    cf.br ^bb97
    ^bb97:
    %516 = llvm.load %342 : !llvm.ptr -> i64
    %517 = arith.cmpi slt, %516, %236 : i64
    cf.cond_br %517, ^bb98, ^bb99
    ^bb98:
      %518 = llvm.load %342 : !llvm.ptr -> i64
      %519 = arith.constant 2 : i32
      %521 = arith.extsi %519 : i32 to i64
      %520 = arith.addi %518, %521 : i64
      %522 = llvm.mlir.constant(1 : i64) : i64
      %523 = llvm.alloca %522 x i64 : (i64) -> !llvm.ptr
      llvm.store %520, %523 : i64, !llvm.ptr
      cf.br ^bb100
      ^bb100:
      %524 = llvm.load %523 : !llvm.ptr -> i64
      %525 = arith.cmpi slt, %524, %236 : i64
      cf.cond_br %525, ^bb101, ^bb102
      ^bb101:
        %527 = llvm.mlir.addressof @G_masks : !llvm.ptr
        %528 = llvm.load %527 : !llvm.ptr -> !llvm.ptr
        %529 = llvm.load %342 : !llvm.ptr -> i64
        %530 = llvm.getelementptr %528[%529] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %526 = llvm.load %530 : !llvm.ptr -> i32
        %532 = llvm.mlir.addressof @G_masks : !llvm.ptr
        %533 = llvm.load %532 : !llvm.ptr -> !llvm.ptr
        %534 = llvm.load %523 : !llvm.ptr -> i64
        %535 = llvm.getelementptr %533[%534] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %531 = llvm.load %535 : !llvm.ptr -> i32
        %536 = arith.andi %526, %531 : i32
        %537 = arith.constant 0 : i32
        %538 = arith.cmpi eq, %536, %537 : i32
        cf.cond_br %538, ^bb103, ^bb104
        ^bb103:
          %539 = arith.constant 1 : i32
          %540 = llvm.mlir.addressof @G_allowed : !llvm.ptr
          %541 = llvm.load %540 : !llvm.ptr -> !llvm.ptr
          %542 = llvm.load %342 : !llvm.ptr -> i64
          %543 = arith.muli %542, %236 : i64
          %544 = llvm.load %523 : !llvm.ptr -> i64
          %545 = arith.addi %543, %544 : i64
          %546 = arith.trunci %539 : i32 to i8
          %547 = llvm.getelementptr %541[%545] : (!llvm.ptr, i64) -> !llvm.ptr, i8
          llvm.store %546, %547 : i8, !llvm.ptr
          cf.br ^bb105
        ^bb104:
          cf.br ^bb105
        ^bb105:
        %548 = llvm.load %523 : !llvm.ptr -> i64
        %549 = arith.constant 1 : i32
        %551 = arith.extsi %549 : i32 to i64
        %550 = arith.addi %548, %551 : i64
        llvm.store %550, %523 : i64, !llvm.ptr
        cf.br ^bb100
      ^bb102:
      %552 = llvm.load %342 : !llvm.ptr -> i64
      %553 = arith.constant 1 : i32
      %555 = arith.extsi %553 : i32 to i64
      %554 = arith.addi %552, %555 : i64
      llvm.store %554, %342 : i64, !llvm.ptr
      cf.br ^bb97
    ^bb99:
    %557 = arith.muli %236, %236 : i64
    %558 = arith.constant 8 : i32
    %559 = arith.extsi %558 : i32 to i64
    %556 = func.call @calloc(%557, %559) : (i64, i64) -> !llvm.ptr
    %560 = llvm.mlir.addressof @G_dp : !llvm.ptr
    llvm.store %556, %560 : !llvm.ptr, !llvm.ptr
    %561 = arith.constant 0 : i32
    %562 = arith.extsi %561 : i32 to i64
    llvm.store %562, %342 : i64, !llvm.ptr
    cf.br ^bb106
    ^bb106:
    %563 = llvm.load %342 : !llvm.ptr -> i64
    %564 = arith.constant 1 : i32
    %566 = arith.extsi %564 : i32 to i64
    %565 = arith.subi %236, %566 : i64
    %567 = arith.cmpi slt, %563, %565 : i64
    cf.cond_br %567, ^bb107, ^bb108
    ^bb107:
      %568 = arith.constant 1 : i32
      %569 = llvm.mlir.addressof @G_dp : !llvm.ptr
      %570 = llvm.load %569 : !llvm.ptr -> !llvm.ptr
      %571 = llvm.load %342 : !llvm.ptr -> i64
      %572 = arith.muli %571, %236 : i64
      %573 = llvm.load %342 : !llvm.ptr -> i64
      %574 = arith.constant 1 : i32
      %576 = arith.extsi %574 : i32 to i64
      %575 = arith.addi %573, %576 : i64
      %577 = arith.addi %572, %575 : i64
      %578 = arith.extsi %568 : i32 to i64
      %579 = llvm.getelementptr %570[%577] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %578, %579 : i64, !llvm.ptr
      %580 = llvm.load %342 : !llvm.ptr -> i64
      %581 = arith.constant 1 : i32
      %583 = arith.extsi %581 : i32 to i64
      %582 = arith.addi %580, %583 : i64
      llvm.store %582, %342 : i64, !llvm.ptr
      cf.br ^bb106
    ^bb108:
    %585 = arith.constant 200003 : i32
    %586 = arith.constant 8 : i32
    %587 = arith.extsi %585 : i32 to i64
    %588 = arith.extsi %586 : i32 to i64
    %584 = func.call @calloc(%587, %588) : (i64, i64) -> !llvm.ptr
    %589 = llvm.mlir.addressof @G_memo_v : !llvm.ptr
    llvm.store %584, %589 : !llvm.ptr, !llvm.ptr
    %591 = arith.constant 200003 : i32
    %592 = arith.constant 4 : i32
    %593 = arith.extsi %591 : i32 to i64
    %594 = arith.extsi %592 : i32 to i64
    %590 = func.call @calloc(%593, %594) : (i64, i64) -> !llvm.ptr
    %595 = llvm.mlir.addressof @G_memo_k : !llvm.ptr
    llvm.store %590, %595 : !llvm.ptr, !llvm.ptr
    %596 = arith.constant 2 : i32
    %597 = arith.extsi %596 : i32 to i64
    %598 = llvm.mlir.constant(1 : i64) : i64
    %599 = llvm.alloca %598 x i64 : (i64) -> !llvm.ptr
    llvm.store %597, %599 : i64, !llvm.ptr
    cf.br ^bb109
    ^bb109:
    %600 = llvm.load %599 : !llvm.ptr -> i64
    %601 = arith.cmpi slt, %600, %236 : i64
    cf.cond_br %601, ^bb110, ^bb111
    ^bb110:
      %602 = arith.constant 0 : i32
      %603 = arith.extsi %602 : i32 to i64
      llvm.store %603, %342 : i64, !llvm.ptr
      cf.br ^bb112
      ^bb112:
      %604 = llvm.load %342 : !llvm.ptr -> i64
      %605 = llvm.load %599 : !llvm.ptr -> i64
      %606 = arith.addi %604, %605 : i64
      %607 = arith.cmpi slt, %606, %236 : i64
      cf.cond_br %607, ^bb113, ^bb114
      ^bb113:
        %608 = llvm.load %342 : !llvm.ptr -> i64
        %609 = llvm.load %599 : !llvm.ptr -> i64
        %610 = arith.addi %608, %609 : i64
        %611 = llvm.load %342 : !llvm.ptr -> i64
        %612 = llvm.mlir.addressof @G_i : !llvm.ptr
        llvm.store %611, %612 : i64, !llvm.ptr
        %613 = llvm.mlir.addressof @G_j : !llvm.ptr
        llvm.store %610, %613 : i64, !llvm.ptr
        %614 = arith.constant 0 : i32
        %615 = arith.extsi %614 : i32 to i64
        %616 = llvm.mlir.constant(1 : i64) : i64
        %617 = llvm.alloca %616 x i64 : (i64) -> !llvm.ptr
        llvm.store %615, %617 : i64, !llvm.ptr
        cf.br ^bb115
        ^bb115:
        %618 = llvm.load %617 : !llvm.ptr -> i64
        %619 = arith.constant 200003 : i32
        %621 = arith.extsi %619 : i32 to i64
        %620 = arith.cmpi slt, %618, %621 : i64
        cf.cond_br %620, ^bb116, ^bb117
        ^bb116:
          %622 = arith.constant 0 : i32
          %623 = llvm.mlir.addressof @G_memo_k : !llvm.ptr
          %624 = llvm.load %623 : !llvm.ptr -> !llvm.ptr
          %625 = llvm.load %617 : !llvm.ptr -> i64
          %626 = llvm.getelementptr %624[%625] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %622, %626 : i32, !llvm.ptr
          %627 = llvm.load %617 : !llvm.ptr -> i64
          %628 = arith.constant 1 : i32
          %630 = arith.extsi %628 : i32 to i64
          %629 = arith.addi %627, %630 : i64
          llvm.store %629, %617 : i64, !llvm.ptr
          cf.br ^bb115
        ^bb117:
        %632 = llvm.load %342 : !llvm.ptr -> i64
        %633 = arith.constant 255 : i32
        %634 = arith.extsi %633 : i32 to i64
        %631 = func.call @f(%632, %634) : (i64, i64) -> i64
        %635 = arith.remsi %631, %233 : i64
        %636 = llvm.mlir.addressof @G_dp : !llvm.ptr
        %637 = llvm.load %636 : !llvm.ptr -> !llvm.ptr
        %638 = llvm.load %342 : !llvm.ptr -> i64
        %639 = arith.muli %638, %236 : i64
        %640 = arith.addi %639, %610 : i64
        %641 = llvm.getelementptr %637[%640] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %635, %641 : i64, !llvm.ptr
        %642 = llvm.load %342 : !llvm.ptr -> i64
        %643 = arith.constant 1 : i32
        %645 = arith.extsi %643 : i32 to i64
        %644 = arith.addi %642, %645 : i64
        llvm.store %644, %342 : i64, !llvm.ptr
        cf.br ^bb112
      ^bb114:
      %646 = llvm.load %599 : !llvm.ptr -> i64
      %647 = arith.constant 1 : i32
      %649 = arith.extsi %647 : i32 to i64
      %648 = arith.addi %646, %649 : i64
      llvm.store %648, %599 : i64, !llvm.ptr
      cf.br ^bb109
    ^bb111:
    %650 = llvm.mlir.addressof @str_0 : !llvm.ptr
    %652 = llvm.mlir.addressof @G_dp : !llvm.ptr
    %653 = llvm.load %652 : !llvm.ptr -> !llvm.ptr
    %654 = arith.constant 0 : i32
    %656 = arith.extsi %654 : i32 to i64
    %655 = arith.muli %656, %236 : i64
    %657 = arith.constant 1 : i32
    %659 = arith.extsi %657 : i32 to i64
    %658 = arith.subi %236, %659 : i64
    %660 = arith.addi %655, %658 : i64
    %661 = llvm.getelementptr %653[%660] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    %651 = llvm.load %661 : !llvm.ptr -> i64
    %662 = arith.remsi %651, %233 : i64
    %663 = llvm.call @printf(%650, %662) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i64) -> i32
    %664 = arith.constant 0 : i32
    func.return %664 : i32
  }
}