Problem 324

f(10^10000) mod 100000007 via Berlekamp-Massey + Kitamasa on a(m)=f(2m).

Answer96972774
Output96972774
StatusPASS
Native helperno
Runtime1040 ms
Peak memory1184 KB
Time complexityO(n^2) (estimated)
Space complexityO(n^2) (estimated)

Performance comparison

MetricOur solutionBest known
Time complexityO(n^2)?
Space complexityO(n^2)?
ApproachFlow solutionNot curated
VerdictUnknown

Flow source

# Project Euler 324
# f(10^10000) mod 100000007 via Berlekamp-Massey + Kitamasa on a(m)=f(2m).

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

function mul_poly(p: ptr<i64>, q: ptr<i64>, rec: ptr<i64>, k: i64, mod: i64, out: ptr<i64>) -> i32 {
    let tmp: ptr<i64> = calloc(2 * k, 8)
    for i in 0..k {
        let pi: i64 = p[i]
        if pi != 0 {
            for j in 0..k {
                let qj: i64 = q[j]
                if qj != 0 {
                    tmp[i + j] = (tmp[i + j] + pi * qj) % mod
                }
            }
        }
    }
    let mut d: i64 = 2 * k - 2
    while d >= k {
        let val: i64 = tmp[d]
        if val != 0 {
            for t in 1..k + 1 {
                tmp[d - t] = (tmp[d - t] + val * rec[t - 1]) % mod
            }
        }
        d = d - 1
    }
    for i in 0..k {
        out[i] = tmp[i]
    }
    free(tmp)
    return 0
}

function big_halve(digits: ptr<i8>, n: i64) -> i64 {
    # divide decimal digit array (MSB at 0) by 2; return old LSB parity
    let mut rem: i64 = 0
    for i in 0..n {
        let cur: i64 = rem * 10 + (digits[i] as i64)
        digits[i] = (cur / 2) as i8
        rem = cur % 2
    }
    return rem
}

function big_is_zero(digits: ptr<i8>, n: i64) -> i64 {
    let mut i: i64 = 0
    while i < n {
        if digits[i] != 0 { return 0 }
        i = i + 1
    }
    return 1
}

function main() -> i32 {
    let mod: i64 = 100000007
    let k: i64 = 19
    let rec: ptr<i64> = calloc(k, 8)
    let init: ptr<i64> = calloc(k, 8)
    # recurrence for a(m)=f(2m)
    rec[0] = 675; rec[1] = 99926536; rec[2] = 3221189; rec[3] = 27416735; rec[4] = 25908201
    rec[5] = 28897274; rec[6] = 23056067; rec[7] = 28479264; rec[8] = 4524104; rec[9] = 95475903
    rec[10] = 71520743; rec[11] = 76943940; rec[12] = 71102733; rec[13] = 74091806; rec[14] = 72583272
    rec[15] = 96778818; rec[16] = 73471; rec[17] = 99999332; rec[18] = 1
    init[0] = 1; init[1] = 229; init[2] = 117805; init[3] = 64647289; init[4] = 69563725
    init[5] = 96149360; init[6] = 40041351; init[7] = 13625499; init[8] = 49444743; init[9] = 7047816
    init[10] = 63444149; init[11] = 71774943; init[12] = 18904145; init[13] = 72062; init[14] = 58262981
    init[15] = 68125412; init[16] = 64015488; init[17] = 12253197; init[18] = 9101639

    # exponent m = 5 * 10^9999 as decimal digits
    let nd: i64 = 10000
    let digits: ptr<i8> = calloc(nd, 1)
    digits[0] = 5
    # rest already 0 => 5 followed by 9999 zeros = 5*10^9999

    let res: ptr<i64> = calloc(k, 8)
    let base: ptr<i64> = calloc(k, 8)
    let tmp: ptr<i64> = calloc(k, 8)
    res[0] = 1
    base[1] = 1

    while big_is_zero(digits, nd) == 0 {
        # skip leading zeros length shrink optional
        let odd: i64 = big_halve(digits, nd)
        if odd == 1 {
            mul_poly(res, base, rec, k, mod, tmp)
            for i in 0..k { res[i] = tmp[i] }
        }
        if big_is_zero(digits, nd) == 0 {
            mul_poly(base, base, rec, k, mod, tmp)
            for j in 0..k { base[j] = tmp[j] }
        }
    }

    let mut ans: i64 = 0
    for i in 0..k {
        ans = (ans + res[i] * init[i]) % mod
    }
    printf("%lld\n", ans)
    free(rec); free(init); free(digits); free(res); free(base); free(tmp)
    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; }

int32_t mul_poly_ptr_i64_ptr_i64_ptr_i64_i64_i64_ptr_i64(int64_t* p, int64_t* q, int64_t* rec, int64_t k, int64_t mod, int64_t* out);
int64_t big_halve_ptr_i8_i64(int8_t* digits, int64_t n);
int64_t big_is_zero_ptr_i8_i64(int8_t* digits, int64_t n);
int32_t main(void);



int32_t mul_poly_ptr_i64_ptr_i64_ptr_i64_i64_i64_ptr_i64(int64_t* p, int64_t* q, int64_t* rec, int64_t k, int64_t mod, int64_t* out) {
    int64_t* tmp = (int64_t*)(calloc((2 * k), 8));
    int32_t __flow_step_1 = 1;
    for (int32_t i = 0; (0 <= k) ? i < k : i > k; i += (0 <= k) ? 1 : -1) {
        int64_t pi = p[i];
        if (pi != 0) {
            int32_t __flow_step_2 = 1;
            for (int32_t j = 0; (0 <= k) ? j < k : j > k; j += (0 <= k) ? 1 : -1) {
                int64_t qj = q[j];
                if (qj != 0) {
                    tmp[(i + j)] = FLOW_CHECKED_MOD(((tmp[(i + j)] + (pi * qj))), (mod));
                }
            }
        }
    }
    int64_t d = ((2 * k) - 2);
    while (d >= k) {
        int64_t val = tmp[d];
        if (val != 0) {
            int32_t __flow_step_3 = 1;
            for (int32_t t = 1; (1 <= (k + 1)) ? t < (k + 1) : t > (k + 1); t += (1 <= (k + 1)) ? 1 : -1) {
                tmp[(d - t)] = FLOW_CHECKED_MOD(((tmp[(d - t)] + (val * rec[(t - 1)]))), (mod));
            }
        }
        d = (d - 1);
    }
    int32_t __flow_step_4 = 1;
    for (int32_t i = 0; (0 <= k) ? i < k : i > k; i += (0 <= k) ? 1 : -1) {
        out[i] = tmp[i];
    }
    free(tmp);
    return 0;
}

int64_t big_halve_ptr_i8_i64(int8_t* digits, int64_t n) {
    int64_t rem = 0;
    int32_t __flow_step_5 = 1;
    for (int32_t i = 0; (0 <= n) ? i < n : i > n; i += (0 <= n) ? 1 : -1) {
        int64_t cur = ((rem * 10) + ((int64_t)(digits[i])));
        digits[i] = ((int8_t)(FLOW_CHECKED_DIV((cur), (2))));
        rem = FLOW_CHECKED_MOD((cur), (2));
    }
    return rem;
}

int64_t big_is_zero_ptr_i8_i64(int8_t* digits, int64_t n) {
    int64_t i = 0;
    while (i < n) {
        if (digits[i] != 0) {
            return 0;
        }
        i = (i + 1);
    }
    return 1;
}

int32_t main(void) {
    int64_t mod = 100000007;
    int64_t k = 19;
    int64_t* rec = (int64_t*)(calloc(k, 8));
    int64_t* init = (int64_t*)(calloc(k, 8));
    rec[0] = 675;
    rec[1] = 99926536;
    rec[2] = 3221189;
    rec[3] = 27416735;
    rec[4] = 25908201;
    rec[5] = 28897274;
    rec[6] = 23056067;
    rec[7] = 28479264;
    rec[8] = 4524104;
    rec[9] = 95475903;
    rec[10] = 71520743;
    rec[11] = 76943940;
    rec[12] = 71102733;
    rec[13] = 74091806;
    rec[14] = 72583272;
    rec[15] = 96778818;
    rec[16] = 73471;
    rec[17] = 99999332;
    rec[18] = 1;
    init[0] = 1;
    init[1] = 229;
    init[2] = 117805;
    init[3] = 64647289;
    init[4] = 69563725;
    init[5] = 96149360;
    init[6] = 40041351;
    init[7] = 13625499;
    init[8] = 49444743;
    init[9] = 7047816;
    init[10] = 63444149;
    init[11] = 71774943;
    init[12] = 18904145;
    init[13] = 72062;
    init[14] = 58262981;
    init[15] = 68125412;
    init[16] = 64015488;
    init[17] = 12253197;
    init[18] = 9101639;
    int64_t nd = 10000;
    int8_t* digits = (int8_t*)(calloc(nd, 1));
    digits[0] = 5;
    int64_t* res = (int64_t*)(calloc(k, 8));
    int64_t* base = (int64_t*)(calloc(k, 8));
    int64_t* tmp = (int64_t*)(calloc(k, 8));
    res[0] = 1;
    base[1] = 1;
    while (big_is_zero_ptr_i8_i64(digits, nd) == 0) {
        int64_t odd = big_halve_ptr_i8_i64(digits, nd);
        if (odd == 1) {
            mul_poly_ptr_i64_ptr_i64_ptr_i64_i64_i64_ptr_i64(res, base, rec, k, mod, tmp);
            int32_t __flow_step_6 = 1;
            for (int32_t i = 0; (0 <= k) ? i < k : i > k; i += (0 <= k) ? 1 : -1) {
                res[i] = tmp[i];
            }
        }
        if (big_is_zero_ptr_i8_i64(digits, nd) == 0) {
            mul_poly_ptr_i64_ptr_i64_ptr_i64_i64_i64_ptr_i64(base, base, rec, k, mod, tmp);
            int32_t __flow_step_7 = 1;
            for (int32_t j = 0; (0 <= k) ? j < k : j > k; j += (0 <= k) ? 1 : -1) {
                base[j] = tmp[j];
            }
        }
    }
    int64_t ans = 0;
    int32_t __flow_step_8 = 1;
    for (int32_t i = 0; (0 <= k) ? i < k : i > k; i += (0 <= k) ? 1 : -1) {
        ans = FLOW_CHECKED_MOD(((ans + (res[i] * init[i]))), (mod));
    }
    printf("%lld\n", ans);
    free(rec);
    free(init);
    free(digits);
    free(res);
    free(base);
    free(tmp);
    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) -> ()
  func.func @mul_poly(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr, %arg3: i64, %arg4: i64, %arg5: !llvm.ptr) -> i32 {
    %1 = arith.constant 2 : i32
    %3 = arith.extsi %1 : i32 to i64
    %2 = arith.muli %3, %arg3 : i64
    %4 = arith.constant 8 : i32
    %5 = arith.extsi %4 : i32 to i64
    %0 = func.call @calloc(%2, %5) : (i64, i64) -> !llvm.ptr
    %6 = arith.constant 0 : i32
    %7 = arith.index_cast %6 : i32 to index
    %8 = arith.index_cast %arg3 : i32 to index
    %10 = arith.constant 1 : index
    %11 = arith.constant -1 : index
    %12 = arith.cmpi sle, %7, %8 : index
    %9 = arith.select %12, %10, %11 : index
    cf.br ^bb0(%7 : index)
    ^bb0(%13: index):
    %14 = arith.cmpi slt, %13, %8 : index
    %15 = arith.cmpi sgt, %13, %8 : index
    %16 = arith.select %12, %14, %15 : i1
    cf.cond_br %16, ^bb1(%13 : index), ^bb2(%13 : index)
    ^bb1(%17: index):
      %19 = arith.index_cast %17 : index to i64
      %20 = llvm.getelementptr %arg0[%19] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %18 = llvm.load %20 : !llvm.ptr -> i64
      %21 = arith.constant 0 : i32
      %23 = arith.extsi %21 : i32 to i64
      %22 = arith.cmpi ne, %18, %23 : i64
      cf.cond_br %22, ^bb3, ^bb4
      ^bb3:
        %24 = arith.constant 0 : i32
        %25 = arith.index_cast %24 : i32 to index
        %26 = arith.index_cast %arg3 : i32 to index
        %28 = arith.constant 1 : index
        %29 = arith.constant -1 : index
        %30 = arith.cmpi sle, %25, %26 : index
        %27 = arith.select %30, %28, %29 : index
        cf.br ^bb6(%25 : index)
        ^bb6(%31: index):
        %32 = arith.cmpi slt, %31, %26 : index
        %33 = arith.cmpi sgt, %31, %26 : index
        %34 = arith.select %30, %32, %33 : i1
        cf.cond_br %34, ^bb7(%31 : index), ^bb8(%31 : index)
        ^bb7(%35: index):
          %37 = arith.index_cast %35 : index to i64
          %38 = llvm.getelementptr %arg1[%37] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %36 = llvm.load %38 : !llvm.ptr -> i64
          %39 = arith.constant 0 : i32
          %41 = arith.extsi %39 : i32 to i64
          %40 = arith.cmpi ne, %36, %41 : i64
          cf.cond_br %40, ^bb9, ^bb10
          ^bb9:
            %43 = arith.addi %17, %35 : index
            %44 = arith.index_cast %43 : index to i64
            %45 = llvm.getelementptr %0[%44] : (!llvm.ptr, i64) -> !llvm.ptr, i64
            %42 = llvm.load %45 : !llvm.ptr -> i64
            %46 = arith.muli %18, %36 : i64
            %47 = arith.addi %42, %46 : i64
            %48 = arith.remsi %47, %arg4 : i64
            %49 = arith.addi %17, %35 : index
            %50 = arith.index_cast %49 : index to i64
            %51 = llvm.getelementptr %0[%50] : (!llvm.ptr, i64) -> !llvm.ptr, i64
            llvm.store %48, %51 : i64, !llvm.ptr
            cf.br ^bb11
          ^bb10:
            cf.br ^bb11
          ^bb11:
          %52 = arith.addi %35, %27 : index
          cf.br ^bb6(%52 : index)
        ^bb8(%53: index):
        cf.br ^bb5
      ^bb4:
        cf.br ^bb5
      ^bb5:
      %54 = arith.addi %17, %9 : index
      cf.br ^bb0(%54 : index)
    ^bb2(%55: index):
    %56 = arith.constant 2 : i32
    %58 = arith.extsi %56 : i32 to i64
    %57 = arith.muli %58, %arg3 : i64
    %59 = arith.constant 2 : i32
    %61 = arith.extsi %59 : i32 to i64
    %60 = arith.subi %57, %61 : i64
    %62 = llvm.mlir.constant(1 : i64) : i64
    %63 = llvm.alloca %62 x i64 : (i64) -> !llvm.ptr
    llvm.store %60, %63 : i64, !llvm.ptr
    cf.br ^bb12
    ^bb12:
    %64 = llvm.load %63 : !llvm.ptr -> i64
    %65 = arith.cmpi sge, %64, %arg3 : i64
    cf.cond_br %65, ^bb13, ^bb14
    ^bb13:
      %67 = llvm.load %63 : !llvm.ptr -> i64
      %68 = llvm.getelementptr %0[%67] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %66 = llvm.load %68 : !llvm.ptr -> i64
      %69 = arith.constant 0 : i32
      %71 = arith.extsi %69 : i32 to i64
      %70 = arith.cmpi ne, %66, %71 : i64
      cf.cond_br %70, ^bb15, ^bb16
      ^bb15:
        %72 = arith.constant 1 : i32
        %73 = arith.constant 1 : i32
        %75 = arith.extsi %73 : i32 to i64
        %74 = arith.addi %arg3, %75 : i64
        %76 = arith.index_cast %72 : i32 to index
        %77 = arith.index_cast %74 : i32 to index
        %79 = arith.constant 1 : index
        %80 = arith.constant -1 : index
        %81 = arith.cmpi sle, %76, %77 : index
        %78 = arith.select %81, %79, %80 : index
        cf.br ^bb18(%76 : index)
        ^bb18(%82: index):
        %83 = arith.cmpi slt, %82, %77 : index
        %84 = arith.cmpi sgt, %82, %77 : index
        %85 = arith.select %81, %83, %84 : i1
        cf.cond_br %85, ^bb19(%82 : index), ^bb20(%82 : index)
        ^bb19(%86: index):
          %88 = llvm.load %63 : !llvm.ptr -> i64
          %90 = arith.trunci %88 : i64 to i32
          %91 = arith.index_cast %86 : index to i32
          %89 = arith.subi %90, %91 : i32
          %92 = arith.extsi %89 : i32 to i64
          %93 = llvm.getelementptr %0[%92] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %87 = llvm.load %93 : !llvm.ptr -> i64
          %95 = arith.constant 1 : i32
          %97 = arith.index_cast %86 : index to i32
          %96 = arith.subi %97, %95 : i32
          %98 = arith.extsi %96 : i32 to i64
          %99 = llvm.getelementptr %arg2[%98] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %94 = llvm.load %99 : !llvm.ptr -> i64
          %100 = arith.muli %66, %94 : i64
          %101 = arith.addi %87, %100 : i64
          %102 = arith.remsi %101, %arg4 : i64
          %103 = llvm.load %63 : !llvm.ptr -> i64
          %105 = arith.trunci %103 : i64 to i32
          %106 = arith.index_cast %86 : index to i32
          %104 = arith.subi %105, %106 : i32
          %107 = arith.extsi %104 : i32 to i64
          %108 = llvm.getelementptr %0[%107] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %102, %108 : i64, !llvm.ptr
          %109 = arith.addi %86, %78 : index
          cf.br ^bb18(%109 : index)
        ^bb20(%110: index):
        cf.br ^bb17
      ^bb16:
        cf.br ^bb17
      ^bb17:
      %111 = llvm.load %63 : !llvm.ptr -> i64
      %112 = arith.constant 1 : i32
      %114 = arith.extsi %112 : i32 to i64
      %113 = arith.subi %111, %114 : i64
      llvm.store %113, %63 : i64, !llvm.ptr
      cf.br ^bb12
    ^bb14:
    %115 = arith.constant 0 : i32
    %116 = arith.index_cast %115 : i32 to index
    %117 = arith.index_cast %arg3 : i32 to index
    %119 = arith.constant 1 : index
    %120 = arith.constant -1 : index
    %121 = arith.cmpi sle, %116, %117 : index
    %118 = arith.select %121, %119, %120 : index
    cf.br ^bb21(%116 : index)
    ^bb21(%122: index):
    %123 = arith.cmpi slt, %122, %117 : index
    %124 = arith.cmpi sgt, %122, %117 : index
    %125 = arith.select %121, %123, %124 : i1
    cf.cond_br %125, ^bb22(%122 : index), ^bb23(%122 : index)
    ^bb22(%126: index):
      %128 = arith.index_cast %126 : index to i64
      %129 = llvm.getelementptr %0[%128] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %127 = llvm.load %129 : !llvm.ptr -> i64
      %130 = arith.index_cast %126 : index to i64
      %131 = llvm.getelementptr %arg5[%130] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %127, %131 : i64, !llvm.ptr
      %132 = arith.addi %126, %118 : index
      cf.br ^bb21(%132 : index)
    ^bb23(%133: index):
    func.call @free(%0) : (!llvm.ptr) -> ()
    %135 = arith.constant 0 : i32
    func.return %135 : i32
  }
  func.func @big_halve(%arg0: !llvm.ptr, %arg1: i64) -> i64 {
    %136 = arith.constant 0 : i32
    %137 = arith.extsi %136 : i32 to i64
    %138 = llvm.mlir.constant(1 : i64) : i64
    %139 = llvm.alloca %138 x i64 : (i64) -> !llvm.ptr
    llvm.store %137, %139 : i64, !llvm.ptr
    %140 = arith.constant 0 : i32
    %141 = arith.index_cast %140 : i32 to index
    %142 = arith.index_cast %arg1 : i32 to index
    %144 = arith.constant 1 : index
    %145 = arith.constant -1 : index
    %146 = arith.cmpi sle, %141, %142 : index
    %143 = arith.select %146, %144, %145 : index
    cf.br ^bb24(%141 : index)
    ^bb24(%147: index):
    %148 = arith.cmpi slt, %147, %142 : index
    %149 = arith.cmpi sgt, %147, %142 : index
    %150 = arith.select %146, %148, %149 : i1
    cf.cond_br %150, ^bb25(%147 : index), ^bb26(%147 : index)
    ^bb25(%151: index):
      %152 = llvm.load %139 : !llvm.ptr -> i64
      %153 = arith.constant 10 : i32
      %155 = arith.extsi %153 : i32 to i64
      %154 = arith.muli %152, %155 : i64
      %157 = arith.index_cast %151 : index to i64
      %158 = llvm.getelementptr %arg0[%157] : (!llvm.ptr, i64) -> !llvm.ptr, i8
      %156 = llvm.load %158 : !llvm.ptr -> i8
      %159 = arith.extsi %156 : i8 to i64
      %160 = arith.addi %154, %159 : i64
      %161 = arith.constant 2 : i32
      %163 = arith.extsi %161 : i32 to i64
      %162 = arith.divsi %160, %163 : i64
      %164 = arith.trunci %162 : i64 to i8
      %165 = arith.index_cast %151 : index to i64
      %166 = llvm.getelementptr %arg0[%165] : (!llvm.ptr, i64) -> !llvm.ptr, i8
      llvm.store %164, %166 : i8, !llvm.ptr
      %167 = arith.constant 2 : i32
      %169 = arith.extsi %167 : i32 to i64
      %168 = arith.remsi %160, %169 : i64
      llvm.store %168, %139 : i64, !llvm.ptr
      %170 = arith.addi %151, %143 : index
      cf.br ^bb24(%170 : index)
    ^bb26(%171: index):
    %172 = llvm.load %139 : !llvm.ptr -> i64
    func.return %172 : i64
  }
  func.func @big_is_zero(%arg0: !llvm.ptr, %arg1: i64) -> i64 {
    %173 = arith.constant 0 : i32
    %174 = arith.extsi %173 : i32 to i64
    %175 = llvm.mlir.constant(1 : i64) : i64
    %176 = llvm.alloca %175 x i64 : (i64) -> !llvm.ptr
    llvm.store %174, %176 : i64, !llvm.ptr
    cf.br ^bb27
    ^bb27:
    %177 = llvm.load %176 : !llvm.ptr -> i64
    %178 = arith.cmpi slt, %177, %arg1 : i64
    cf.cond_br %178, ^bb28, ^bb29
    ^bb28:
      %180 = llvm.load %176 : !llvm.ptr -> i64
      %181 = llvm.getelementptr %arg0[%180] : (!llvm.ptr, i64) -> !llvm.ptr, i8
      %179 = llvm.load %181 : !llvm.ptr -> i8
      %182 = arith.constant 0 : i32
      %184 = arith.extsi %179 : i8 to i32
      %183 = arith.cmpi ne, %184, %182 : i32
      cf.cond_br %183, ^bb30, ^bb31
      ^bb30:
        %185 = arith.constant 0 : i32
        %186 = arith.extsi %185 : i32 to i64
        func.return %186 : i64
      ^bb31:
        cf.br ^bb32
      ^bb32:
      %187 = llvm.load %176 : !llvm.ptr -> i64
      %188 = arith.constant 1 : i32
      %190 = arith.extsi %188 : i32 to i64
      %189 = arith.addi %187, %190 : i64
      llvm.store %189, %176 : i64, !llvm.ptr
      cf.br ^bb27
    ^bb29:
    %191 = arith.constant 1 : i32
    %192 = arith.extsi %191 : i32 to i64
    func.return %192 : i64
  }
  func.func @main() -> i32 {
    %193 = arith.constant 100000007 : i32
    %194 = arith.extsi %193 : i32 to i64
    %195 = arith.constant 19 : i32
    %196 = arith.extsi %195 : i32 to i64
    %198 = arith.constant 8 : i32
    %199 = arith.extsi %198 : i32 to i64
    %197 = func.call @calloc(%196, %199) : (i64, i64) -> !llvm.ptr
    %201 = arith.constant 8 : i32
    %202 = arith.extsi %201 : i32 to i64
    %200 = func.call @calloc(%196, %202) : (i64, i64) -> !llvm.ptr
    %203 = arith.constant 675 : i32
    %204 = arith.constant 0 : i32
    %205 = arith.extsi %203 : i32 to i64
    %206 = arith.extsi %204 : i32 to i64
    %207 = llvm.getelementptr %197[%206] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %205, %207 : i64, !llvm.ptr
    %208 = arith.constant 99926536 : i32
    %209 = arith.constant 1 : i32
    %210 = arith.extsi %208 : i32 to i64
    %211 = arith.extsi %209 : i32 to i64
    %212 = llvm.getelementptr %197[%211] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %210, %212 : i64, !llvm.ptr
    %213 = arith.constant 3221189 : i32
    %214 = arith.constant 2 : i32
    %215 = arith.extsi %213 : i32 to i64
    %216 = arith.extsi %214 : i32 to i64
    %217 = llvm.getelementptr %197[%216] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %215, %217 : i64, !llvm.ptr
    %218 = arith.constant 27416735 : i32
    %219 = arith.constant 3 : i32
    %220 = arith.extsi %218 : i32 to i64
    %221 = arith.extsi %219 : i32 to i64
    %222 = llvm.getelementptr %197[%221] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %220, %222 : i64, !llvm.ptr
    %223 = arith.constant 25908201 : i32
    %224 = arith.constant 4 : i32
    %225 = arith.extsi %223 : i32 to i64
    %226 = arith.extsi %224 : i32 to i64
    %227 = llvm.getelementptr %197[%226] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %225, %227 : i64, !llvm.ptr
    %228 = arith.constant 28897274 : i32
    %229 = arith.constant 5 : i32
    %230 = arith.extsi %228 : i32 to i64
    %231 = arith.extsi %229 : i32 to i64
    %232 = llvm.getelementptr %197[%231] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %230, %232 : i64, !llvm.ptr
    %233 = arith.constant 23056067 : i32
    %234 = arith.constant 6 : i32
    %235 = arith.extsi %233 : i32 to i64
    %236 = arith.extsi %234 : i32 to i64
    %237 = llvm.getelementptr %197[%236] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %235, %237 : i64, !llvm.ptr
    %238 = arith.constant 28479264 : i32
    %239 = arith.constant 7 : i32
    %240 = arith.extsi %238 : i32 to i64
    %241 = arith.extsi %239 : i32 to i64
    %242 = llvm.getelementptr %197[%241] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %240, %242 : i64, !llvm.ptr
    %243 = arith.constant 4524104 : i32
    %244 = arith.constant 8 : i32
    %245 = arith.extsi %243 : i32 to i64
    %246 = arith.extsi %244 : i32 to i64
    %247 = llvm.getelementptr %197[%246] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %245, %247 : i64, !llvm.ptr
    %248 = arith.constant 95475903 : i32
    %249 = arith.constant 9 : i32
    %250 = arith.extsi %248 : i32 to i64
    %251 = arith.extsi %249 : i32 to i64
    %252 = llvm.getelementptr %197[%251] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %250, %252 : i64, !llvm.ptr
    %253 = arith.constant 71520743 : i32
    %254 = arith.constant 10 : i32
    %255 = arith.extsi %253 : i32 to i64
    %256 = arith.extsi %254 : i32 to i64
    %257 = llvm.getelementptr %197[%256] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %255, %257 : i64, !llvm.ptr
    %258 = arith.constant 76943940 : i32
    %259 = arith.constant 11 : i32
    %260 = arith.extsi %258 : i32 to i64
    %261 = arith.extsi %259 : i32 to i64
    %262 = llvm.getelementptr %197[%261] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %260, %262 : i64, !llvm.ptr
    %263 = arith.constant 71102733 : i32
    %264 = arith.constant 12 : i32
    %265 = arith.extsi %263 : i32 to i64
    %266 = arith.extsi %264 : i32 to i64
    %267 = llvm.getelementptr %197[%266] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %265, %267 : i64, !llvm.ptr
    %268 = arith.constant 74091806 : i32
    %269 = arith.constant 13 : i32
    %270 = arith.extsi %268 : i32 to i64
    %271 = arith.extsi %269 : i32 to i64
    %272 = llvm.getelementptr %197[%271] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %270, %272 : i64, !llvm.ptr
    %273 = arith.constant 72583272 : i32
    %274 = arith.constant 14 : i32
    %275 = arith.extsi %273 : i32 to i64
    %276 = arith.extsi %274 : i32 to i64
    %277 = llvm.getelementptr %197[%276] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %275, %277 : i64, !llvm.ptr
    %278 = arith.constant 96778818 : i32
    %279 = arith.constant 15 : i32
    %280 = arith.extsi %278 : i32 to i64
    %281 = arith.extsi %279 : i32 to i64
    %282 = llvm.getelementptr %197[%281] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %280, %282 : i64, !llvm.ptr
    %283 = arith.constant 73471 : i32
    %284 = arith.constant 16 : i32
    %285 = arith.extsi %283 : i32 to i64
    %286 = arith.extsi %284 : i32 to i64
    %287 = llvm.getelementptr %197[%286] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %285, %287 : i64, !llvm.ptr
    %288 = arith.constant 99999332 : i32
    %289 = arith.constant 17 : i32
    %290 = arith.extsi %288 : i32 to i64
    %291 = arith.extsi %289 : i32 to i64
    %292 = llvm.getelementptr %197[%291] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %290, %292 : i64, !llvm.ptr
    %293 = arith.constant 1 : i32
    %294 = arith.constant 18 : i32
    %295 = arith.extsi %293 : i32 to i64
    %296 = arith.extsi %294 : i32 to i64
    %297 = llvm.getelementptr %197[%296] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %295, %297 : i64, !llvm.ptr
    %298 = arith.constant 1 : i32
    %299 = arith.constant 0 : i32
    %300 = arith.extsi %298 : i32 to i64
    %301 = arith.extsi %299 : i32 to i64
    %302 = llvm.getelementptr %200[%301] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %300, %302 : i64, !llvm.ptr
    %303 = arith.constant 229 : i32
    %304 = arith.constant 1 : i32
    %305 = arith.extsi %303 : i32 to i64
    %306 = arith.extsi %304 : i32 to i64
    %307 = llvm.getelementptr %200[%306] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %305, %307 : i64, !llvm.ptr
    %308 = arith.constant 117805 : i32
    %309 = arith.constant 2 : i32
    %310 = arith.extsi %308 : i32 to i64
    %311 = arith.extsi %309 : i32 to i64
    %312 = llvm.getelementptr %200[%311] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %310, %312 : i64, !llvm.ptr
    %313 = arith.constant 64647289 : i32
    %314 = arith.constant 3 : i32
    %315 = arith.extsi %313 : i32 to i64
    %316 = arith.extsi %314 : i32 to i64
    %317 = llvm.getelementptr %200[%316] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %315, %317 : i64, !llvm.ptr
    %318 = arith.constant 69563725 : i32
    %319 = arith.constant 4 : i32
    %320 = arith.extsi %318 : i32 to i64
    %321 = arith.extsi %319 : i32 to i64
    %322 = llvm.getelementptr %200[%321] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %320, %322 : i64, !llvm.ptr
    %323 = arith.constant 96149360 : i32
    %324 = arith.constant 5 : i32
    %325 = arith.extsi %323 : i32 to i64
    %326 = arith.extsi %324 : i32 to i64
    %327 = llvm.getelementptr %200[%326] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %325, %327 : i64, !llvm.ptr
    %328 = arith.constant 40041351 : i32
    %329 = arith.constant 6 : i32
    %330 = arith.extsi %328 : i32 to i64
    %331 = arith.extsi %329 : i32 to i64
    %332 = llvm.getelementptr %200[%331] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %330, %332 : i64, !llvm.ptr
    %333 = arith.constant 13625499 : i32
    %334 = arith.constant 7 : i32
    %335 = arith.extsi %333 : i32 to i64
    %336 = arith.extsi %334 : i32 to i64
    %337 = llvm.getelementptr %200[%336] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %335, %337 : i64, !llvm.ptr
    %338 = arith.constant 49444743 : i32
    %339 = arith.constant 8 : i32
    %340 = arith.extsi %338 : i32 to i64
    %341 = arith.extsi %339 : i32 to i64
    %342 = llvm.getelementptr %200[%341] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %340, %342 : i64, !llvm.ptr
    %343 = arith.constant 7047816 : i32
    %344 = arith.constant 9 : i32
    %345 = arith.extsi %343 : i32 to i64
    %346 = arith.extsi %344 : i32 to i64
    %347 = llvm.getelementptr %200[%346] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %345, %347 : i64, !llvm.ptr
    %348 = arith.constant 63444149 : i32
    %349 = arith.constant 10 : i32
    %350 = arith.extsi %348 : i32 to i64
    %351 = arith.extsi %349 : i32 to i64
    %352 = llvm.getelementptr %200[%351] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %350, %352 : i64, !llvm.ptr
    %353 = arith.constant 71774943 : i32
    %354 = arith.constant 11 : i32
    %355 = arith.extsi %353 : i32 to i64
    %356 = arith.extsi %354 : i32 to i64
    %357 = llvm.getelementptr %200[%356] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %355, %357 : i64, !llvm.ptr
    %358 = arith.constant 18904145 : i32
    %359 = arith.constant 12 : i32
    %360 = arith.extsi %358 : i32 to i64
    %361 = arith.extsi %359 : i32 to i64
    %362 = llvm.getelementptr %200[%361] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %360, %362 : i64, !llvm.ptr
    %363 = arith.constant 72062 : i32
    %364 = arith.constant 13 : i32
    %365 = arith.extsi %363 : i32 to i64
    %366 = arith.extsi %364 : i32 to i64
    %367 = llvm.getelementptr %200[%366] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %365, %367 : i64, !llvm.ptr
    %368 = arith.constant 58262981 : i32
    %369 = arith.constant 14 : i32
    %370 = arith.extsi %368 : i32 to i64
    %371 = arith.extsi %369 : i32 to i64
    %372 = llvm.getelementptr %200[%371] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %370, %372 : i64, !llvm.ptr
    %373 = arith.constant 68125412 : i32
    %374 = arith.constant 15 : i32
    %375 = arith.extsi %373 : i32 to i64
    %376 = arith.extsi %374 : i32 to i64
    %377 = llvm.getelementptr %200[%376] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %375, %377 : i64, !llvm.ptr
    %378 = arith.constant 64015488 : i32
    %379 = arith.constant 16 : i32
    %380 = arith.extsi %378 : i32 to i64
    %381 = arith.extsi %379 : i32 to i64
    %382 = llvm.getelementptr %200[%381] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %380, %382 : i64, !llvm.ptr
    %383 = arith.constant 12253197 : i32
    %384 = arith.constant 17 : i32
    %385 = arith.extsi %383 : i32 to i64
    %386 = arith.extsi %384 : i32 to i64
    %387 = llvm.getelementptr %200[%386] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %385, %387 : i64, !llvm.ptr
    %388 = arith.constant 9101639 : i32
    %389 = arith.constant 18 : i32
    %390 = arith.extsi %388 : i32 to i64
    %391 = arith.extsi %389 : i32 to i64
    %392 = llvm.getelementptr %200[%391] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %390, %392 : i64, !llvm.ptr
    %393 = arith.constant 10000 : i32
    %394 = arith.extsi %393 : i32 to i64
    %396 = arith.constant 1 : i32
    %397 = arith.extsi %396 : i32 to i64
    %395 = func.call @calloc(%394, %397) : (i64, i64) -> !llvm.ptr
    %398 = arith.constant 5 : i32
    %399 = arith.constant 0 : i32
    %400 = arith.trunci %398 : i32 to i8
    %401 = arith.extsi %399 : i32 to i64
    %402 = llvm.getelementptr %395[%401] : (!llvm.ptr, i64) -> !llvm.ptr, i8
    llvm.store %400, %402 : i8, !llvm.ptr
    %404 = arith.constant 8 : i32
    %405 = arith.extsi %404 : i32 to i64
    %403 = func.call @calloc(%196, %405) : (i64, i64) -> !llvm.ptr
    %407 = arith.constant 8 : i32
    %408 = arith.extsi %407 : i32 to i64
    %406 = func.call @calloc(%196, %408) : (i64, i64) -> !llvm.ptr
    %410 = arith.constant 8 : i32
    %411 = arith.extsi %410 : i32 to i64
    %409 = func.call @calloc(%196, %411) : (i64, i64) -> !llvm.ptr
    %412 = arith.constant 1 : i32
    %413 = arith.constant 0 : i32
    %414 = arith.extsi %412 : i32 to i64
    %415 = arith.extsi %413 : i32 to i64
    %416 = llvm.getelementptr %403[%415] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %414, %416 : i64, !llvm.ptr
    %417 = arith.constant 1 : i32
    %418 = arith.constant 1 : i32
    %419 = arith.extsi %417 : i32 to i64
    %420 = arith.extsi %418 : i32 to i64
    %421 = llvm.getelementptr %406[%420] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %419, %421 : i64, !llvm.ptr
    cf.br ^bb33
    ^bb33:
    %422 = func.call @big_is_zero(%395, %394) : (!llvm.ptr, i64) -> i64
    %423 = arith.constant 0 : i32
    %425 = arith.extsi %423 : i32 to i64
    %424 = arith.cmpi eq, %422, %425 : i64
    cf.cond_br %424, ^bb34, ^bb35
    ^bb34:
      %426 = func.call @big_halve(%395, %394) : (!llvm.ptr, i64) -> i64
      %427 = arith.constant 1 : i32
      %429 = arith.extsi %427 : i32 to i64
      %428 = arith.cmpi eq, %426, %429 : i64
      cf.cond_br %428, ^bb36, ^bb37
      ^bb36:
        %430 = func.call @mul_poly(%403, %406, %197, %196, %194, %409) : (!llvm.ptr, !llvm.ptr, !llvm.ptr, i64, i64, !llvm.ptr) -> i32
        %431 = arith.constant 0 : i32
        %432 = arith.index_cast %431 : i32 to index
        %433 = arith.index_cast %196 : i32 to index
        %435 = arith.constant 1 : index
        %436 = arith.constant -1 : index
        %437 = arith.cmpi sle, %432, %433 : index
        %434 = arith.select %437, %435, %436 : index
        cf.br ^bb39(%432 : index)
        ^bb39(%438: index):
        %439 = arith.cmpi slt, %438, %433 : index
        %440 = arith.cmpi sgt, %438, %433 : index
        %441 = arith.select %437, %439, %440 : i1
        cf.cond_br %441, ^bb40(%438 : index), ^bb41(%438 : index)
        ^bb40(%442: index):
          %444 = arith.index_cast %442 : index to i64
          %445 = llvm.getelementptr %409[%444] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %443 = llvm.load %445 : !llvm.ptr -> i64
          %446 = arith.index_cast %442 : index to i64
          %447 = llvm.getelementptr %403[%446] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %443, %447 : i64, !llvm.ptr
          %448 = arith.addi %442, %434 : index
          cf.br ^bb39(%448 : index)
        ^bb41(%449: index):
        cf.br ^bb38
      ^bb37:
        cf.br ^bb38
      ^bb38:
      %450 = func.call @big_is_zero(%395, %394) : (!llvm.ptr, i64) -> i64
      %451 = arith.constant 0 : i32
      %453 = arith.extsi %451 : i32 to i64
      %452 = arith.cmpi eq, %450, %453 : i64
      cf.cond_br %452, ^bb42, ^bb43
      ^bb42:
        %454 = func.call @mul_poly(%406, %406, %197, %196, %194, %409) : (!llvm.ptr, !llvm.ptr, !llvm.ptr, i64, i64, !llvm.ptr) -> i32
        %455 = arith.constant 0 : i32
        %456 = arith.index_cast %455 : i32 to index
        %457 = arith.index_cast %196 : i32 to index
        %459 = arith.constant 1 : index
        %460 = arith.constant -1 : index
        %461 = arith.cmpi sle, %456, %457 : index
        %458 = arith.select %461, %459, %460 : index
        cf.br ^bb45(%456 : index)
        ^bb45(%462: index):
        %463 = arith.cmpi slt, %462, %457 : index
        %464 = arith.cmpi sgt, %462, %457 : index
        %465 = arith.select %461, %463, %464 : i1
        cf.cond_br %465, ^bb46(%462 : index), ^bb47(%462 : index)
        ^bb46(%466: index):
          %468 = arith.index_cast %466 : index to i64
          %469 = llvm.getelementptr %409[%468] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %467 = llvm.load %469 : !llvm.ptr -> i64
          %470 = arith.index_cast %466 : index to i64
          %471 = llvm.getelementptr %406[%470] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %467, %471 : i64, !llvm.ptr
          %472 = arith.addi %466, %458 : index
          cf.br ^bb45(%472 : index)
        ^bb47(%473: index):
        cf.br ^bb44
      ^bb43:
        cf.br ^bb44
      ^bb44:
      cf.br ^bb33
    ^bb35:
    %474 = arith.constant 0 : i32
    %475 = arith.extsi %474 : i32 to i64
    %476 = llvm.mlir.constant(1 : i64) : i64
    %477 = llvm.alloca %476 x i64 : (i64) -> !llvm.ptr
    llvm.store %475, %477 : i64, !llvm.ptr
    %478 = arith.constant 0 : i32
    %479 = arith.index_cast %478 : i32 to index
    %480 = arith.index_cast %196 : i32 to index
    %482 = arith.constant 1 : index
    %483 = arith.constant -1 : index
    %484 = arith.cmpi sle, %479, %480 : index
    %481 = arith.select %484, %482, %483 : index
    cf.br ^bb48(%479 : index)
    ^bb48(%485: index):
    %486 = arith.cmpi slt, %485, %480 : index
    %487 = arith.cmpi sgt, %485, %480 : index
    %488 = arith.select %484, %486, %487 : i1
    cf.cond_br %488, ^bb49(%485 : index), ^bb50(%485 : index)
    ^bb49(%489: index):
      %490 = llvm.load %477 : !llvm.ptr -> i64
      %492 = arith.index_cast %489 : index to i64
      %493 = llvm.getelementptr %403[%492] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %491 = llvm.load %493 : !llvm.ptr -> i64
      %495 = arith.index_cast %489 : index to i64
      %496 = llvm.getelementptr %200[%495] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %494 = llvm.load %496 : !llvm.ptr -> i64
      %497 = arith.muli %491, %494 : i64
      %498 = arith.addi %490, %497 : i64
      %499 = arith.remsi %498, %194 : i64
      llvm.store %499, %477 : i64, !llvm.ptr
      %500 = arith.addi %489, %481 : index
      cf.br ^bb48(%500 : index)
    ^bb50(%501: index):
    %502 = llvm.mlir.addressof @str_0 : !llvm.ptr
    %503 = llvm.load %477 : !llvm.ptr -> i64
    %504 = llvm.call @printf(%502, %503) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i64) -> i32
    func.call @free(%197) : (!llvm.ptr) -> ()
    func.call @free(%200) : (!llvm.ptr) -> ()
    func.call @free(%395) : (!llvm.ptr) -> ()
    func.call @free(%403) : (!llvm.ptr) -> ()
    func.call @free(%406) : (!llvm.ptr) -> ()
    func.call @free(%409) : (!llvm.ptr) -> ()
    %511 = arith.constant 0 : i32
    func.return %511 : i32
  }
}