Problem 939

Partisan Nim. E(N) mod 1234567891 for N=5000. O(N^2) partition DP.

Answer246776732
Output246776732
StatusPASS
Native helperno
Runtime210 ms
Peak memory99232 KB
Time complexityO(n^2) (estimated)
Space complexityO(n^2) (estimated)

Performance comparison

MetricOur solutionBest known
Time complexityO(n^2)O(n * m)
Space complexityO(n^2)O(n)
ApproachFlow solutionDynamic programming or generating function
VerdictUnknown

Flow source

# Project Euler 939
# Partisan Nim. E(N) mod 1234567891 for N=5000.
# O(N^2) partition DP.

extern {
    function calloc(n: i64, size: i64) -> ptr<void>
    function malloc(n: i64) -> ptr<void>
    function free(p: ptr<void>) -> void
    function memset(s: ptr<void>, c: i32, n: i64) -> ptr<void>
}

const MOD: i64 = 1234567891
const N: i64 = 5000

function solve() -> i64 {
    # Triangular offsets: start[n] = n*(n+1)/2
    let start: ptr<i64> = calloc(N + 1, 8)
    start[0] = 0
    let mut n_val: i64 = 1
    while n_val <= N {
        start[n_val] = start[n_val - 1] + n_val
        n_val = n_val + 1
    }

    let total_entries: i64 = (N + 1) * (N + 2) / 2
    let cnt0: ptr<i32> = calloc(total_entries, 4)
    let cnt1: ptr<i32> = calloc(total_entries, 4)

    # Empty partition of 0
    cnt0[0] = 1

    let mut prev0: ptr<i32> = calloc(N + 1, 4)
    let mut prev1: ptr<i32> = calloc(N + 1, 4)
    prev0[0] = 1

    let mut cur0: ptr<i32> = malloc((N + 1) * 4)
    let mut cur1: ptr<i32> = malloc((N + 1) * 4)

    # Build partition stats
    let mut k: i64 = 1
    while k <= N {
        memset(cur0, 0, (N + 1) * 4)
        memset(cur1, 0, (N + 1) * 4)

        if k % 2 == 0 {
            # parity unchanged in (n-k, k) branch
            let mut nn: i64 = k
            while nn <= N {
                let a0: i64 = prev1[nn - 1] as i64
                let a1: i64 = prev0[nn - 1] as i64
                let b0: i64 = cur0[nn - k] as i64
                let b1: i64 = cur1[nn - k] as i64

                let mut s0: i64 = a0 + b0
                if s0 >= MOD {
                    s0 = s0 - MOD
                }
                let mut s1: i64 = a1 + b1
                if s1 >= MOD {
                    s1 = s1 - MOD
                }

                cur0[nn] = s0 as i32
                cur1[nn] = s1 as i32

                let v: i64 = nn - k
                let idx: i64 = start[nn] + v

                let mut t: i64 = cnt0[idx] as i64 + s0
                if t >= MOD {
                    t = t - MOD
                }
                cnt0[idx] = t as i32

                t = cnt1[idx] as i64 + s1
                if t >= MOD {
                    t = t - MOD
                }
                cnt1[idx] = t as i32

                nn = nn + 1
            }
        } else {
            # parity flips in (n-k, k) branch
            let mut nn: i64 = k
            while nn <= N {
                let a0: i64 = prev1[nn - 1] as i64
                let a1: i64 = prev0[nn - 1] as i64
                let b0: i64 = cur1[nn - k] as i64
                let b1: i64 = cur0[nn - k] as i64

                let mut s0: i64 = a0 + b0
                if s0 >= MOD {
                    s0 = s0 - MOD
                }
                let mut s1: i64 = a1 + b1
                if s1 >= MOD {
                    s1 = s1 - MOD
                }

                cur0[nn] = s0 as i32
                cur1[nn] = s1 as i32

                let v: i64 = nn - k
                let idx: i64 = start[nn] + v

                let mut t: i64 = cnt0[idx] as i64 + s0
                if t >= MOD {
                    t = t - MOD
                }
                cnt0[idx] = t as i32

                t = cnt1[idx] as i64 + s1
                if t >= MOD {
                    t = t - MOD
                }
                cnt1[idx] = t as i32

                nn = nn + 1
            }
        }

        # swap prev and cur
        let tmp0: ptr<i32> = prev0
        prev0 = cur0
        cur0 = tmp0
        let tmp1: ptr<i32> = prev1
        prev1 = cur1
        cur1 = tmp1

        k = k + 1
    }

    free(prev0)
    free(prev1)
    free(cur0)
    free(cur1)

    # Compute E
    let cum0: ptr<i64> = calloc(N + 1, 8)
    let cum1: ptr<i64> = calloc(N + 1, 8)
    let pref0: ptr<i64> = malloc((N + 1) * 8)
    let pref1: ptr<i64> = malloc((N + 1) * 8)

    let mut ans: i64 = 0

    let mut m: i64 = 0
    while m <= N {
        let sb: i64 = start[m]

        # Add distributions for total b = m into cumulative B-side counts
        let mut v: i64 = 0
        while v <= m {
            let idx: i64 = sb + v

            let x0: i64 = cnt0[idx] as i64
            if x0 != 0 {
                let mut s: i64 = cum0[v] + x0
                if s >= MOD {
                    s = s - MOD
                }
                cum0[v] = s
            }

            let x1: i64 = cnt1[idx] as i64
            if x1 != 0 {
                let mut s: i64 = cum1[v] + x1
                if s >= MOD {
                    s = s - MOD
                }
                cum1[v] = s
            }

            v = v + 1
        }

        let a: i64 = N - m
        let sa: i64 = start[a]

        # Build prefix sums up to v = a
        let mut run: i64 = 0
        v = 0
        while v <= a {
            run = run + cum0[v]
            if run >= MOD {
                run = run - MOD
            }
            pref0[v] = run
            v = v + 1
        }

        run = 0
        v = 0
        while v <= a {
            run = run + cum1[v]
            if run >= MOD {
                run = run - MOD
            }
            pref1[v] = run
            v = v + 1
        }

        # Count A partitions of total a against all B partitions of total <= m
        let mut vA: i64 = 0
        while vA <= a {
            let idxA: i64 = sa + vA
            let a0: i64 = cnt0[idxA] as i64
            let a1: i64 = cnt1[idxA] as i64

            let x_same: i64 = vA - 1
            let x_diff: i64 = vA - 2

            if a0 != 0 {
                let mut s: i64 = 0
                if x_same >= 0 {
                    s = s + pref0[x_same]
                }
                if x_diff >= 0 {
                    s = s + pref1[x_diff]
                }
                s = s % MOD
                ans = (ans + a0 * s) % MOD
            }

            if a1 != 0 {
                let mut t: i64 = 0
                if x_same >= 0 {
                    t = t + pref1[x_same]
                }
                if x_diff >= 0 {
                    t = t + pref0[x_diff]
                }
                t = t % MOD
                ans = (ans + a1 * t) % MOD
            }

            vA = vA + 1
        }

        m = m + 1
    }

    free(cum0)
    free(cum1)
    free(pref0)
    free(pref1)
    free(cnt0)
    free(cnt1)
    free(start)

    return ans
}

function main() -> i32 {
    printf("%lld\n", solve())
    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 solve(void);
int32_t main(void);

static const int64_t MOD = 1234567891;
static const int64_t N = 5000;





int64_t solve(void) {
    int64_t* start = (int64_t*)(calloc((N + 1), 8));
    start[0] = 0;
    int64_t n_val = 1;
    while (n_val <= N) {
        start[n_val] = (start[(n_val - 1)] + n_val);
        n_val = (n_val + 1);
    }
    int64_t total_entries = FLOW_CHECKED_DIV((((N + 1) * (N + 2))), (2));
    int32_t* cnt0 = (int32_t*)(calloc(total_entries, 4));
    int32_t* cnt1 = (int32_t*)(calloc(total_entries, 4));
    cnt0[0] = 1;
    int32_t* prev0 = (int32_t*)(calloc((N + 1), 4));
    int32_t* prev1 = (int32_t*)(calloc((N + 1), 4));
    prev0[0] = 1;
    int32_t* cur0 = (int32_t*)(malloc(((N + 1) * 4)));
    int32_t* cur1 = (int32_t*)(malloc(((N + 1) * 4)));
    int64_t k = 1;
    while (k <= N) {
        memset(cur0, 0, ((N + 1) * 4));
        memset(cur1, 0, ((N + 1) * 4));
        if (FLOW_CHECKED_MOD((k), (2)) == 0) {
            int64_t nn = k;
            while (nn <= N) {
                int64_t a0 = ((int64_t)(prev1[(nn - 1)]));
                int64_t a1 = ((int64_t)(prev0[(nn - 1)]));
                int64_t b0 = ((int64_t)(cur0[(nn - k)]));
                int64_t b1 = ((int64_t)(cur1[(nn - k)]));
                int64_t s0 = (a0 + b0);
                if (s0 >= MOD) {
                    s0 = (s0 - MOD);
                }
                int64_t s1 = (a1 + b1);
                if (s1 >= MOD) {
                    s1 = (s1 - MOD);
                }
                cur0[nn] = ((int32_t)(s0));
                cur1[nn] = ((int32_t)(s1));
                int64_t v = (nn - k);
                int64_t idx = (start[nn] + v);
                int64_t t = (((int64_t)(cnt0[idx])) + s0);
                if (t >= MOD) {
                    t = (t - MOD);
                }
                cnt0[idx] = ((int32_t)(t));
                t = (((int64_t)(cnt1[idx])) + s1);
                if (t >= MOD) {
                    t = (t - MOD);
                }
                cnt1[idx] = ((int32_t)(t));
                nn = (nn + 1);
            }
        } else {
            int64_t nn = k;
            while (nn <= N) {
                int64_t a0 = ((int64_t)(prev1[(nn - 1)]));
                int64_t a1 = ((int64_t)(prev0[(nn - 1)]));
                int64_t b0 = ((int64_t)(cur1[(nn - k)]));
                int64_t b1 = ((int64_t)(cur0[(nn - k)]));
                int64_t s0 = (a0 + b0);
                if (s0 >= MOD) {
                    s0 = (s0 - MOD);
                }
                int64_t s1 = (a1 + b1);
                if (s1 >= MOD) {
                    s1 = (s1 - MOD);
                }
                cur0[nn] = ((int32_t)(s0));
                cur1[nn] = ((int32_t)(s1));
                int64_t v = (nn - k);
                int64_t idx = (start[nn] + v);
                int64_t t = (((int64_t)(cnt0[idx])) + s0);
                if (t >= MOD) {
                    t = (t - MOD);
                }
                cnt0[idx] = ((int32_t)(t));
                t = (((int64_t)(cnt1[idx])) + s1);
                if (t >= MOD) {
                    t = (t - MOD);
                }
                cnt1[idx] = ((int32_t)(t));
                nn = (nn + 1);
            }
        }
        int32_t* tmp0 = (int32_t*)(prev0);
        prev0 = cur0;
        cur0 = tmp0;
        int32_t* tmp1 = (int32_t*)(prev1);
        prev1 = cur1;
        cur1 = tmp1;
        k = (k + 1);
    }
    free(prev0);
    free(prev1);
    free(cur0);
    free(cur1);
    int64_t* cum0 = (int64_t*)(calloc((N + 1), 8));
    int64_t* cum1 = (int64_t*)(calloc((N + 1), 8));
    int64_t* pref0 = (int64_t*)(malloc(((N + 1) * 8)));
    int64_t* pref1 = (int64_t*)(malloc(((N + 1) * 8)));
    int64_t ans = 0;
    int64_t m = 0;
    while (m <= N) {
        int64_t sb = start[m];
        int64_t v = 0;
        while (v <= m) {
            int64_t idx = (sb + v);
            int64_t x0 = ((int64_t)(cnt0[idx]));
            if (x0 != 0) {
                int64_t s = (cum0[v] + x0);
                if (s >= MOD) {
                    s = (s - MOD);
                }
                cum0[v] = s;
            }
            int64_t x1 = ((int64_t)(cnt1[idx]));
            if (x1 != 0) {
                int64_t s = (cum1[v] + x1);
                if (s >= MOD) {
                    s = (s - MOD);
                }
                cum1[v] = s;
            }
            v = (v + 1);
        }
        int64_t a = (N - m);
        int64_t sa = start[a];
        int64_t run = 0;
        v = 0;
        while (v <= a) {
            run = (run + cum0[v]);
            if (run >= MOD) {
                run = (run - MOD);
            }
            pref0[v] = run;
            v = (v + 1);
        }
        run = 0;
        v = 0;
        while (v <= a) {
            run = (run + cum1[v]);
            if (run >= MOD) {
                run = (run - MOD);
            }
            pref1[v] = run;
            v = (v + 1);
        }
        int64_t vA = 0;
        while (vA <= a) {
            int64_t idxA = (sa + vA);
            int64_t a0 = ((int64_t)(cnt0[idxA]));
            int64_t a1 = ((int64_t)(cnt1[idxA]));
            int64_t x_same = (vA - 1);
            int64_t x_diff = (vA - 2);
            if (a0 != 0) {
                int64_t s = 0;
                if (x_same >= 0) {
                    s = (s + pref0[x_same]);
                }
                if (x_diff >= 0) {
                    s = (s + pref1[x_diff]);
                }
                s = FLOW_CHECKED_MOD((s), (MOD));
                ans = FLOW_CHECKED_MOD(((ans + (a0 * s))), (MOD));
            }
            if (a1 != 0) {
                int64_t t = 0;
                if (x_same >= 0) {
                    t = (t + pref1[x_same]);
                }
                if (x_diff >= 0) {
                    t = (t + pref0[x_diff]);
                }
                t = FLOW_CHECKED_MOD((t), (MOD));
                ans = FLOW_CHECKED_MOD(((ans + (a1 * t))), (MOD));
            }
            vA = (vA + 1);
        }
        m = (m + 1);
    }
    free(cum0);
    free(cum1);
    free(pref0);
    free(pref1);
    free(cnt0);
    free(cnt1);
    free(start);
    return ans;
}

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