Problem 654

Neighbourly Constraints: T(5000, 10^12) mod 1e9+7. States are the last tuple element a in [1, n-1]; the transfer operator (Mv)_a = sum_{b <= n-a} v_b is one prefix-sum plus a reversal, so each application costs O(n). Generate u_j = sum(M^j * 1) for 2(n-1)+12 terms, recover the minimal linear recurrence with Berlekamp-Massey (degree n-1), then jump to u_{m-1} with Kitamasa (x^K mod the recurrence polynomial).

Answer815868280
Output815868280
StatusPASS
Native helperno
Runtime3150 ms
Peak memory2000 KB
Time complexityO(n^2) (estimated)
Space complexityO(n^2) (estimated)

Performance comparison

MetricOur solutionBest known
Time complexityO(n^2)O(log n)
Space complexityO(n^2)O(n^2)
ApproachFlow solutionMatrix exponentiation
VerdictSuboptimal

Flow source

# Project Euler 654
# Neighbourly Constraints: T(5000, 10^12) mod 1e9+7.
#
# States are the last tuple element a in [1, n-1]; the transfer operator
# (Mv)_a = sum_{b <= n-a} v_b is one prefix-sum plus a reversal, so each
# application costs O(n).  Generate u_j = sum(M^j * 1) for 2(n-1)+12 terms,
# recover the minimal linear recurrence with Berlekamp-Massey (degree n-1),
# then jump to u_{m-1} with Kitamasa (x^K mod the recurrence polynomial).

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

const MOD: i64 = 1000000007
const N: i64 = 5000
const EM: i64 = 999999999999      # m - 1, m = 10^12

function powmod(base: i64, exp: i64) -> i64 {
    let mut result: i64 = 1
    let mut b: i64 = base % MOD
    let mut e: i64 = exp
    while e > 0 {
        if (e & 1) == 1 {
            result = result * b % MOD
        }
        b = b * b % MOD
        e = e >> 1
    }
    return result
}

# multiply a (len la) by b (len lb) into res, reduce mod the monic
# recurrence x^L = sum_{j=0..L-1} D[j] x^{L-1-j}; res has length L
function polymulred(a: ptr<i64>, la: i64, b: ptr<i64>, lb: i64,
                    D: ptr<i64>, L: i64, res: ptr<i64>, work: ptr<i64>) -> void {
    let lr: i64 = la + lb - 1
    let mut i: i64 = 0
    while i < lr {
        work[i] = 0
        i = i + 1
    }
    i = 0
    while i < la {
        let ai: i64 = a[i]
        if ai != 0 {
            let mut j: i64 = 0
            while j < lb {
                work[i + j] = (work[i + j] + ai * b[j]) % MOD
                j = j + 1
            }
        }
        i = i + 1
    }
    i = lr - 1
    while i >= L {
        let c: i64 = work[i]
        if c != 0 {
            work[i] = 0
            let mut j: i64 = 0
            while j < L {
                work[i - 1 - j] = (work[i - 1 - j] + c * D[j]) % MOD
                j = j + 1
            }
        }
        i = i - 1
    }
    i = 0
    while i < L {
        if i < lr {
            res[i] = work[i]
        } else {
            res[i] = 0
        }
        i = i + 1
    }
}

function k2_copy(dst: ptr<i64>, src: ptr<i64>, n: i64) -> void {
    let mut i: i64 = 0
    while i < n {
        dst[i] = src[i]
        i = i + 1
    }
}

function main() -> i32 {
    let terms: i64 = 2 * (N - 1) + 12

    # ---- generate u_j = 1^T M^j 1 ----
    let v: ptr<i64> = calloc(N + 1, 8)
    let pre: ptr<i64> = calloc(N + 1, 8)
    let S: ptr<i64> = calloc(terms + 2, 8)
    let mut a: i64 = 1
    while a < N {
        v[a] = 1
        a = a + 1
    }
    let mut j: i64 = 0
    while j < terms {
        # record sum and prefix sums in one pass
        let mut s: i64 = 0
        let mut b: i64 = 1
        while b < N {
            s = (s + v[b]) % MOD
            pre[b] = s
            b = b + 1
        }
        S[j] = s
        # (Mv)_a = pre[n-a]
        a = 1
        while a < N {
            v[a] = pre[N - a]
            a = a + 1
        }
        j = j + 1
    }

    if EM < terms {
        printf("%lld\n", S[EM])
        return 0
    }

    # ---- Berlekamp-Massey ----
    # C, B polynomials with C[0] = B[0] = 1
    let C: ptr<i64> = calloc(terms + 2, 8)
    let B: ptr<i64> = calloc(terms + 2, 8)
    let T: ptr<i64> = calloc(terms + 2, 8)
    C[0] = 1
    B[0] = 1
    let mut lenC: i64 = 1
    let mut lenB: i64 = 1
    let mut L: i64 = 0
    let mut m: i64 = 1
    let mut bb: i64 = 1
    let mut i: i64 = 0
    while i < terms {
        let mut d: i64 = 0
        let mut k: i64 = 0
        while k <= L {
            d = (d + C[k] * S[i - k]) % MOD
            k = k + 1
        }
        if d == 0 {
            m = m + 1
        } else {
            let coef: i64 = d * powmod(bb, MOD - 2) % MOD
            if 2 * L <= i {
                # save C into T
                k = 0
                while k < lenC {
                    T[k] = C[k]
                    k = k + 1
                }
                let lenT: i64 = lenC
                if lenB + m > lenC {
                    k = lenC
                    while k < lenB + m {
                        C[k] = 0
                        k = k + 1
                    }
                    lenC = lenB + m
                }
                k = 0
                while k < lenB {
                    C[k + m] = ((C[k + m] - coef * B[k]) % MOD + MOD) % MOD
                    k = k + 1
                }
                L = i + 1 - L
                k = 0
                while k < lenT {
                    B[k] = T[k]
                    k = k + 1
                }
                lenB = lenT
                bb = d
                m = 1
            } else {
                if lenB + m > lenC {
                    k = lenC
                    while k < lenB + m {
                        C[k] = 0
                        k = k + 1
                    }
                    lenC = lenB + m
                }
                k = 0
                while k < lenB {
                    C[k + m] = ((C[k + m] - coef * B[k]) % MOD + MOD) % MOD
                    k = k + 1
                }
                m = m + 1
            }
        }
        i = i + 1
    }

    # recurrence: s_n = sum_{j=1..L} D[j-1] s_{n-j}, D[j-1] = -C[j]
    let D: ptr<i64> = calloc(L + 1, 8)
    i = 0
    while i < L {
        D[i] = (MOD - C[i + 1]) % MOD
        i = i + 1
    }

    # ---- Kitamasa: r(x) = x^EM mod (x^L - sum D[j] x^{L-1-j}) ----
    let r: ptr<i64> = calloc(L + 1, 8)
    let base: ptr<i64> = calloc(L + 1, 8)
    let tmp: ptr<i64> = calloc(L + 1, 8)
    let work: ptr<i64> = calloc(2 * L + 2, 8)
    r[0] = 1
    let mut lenR: i64 = 1
    base[1] = 1          # the polynomial x (L >= 2 here)
    let mut lenBase: i64 = 2
    let mut e: i64 = EM
    while e > 0 {
        if (e & 1) == 1 {
            polymulred(r, lenR, base, lenBase, D, L, tmp, work)
            k2_copy(r, tmp, L)
            lenR = L
        }
        e = e >> 1
        if e > 0 {
            polymulred(base, lenBase, base, lenBase, D, L, tmp, work)
            k2_copy(base, tmp, L)
            lenBase = L
        }
    }

    let mut ans: i64 = 0
    i = 0
    while i < L {
        ans = (ans + r[i] * S[i]) % MOD
        i = i + 1
    }
    printf("%lld\n", ans)

    free(v)
    free(pre)
    free(S)
    free(C)
    free(B)
    free(T)
    free(D)
    free(r)
    free(base)
    free(tmp)
    free(work)
    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 powmod_i64_i64(int64_t base, int64_t exp);
void polymulred_ptr_i64_i64_ptr_i64_i64_ptr_i64_i64_ptr_i64_ptr_i64(int64_t* a, int64_t la, int64_t* b, int64_t lb, int64_t* D, int64_t L, int64_t* res, int64_t* work);
void k2_copy_ptr_i64_ptr_i64_i64(int64_t* dst, int64_t* src, int64_t n);
int32_t main(void);

static const int64_t MOD = 1000000007;
static const int64_t N = 5000;
static const int64_t EM = 999999999999;



int64_t powmod_i64_i64(int64_t base, int64_t exp) {
    int64_t result = 1;
    int64_t b = FLOW_CHECKED_MOD((base), (MOD));
    int64_t e = exp;
    while (e > 0) {
        if ((e & 1) == 1) {
            result = FLOW_CHECKED_MOD(((result * b)), (MOD));
        }
        b = FLOW_CHECKED_MOD(((b * b)), (MOD));
        e = FLOW_CHECKED_SHR((e), (1));
    }
    return result;
}

void polymulred_ptr_i64_i64_ptr_i64_i64_ptr_i64_i64_ptr_i64_ptr_i64(int64_t* a, int64_t la, int64_t* b, int64_t lb, int64_t* D, int64_t L, int64_t* res, int64_t* work) {
    int64_t lr = ((la + lb) - 1);
    int64_t i = 0;
    while (i < lr) {
        work[i] = 0;
        i = (i + 1);
    }
    i = 0;
    while (i < la) {
        int64_t ai = a[i];
        if (ai != 0) {
            int64_t j = 0;
            while (j < lb) {
                work[(i + j)] = FLOW_CHECKED_MOD(((work[(i + j)] + (ai * b[j]))), (MOD));
                j = (j + 1);
            }
        }
        i = (i + 1);
    }
    i = (lr - 1);
    while (i >= L) {
        int64_t c = work[i];
        if (c != 0) {
            work[i] = 0;
            int64_t j = 0;
            while (j < L) {
                work[((i - 1) - j)] = FLOW_CHECKED_MOD(((work[((i - 1) - j)] + (c * D[j]))), (MOD));
                j = (j + 1);
            }
        }
        i = (i - 1);
    }
    i = 0;
    while (i < L) {
        if (i < lr) {
            res[i] = work[i];
        } else {
            res[i] = 0;
        }
        i = (i + 1);
    }
}

void k2_copy_ptr_i64_ptr_i64_i64(int64_t* dst, int64_t* src, int64_t n) {
    int64_t i = 0;
    while (i < n) {
        dst[i] = src[i];
        i = (i + 1);
    }
}

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