Problem 365

sum M(10^18, 10^9, pqr) over primes 1000<p<q<r<5000 (Lucas + CRT).

Answer162619462356610313
Output162619462356610313
StatusPASS
Native helperno
Runtime90 ms
Peak memory2416 KB
Time complexityO(n^3) (estimated)
Space complexityO(n^2) (estimated)

Performance comparison

MetricOur solutionBest known
Time complexityO(n^3)O(n log n)
Space complexityO(n^2)O(n)
ApproachFlow solutionChinese Remainder Theorem
VerdictSuboptimal

Flow source

# Project Euler 365
# sum M(10^18, 10^9, pqr) over primes 1000<p<q<r<5000 (Lucas + CRT).

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

function modpow(base: i64, exp: i64, mod: i64) -> i64 {
    let mut r: i64 = 1
    let mut b: i64 = base % mod
    let mut e: i64 = exp
    while e > 0 {
        if e % 2 == 1 { r = (r * b) % mod }
        b = (b * b) % mod
        e = e / 2
    }
    return r
}

function lucas(n0: i64, k0: i64, p: i64) -> i64 {
    let fact: ptr<i64> = calloc(p, 8)
    let invfact: ptr<i64> = calloc(p, 8)
    if fact == null || invfact == null { return 0 }
    fact[0] = 1
    let mut i: i64 = 1
    while i < p {
        fact[i] = (fact[i - 1] * i) % p
        i = i + 1
    }
    invfact[p - 1] = modpow(fact[p - 1], p - 2, p)
    i = p - 1
    while i > 0 {
        invfact[i - 1] = (invfact[i] * i) % p
        i = i - 1
    }
    let mut res: i64 = 1
    let mut n: i64 = n0
    let mut k: i64 = k0
    while k > 0 || n > 0 {
        let ni: i64 = n % p
        let ki: i64 = k % p
        if ki > ni {
            free(invfact)
            free(fact)
            return 0
        }
        res = (res * fact[ni] % p * invfact[ki] % p * invfact[ni - ki]) % p
        n = n / p
        k = k / p
    }
    free(invfact)
    free(fact)
    return res
}

function main() -> i32 {
    let HI: i32 = 5000
    let sieve: ptr<i8> = calloc(HI as i64, 1)
    if sieve == null { return 1 }
    let mut i: i32 = 0
    while i < HI {
        sieve[i] = 1
        i = i + 1
    }
    sieve[0] = 0
    sieve[1] = 0
    let mut p: i32 = 2
    while p * p < HI {
        if sieve[p] == 1 {
            let mut m: i32 = p * p
            while m < HI {
                sieve[m] = 0
                m = m + p
            }
        }
        p = p + 1
    }
    let primes: ptr<i32> = calloc(1000, 4)
    if primes == null { return 1 }
    let mut L: i32 = 0
    p = 1001
    while p < HI {
        if sieve[p] == 1 {
            primes[L] = p
            L = L + 1
        }
        p = p + 1
    }

    let N: i64 = 1000000000000000000
    let K: i64 = 1000000000
    let residues: ptr<i32> = calloc(L as i64, 4)
    if residues == null { return 1 }
    i = 0
    while i < L {
        residues[i] = lucas(N, K, primes[i] as i64) as i32
        i = i + 1
    }

    # inv_rows[i][j-i-1] = p_i^{-1} mod p_j for j>i
    # Store flat: for each i, row of length L-i-1
    let invflat: ptr<i32> = calloc((L as i64) * (L as i64), 4)
    if invflat == null { return 1 }
    i = 0
    while i < L {
        let mut j: i32 = i + 1
        while j < L {
            let pi: i64 = primes[i] as i64
            let pj: i64 = primes[j] as i64
            invflat[i * L + j] = modpow(pi, pj - 2, pj) as i32
            j = j + 1
        }
        i = i + 1
    }

    let mut total: i64 = 0
    i = 0
    while i < L - 2 {
        let pi: i64 = primes[i] as i64
        let a: i64 = residues[i] as i64
        let mut j: i32 = i + 1
        while j < L - 1 {
            let q: i64 = primes[j] as i64
            let b: i64 = residues[j] as i64
            let inv_pq: i64 = invflat[i * L + j] as i64
            let t1: i64 = ((b - a) % q + q) % q * inv_pq % q
            let x1: i64 = a + pi * t1
            let pq: i64 = pi * q
            let mut k: i32 = j + 1
            while k < L {
                let r: i64 = primes[k] as i64
                let c: i64 = residues[k] as i64
                let inv_p_r: i64 = invflat[i * L + k] as i64
                let inv_q_r: i64 = invflat[j * L + k] as i64
                let inv_pq_r: i64 = (inv_p_r * inv_q_r) % r
                let t2: i64 = ((c - x1) % r + r) % r * inv_pq_r % r
                total = total + x1 + pq * t2
                k = k + 1
            }
            j = j + 1
        }
        i = i + 1
    }

    printf("%lld\n", total)
    free(invflat)
    free(residues)
    free(primes)
    free(sieve)
    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 modpow_i64_i64_i64(int64_t base, int64_t exp, int64_t mod);
int64_t lucas_i64_i64_i64(int64_t n0, int64_t k0, int64_t p);
int32_t main(void);



int64_t modpow_i64_i64_i64(int64_t base, int64_t exp, int64_t mod) {
    int64_t r = 1;
    int64_t b = FLOW_CHECKED_MOD((base), (mod));
    int64_t e = exp;
    while (e > 0) {
        if (FLOW_CHECKED_MOD((e), (2)) == 1) {
            r = FLOW_CHECKED_MOD(((r * b)), (mod));
        }
        b = FLOW_CHECKED_MOD(((b * b)), (mod));
        e = FLOW_CHECKED_DIV((e), (2));
    }
    return r;
}

int64_t lucas_i64_i64_i64(int64_t n0, int64_t k0, int64_t p) {
    int64_t* fact = (int64_t*)(calloc(p, 8));
    int64_t* invfact = (int64_t*)(calloc(p, 8));
    if ((fact == NULL || invfact == NULL)) {
        return 0;
    }
    fact[0] = 1;
    int64_t i = 1;
    while (i < p) {
        fact[i] = FLOW_CHECKED_MOD(((fact[(i - 1)] * i)), (p));
        i = (i + 1);
    }
    invfact[(p - 1)] = modpow_i64_i64_i64(fact[(p - 1)], (p - 2), p);
    i = (p - 1);
    while (i > 0) {
        invfact[(i - 1)] = FLOW_CHECKED_MOD(((invfact[i] * i)), (p));
        i = (i - 1);
    }
    int64_t res = 1;
    int64_t n = n0;
    int64_t k = k0;
    while ((k > 0 || n > 0)) {
        int64_t ni = FLOW_CHECKED_MOD((n), (p));
        int64_t ki = FLOW_CHECKED_MOD((k), (p));
        if (ki > ni) {
            free(invfact);
            free(fact);
            return 0;
        }
        res = FLOW_CHECKED_MOD(((FLOW_CHECKED_MOD(((FLOW_CHECKED_MOD(((res * fact[ni])), (p)) * invfact[ki])), (p)) * invfact[(ni - ki)])), (p));
        n = FLOW_CHECKED_DIV((n), (p));
        k = FLOW_CHECKED_DIV((k), (p));
    }
    free(invfact);
    free(fact);
    return res;
}

int32_t main(void) {
    int32_t HI = 5000;
    int8_t* sieve = (int8_t*)(calloc(((int64_t)(HI)), 1));
    if (sieve == NULL) {
        return 1;
    }
    int32_t i = 0;
    while (i < HI) {
        sieve[i] = 1;
        i = (i + 1);
    }
    sieve[0] = 0;
    sieve[1] = 0;
    int32_t p = 2;
    while ((p * p) < HI) {
        if (sieve[p] == 1) {
            int32_t m = (p * p);
            while (m < HI) {
                sieve[m] = 0;
                m = (m + p);
            }
        }
        p = (p + 1);
    }
    int32_t* primes = (int32_t*)(calloc(1000, 4));
    if (primes == NULL) {
        return 1;
    }
    int32_t L = 0;
    p = 1001;
    while (p < HI) {
        if (sieve[p] == 1) {
            primes[L] = p;
            L = (L + 1);
        }
        p = (p + 1);
    }
    int64_t N = 1000000000000000000;
    int64_t K = 1000000000;
    int32_t* residues = (int32_t*)(calloc(((int64_t)(L)), 4));
    if (residues == NULL) {
        return 1;
    }
    i = 0;
    while (i < L) {
        residues[i] = ((int32_t)(lucas_i64_i64_i64(N, K, ((int64_t)(primes[i])))));
        i = (i + 1);
    }
    int32_t* invflat = (int32_t*)(calloc((((int64_t)(L)) * ((int64_t)(L))), 4));
    if (invflat == NULL) {
        return 1;
    }
    i = 0;
    while (i < L) {
        int32_t j = (i + 1);
        while (j < L) {
            int64_t pi = ((int64_t)(primes[i]));
            int64_t pj = ((int64_t)(primes[j]));
            invflat[((i * L) + j)] = ((int32_t)(modpow_i64_i64_i64(pi, (pj - 2), pj)));
            j = (j + 1);
        }
        i = (i + 1);
    }
    int64_t total = 0;
    i = 0;
    while (i < (L - 2)) {
        int64_t pi = ((int64_t)(primes[i]));
        int64_t a = ((int64_t)(residues[i]));
        int32_t j = (i + 1);
        while (j < (L - 1)) {
            int64_t q = ((int64_t)(primes[j]));
            int64_t b = ((int64_t)(residues[j]));
            int64_t inv_pq = ((int64_t)(invflat[((i * L) + j)]));
            int64_t t1 = FLOW_CHECKED_MOD(((FLOW_CHECKED_MOD(((FLOW_CHECKED_MOD(((b - a)), (q)) + q)), (q)) * inv_pq)), (q));
            int64_t x1 = (a + (pi * t1));
            int64_t pq = (pi * q);
            int32_t k = (j + 1);
            while (k < L) {
                int64_t r = ((int64_t)(primes[k]));
                int64_t c = ((int64_t)(residues[k]));
                int64_t inv_p_r = ((int64_t)(invflat[((i * L) + k)]));
                int64_t inv_q_r = ((int64_t)(invflat[((j * L) + k)]));
                int64_t inv_pq_r = FLOW_CHECKED_MOD(((inv_p_r * inv_q_r)), (r));
                int64_t t2 = FLOW_CHECKED_MOD(((FLOW_CHECKED_MOD(((FLOW_CHECKED_MOD(((c - x1)), (r)) + r)), (r)) * inv_pq_r)), (r));
                total = ((total + x1) + (pq * t2));
                k = (k + 1);
            }
            j = (j + 1);
        }
        i = (i + 1);
    }
    printf("%lld\n", total);
    free(invflat);
    free(residues);
    free(primes);
    free(sieve);
    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 @modpow(%arg0: i64, %arg1: i64, %arg2: i64) -> i64 {
    %0 = arith.constant 1 : i32
    %1 = arith.extsi %0 : i32 to i64
    %2 = llvm.mlir.constant(1 : i64) : i64
    %3 = llvm.alloca %2 x i64 : (i64) -> !llvm.ptr
    llvm.store %1, %3 : i64, !llvm.ptr
    %4 = arith.remsi %arg0, %arg2 : i64
    %5 = llvm.mlir.constant(1 : i64) : i64
    %6 = llvm.alloca %5 x i64 : (i64) -> !llvm.ptr
    llvm.store %4, %6 : i64, !llvm.ptr
    %7 = llvm.mlir.constant(1 : i64) : i64
    %8 = llvm.alloca %7 x i64 : (i64) -> !llvm.ptr
    llvm.store %arg1, %8 : i64, !llvm.ptr
    cf.br ^bb0
    ^bb0:
    %9 = llvm.load %8 : !llvm.ptr -> i64
    %10 = arith.constant 0 : i32
    %12 = arith.extsi %10 : i32 to i64
    %11 = arith.cmpi sgt, %9, %12 : i64
    cf.cond_br %11, ^bb1, ^bb2
    ^bb1:
      %13 = llvm.load %8 : !llvm.ptr -> i64
      %14 = arith.constant 2 : i32
      %16 = arith.extsi %14 : i32 to i64
      %15 = arith.remsi %13, %16 : i64
      %17 = arith.constant 1 : i32
      %19 = arith.extsi %17 : i32 to i64
      %18 = arith.cmpi eq, %15, %19 : i64
      cf.cond_br %18, ^bb3, ^bb4
      ^bb3:
        %20 = llvm.load %3 : !llvm.ptr -> i64
        %21 = llvm.load %6 : !llvm.ptr -> i64
        %22 = arith.muli %20, %21 : i64
        %23 = arith.remsi %22, %arg2 : i64
        llvm.store %23, %3 : i64, !llvm.ptr
        cf.br ^bb5
      ^bb4:
        cf.br ^bb5
      ^bb5:
      %24 = llvm.load %6 : !llvm.ptr -> i64
      %25 = llvm.load %6 : !llvm.ptr -> i64
      %26 = arith.muli %24, %25 : i64
      %27 = arith.remsi %26, %arg2 : i64
      llvm.store %27, %6 : i64, !llvm.ptr
      %28 = llvm.load %8 : !llvm.ptr -> i64
      %29 = arith.constant 2 : i32
      %31 = arith.extsi %29 : i32 to i64
      %30 = arith.divsi %28, %31 : i64
      llvm.store %30, %8 : i64, !llvm.ptr
      cf.br ^bb0
    ^bb2:
    %32 = llvm.load %3 : !llvm.ptr -> i64
    func.return %32 : i64
  }
  func.func @lucas(%arg0: i64, %arg1: i64, %arg2: i64) -> i64 {
    %34 = arith.constant 8 : i32
    %35 = arith.extsi %34 : i32 to i64
    %33 = func.call @calloc(%arg2, %35) : (i64, i64) -> !llvm.ptr
    %37 = arith.constant 8 : i32
    %38 = arith.extsi %37 : i32 to i64
    %36 = func.call @calloc(%arg2, %38) : (i64, i64) -> !llvm.ptr
    %39 = llvm.mlir.zero : !llvm.ptr
    %40 = llvm.icmp "eq" %33, %39 : !llvm.ptr
    %41 = scf.if %40 -> (i1) {
      %42 = arith.constant true
      scf.yield %42 : i1
    } else {
      %43 = llvm.mlir.zero : !llvm.ptr
      %44 = llvm.icmp "eq" %36, %43 : !llvm.ptr
      scf.yield %44 : i1
    }
    cf.cond_br %41, ^bb6, ^bb7
    ^bb6:
      %45 = arith.constant 0 : i32
      %46 = arith.extsi %45 : i32 to i64
      func.return %46 : i64
    ^bb7:
      cf.br ^bb8
    ^bb8:
    %47 = arith.constant 1 : i32
    %48 = arith.constant 0 : i32
    %49 = arith.extsi %47 : i32 to i64
    %50 = arith.extsi %48 : i32 to i64
    %51 = llvm.getelementptr %33[%50] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %49, %51 : i64, !llvm.ptr
    %52 = arith.constant 1 : i32
    %53 = arith.extsi %52 : i32 to i64
    %54 = llvm.mlir.constant(1 : i64) : i64
    %55 = llvm.alloca %54 x i64 : (i64) -> !llvm.ptr
    llvm.store %53, %55 : i64, !llvm.ptr
    cf.br ^bb9
    ^bb9:
    %56 = llvm.load %55 : !llvm.ptr -> i64
    %57 = arith.cmpi slt, %56, %arg2 : i64
    cf.cond_br %57, ^bb10, ^bb11
    ^bb10:
      %59 = llvm.load %55 : !llvm.ptr -> i64
      %60 = arith.constant 1 : i32
      %62 = arith.extsi %60 : i32 to i64
      %61 = arith.subi %59, %62 : i64
      %63 = llvm.getelementptr %33[%61] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %58 = llvm.load %63 : !llvm.ptr -> i64
      %64 = llvm.load %55 : !llvm.ptr -> i64
      %65 = arith.muli %58, %64 : i64
      %66 = arith.remsi %65, %arg2 : i64
      %67 = llvm.load %55 : !llvm.ptr -> i64
      %68 = llvm.getelementptr %33[%67] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %66, %68 : i64, !llvm.ptr
      %69 = llvm.load %55 : !llvm.ptr -> i64
      %70 = arith.constant 1 : i32
      %72 = arith.extsi %70 : i32 to i64
      %71 = arith.addi %69, %72 : i64
      llvm.store %71, %55 : i64, !llvm.ptr
      cf.br ^bb9
    ^bb11:
    %75 = arith.constant 1 : i32
    %77 = arith.extsi %75 : i32 to i64
    %76 = arith.subi %arg2, %77 : i64
    %78 = llvm.getelementptr %33[%76] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    %74 = llvm.load %78 : !llvm.ptr -> i64
    %79 = arith.constant 2 : i32
    %81 = arith.extsi %79 : i32 to i64
    %80 = arith.subi %arg2, %81 : i64
    %73 = func.call @modpow(%74, %80, %arg2) : (i64, i64, i64) -> i64
    %82 = arith.constant 1 : i32
    %84 = arith.extsi %82 : i32 to i64
    %83 = arith.subi %arg2, %84 : i64
    %85 = llvm.getelementptr %36[%83] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %73, %85 : i64, !llvm.ptr
    %86 = arith.constant 1 : i32
    %88 = arith.extsi %86 : i32 to i64
    %87 = arith.subi %arg2, %88 : i64
    llvm.store %87, %55 : i64, !llvm.ptr
    cf.br ^bb12
    ^bb12:
    %89 = llvm.load %55 : !llvm.ptr -> i64
    %90 = arith.constant 0 : i32
    %92 = arith.extsi %90 : i32 to i64
    %91 = arith.cmpi sgt, %89, %92 : i64
    cf.cond_br %91, ^bb13, ^bb14
    ^bb13:
      %94 = llvm.load %55 : !llvm.ptr -> i64
      %95 = llvm.getelementptr %36[%94] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %93 = llvm.load %95 : !llvm.ptr -> i64
      %96 = llvm.load %55 : !llvm.ptr -> i64
      %97 = arith.muli %93, %96 : i64
      %98 = arith.remsi %97, %arg2 : i64
      %99 = llvm.load %55 : !llvm.ptr -> i64
      %100 = arith.constant 1 : i32
      %102 = arith.extsi %100 : i32 to i64
      %101 = arith.subi %99, %102 : i64
      %103 = llvm.getelementptr %36[%101] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %98, %103 : i64, !llvm.ptr
      %104 = llvm.load %55 : !llvm.ptr -> i64
      %105 = arith.constant 1 : i32
      %107 = arith.extsi %105 : i32 to i64
      %106 = arith.subi %104, %107 : i64
      llvm.store %106, %55 : i64, !llvm.ptr
      cf.br ^bb12
    ^bb14:
    %108 = arith.constant 1 : i32
    %109 = arith.extsi %108 : i32 to i64
    %110 = llvm.mlir.constant(1 : i64) : i64
    %111 = llvm.alloca %110 x i64 : (i64) -> !llvm.ptr
    llvm.store %109, %111 : i64, !llvm.ptr
    %112 = llvm.mlir.constant(1 : i64) : i64
    %113 = llvm.alloca %112 x i64 : (i64) -> !llvm.ptr
    llvm.store %arg0, %113 : i64, !llvm.ptr
    %114 = llvm.mlir.constant(1 : i64) : i64
    %115 = llvm.alloca %114 x i64 : (i64) -> !llvm.ptr
    llvm.store %arg1, %115 : i64, !llvm.ptr
    cf.br ^bb15
    ^bb15:
    %116 = llvm.load %115 : !llvm.ptr -> i64
    %117 = arith.constant 0 : i32
    %119 = arith.extsi %117 : i32 to i64
    %118 = arith.cmpi sgt, %116, %119 : i64
    %120 = scf.if %118 -> (i1) {
      %121 = arith.constant true
      scf.yield %121 : i1
    } else {
      %122 = llvm.load %113 : !llvm.ptr -> i64
      %123 = arith.constant 0 : i32
      %125 = arith.extsi %123 : i32 to i64
      %124 = arith.cmpi sgt, %122, %125 : i64
      scf.yield %124 : i1
    }
    cf.cond_br %120, ^bb16, ^bb17
    ^bb16:
      %126 = llvm.load %113 : !llvm.ptr -> i64
      %127 = arith.remsi %126, %arg2 : i64
      %128 = llvm.load %115 : !llvm.ptr -> i64
      %129 = arith.remsi %128, %arg2 : i64
      %130 = arith.cmpi sgt, %129, %127 : i64
      cf.cond_br %130, ^bb18, ^bb19
      ^bb18:
        func.call @free(%36) : (!llvm.ptr) -> ()
        func.call @free(%33) : (!llvm.ptr) -> ()
        %133 = arith.constant 0 : i32
        %134 = arith.extsi %133 : i32 to i64
        func.return %134 : i64
      ^bb19:
        cf.br ^bb20
      ^bb20:
      %135 = llvm.load %111 : !llvm.ptr -> i64
      %137 = llvm.getelementptr %33[%127] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %136 = llvm.load %137 : !llvm.ptr -> i64
      %138 = arith.muli %135, %136 : i64
      %139 = arith.remsi %138, %arg2 : i64
      %141 = llvm.getelementptr %36[%129] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %140 = llvm.load %141 : !llvm.ptr -> i64
      %142 = arith.muli %139, %140 : i64
      %143 = arith.remsi %142, %arg2 : i64
      %145 = arith.subi %127, %129 : i64
      %146 = llvm.getelementptr %36[%145] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %144 = llvm.load %146 : !llvm.ptr -> i64
      %147 = arith.muli %143, %144 : i64
      %148 = arith.remsi %147, %arg2 : i64
      llvm.store %148, %111 : i64, !llvm.ptr
      %149 = llvm.load %113 : !llvm.ptr -> i64
      %150 = arith.divsi %149, %arg2 : i64
      llvm.store %150, %113 : i64, !llvm.ptr
      %151 = llvm.load %115 : !llvm.ptr -> i64
      %152 = arith.divsi %151, %arg2 : i64
      llvm.store %152, %115 : i64, !llvm.ptr
      cf.br ^bb15
    ^bb17:
    func.call @free(%36) : (!llvm.ptr) -> ()
    func.call @free(%33) : (!llvm.ptr) -> ()
    %155 = llvm.load %111 : !llvm.ptr -> i64
    func.return %155 : i64
  }
  func.func @main() -> i32 {
    %156 = arith.constant 5000 : i32
    %158 = arith.extsi %156 : i32 to i64
    %159 = arith.constant 1 : i32
    %160 = arith.extsi %159 : i32 to i64
    %157 = func.call @calloc(%158, %160) : (i64, i64) -> !llvm.ptr
    %161 = llvm.mlir.zero : !llvm.ptr
    %162 = llvm.icmp "eq" %157, %161 : !llvm.ptr
    cf.cond_br %162, ^bb21, ^bb22
    ^bb21:
      %163 = arith.constant 1 : i32
      func.return %163 : i32
    ^bb22:
      cf.br ^bb23
    ^bb23:
    %164 = arith.constant 0 : i32
    %165 = llvm.mlir.constant(1 : i64) : i64
    %166 = llvm.alloca %165 x i32 : (i64) -> !llvm.ptr
    llvm.store %164, %166 : i32, !llvm.ptr
    cf.br ^bb24
    ^bb24:
    %167 = llvm.load %166 : !llvm.ptr -> i32
    %168 = arith.cmpi slt, %167, %156 : i32
    cf.cond_br %168, ^bb25, ^bb26
    ^bb25:
      %169 = arith.constant 1 : i32
      %170 = llvm.load %166 : !llvm.ptr -> i32
      %171 = arith.trunci %169 : i32 to i8
      %172 = arith.extsi %170 : i32 to i64
      %173 = llvm.getelementptr %157[%172] : (!llvm.ptr, i64) -> !llvm.ptr, i8
      llvm.store %171, %173 : i8, !llvm.ptr
      %174 = llvm.load %166 : !llvm.ptr -> i32
      %175 = arith.constant 1 : i32
      %176 = arith.addi %174, %175 : i32
      llvm.store %176, %166 : i32, !llvm.ptr
      cf.br ^bb24
    ^bb26:
    %177 = arith.constant 0 : i32
    %178 = arith.constant 0 : i32
    %179 = arith.trunci %177 : i32 to i8
    %180 = arith.extsi %178 : i32 to i64
    %181 = llvm.getelementptr %157[%180] : (!llvm.ptr, i64) -> !llvm.ptr, i8
    llvm.store %179, %181 : i8, !llvm.ptr
    %182 = arith.constant 0 : i32
    %183 = arith.constant 1 : i32
    %184 = arith.trunci %182 : i32 to i8
    %185 = arith.extsi %183 : i32 to i64
    %186 = llvm.getelementptr %157[%185] : (!llvm.ptr, i64) -> !llvm.ptr, i8
    llvm.store %184, %186 : i8, !llvm.ptr
    %187 = arith.constant 2 : i32
    %188 = llvm.mlir.constant(1 : i64) : i64
    %189 = llvm.alloca %188 x i32 : (i64) -> !llvm.ptr
    llvm.store %187, %189 : i32, !llvm.ptr
    cf.br ^bb27
    ^bb27:
    %190 = llvm.load %189 : !llvm.ptr -> i32
    %191 = llvm.load %189 : !llvm.ptr -> i32
    %192 = arith.muli %190, %191 : i32
    %193 = arith.cmpi slt, %192, %156 : i32
    cf.cond_br %193, ^bb28, ^bb29
    ^bb28:
      %195 = llvm.load %189 : !llvm.ptr -> i32
      %196 = arith.extsi %195 : i32 to i64
      %197 = llvm.getelementptr %157[%196] : (!llvm.ptr, i64) -> !llvm.ptr, i8
      %194 = llvm.load %197 : !llvm.ptr -> i8
      %198 = arith.constant 1 : i32
      %200 = arith.extsi %194 : i8 to i32
      %199 = arith.cmpi eq, %200, %198 : i32
      cf.cond_br %199, ^bb30, ^bb31
      ^bb30:
        %201 = llvm.load %189 : !llvm.ptr -> i32
        %202 = llvm.load %189 : !llvm.ptr -> i32
        %203 = arith.muli %201, %202 : i32
        %204 = llvm.mlir.constant(1 : i64) : i64
        %205 = llvm.alloca %204 x i32 : (i64) -> !llvm.ptr
        llvm.store %203, %205 : i32, !llvm.ptr
        cf.br ^bb33
        ^bb33:
        %206 = llvm.load %205 : !llvm.ptr -> i32
        %207 = arith.cmpi slt, %206, %156 : i32
        cf.cond_br %207, ^bb34, ^bb35
        ^bb34:
          %208 = arith.constant 0 : i32
          %209 = llvm.load %205 : !llvm.ptr -> i32
          %210 = arith.trunci %208 : i32 to i8
          %211 = arith.extsi %209 : i32 to i64
          %212 = llvm.getelementptr %157[%211] : (!llvm.ptr, i64) -> !llvm.ptr, i8
          llvm.store %210, %212 : i8, !llvm.ptr
          %213 = llvm.load %205 : !llvm.ptr -> i32
          %214 = llvm.load %189 : !llvm.ptr -> i32
          %215 = arith.addi %213, %214 : i32
          llvm.store %215, %205 : i32, !llvm.ptr
          cf.br ^bb33
        ^bb35:
        cf.br ^bb32
      ^bb31:
        cf.br ^bb32
      ^bb32:
      %216 = llvm.load %189 : !llvm.ptr -> i32
      %217 = arith.constant 1 : i32
      %218 = arith.addi %216, %217 : i32
      llvm.store %218, %189 : i32, !llvm.ptr
      cf.br ^bb27
    ^bb29:
    %220 = arith.constant 1000 : i32
    %221 = arith.constant 4 : i32
    %222 = arith.extsi %220 : i32 to i64
    %223 = arith.extsi %221 : i32 to i64
    %219 = func.call @calloc(%222, %223) : (i64, i64) -> !llvm.ptr
    %224 = llvm.mlir.zero : !llvm.ptr
    %225 = llvm.icmp "eq" %219, %224 : !llvm.ptr
    cf.cond_br %225, ^bb36, ^bb37
    ^bb36:
      %226 = arith.constant 1 : i32
      func.return %226 : i32
    ^bb37:
      cf.br ^bb38
    ^bb38:
    %227 = arith.constant 0 : i32
    %228 = llvm.mlir.constant(1 : i64) : i64
    %229 = llvm.alloca %228 x i32 : (i64) -> !llvm.ptr
    llvm.store %227, %229 : i32, !llvm.ptr
    %230 = arith.constant 1001 : i32
    llvm.store %230, %189 : i32, !llvm.ptr
    cf.br ^bb39
    ^bb39:
    %231 = llvm.load %189 : !llvm.ptr -> i32
    %232 = arith.cmpi slt, %231, %156 : i32
    cf.cond_br %232, ^bb40, ^bb41
    ^bb40:
      %234 = llvm.load %189 : !llvm.ptr -> i32
      %235 = arith.extsi %234 : i32 to i64
      %236 = llvm.getelementptr %157[%235] : (!llvm.ptr, i64) -> !llvm.ptr, i8
      %233 = llvm.load %236 : !llvm.ptr -> i8
      %237 = arith.constant 1 : i32
      %239 = arith.extsi %233 : i8 to i32
      %238 = arith.cmpi eq, %239, %237 : i32
      cf.cond_br %238, ^bb42, ^bb43
      ^bb42:
        %240 = llvm.load %189 : !llvm.ptr -> i32
        %241 = llvm.load %229 : !llvm.ptr -> i32
        %242 = arith.extsi %241 : i32 to i64
        %243 = llvm.getelementptr %219[%242] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %240, %243 : i32, !llvm.ptr
        %244 = llvm.load %229 : !llvm.ptr -> i32
        %245 = arith.constant 1 : i32
        %246 = arith.addi %244, %245 : i32
        llvm.store %246, %229 : i32, !llvm.ptr
        cf.br ^bb44
      ^bb43:
        cf.br ^bb44
      ^bb44:
      %247 = llvm.load %189 : !llvm.ptr -> i32
      %248 = arith.constant 1 : i32
      %249 = arith.addi %247, %248 : i32
      llvm.store %249, %189 : i32, !llvm.ptr
      cf.br ^bb39
    ^bb41:
    %250 = arith.constant 999999995705032704 : i32
    %251 = arith.extsi %250 : i32 to i64
    %252 = arith.constant 1000000000 : i32
    %253 = arith.extsi %252 : i32 to i64
    %255 = llvm.load %229 : !llvm.ptr -> i32
    %256 = arith.extsi %255 : i32 to i64
    %257 = arith.constant 4 : i32
    %258 = arith.extsi %257 : i32 to i64
    %254 = func.call @calloc(%256, %258) : (i64, i64) -> !llvm.ptr
    %259 = llvm.mlir.zero : !llvm.ptr
    %260 = llvm.icmp "eq" %254, %259 : !llvm.ptr
    cf.cond_br %260, ^bb45, ^bb46
    ^bb45:
      %261 = arith.constant 1 : i32
      func.return %261 : i32
    ^bb46:
      cf.br ^bb47
    ^bb47:
    %262 = arith.constant 0 : i32
    llvm.store %262, %166 : i32, !llvm.ptr
    cf.br ^bb48
    ^bb48:
    %263 = llvm.load %166 : !llvm.ptr -> i32
    %264 = llvm.load %229 : !llvm.ptr -> i32
    %265 = arith.cmpi slt, %263, %264 : i32
    cf.cond_br %265, ^bb49, ^bb50
    ^bb49:
      %268 = llvm.load %166 : !llvm.ptr -> i32
      %269 = arith.extsi %268 : i32 to i64
      %270 = llvm.getelementptr %219[%269] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %267 = llvm.load %270 : !llvm.ptr -> i32
      %271 = arith.extsi %267 : i32 to i64
      %266 = func.call @lucas(%251, %253, %271) : (i64, i64, i64) -> i64
      %272 = arith.trunci %266 : i64 to i32
      %273 = llvm.load %166 : !llvm.ptr -> i32
      %274 = arith.extsi %273 : i32 to i64
      %275 = llvm.getelementptr %254[%274] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %272, %275 : i32, !llvm.ptr
      %276 = llvm.load %166 : !llvm.ptr -> i32
      %277 = arith.constant 1 : i32
      %278 = arith.addi %276, %277 : i32
      llvm.store %278, %166 : i32, !llvm.ptr
      cf.br ^bb48
    ^bb50:
    %280 = llvm.load %229 : !llvm.ptr -> i32
    %281 = arith.extsi %280 : i32 to i64
    %282 = llvm.load %229 : !llvm.ptr -> i32
    %283 = arith.extsi %282 : i32 to i64
    %284 = arith.muli %281, %283 : i64
    %285 = arith.constant 4 : i32
    %286 = arith.extsi %285 : i32 to i64
    %279 = func.call @calloc(%284, %286) : (i64, i64) -> !llvm.ptr
    %287 = llvm.mlir.zero : !llvm.ptr
    %288 = llvm.icmp "eq" %279, %287 : !llvm.ptr
    cf.cond_br %288, ^bb51, ^bb52
    ^bb51:
      %289 = arith.constant 1 : i32
      func.return %289 : i32
    ^bb52:
      cf.br ^bb53
    ^bb53:
    %290 = arith.constant 0 : i32
    llvm.store %290, %166 : i32, !llvm.ptr
    cf.br ^bb54
    ^bb54:
    %291 = llvm.load %166 : !llvm.ptr -> i32
    %292 = llvm.load %229 : !llvm.ptr -> i32
    %293 = arith.cmpi slt, %291, %292 : i32
    cf.cond_br %293, ^bb55, ^bb56
    ^bb55:
      %294 = llvm.load %166 : !llvm.ptr -> i32
      %295 = arith.constant 1 : i32
      %296 = arith.addi %294, %295 : i32
      %297 = llvm.mlir.constant(1 : i64) : i64
      %298 = llvm.alloca %297 x i32 : (i64) -> !llvm.ptr
      llvm.store %296, %298 : i32, !llvm.ptr
      cf.br ^bb57
      ^bb57:
      %299 = llvm.load %298 : !llvm.ptr -> i32
      %300 = llvm.load %229 : !llvm.ptr -> i32
      %301 = arith.cmpi slt, %299, %300 : i32
      cf.cond_br %301, ^bb58, ^bb59
      ^bb58:
        %303 = llvm.load %166 : !llvm.ptr -> i32
        %304 = arith.extsi %303 : i32 to i64
        %305 = llvm.getelementptr %219[%304] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %302 = llvm.load %305 : !llvm.ptr -> i32
        %306 = arith.extsi %302 : i32 to i64
        %308 = llvm.load %298 : !llvm.ptr -> i32
        %309 = arith.extsi %308 : i32 to i64
        %310 = llvm.getelementptr %219[%309] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %307 = llvm.load %310 : !llvm.ptr -> i32
        %311 = arith.extsi %307 : i32 to i64
        %313 = arith.constant 2 : i32
        %315 = arith.extsi %313 : i32 to i64
        %314 = arith.subi %311, %315 : i64
        %312 = func.call @modpow(%306, %314, %311) : (i64, i64, i64) -> i64
        %316 = arith.trunci %312 : i64 to i32
        %317 = llvm.load %166 : !llvm.ptr -> i32
        %318 = llvm.load %229 : !llvm.ptr -> i32
        %319 = arith.muli %317, %318 : i32
        %320 = llvm.load %298 : !llvm.ptr -> i32
        %321 = arith.addi %319, %320 : i32
        %322 = arith.extsi %321 : i32 to i64
        %323 = llvm.getelementptr %279[%322] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %316, %323 : i32, !llvm.ptr
        %324 = llvm.load %298 : !llvm.ptr -> i32
        %325 = arith.constant 1 : i32
        %326 = arith.addi %324, %325 : i32
        llvm.store %326, %298 : i32, !llvm.ptr
        cf.br ^bb57
      ^bb59:
      %327 = llvm.load %166 : !llvm.ptr -> i32
      %328 = arith.constant 1 : i32
      %329 = arith.addi %327, %328 : i32
      llvm.store %329, %166 : i32, !llvm.ptr
      cf.br ^bb54
    ^bb56:
    %330 = arith.constant 0 : i32
    %331 = arith.extsi %330 : i32 to i64
    %332 = llvm.mlir.constant(1 : i64) : i64
    %333 = llvm.alloca %332 x i64 : (i64) -> !llvm.ptr
    llvm.store %331, %333 : i64, !llvm.ptr
    %334 = arith.constant 0 : i32
    llvm.store %334, %166 : i32, !llvm.ptr
    cf.br ^bb60
    ^bb60:
    %335 = llvm.load %166 : !llvm.ptr -> i32
    %336 = llvm.load %229 : !llvm.ptr -> i32
    %337 = arith.constant 2 : i32
    %338 = arith.subi %336, %337 : i32
    %339 = arith.cmpi slt, %335, %338 : i32
    cf.cond_br %339, ^bb61, ^bb62
    ^bb61:
      %341 = llvm.load %166 : !llvm.ptr -> i32
      %342 = arith.extsi %341 : i32 to i64
      %343 = llvm.getelementptr %219[%342] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %340 = llvm.load %343 : !llvm.ptr -> i32
      %344 = arith.extsi %340 : i32 to i64
      %346 = llvm.load %166 : !llvm.ptr -> i32
      %347 = arith.extsi %346 : i32 to i64
      %348 = llvm.getelementptr %254[%347] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %345 = llvm.load %348 : !llvm.ptr -> i32
      %349 = arith.extsi %345 : i32 to i64
      %350 = llvm.load %166 : !llvm.ptr -> i32
      %351 = arith.constant 1 : i32
      %352 = arith.addi %350, %351 : i32
      %353 = llvm.mlir.constant(1 : i64) : i64
      %354 = llvm.alloca %353 x i32 : (i64) -> !llvm.ptr
      llvm.store %352, %354 : i32, !llvm.ptr
      cf.br ^bb63
      ^bb63:
      %355 = llvm.load %354 : !llvm.ptr -> i32
      %356 = llvm.load %229 : !llvm.ptr -> i32
      %357 = arith.constant 1 : i32
      %358 = arith.subi %356, %357 : i32
      %359 = arith.cmpi slt, %355, %358 : i32
      cf.cond_br %359, ^bb64, ^bb65
      ^bb64:
        %361 = llvm.load %354 : !llvm.ptr -> i32
        %362 = arith.extsi %361 : i32 to i64
        %363 = llvm.getelementptr %219[%362] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %360 = llvm.load %363 : !llvm.ptr -> i32
        %364 = arith.extsi %360 : i32 to i64
        %366 = llvm.load %354 : !llvm.ptr -> i32
        %367 = arith.extsi %366 : i32 to i64
        %368 = llvm.getelementptr %254[%367] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %365 = llvm.load %368 : !llvm.ptr -> i32
        %369 = arith.extsi %365 : i32 to i64
        %371 = llvm.load %166 : !llvm.ptr -> i32
        %372 = llvm.load %229 : !llvm.ptr -> i32
        %373 = arith.muli %371, %372 : i32
        %374 = llvm.load %354 : !llvm.ptr -> i32
        %375 = arith.addi %373, %374 : i32
        %376 = arith.extsi %375 : i32 to i64
        %377 = llvm.getelementptr %279[%376] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %370 = llvm.load %377 : !llvm.ptr -> i32
        %378 = arith.extsi %370 : i32 to i64
        %379 = arith.subi %369, %349 : i64
        %380 = arith.remsi %379, %364 : i64
        %381 = arith.addi %380, %364 : i64
        %382 = arith.remsi %381, %364 : i64
        %383 = arith.muli %382, %378 : i64
        %384 = arith.remsi %383, %364 : i64
        %385 = arith.muli %344, %384 : i64
        %386 = arith.addi %349, %385 : i64
        %387 = arith.muli %344, %364 : i64
        %388 = llvm.load %354 : !llvm.ptr -> i32
        %389 = arith.constant 1 : i32
        %390 = arith.addi %388, %389 : i32
        %391 = llvm.mlir.constant(1 : i64) : i64
        %392 = llvm.alloca %391 x i32 : (i64) -> !llvm.ptr
        llvm.store %390, %392 : i32, !llvm.ptr
        cf.br ^bb66
        ^bb66:
        %393 = llvm.load %392 : !llvm.ptr -> i32
        %394 = llvm.load %229 : !llvm.ptr -> i32
        %395 = arith.cmpi slt, %393, %394 : i32
        cf.cond_br %395, ^bb67, ^bb68
        ^bb67:
          %397 = llvm.load %392 : !llvm.ptr -> i32
          %398 = arith.extsi %397 : i32 to i64
          %399 = llvm.getelementptr %219[%398] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %396 = llvm.load %399 : !llvm.ptr -> i32
          %400 = arith.extsi %396 : i32 to i64
          %402 = llvm.load %392 : !llvm.ptr -> i32
          %403 = arith.extsi %402 : i32 to i64
          %404 = llvm.getelementptr %254[%403] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %401 = llvm.load %404 : !llvm.ptr -> i32
          %405 = arith.extsi %401 : i32 to i64
          %407 = llvm.load %166 : !llvm.ptr -> i32
          %408 = llvm.load %229 : !llvm.ptr -> i32
          %409 = arith.muli %407, %408 : i32
          %410 = llvm.load %392 : !llvm.ptr -> i32
          %411 = arith.addi %409, %410 : i32
          %412 = arith.extsi %411 : i32 to i64
          %413 = llvm.getelementptr %279[%412] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %406 = llvm.load %413 : !llvm.ptr -> i32
          %414 = arith.extsi %406 : i32 to i64
          %416 = llvm.load %354 : !llvm.ptr -> i32
          %417 = llvm.load %229 : !llvm.ptr -> i32
          %418 = arith.muli %416, %417 : i32
          %419 = llvm.load %392 : !llvm.ptr -> i32
          %420 = arith.addi %418, %419 : i32
          %421 = arith.extsi %420 : i32 to i64
          %422 = llvm.getelementptr %279[%421] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %415 = llvm.load %422 : !llvm.ptr -> i32
          %423 = arith.extsi %415 : i32 to i64
          %424 = arith.muli %414, %423 : i64
          %425 = arith.remsi %424, %400 : i64
          %426 = arith.subi %405, %386 : i64
          %427 = arith.remsi %426, %400 : i64
          %428 = arith.addi %427, %400 : i64
          %429 = arith.remsi %428, %400 : i64
          %430 = arith.muli %429, %425 : i64
          %431 = arith.remsi %430, %400 : i64
          %432 = llvm.load %333 : !llvm.ptr -> i64
          %433 = arith.addi %432, %386 : i64
          %434 = arith.muli %387, %431 : i64
          %435 = arith.addi %433, %434 : i64
          llvm.store %435, %333 : i64, !llvm.ptr
          %436 = llvm.load %392 : !llvm.ptr -> i32
          %437 = arith.constant 1 : i32
          %438 = arith.addi %436, %437 : i32
          llvm.store %438, %392 : i32, !llvm.ptr
          cf.br ^bb66
        ^bb68:
        %439 = llvm.load %354 : !llvm.ptr -> i32
        %440 = arith.constant 1 : i32
        %441 = arith.addi %439, %440 : i32
        llvm.store %441, %354 : i32, !llvm.ptr
        cf.br ^bb63
      ^bb65:
      %442 = llvm.load %166 : !llvm.ptr -> i32
      %443 = arith.constant 1 : i32
      %444 = arith.addi %442, %443 : i32
      llvm.store %444, %166 : i32, !llvm.ptr
      cf.br ^bb60
    ^bb62:
    %445 = llvm.mlir.addressof @str_0 : !llvm.ptr
    %446 = llvm.load %333 : !llvm.ptr -> i64
    %447 = llvm.call @printf(%445, %446) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i64) -> i32
    func.call @free(%279) : (!llvm.ptr) -> ()
    func.call @free(%254) : (!llvm.ptr) -> ()
    func.call @free(%219) : (!llvm.ptr) -> ()
    func.call @free(%157) : (!llvm.ptr) -> ()
    %452 = arith.constant 0 : i32
    func.return %452 : i32
  }
}