Problem 827

sum_{k=1..18} Q(10^k) mod 409120391 Uses f64 log2 for comparison (sufficient precision for this problem).

Answer397289979
Output397289979
StatusPASS
Native helperno
Runtime210 ms
Peak memory23952 KB
Time complexityO(n^3) (estimated)
Space complexityO(1) (estimated)

Performance comparison

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

Flow source

# Project Euler 827: Pythagorean Triple Occurrence
# sum_{k=1..18} Q(10^k) mod 409120391
# Uses f64 log2 for comparison (sufficient precision for this problem).

extern {
    function calloc(n: i64, size: i64) -> ptr<void>
    function free(p: ptr<void>)
    function printf(fmt: ptr<i8>, ...) -> i32
    function log2(x: f64) -> f64
    function sqrt(x: f64) -> f64
}

const MOD: i64 = 409120391
const MAX_EXPS: i32 = 50
const MAX_PRIMES: i32 = 80

# Global primes
let mut primes_p1: ptr<i32> = 0 as ptr<i32>
let mut primes_p3: ptr<i32> = 0 as ptr<i32>
let mut log2_p1: ptr<f64> = 0 as ptr<f64>
let mut log2_p3: ptr<f64> = 0 as ptr<f64>
let mut np1: i32 = 0
let mut np3: i32 = 0
let mut log2_2: f64 = 1.0

# Memoization for dfs_min_rep - parallel arrays
let mut memo_rem: ptr<i64> = 0 as ptr<i64>
let mut memo_idx: ptr<i32> = 0 as ptr<i32>
let mut memo_prev_f: ptr<i32> = 0 as ptr<i32>
let mut memo_pset: ptr<i32> = 0 as ptr<i32>
let mut memo_valid: ptr<i32> = 0 as ptr<i32>
let mut memo_n: ptr<i32> = 0 as ptr<i32>
let mut memo_log2_val: ptr<f64> = 0 as ptr<f64>
let mut memo_exps_off: ptr<i32> = 0 as ptr<i32>
let mut memo_count: i32 = 0
let mut exps_pool: ptr<i32> = 0 as ptr<i32>
let mut exps_pool_next: i32 = 0

# DRep cache - parallel arrays
let mut d_keys: ptr<i64> = 0 as ptr<i64>
let mut d_e2: ptr<i64> = 0 as ptr<i64>
let mut d_log2: ptr<f64> = 0 as ptr<f64>
let mut d_rep3_n: ptr<i32> = 0 as ptr<i32>
let mut d_rep3_log2: ptr<f64> = 0 as ptr<f64>
let mut d_rep3_off: ptr<i32> = 0 as ptr<i32>
let mut d_count: i32 = 0

# Q cache - parallel arrays
let mut q_keys: ptr<i64> = 0 as ptr<i64>
let mut q_e2: ptr<i64> = 0 as ptr<i64>
let mut q_rep1_n: ptr<i32> = 0 as ptr<i32>
let mut q_rep1_log2: ptr<f64> = 0 as ptr<f64>
let mut q_rep1_off: ptr<i32> = 0 as ptr<i32>
let mut q_rep3_n: ptr<i32> = 0 as ptr<i32>
let mut q_rep3_log2: ptr<f64> = 0 as ptr<f64>
let mut q_rep3_off: ptr<i32> = 0 as ptr<i32>
let mut q_count: i32 = 0

function mulmod(a: i64, b: i64, m: i64) -> i64 {
    return ((a as i128) * (b as i128) % (m as i128)) as i64
}

function powmod(a: i64, d: i64, n: i64) -> i64 {
    let mut r: i64 = 1
    let mut aa: i64 = a % n
    let mut dd: i64 = d
    while dd > 0 {
        if (dd & 1) == 1 { r = mulmod(r, aa, n) }
        aa = mulmod(aa, aa, n)
        dd = dd >> 1
    }
    return r
}

function is_prime_u64(n: i64) -> i32 {
    if n < 2 { return 0 }
    let mut i: i32 = 0
    while i < 12 {
        let sp: i64 = 0
        if i == 0 { sp = 2 }
        if i == 1 { sp = 3 }
        if i == 2 { sp = 5 }
        if i == 3 { sp = 7 }
        if i == 4 { sp = 11 }
        if i == 5 { sp = 13 }
        if i == 6 { sp = 17 }
        if i == 7 { sp = 19 }
        if i == 8 { sp = 23 }
        if i == 9 { sp = 29 }
        if i == 10 { sp = 31 }
        if i == 11 { sp = 37 }
        if n == sp { return 1 }
        if n % sp == 0 { return 0 }
        i = i + 1
    }
    let mut d: i64 = n - 1
    let mut s: i32 = 0
    while d % 2 == 0 {
        d = d / 2
        s = s + 1
    }
    let mut i2: i32 = 0
    while i2 < 7 {
        let a: i64 = 0
        if i2 == 0 { a = 2 % n }
        if i2 == 1 { a = 325 % n }
        if i2 == 2 { a = 9375 % n }
        if i2 == 3 { a = 28178 % n }
        if i2 == 4 { a = 450775 % n }
        if i2 == 5 { a = 9780504 % n }
        if i2 == 6 { a = 1795265022 % n }
        if a == 0 { i2 = i2 + 1; continue }
        let mut x: i64 = powmod(a, d, n)
        if x == 1 { i2 = i2 + 1; continue }
        if x == n - 1 { i2 = i2 + 1; continue }
        let mut found: i32 = 0
        let mut j: i32 = 0
        while j < s - 1 {
            x = mulmod(x, x, n)
            if x == n - 1 { found = 1; break }
            j = j + 1
        }
        if found == 0 { return 0 }
        i2 = i2 + 1
    }
    return 1
}

function gcd_u64(a: i64, b: i64) -> i64 {
    let mut x: i64 = a
    let mut y: i64 = b
    while y != 0 {
        let t: i64 = x % y
        x = y
        y = t
    }
    return x
}

function pollard_rho(n: i64) -> i64 {
    if n % 2 == 0 { return 2 }
    if n % 3 == 0 { return 3 }
    if n % 5 == 0 { return 5 }
    let mut ci: i32 = 0
    while ci < 12 {
        let c: i64 = 0
        if ci == 0 { c = 1 }
        if ci == 1 { c = 3 }
        if ci == 2 { c = 5 }
        if ci == 3 { c = 7 }
        if ci == 4 { c = 11 }
        if ci == 5 { c = 13 }
        if ci == 6 { c = 17 }
        if ci == 7 { c = 19 }
        if ci == 8 { c = 23 }
        if ci == 9 { c = 29 }
        if ci == 10 { c = 31 }
        if ci == 11 { c = 37 }
        let mut x: i64 = 3
        let mut y: i64 = 3
        let mut d: i64 = 1
        while d == 1 {
            x = (mulmod(x, x, n) + c) % n
            y = (mulmod(y, y, n) + c) % n
            y = (mulmod(y, y, n) + c) % n
            let diff: i64 = if x > y { x - y } else { y - x }
            d = gcd_u64(diff, n)
        }
        if d != n { return d }
        ci = ci + 1
    }
    return n
}

# Factorize: returns count, fills fac_p[] and fac_e[]
function factorize(n_in: i64, fac_p: ptr<i64>, fac_e: ptr<i32>) -> i32 {
    let mut n: i64 = n_in
    let mut nf: i32 = 0
    let mut i: i32 = 0
    while i < 12 {
        let sp: i64 = 0
        if i == 0 { sp = 2 }
        if i == 1 { sp = 3 }
        if i == 2 { sp = 5 }
        if i == 3 { sp = 7 }
        if i == 4 { sp = 11 }
        if i == 5 { sp = 13 }
        if i == 6 { sp = 17 }
        if i == 7 { sp = 19 }
        if i == 8 { sp = 23 }
        if i == 9 { sp = 29 }
        if i == 10 { sp = 31 }
        if i == 11 { sp = 37 }
        if n % sp == 0 {
            let mut e: i32 = 0
            while n % sp == 0 {
                n = n / sp
                e = e + 1
            }
            fac_p[nf] = sp
            fac_e[nf] = e
            nf = nf + 1
        }
        i = i + 1
    }
    let stack: ptr<i64> = calloc(64, 8)
    let mut sp2: i32 = 0
    if n > 1 {
        stack[sp2] = n
        sp2 = sp2 + 1
    }
    while sp2 > 0 {
        sp2 = sp2 - 1
        let m: i64 = stack[sp2]
        if m == 1 { continue }
        if is_prime_u64(m) == 1 {
            let mut found: i32 = 0
            let mut i2: i32 = 0
            while i2 < nf {
                if fac_p[i2] == m {
                    fac_e[i2] = fac_e[i2] + 1
                    found = 1
                    break
                }
                i2 = i2 + 1
            }
            if found == 0 {
                fac_p[nf] = m
                fac_e[nf] = 1
                nf = nf + 1
            }
            continue
        }
        let d: i64 = pollard_rho(m)
        if d == m {
            let mut found: i32 = 0
            let mut i3: i32 = 0
            while i3 < nf {
                if fac_p[i3] == m {
                    fac_e[i3] = fac_e[i3] + 1
                    found = 1
                    break
                }
                i3 = i3 + 1
            }
            if found == 0 {
                fac_p[nf] = m
                fac_e[nf] = 1
                nf = nf + 1
            }
            continue
        }
        stack[sp2] = d
        sp2 = sp2 + 1
        stack[sp2] = m / d
        sp2 = sp2 + 1
    }
    free(stack as ptr<void>)
    return nf
}

function odd_divisors(n: i64, out: ptr<i64>) -> i32 {
    let fac_p: ptr<i64> = calloc(20, 8)
    let fac_e: ptr<i32> = calloc(20, 4)
    let nf: i32 = factorize(n, fac_p, fac_e)
    let odd_p: ptr<i64> = calloc(20, 8)
    let odd_e: ptr<i32> = calloc(20, 4)
    let mut onf: i32 = 0
    let mut i: i32 = 0
    while i < nf {
        if fac_p[i] != 2 {
            odd_p[onf] = fac_p[i]
            odd_e[onf] = fac_e[i]
            onf = onf + 1
        }
        i = i + 1
    }
    let mut nd: i32 = 1
    out[0] = 1
    let mut i2: i32 = 0
    while i2 < onf {
        let cur: i32 = nd
        let mut pe: i64 = 1
        let mut e: i32 = 1
        while e <= odd_e[i2] {
            pe = pe * odd_p[i2]
            let mut j: i32 = 0
            while j < cur {
                out[nd] = out[j] * pe
                nd = nd + 1
                j = j + 1
            }
            e = e + 1
        }
        i2 = i2 + 1
    }
    let mut i3: i32 = 1
    while i3 < nd {
        let key: i64 = out[i3]
        let mut j2: i32 = i3 - 1
        while j2 >= 0 && out[j2] > key {
            out[j2 + 1] = out[j2]
            j2 = j2 - 1
        }
        out[j2 + 1] = key
        i3 = i3 + 1
    }
    free(fac_p as ptr<void>)
    free(fac_e as ptr<void>)
    free(odd_p as ptr<void>)
    free(odd_e as ptr<void>)
    return nd
}

function gen_primes() -> void {
    let mut x: i32 = 2
    while np1 < MAX_PRIMES || np3 < MAX_PRIMES {
        let mut is_p: i32 = 1
        let mut d: i32 = 2
        while d * d <= x {
            if x % d == 0 {
                is_p = 0
                break
            }
            d = d + 1
        }
        if is_p == 1 {
            if x % 4 == 1 && np1 < MAX_PRIMES {
                primes_p1[np1] = x
                log2_p1[np1] = log2((x as f64))
                np1 = np1 + 1
            } else {
                if x % 4 == 3 && np3 < MAX_PRIMES {
                    primes_p3[np3] = x
                    log2_p3[np3] = log2((x as f64))
                    np3 = np3 + 1
                }
            }
        }
        x = x + 1
    }
    log2_2 = log2(2.0)
}

# Allocate exps from pool
function alloc_exps(n: i32) -> i32 {
    let off: i32 = exps_pool_next
    exps_pool_next = exps_pool_next + n
    return off
}

# Memo lookup: returns 1 if found valid, 0 if found invalid, -1 if not found
function memo_lookup(rem: i64, idx: i32, prev_f: i32, pset: i32, out_n: ptr<i32>, out_log2: ptr<f64>, out_off: ptr<i32>) -> i32 {
    let mut i: i32 = 0
    while i < memo_count {
        if memo_rem[i] == rem && memo_idx[i] == idx && memo_prev_f[i] == prev_f && memo_pset[i] == pset {
            if memo_valid[i] == 1 {
                out_n[0] = memo_n[i]
                out_log2[0] = memo_log2_val[i]
                out_off[0] = memo_exps_off[i]
                return 1
            }
            return 0
        }
        i = i + 1
    }
    return -1
}

function memo_store(rem: i64, idx: i32, prev_f: i32, pset: i32, valid: i32, n: i32, log2_val: f64, off: i32) -> void {
    memo_rem[memo_count] = rem
    memo_idx[memo_count] = idx
    memo_prev_f[memo_count] = prev_f
    memo_pset[memo_count] = pset
    memo_valid[memo_count] = valid
    if valid == 1 {
        memo_n[memo_count] = n
        memo_log2_val[memo_count] = log2_val
        memo_exps_off[memo_count] = off
    }
    memo_count = memo_count + 1
}

# dfs_min_rep: find minimum representation of rem as product of prime^e
# Returns 1 if found, 0 if not. Fills out_n, out_log2, out_off.
function dfs_min_rep(rem: i64, idx: i32, prev_f: i32, primes: ptr<i32>, logs: ptr<f64>, nprimes: i32, pset: i32, out_n: ptr<i32>, out_log2: ptr<f64>, out_off: ptr<i32>) -> i32 {
    if rem == 1 {
        out_n[0] = 0
        out_log2[0] = 0.0
        out_off[0] = 0
        return 1
    }
    if idx >= nprimes { return 0 }

    let dummy_n: ptr<i32> = calloc(1, 4)
    let dummy_l: ptr<f64> = calloc(1, 8)
    let dummy_o: ptr<i32> = calloc(1, 4)
    let cached: i32 = memo_lookup(rem, idx, prev_f, pset, dummy_n, dummy_l, dummy_o)
    if cached >= 0 {
        if cached == 1 {
            out_n[0] = dummy_n[0]
            out_log2[0] = dummy_l[0]
            out_off[0] = dummy_o[0]
        }
        free(dummy_n as ptr<void>)
        free(dummy_l as ptr<void>)
        free(dummy_o as ptr<void>)
        return cached
    }
    free(dummy_n as ptr<void>)
    free(dummy_l as ptr<void>)
    free(dummy_o as ptr<void>)

    let divs: ptr<i64> = calloc(20000, 8)
    let nd: i32 = odd_divisors(rem, divs)

    let mut best_n: i32 = -1
    let mut best_log2: f64 = 0.0
    let mut best_off: i32 = 0
    let mut found: i32 = 0

    let mut i: i32 = nd - 1
    while i >= 0 {
        let f: i64 = divs[i]
        if f == 1 { i = i - 1; continue }
        if f > (prev_f as i64) { i = i - 1; continue }
        let e: i32 = ((f - 1) / 2) as i32
        if e <= 0 { i = i - 1; continue }

        let sub_n: ptr<i32> = calloc(1, 4)
        let sub_log2: ptr<f64> = calloc(1, 8)
        let sub_off: ptr<i32> = calloc(1, 4)
        if dfs_min_rep(rem / f, idx + 1, f as i32, primes, logs, nprimes, pset, sub_n, sub_log2, sub_off) == 1 {
            let cur_log: f64 = logs[idx] * (e as f64) + sub_log2[0]
            if best_n < 0 || cur_log < best_log2 {
                best_n = sub_n[0] + 1
                let new_off: i32 = alloc_exps(best_n)
                exps_pool[new_off] = e
                let mut j: i32 = 0
                while j < sub_n[0] {
                    exps_pool[new_off + 1 + j] = exps_pool[sub_off[0] + j]
                    j = j + 1
                }
                best_off = new_off
                best_log2 = cur_log
            }
            found = 1
        }
        free(sub_n as ptr<void>)
        free(sub_log2 as ptr<void>)
        free(sub_off as ptr<void>)
        i = i - 1
    }

    free(divs as ptr<void>)

    if found == 1 {
        out_n[0] = best_n
        out_log2[0] = best_log2
        out_off[0] = best_off
        memo_store(rem, idx, prev_f, pset, 1, best_n, best_log2, best_off)
        return 1
    }
    memo_store(rem, idx, prev_f, pset, 0, 0, 0.0, 0)
    return 0
}

function min_rep_for_product(P: i64, primes: ptr<i32>, logs: ptr<f64>, nprimes: i32, pset: i32, out_n: ptr<i32>, out_log2: ptr<f64>, out_off: ptr<i32>) -> void {
    out_n[0] = -1
    if P == 1 {
        out_n[0] = 0
        out_log2[0] = 0.0
        out_off[0] = 0
        return
    }
    dfs_min_rep(P, 0, P as i32, primes, logs, nprimes, pset, out_n, out_log2, out_off)
}

function best_rep_for_D(D: i64, out_e2: ptr<i64>, out_log2: ptr<f64>, out_rep3_n: ptr<i32>, out_rep3_log2: ptr<f64>, out_rep3_off: ptr<i32>) -> i32 {
    if D == 1 {
        out_e2[0] = 0
        out_rep3_n[0] = 0
        out_rep3_log2[0] = 0.0
        out_rep3_off[0] = 0
        out_log2[0] = 0.0
        return 1
    }

    let mut i: i32 = 0
    while i < d_count {
        if d_keys[i] == D {
            out_e2[0] = d_e2[i]
            out_log2[0] = d_log2[i]
            out_rep3_n[0] = d_rep3_n[i]
            out_rep3_log2[0] = d_rep3_log2[i]
            out_rep3_off[0] = d_rep3_off[i]
            return 1
        }
        i = i + 1
    }

    let divs: ptr<i64> = calloc(20000, 8)
    let nd: i32 = odd_divisors(D, divs)

    let mut best_e2: i64 = -1
    let mut best_log2: f64 = 0.0
    let mut best_rep3_n: i32 = 0
    let mut best_rep3_log2: f64 = 0.0
    let mut best_rep3_off: i32 = 0
    let mut initialized: i32 = 0

    let mut i2: i32 = 0
    while i2 < nd {
        let a2: i64 = divs[i2]
        let e2: i64 = if a2 == 1 { 0 } else { (a2 + 1) / 2 }
        let C: i64 = D / a2
        let rn: ptr<i32> = calloc(1, 4)
        let rl: ptr<f64> = calloc(1, 8)
        let ro: ptr<i32> = calloc(1, 4)
        min_rep_for_product(C, primes_p3, log2_p3, np3, 1, rn, rl, ro)
        if rn[0] >= 0 {
            let cur_log: f64 = log2_2 * (e2 as f64) + rl[0]
            if initialized == 0 || cur_log < best_log2 {
                best_e2 = e2
                best_rep3_n = rn[0]
                best_rep3_log2 = rl[0]
                best_rep3_off = ro[0]
                best_log2 = cur_log
                initialized = 1
            }
        }
        free(rn as ptr<void>)
        free(rl as ptr<void>)
        free(ro as ptr<void>)
        i2 = i2 + 1
    }

    free(divs as ptr<void>)

    if initialized == 1 {
        out_e2[0] = best_e2
        out_log2[0] = best_log2
        out_rep3_n[0] = best_rep3_n
        out_rep3_log2[0] = best_rep3_log2
        out_rep3_off[0] = best_rep3_off

        d_keys[d_count] = D
        d_e2[d_count] = best_e2
        d_log2[d_count] = best_log2
        d_rep3_n[d_count] = best_rep3_n
        d_rep3_log2[d_count] = best_rep3_log2
        d_rep3_off[d_count] = best_rep3_off
        d_count = d_count + 1
        return 1
    }
    return 0
}

function Q_rep(n: i64, out_e2: ptr<i64>, out_rep1_n: ptr<i32>, out_rep1_log2: ptr<f64>, out_rep1_off: ptr<i32>, out_rep3_n: ptr<i32>, out_rep3_log2: ptr<f64>, out_rep3_off: ptr<i32>) -> i32 {
    let mut i: i32 = 0
    while i < q_count {
        if q_keys[i] == n {
            out_e2[0] = q_e2[i]
            out_rep1_n[0] = q_rep1_n[i]
            out_rep1_log2[0] = q_rep1_log2[i]
            out_rep1_off[0] = q_rep1_off[i]
            out_rep3_n[0] = q_rep3_n[i]
            out_rep3_log2[0] = q_rep3_log2[i]
            out_rep3_off[0] = q_rep3_off[i]
            return 1
        }
        i = i + 1
    }

    let S: i64 = n + 1
    let divs: ptr<i64> = calloc(20000, 8)
    let nd: i32 = odd_divisors(S, divs)

    let mut best_e2: i64 = -1
    let mut best_log2: f64 = 0.0
    let mut best_rep1_n: i32 = 0
    let mut best_rep1_log2: f64 = 0.0
    let mut best_rep1_off: i32 = 0
    let mut best_rep3_n: i32 = 0
    let mut best_rep3_log2: f64 = 0.0
    let mut best_rep3_off: i32 = 0
    let mut found: i32 = 0

    let mut i2: i32 = 0
    while i2 < nd {
        let B: i64 = divs[i2]
        let rn: ptr<i32> = calloc(1, 4)
        let rl: ptr<f64> = calloc(1, 8)
        let ro: ptr<i32> = calloc(1, 4)
        min_rep_for_product(B, primes_p1, log2_p1, np1, 0, rn, rl, ro)
        if rn[0] >= 0 {
            let D: i64 = (2 * S) / B - 1
            let de2: ptr<i64> = calloc(1, 8)
            let dl: ptr<f64> = calloc(1, 8)
            let drn: ptr<i32> = calloc(1, 4)
            let drl: ptr<f64> = calloc(1, 8)
            let dro: ptr<i32> = calloc(1, 4)
            if best_rep_for_D(D, de2, dl, drn, drl, dro) == 1 {
                let cur_log: f64 = rl[0] + dl[0]
                if found == 0 || cur_log < best_log2 {
                    found = 1
                    best_rep1_n = rn[0]
                    best_rep1_log2 = rl[0]
                    best_rep1_off = ro[0]
                    best_e2 = de2[0]
                    best_rep3_n = drn[0]
                    best_rep3_log2 = drl[0]
                    best_rep3_off = dro[0]
                    best_log2 = cur_log
                }
            }
            free(de2 as ptr<void>)
            free(dl as ptr<void>)
            free(drn as ptr<void>)
            free(drl as ptr<void>)
            free(dro as ptr<void>)
        }
        free(rn as ptr<void>)
        free(rl as ptr<void>)
        free(ro as ptr<void>)
        i2 = i2 + 1
    }

    free(divs as ptr<void>)

    if found == 1 {
        out_e2[0] = best_e2
        out_rep1_n[0] = best_rep1_n
        out_rep1_log2[0] = best_rep1_log2
        out_rep1_off[0] = best_rep1_off
        out_rep3_n[0] = best_rep3_n
        out_rep3_log2[0] = best_rep3_log2
        out_rep3_off[0] = best_rep3_off

        q_keys[q_count] = n
        q_e2[q_count] = best_e2
        q_rep1_n[q_count] = best_rep1_n
        q_rep1_log2[q_count] = best_rep1_log2
        q_rep1_off[q_count] = best_rep1_off
        q_rep3_n[q_count] = best_rep3_n
        q_rep3_log2[q_count] = best_rep3_log2
        q_rep3_off[q_count] = best_rep3_off
        q_count = q_count + 1
        return 1
    }
    return 0
}

function Q_mod(n: i64) -> i64 {
    let e2: ptr<i64> = calloc(1, 8)
    let r1n: ptr<i32> = calloc(1, 4)
    let r1l: ptr<f64> = calloc(1, 8)
    let r1o: ptr<i32> = calloc(1, 4)
    let r3n: ptr<i32> = calloc(1, 4)
    let r3l: ptr<f64> = calloc(1, 8)
    let r3o: ptr<i32> = calloc(1, 4)
    Q_rep(n, e2, r1n, r1l, r1o, r3n, r3l, r3o)
    let mut r: i64 = 1
    let mut i: i32 = 0
    while i < r1n[0] {
        let pe: i64 = powmod(primes_p1[i] as i64, exps_pool[r1o[0] + i] as i64, MOD)
        r = r * pe % MOD
        i = i + 1
    }
    let p2: i64 = powmod(2, e2[0], MOD)
    r = r * p2 % MOD
    let mut i2: i32 = 0
    while i2 < r3n[0] {
        let pe: i64 = powmod(primes_p3[i2] as i64, exps_pool[r3o[0] + i2] as i64, MOD)
        r = r * pe % MOD
        i2 = i2 + 1
    }
    free(e2 as ptr<void>)
    free(r1n as ptr<void>)
    free(r1l as ptr<void>)
    free(r1o as ptr<void>)
    free(r3n as ptr<void>)
    free(r3l as ptr<void>)
    free(r3o as ptr<void>)
    return r
}


function init_globals() -> void {
    primes_p1 = calloc(200, 4)
    primes_p3 = calloc(200, 4)
    log2_p1 = calloc(200, 8)
    log2_p3 = calloc(200, 8)
    memo_rem = calloc(500000, 8)
    memo_idx = calloc(500000, 4)
    memo_prev_f = calloc(500000, 4)
    memo_pset = calloc(500000, 4)
    memo_valid = calloc(500000, 4)
    memo_n = calloc(500000, 4)
    memo_log2_val = calloc(500000, 8)
    memo_exps_off = calloc(500000, 4)
    exps_pool = calloc(10000000, 4)
    d_keys = calloc(65536, 8)
    d_e2 = calloc(65536, 8)
    d_log2 = calloc(65536, 8)
    d_rep3_n = calloc(65536, 4)
    d_rep3_log2 = calloc(65536, 8)
    d_rep3_off = calloc(65536, 4)
    q_keys = calloc(256, 8)
    q_e2 = calloc(256, 8)
    q_rep1_n = calloc(256, 4)
    q_rep1_log2 = calloc(256, 8)
    q_rep1_off = calloc(256, 4)
    q_rep3_n = calloc(256, 4)
    q_rep3_log2 = calloc(256, 8)
    q_rep3_off = calloc(256, 4)
}

function main() -> i32 {
    init_globals()
    gen_primes()
    let mut total: i64 = 0
    let mut k: i32 = 1
    while k <= 18 {
        let mut n: i64 = 1
        let mut j: i32 = 0
        while j < k {
            n = n * 10
            j = j + 1
        }
        let q: i64 = Q_mod(n)
        total = (total + q) % MOD
        k = k + 1
    }
    printf("%lld\n", total)
    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 mulmod_i64_i64_i64(int64_t a, int64_t b, int64_t m);
int64_t powmod_i64_i64_i64(int64_t a, int64_t d, int64_t n);
int32_t is_prime_u64_i64(int64_t n);
int64_t gcd_u64_i64_i64(int64_t a, int64_t b);
int64_t pollard_rho_i64(int64_t n);
int32_t factorize_i64_ptr_i64_ptr_i32(int64_t n_in, int64_t* fac_p, int32_t* fac_e);
int32_t odd_divisors_i64_ptr_i64(int64_t n, int64_t* out);
void gen_primes(void);
int32_t alloc_exps_i32(int32_t n);
int32_t memo_lookup_i64_i32_i32_i32_ptr_i32_ptr_f64_ptr_i32(int64_t rem, int32_t idx, int32_t prev_f, int32_t pset, int32_t* out_n, double* out_log2, int32_t* out_off);
void memo_store_i64_i32_i32_i32_i32_i32_f64_i32(int64_t rem, int32_t idx, int32_t prev_f, int32_t pset, int32_t valid, int32_t n, double log2_val, int32_t off);
int32_t dfs_min_rep_i64_i32_i32_ptr_i32_ptr_f64_i32_i32_ptr_i32_ptr_f64_ptr_i32(int64_t rem, int32_t idx, int32_t prev_f, int32_t* primes, double* logs, int32_t nprimes, int32_t pset, int32_t* out_n, double* out_log2, int32_t* out_off);
void min_rep_for_product_i64_ptr_i32_ptr_f64_i32_i32_ptr_i32_ptr_f64_ptr_i32(int64_t P, int32_t* primes, double* logs, int32_t nprimes, int32_t pset, int32_t* out_n, double* out_log2, int32_t* out_off);
int32_t best_rep_for_D_i64_ptr_i64_ptr_f64_ptr_i32_ptr_f64_ptr_i32(int64_t D, int64_t* out_e2, double* out_log2, int32_t* out_rep3_n, double* out_rep3_log2, int32_t* out_rep3_off);
int32_t Q_rep_i64_ptr_i64_ptr_i32_ptr_f64_ptr_i32_ptr_i32_ptr_f64_ptr_i32(int64_t n, int64_t* out_e2, int32_t* out_rep1_n, double* out_rep1_log2, int32_t* out_rep1_off, int32_t* out_rep3_n, double* out_rep3_log2, int32_t* out_rep3_off);
int64_t Q_mod_i64(int64_t n);
void init_globals(void);
int32_t main(void);

static const int64_t MOD = 409120391;
static const int32_t MAX_EXPS = 50;
static const int32_t MAX_PRIMES = 80;

/* Module statics */
static int32_t* primes_p1 = ((int32_t*)(0));
static int32_t* primes_p3 = ((int32_t*)(0));
static double* log2_p1 = ((double*)(0));
static double* log2_p3 = ((double*)(0));
static int32_t np1 = 0;
static int32_t np3 = 0;
static double log2_2 = 1.0;
static int64_t* memo_rem = ((int64_t*)(0));
static int32_t* memo_idx = ((int32_t*)(0));
static int32_t* memo_prev_f = ((int32_t*)(0));
static int32_t* memo_pset = ((int32_t*)(0));
static int32_t* memo_valid = ((int32_t*)(0));
static int32_t* memo_n = ((int32_t*)(0));
static double* memo_log2_val = ((double*)(0));
static int32_t* memo_exps_off = ((int32_t*)(0));
static int32_t memo_count = 0;
static int32_t* exps_pool = ((int32_t*)(0));
static int32_t exps_pool_next = 0;
static int64_t* d_keys = ((int64_t*)(0));
static int64_t* d_e2 = ((int64_t*)(0));
static double* d_log2 = ((double*)(0));
static int32_t* d_rep3_n = ((int32_t*)(0));
static double* d_rep3_log2 = ((double*)(0));
static int32_t* d_rep3_off = ((int32_t*)(0));
static int32_t d_count = 0;
static int64_t* q_keys = ((int64_t*)(0));
static int64_t* q_e2 = ((int64_t*)(0));
static int32_t* q_rep1_n = ((int32_t*)(0));
static double* q_rep1_log2 = ((double*)(0));
static int32_t* q_rep1_off = ((int32_t*)(0));
static int32_t* q_rep3_n = ((int32_t*)(0));
static double* q_rep3_log2 = ((double*)(0));
static int32_t* q_rep3_off = ((int32_t*)(0));
static int32_t q_count = 0;






int64_t mulmod_i64_i64_i64(int64_t a, int64_t b, int64_t m) {
    return ((int64_t)(FLOW_CHECKED_MOD(((((__int128)(a)) * ((__int128)(b)))), (((__int128)(m))))));
}

int64_t powmod_i64_i64_i64(int64_t a, int64_t d, int64_t n) {
    int64_t r = 1;
    int64_t aa = FLOW_CHECKED_MOD((a), (n));
    int64_t dd = d;
    while (dd > 0) {
        if ((dd & 1) == 1) {
            r = mulmod_i64_i64_i64(r, aa, n);
        }
        aa = mulmod_i64_i64_i64(aa, aa, n);
        dd = FLOW_CHECKED_SHR((dd), (1));
    }
    return r;
}

int32_t is_prime_u64_i64(int64_t n) {
    if (n < 2) {
        return 0;
    }
    int32_t i = 0;
    while (i < 12) {
        int64_t sp = 0;
        if (i == 0) {
            sp = 2;
        }
        if (i == 1) {
            sp = 3;
        }
        if (i == 2) {
            sp = 5;
        }
        if (i == 3) {
            sp = 7;
        }
        if (i == 4) {
            sp = 11;
        }
        if (i == 5) {
            sp = 13;
        }
        if (i == 6) {
            sp = 17;
        }
        if (i == 7) {
            sp = 19;
        }
        if (i == 8) {
            sp = 23;
        }
        if (i == 9) {
            sp = 29;
        }
        if (i == 10) {
            sp = 31;
        }
        if (i == 11) {
            sp = 37;
        }
        if (n == sp) {
            return 1;
        }
        if (FLOW_CHECKED_MOD((n), (sp)) == 0) {
            return 0;
        }
        i = (i + 1);
    }
    int64_t d = (n - 1);
    int32_t s = 0;
    while (FLOW_CHECKED_MOD((d), (2)) == 0) {
        d = FLOW_CHECKED_DIV((d), (2));
        s = (s + 1);
    }
    int32_t i2 = 0;
    while (i2 < 7) {
        int64_t a = 0;
        if (i2 == 0) {
            a = FLOW_CHECKED_MOD((2), (n));
        }
        if (i2 == 1) {
            a = FLOW_CHECKED_MOD((325), (n));
        }
        if (i2 == 2) {
            a = FLOW_CHECKED_MOD((9375), (n));
        }
        if (i2 == 3) {
            a = FLOW_CHECKED_MOD((28178), (n));
        }
        if (i2 == 4) {
            a = FLOW_CHECKED_MOD((450775), (n));
        }
        if (i2 == 5) {
            a = FLOW_CHECKED_MOD((9780504), (n));
        }
        if (i2 == 6) {
            a = FLOW_CHECKED_MOD((1795265022), (n));
        }
        if (a == 0) {
            i2 = (i2 + 1);
            continue;
        }
        int64_t x = powmod_i64_i64_i64(a, d, n);
        if (x == 1) {
            i2 = (i2 + 1);
            continue;
        }
        if (x == (n - 1)) {
            i2 = (i2 + 1);
            continue;
        }
        int32_t found = 0;
        int32_t j = 0;
        while (j < (s - 1)) {
            x = mulmod_i64_i64_i64(x, x, n);
            if (x == (n - 1)) {
                found = 1;
                break;
            }
            j = (j + 1);
        }
        if (found == 0) {
            return 0;
        }
        i2 = (i2 + 1);
    }
    return 1;
}

int64_t gcd_u64_i64_i64(int64_t a, int64_t b) {
    int64_t x = a;
    int64_t y = b;
    while (y != 0) {
        int64_t t = FLOW_CHECKED_MOD((x), (y));
        x = y;
        y = t;
    }
    return x;
}

int64_t pollard_rho_i64(int64_t n) {
    if (FLOW_CHECKED_MOD((n), (2)) == 0) {
        return 2;
    }
    if (FLOW_CHECKED_MOD((n), (3)) == 0) {
        return 3;
    }
    if (FLOW_CHECKED_MOD((n), (5)) == 0) {
        return 5;
    }
    int32_t ci = 0;
    while (ci < 12) {
        int64_t c = 0;
        if (ci == 0) {
            c = 1;
        }
        if (ci == 1) {
            c = 3;
        }
        if (ci == 2) {
            c = 5;
        }
        if (ci == 3) {
            c = 7;
        }
        if (ci == 4) {
            c = 11;
        }
        if (ci == 5) {
            c = 13;
        }
        if (ci == 6) {
            c = 17;
        }
        if (ci == 7) {
            c = 19;
        }
        if (ci == 8) {
            c = 23;
        }
        if (ci == 9) {
            c = 29;
        }
        if (ci == 10) {
            c = 31;
        }
        if (ci == 11) {
            c = 37;
        }
        int64_t x = 3;
        int64_t y = 3;
        int64_t d = 1;
        while (d == 1) {
            x = FLOW_CHECKED_MOD(((mulmod_i64_i64_i64(x, x, n) + c)), (n));
            y = FLOW_CHECKED_MOD(((mulmod_i64_i64_i64(y, y, n) + c)), (n));
            y = FLOW_CHECKED_MOD(((mulmod_i64_i64_i64(y, y, n) + c)), (n));
            int64_t diff = ((x > y) ? ((x - y)) : ((y - x)));
            d = gcd_u64_i64_i64(diff, n);
        }
        if (d != n) {
            return d;
        }
        ci = (ci + 1);
    }
    return n;
}

int32_t factorize_i64_ptr_i64_ptr_i32(int64_t n_in, int64_t* fac_p, int32_t* fac_e) {
    int64_t n = n_in;
    int32_t nf = 0;
    int32_t i = 0;
    while (i < 12) {
        int64_t sp = 0;
        if (i == 0) {
            sp = 2;
        }
        if (i == 1) {
            sp = 3;
        }
        if (i == 2) {
            sp = 5;
        }
        if (i == 3) {
            sp = 7;
        }
        if (i == 4) {
            sp = 11;
        }
        if (i == 5) {
            sp = 13;
        }
        if (i == 6) {
            sp = 17;
        }
        if (i == 7) {
            sp = 19;
        }
        if (i == 8) {
            sp = 23;
        }
        if (i == 9) {
            sp = 29;
        }
        if (i == 10) {
            sp = 31;
        }
        if (i == 11) {
            sp = 37;
        }
        if (FLOW_CHECKED_MOD((n), (sp)) == 0) {
            int32_t e = 0;
            while (FLOW_CHECKED_MOD((n), (sp)) == 0) {
                n = FLOW_CHECKED_DIV((n), (sp));
                e = (e + 1);
            }
            fac_p[nf] = sp;
            fac_e[nf] = e;
            nf = (nf + 1);
        }
        i = (i + 1);
    }
    int64_t* stack = (int64_t*)(calloc(64, 8));
    int32_t sp2 = 0;
    if (n > 1) {
        stack[sp2] = n;
        sp2 = (sp2 + 1);
    }
    while (sp2 > 0) {
        sp2 = (sp2 - 1);
        int64_t m = stack[sp2];
        if (m == 1) {
            continue;
        }
        if (is_prime_u64_i64(m) == 1) {
            int32_t found = 0;
            int32_t i2 = 0;
            while (i2 < nf) {
                if (fac_p[i2] == m) {
                    fac_e[i2] = (fac_e[i2] + 1);
                    found = 1;
                    break;
                }
                i2 = (i2 + 1);
            }
            if (found == 0) {
                fac_p[nf] = m;
                fac_e[nf] = 1;
                nf = (nf + 1);
            }
            continue;
        }
        int64_t d = pollard_rho_i64(m);
        if (d == m) {
            int32_t found = 0;
            int32_t i3 = 0;
            while (i3 < nf) {
                if (fac_p[i3] == m) {
                    fac_e[i3] = (fac_e[i3] + 1);
                    found = 1;
                    break;
                }
                i3 = (i3 + 1);
            }
            if (found == 0) {
                fac_p[nf] = m;
                fac_e[nf] = 1;
                nf = (nf + 1);
            }
            continue;
        }
        stack[sp2] = d;
        sp2 = (sp2 + 1);
        stack[sp2] = FLOW_CHECKED_DIV((m), (d));
        sp2 = (sp2 + 1);
    }
    free(((void*)(stack)));
    return nf;
}

int32_t odd_divisors_i64_ptr_i64(int64_t n, int64_t* out) {
    int64_t* fac_p = (int64_t*)(calloc(20, 8));
    int32_t* fac_e = (int32_t*)(calloc(20, 4));
    int32_t nf = factorize_i64_ptr_i64_ptr_i32(n, fac_p, fac_e);
    int64_t* odd_p = (int64_t*)(calloc(20, 8));
    int32_t* odd_e = (int32_t*)(calloc(20, 4));
    int32_t onf = 0;
    int32_t i = 0;
    while (i < nf) {
        if (fac_p[i] != 2) {
            odd_p[onf] = fac_p[i];
            odd_e[onf] = fac_e[i];
            onf = (onf + 1);
        }
        i = (i + 1);
    }
    int32_t nd = 1;
    out[0] = 1;
    int32_t i2 = 0;
    while (i2 < onf) {
        int32_t cur = nd;
        int64_t pe = 1;
        int32_t e = 1;
        while (e <= odd_e[i2]) {
            pe = (pe * odd_p[i2]);
            int32_t j = 0;
            while (j < cur) {
                out[nd] = (out[j] * pe);
                nd = (nd + 1);
                j = (j + 1);
            }
            e = (e + 1);
        }
        i2 = (i2 + 1);
    }
    int32_t i3 = 1;
    while (i3 < nd) {
        int64_t key = out[i3];
        int32_t j2 = (i3 - 1);
        while ((j2 >= 0 && out[j2] > key)) {
            out[(j2 + 1)] = out[j2];
            j2 = (j2 - 1);
        }
        out[(j2 + 1)] = key;
        i3 = (i3 + 1);
    }
    free(((void*)(fac_p)));
    free(((void*)(fac_e)));
    free(((void*)(odd_p)));
    free(((void*)(odd_e)));
    return nd;
}

void gen_primes(void) {
    int32_t x = 2;
    while ((np1 < MAX_PRIMES || np3 < MAX_PRIMES)) {
        int32_t is_p = 1;
        int32_t d = 2;
        while ((d * d) <= x) {
            if (FLOW_CHECKED_MOD((x), (d)) == 0) {
                is_p = 0;
                break;
            }
            d = (d + 1);
        }
        if (is_p == 1) {
            if ((FLOW_CHECKED_MOD((x), (4)) == 1 && np1 < MAX_PRIMES)) {
                primes_p1[np1] = x;
                log2_p1[np1] = log2(((double)(x)));
                np1 = (np1 + 1);
            } else {
                if ((FLOW_CHECKED_MOD((x), (4)) == 3 && np3 < MAX_PRIMES)) {
                    primes_p3[np3] = x;
                    log2_p3[np3] = log2(((double)(x)));
                    np3 = (np3 + 1);
                }
            }
        }
        x = (x + 1);
    }
    log2_2 = log2(2.0);
}

int32_t alloc_exps_i32(int32_t n) {
    int32_t off = exps_pool_next;
    exps_pool_next = (exps_pool_next + n);
    return off;
}

int32_t memo_lookup_i64_i32_i32_i32_ptr_i32_ptr_f64_ptr_i32(int64_t rem, int32_t idx, int32_t prev_f, int32_t pset, int32_t* out_n, double* out_log2, int32_t* out_off) {
    int32_t i = 0;
    while (i < memo_count) {
        if ((((memo_rem[i] == rem && memo_idx[i] == idx) && memo_prev_f[i] == prev_f) && memo_pset[i] == pset)) {
            if (memo_valid[i] == 1) {
                out_n[0] = memo_n[i];
                out_log2[0] = memo_log2_val[i];
                out_off[0] = memo_exps_off[i];
                return 1;
            }
            return 0;
        }
        i = (i + 1);
    }
    return (-1);
}

void memo_store_i64_i32_i32_i32_i32_i32_f64_i32(int64_t rem, int32_t idx, int32_t prev_f, int32_t pset, int32_t valid, int32_t n, double log2_val, int32_t off) {
    memo_rem[memo_count] = rem;
    memo_idx[memo_count] = idx;
    memo_prev_f[memo_count] = prev_f;
    memo_pset[memo_count] = pset;
    memo_valid[memo_count] = valid;
    if (valid == 1) {
        memo_n[memo_count] = n;
        memo_log2_val[memo_count] = log2_val;
        memo_exps_off[memo_count] = off;
    }
    memo_count = (memo_count + 1);
}

int32_t dfs_min_rep_i64_i32_i32_ptr_i32_ptr_f64_i32_i32_ptr_i32_ptr_f64_ptr_i32(int64_t rem, int32_t idx, int32_t prev_f, int32_t* primes, double* logs, int32_t nprimes, int32_t pset, int32_t* out_n, double* out_log2, int32_t* out_off) {
    if (rem == 1) {
        out_n[0] = 0;
        out_log2[0] = 0.0;
        out_off[0] = 0;
        return 1;
    }
    if (idx >= nprimes) {
        return 0;
    }
    int32_t* dummy_n = (int32_t*)(calloc(1, 4));
    double* dummy_l = (double*)(calloc(1, 8));
    int32_t* dummy_o = (int32_t*)(calloc(1, 4));
    int32_t cached = memo_lookup_i64_i32_i32_i32_ptr_i32_ptr_f64_ptr_i32(rem, idx, prev_f, pset, dummy_n, dummy_l, dummy_o);
    if (cached >= 0) {
        if (cached == 1) {
            out_n[0] = dummy_n[0];
            out_log2[0] = dummy_l[0];
            out_off[0] = dummy_o[0];
        }
        free(((void*)(dummy_n)));
        free(((void*)(dummy_l)));
        free(((void*)(dummy_o)));
        return cached;
    }
    free(((void*)(dummy_n)));
    free(((void*)(dummy_l)));
    free(((void*)(dummy_o)));
    int64_t* divs = (int64_t*)(calloc(20000, 8));
    int32_t nd = odd_divisors_i64_ptr_i64(rem, divs);
    int32_t best_n = (-1);
    double best_log2 = 0.0;
    int32_t best_off = 0;
    int32_t found = 0;
    int32_t i = (nd - 1);
    while (i >= 0) {
        int64_t f = divs[i];
        if (f == 1) {
            i = (i - 1);
            continue;
        }
        if (f > ((int64_t)(prev_f))) {
            i = (i - 1);
            continue;
        }
        int32_t e = ((int32_t)(FLOW_CHECKED_DIV(((f - 1)), (2))));
        if (e <= 0) {
            i = (i - 1);
            continue;
        }
        int32_t* sub_n = (int32_t*)(calloc(1, 4));
        double* sub_log2 = (double*)(calloc(1, 8));
        int32_t* sub_off = (int32_t*)(calloc(1, 4));
        if (dfs_min_rep_i64_i32_i32_ptr_i32_ptr_f64_i32_i32_ptr_i32_ptr_f64_ptr_i32(FLOW_CHECKED_DIV((rem), (f)), (idx + 1), ((int32_t)(f)), primes, logs, nprimes, pset, sub_n, sub_log2, sub_off) == 1) {
            double cur_log = ((logs[idx] * ((double)(e))) + sub_log2[0]);
            if ((best_n < 0 || cur_log < best_log2)) {
                best_n = (sub_n[0] + 1);
                int32_t new_off = alloc_exps_i32(best_n);
                exps_pool[new_off] = e;
                int32_t j = 0;
                while (j < sub_n[0]) {
                    exps_pool[((new_off + 1) + j)] = exps_pool[(sub_off[0] + j)];
                    j = (j + 1);
                }
                best_off = new_off;
                best_log2 = cur_log;
            }
            found = 1;
        }
        free(((void*)(sub_n)));
        free(((void*)(sub_log2)));
        free(((void*)(sub_off)));
        i = (i - 1);
    }
    free(((void*)(divs)));
    if (found == 1) {
        out_n[0] = best_n;
        out_log2[0] = best_log2;
        out_off[0] = best_off;
        memo_store_i64_i32_i32_i32_i32_i32_f64_i32(rem, idx, prev_f, pset, 1, best_n, best_log2, best_off);
        return 1;
    }
    memo_store_i64_i32_i32_i32_i32_i32_f64_i32(rem, idx, prev_f, pset, 0, 0, 0.0, 0);
    return 0;
}

void min_rep_for_product_i64_ptr_i32_ptr_f64_i32_i32_ptr_i32_ptr_f64_ptr_i32(int64_t P, int32_t* primes, double* logs, int32_t nprimes, int32_t pset, int32_t* out_n, double* out_log2, int32_t* out_off) {
    out_n[0] = (-1);
    if (P == 1) {
        out_n[0] = 0;
        out_log2[0] = 0.0;
        out_off[0] = 0;
        return;
    }
    dfs_min_rep_i64_i32_i32_ptr_i32_ptr_f64_i32_i32_ptr_i32_ptr_f64_ptr_i32(P, 0, ((int32_t)(P)), primes, logs, nprimes, pset, out_n, out_log2, out_off);
}

int32_t best_rep_for_D_i64_ptr_i64_ptr_f64_ptr_i32_ptr_f64_ptr_i32(int64_t D, int64_t* out_e2, double* out_log2, int32_t* out_rep3_n, double* out_rep3_log2, int32_t* out_rep3_off) {
    if (D == 1) {
        out_e2[0] = 0;
        out_rep3_n[0] = 0;
        out_rep3_log2[0] = 0.0;
        out_rep3_off[0] = 0;
        out_log2[0] = 0.0;
        return 1;
    }
    int32_t i = 0;
    while (i < d_count) {
        if (d_keys[i] == D) {
            out_e2[0] = d_e2[i];
            out_log2[0] = d_log2[i];
            out_rep3_n[0] = d_rep3_n[i];
            out_rep3_log2[0] = d_rep3_log2[i];
            out_rep3_off[0] = d_rep3_off[i];
            return 1;
        }
        i = (i + 1);
    }
    int64_t* divs = (int64_t*)(calloc(20000, 8));
    int32_t nd = odd_divisors_i64_ptr_i64(D, divs);
    int64_t best_e2 = (-1);
    double best_log2 = 0.0;
    int32_t best_rep3_n = 0;
    double best_rep3_log2 = 0.0;
    int32_t best_rep3_off = 0;
    int32_t initialized = 0;
    int32_t i2 = 0;
    while (i2 < nd) {
        int64_t a2 = divs[i2];
        int64_t e2 = ((a2 == 1) ? (0) : (FLOW_CHECKED_DIV(((a2 + 1)), (2))));
        int64_t C = FLOW_CHECKED_DIV((D), (a2));
        int32_t* rn = (int32_t*)(calloc(1, 4));
        double* rl = (double*)(calloc(1, 8));
        int32_t* ro = (int32_t*)(calloc(1, 4));
        min_rep_for_product_i64_ptr_i32_ptr_f64_i32_i32_ptr_i32_ptr_f64_ptr_i32(C, primes_p3, log2_p3, np3, 1, rn, rl, ro);
        if (rn[0] >= 0) {
            double cur_log = ((log2_2 * ((double)(e2))) + rl[0]);
            if ((initialized == 0 || cur_log < best_log2)) {
                best_e2 = e2;
                best_rep3_n = rn[0];
                best_rep3_log2 = rl[0];
                best_rep3_off = ro[0];
                best_log2 = cur_log;
                initialized = 1;
            }
        }
        free(((void*)(rn)));
        free(((void*)(rl)));
        free(((void*)(ro)));
        i2 = (i2 + 1);
    }
    free(((void*)(divs)));
    if (initialized == 1) {
        out_e2[0] = best_e2;
        out_log2[0] = best_log2;
        out_rep3_n[0] = best_rep3_n;
        out_rep3_log2[0] = best_rep3_log2;
        out_rep3_off[0] = best_rep3_off;
        d_keys[d_count] = D;
        d_e2[d_count] = best_e2;
        d_log2[d_count] = best_log2;
        d_rep3_n[d_count] = best_rep3_n;
        d_rep3_log2[d_count] = best_rep3_log2;
        d_rep3_off[d_count] = best_rep3_off;
        d_count = (d_count + 1);
        return 1;
    }
    return 0;
}

int32_t Q_rep_i64_ptr_i64_ptr_i32_ptr_f64_ptr_i32_ptr_i32_ptr_f64_ptr_i32(int64_t n, int64_t* out_e2, int32_t* out_rep1_n, double* out_rep1_log2, int32_t* out_rep1_off, int32_t* out_rep3_n, double* out_rep3_log2, int32_t* out_rep3_off) {
    int32_t i = 0;
    while (i < q_count) {
        if (q_keys[i] == n) {
            out_e2[0] = q_e2[i];
            out_rep1_n[0] = q_rep1_n[i];
            out_rep1_log2[0] = q_rep1_log2[i];
            out_rep1_off[0] = q_rep1_off[i];
            out_rep3_n[0] = q_rep3_n[i];
            out_rep3_log2[0] = q_rep3_log2[i];
            out_rep3_off[0] = q_rep3_off[i];
            return 1;
        }
        i = (i + 1);
    }
    int64_t S = (n + 1);
    int64_t* divs = (int64_t*)(calloc(20000, 8));
    int32_t nd = odd_divisors_i64_ptr_i64(S, divs);
    int64_t best_e2 = (-1);
    double best_log2 = 0.0;
    int32_t best_rep1_n = 0;
    double best_rep1_log2 = 0.0;
    int32_t best_rep1_off = 0;
    int32_t best_rep3_n = 0;
    double best_rep3_log2 = 0.0;
    int32_t best_rep3_off = 0;
    int32_t found = 0;
    int32_t i2 = 0;
    while (i2 < nd) {
        int64_t B = divs[i2];
        int32_t* rn = (int32_t*)(calloc(1, 4));
        double* rl = (double*)(calloc(1, 8));
        int32_t* ro = (int32_t*)(calloc(1, 4));
        min_rep_for_product_i64_ptr_i32_ptr_f64_i32_i32_ptr_i32_ptr_f64_ptr_i32(B, primes_p1, log2_p1, np1, 0, rn, rl, ro);
        if (rn[0] >= 0) {
            int64_t D = (FLOW_CHECKED_DIV(((2 * S)), (B)) - 1);
            int64_t* de2 = (int64_t*)(calloc(1, 8));
            double* dl = (double*)(calloc(1, 8));
            int32_t* drn = (int32_t*)(calloc(1, 4));
            double* drl = (double*)(calloc(1, 8));
            int32_t* dro = (int32_t*)(calloc(1, 4));
            if (best_rep_for_D_i64_ptr_i64_ptr_f64_ptr_i32_ptr_f64_ptr_i32(D, de2, dl, drn, drl, dro) == 1) {
                double cur_log = (rl[0] + dl[0]);
                if ((found == 0 || cur_log < best_log2)) {
                    found = 1;
                    best_rep1_n = rn[0];
                    best_rep1_log2 = rl[0];
                    best_rep1_off = ro[0];
                    best_e2 = de2[0];
                    best_rep3_n = drn[0];
                    best_rep3_log2 = drl[0];
                    best_rep3_off = dro[0];
                    best_log2 = cur_log;
                }
            }
            free(((void*)(de2)));
            free(((void*)(dl)));
            free(((void*)(drn)));
            free(((void*)(drl)));
            free(((void*)(dro)));
        }
        free(((void*)(rn)));
        free(((void*)(rl)));
        free(((void*)(ro)));
        i2 = (i2 + 1);
    }
    free(((void*)(divs)));
    if (found == 1) {
        out_e2[0] = best_e2;
        out_rep1_n[0] = best_rep1_n;
        out_rep1_log2[0] = best_rep1_log2;
        out_rep1_off[0] = best_rep1_off;
        out_rep3_n[0] = best_rep3_n;
        out_rep3_log2[0] = best_rep3_log2;
        out_rep3_off[0] = best_rep3_off;
        q_keys[q_count] = n;
        q_e2[q_count] = best_e2;
        q_rep1_n[q_count] = best_rep1_n;
        q_rep1_log2[q_count] = best_rep1_log2;
        q_rep1_off[q_count] = best_rep1_off;
        q_rep3_n[q_count] = best_rep3_n;
        q_rep3_log2[q_count] = best_rep3_log2;
        q_rep3_off[q_count] = best_rep3_off;
        q_count = (q_count + 1);
        return 1;
    }
    return 0;
}

int64_t Q_mod_i64(int64_t n) {
    int64_t* e2 = (int64_t*)(calloc(1, 8));
    int32_t* r1n = (int32_t*)(calloc(1, 4));
    double* r1l = (double*)(calloc(1, 8));
    int32_t* r1o = (int32_t*)(calloc(1, 4));
    int32_t* r3n = (int32_t*)(calloc(1, 4));
    double* r3l = (double*)(calloc(1, 8));
    int32_t* r3o = (int32_t*)(calloc(1, 4));
    Q_rep_i64_ptr_i64_ptr_i32_ptr_f64_ptr_i32_ptr_i32_ptr_f64_ptr_i32(n, e2, r1n, r1l, r1o, r3n, r3l, r3o);
    int64_t r = 1;
    int32_t i = 0;
    while (i < r1n[0]) {
        int64_t pe = powmod_i64_i64_i64(((int64_t)(primes_p1[i])), ((int64_t)(exps_pool[(r1o[0] + i)])), MOD);
        r = FLOW_CHECKED_MOD(((r * pe)), (MOD));
        i = (i + 1);
    }
    int64_t p2 = powmod_i64_i64_i64(2, e2[0], MOD);
    r = FLOW_CHECKED_MOD(((r * p2)), (MOD));
    int32_t i2 = 0;
    while (i2 < r3n[0]) {
        int64_t pe = powmod_i64_i64_i64(((int64_t)(primes_p3[i2])), ((int64_t)(exps_pool[(r3o[0] + i2)])), MOD);
        r = FLOW_CHECKED_MOD(((r * pe)), (MOD));
        i2 = (i2 + 1);
    }
    free(((void*)(e2)));
    free(((void*)(r1n)));
    free(((void*)(r1l)));
    free(((void*)(r1o)));
    free(((void*)(r3n)));
    free(((void*)(r3l)));
    free(((void*)(r3o)));
    return r;
}

void init_globals(void) {
    primes_p1 = calloc(200, 4);
    primes_p3 = calloc(200, 4);
    log2_p1 = calloc(200, 8);
    log2_p3 = calloc(200, 8);
    memo_rem = calloc(500000, 8);
    memo_idx = calloc(500000, 4);
    memo_prev_f = calloc(500000, 4);
    memo_pset = calloc(500000, 4);
    memo_valid = calloc(500000, 4);
    memo_n = calloc(500000, 4);
    memo_log2_val = calloc(500000, 8);
    memo_exps_off = calloc(500000, 4);
    exps_pool = calloc(10000000, 4);
    d_keys = calloc(65536, 8);
    d_e2 = calloc(65536, 8);
    d_log2 = calloc(65536, 8);
    d_rep3_n = calloc(65536, 4);
    d_rep3_log2 = calloc(65536, 8);
    d_rep3_off = calloc(65536, 4);
    q_keys = calloc(256, 8);
    q_e2 = calloc(256, 8);
    q_rep1_n = calloc(256, 4);
    q_rep1_log2 = calloc(256, 8);
    q_rep1_off = calloc(256, 4);
    q_rep3_n = calloc(256, 4);
    q_rep3_log2 = calloc(256, 8);
    q_rep3_off = calloc(256, 4);
}

int32_t main(void) {
    init_globals();
    gen_primes();
    int64_t total = 0;
    int32_t k = 1;
    while (k <= 18) {
        int64_t n = 1;
        int32_t j = 0;
        while (j < k) {
            n = (n * 10);
            j = (j + 1);
        }
        int64_t q = Q_mod_i64(n);
        total = FLOW_CHECKED_MOD(((total + q)), (MOD));
        k = (k + 1);
    }
    printf("%lld\n", total);
    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 private @log2(f64) -> f64
  func.func private @sqrt(f64) -> f64
  // Constant: MOD
  llvm.mlir.global internal constant @MOD(409120391 : i64) : i64
  // Constant: MAX_EXPS
  llvm.mlir.global internal constant @MAX_EXPS(50 : i32) : i32
  // Constant: MAX_PRIMES
  llvm.mlir.global internal constant @MAX_PRIMES(80 : i32) : i32
  // Module static: primes_p1
  llvm.mlir.global internal @primes_p1() {addr_space = 0 : i32} : !llvm.ptr {
    %0 = llvm.mlir.zero : !llvm.ptr
    llvm.return %0 : !llvm.ptr
  }
  // Module static: primes_p3
  llvm.mlir.global internal @primes_p3() {addr_space = 0 : i32} : !llvm.ptr {
    %1 = llvm.mlir.zero : !llvm.ptr
    llvm.return %1 : !llvm.ptr
  }
  // Module static: log2_p1
  llvm.mlir.global internal @log2_p1() {addr_space = 0 : i32} : !llvm.ptr {
    %2 = llvm.mlir.zero : !llvm.ptr
    llvm.return %2 : !llvm.ptr
  }
  // Module static: log2_p3
  llvm.mlir.global internal @log2_p3() {addr_space = 0 : i32} : !llvm.ptr {
    %3 = llvm.mlir.zero : !llvm.ptr
    llvm.return %3 : !llvm.ptr
  }
  // Module static: np1
  llvm.mlir.global internal @np1(0 : i32) : i32
  // Module static: np3
  llvm.mlir.global internal @np3(0 : i32) : i32
  // Module static: log2_2
  llvm.mlir.global internal @log2_2(1.0 : f64) : f64
  // Module static: memo_rem
  llvm.mlir.global internal @memo_rem() {addr_space = 0 : i32} : !llvm.ptr {
    %4 = llvm.mlir.zero : !llvm.ptr
    llvm.return %4 : !llvm.ptr
  }
  // Module static: memo_idx
  llvm.mlir.global internal @memo_idx() {addr_space = 0 : i32} : !llvm.ptr {
    %5 = llvm.mlir.zero : !llvm.ptr
    llvm.return %5 : !llvm.ptr
  }
  // Module static: memo_prev_f
  llvm.mlir.global internal @memo_prev_f() {addr_space = 0 : i32} : !llvm.ptr {
    %6 = llvm.mlir.zero : !llvm.ptr
    llvm.return %6 : !llvm.ptr
  }
  // Module static: memo_pset
  llvm.mlir.global internal @memo_pset() {addr_space = 0 : i32} : !llvm.ptr {
    %7 = llvm.mlir.zero : !llvm.ptr
    llvm.return %7 : !llvm.ptr
  }
  // Module static: memo_valid
  llvm.mlir.global internal @memo_valid() {addr_space = 0 : i32} : !llvm.ptr {
    %8 = llvm.mlir.zero : !llvm.ptr
    llvm.return %8 : !llvm.ptr
  }
  // Module static: memo_n
  llvm.mlir.global internal @memo_n() {addr_space = 0 : i32} : !llvm.ptr {
    %9 = llvm.mlir.zero : !llvm.ptr
    llvm.return %9 : !llvm.ptr
  }
  // Module static: memo_log2_val
  llvm.mlir.global internal @memo_log2_val() {addr_space = 0 : i32} : !llvm.ptr {
    %10 = llvm.mlir.zero : !llvm.ptr
    llvm.return %10 : !llvm.ptr
  }
  // Module static: memo_exps_off
  llvm.mlir.global internal @memo_exps_off() {addr_space = 0 : i32} : !llvm.ptr {
    %11 = llvm.mlir.zero : !llvm.ptr
    llvm.return %11 : !llvm.ptr
  }
  // Module static: memo_count
  llvm.mlir.global internal @memo_count(0 : i32) : i32
  // Module static: exps_pool
  llvm.mlir.global internal @exps_pool() {addr_space = 0 : i32} : !llvm.ptr {
    %12 = llvm.mlir.zero : !llvm.ptr
    llvm.return %12 : !llvm.ptr
  }
  // Module static: exps_pool_next
  llvm.mlir.global internal @exps_pool_next(0 : i32) : i32
  // Module static: d_keys
  llvm.mlir.global internal @d_keys() {addr_space = 0 : i32} : !llvm.ptr {
    %13 = llvm.mlir.zero : !llvm.ptr
    llvm.return %13 : !llvm.ptr
  }
  // Module static: d_e2
  llvm.mlir.global internal @d_e2() {addr_space = 0 : i32} : !llvm.ptr {
    %14 = llvm.mlir.zero : !llvm.ptr
    llvm.return %14 : !llvm.ptr
  }
  // Module static: d_log2
  llvm.mlir.global internal @d_log2() {addr_space = 0 : i32} : !llvm.ptr {
    %15 = llvm.mlir.zero : !llvm.ptr
    llvm.return %15 : !llvm.ptr
  }
  // Module static: d_rep3_n
  llvm.mlir.global internal @d_rep3_n() {addr_space = 0 : i32} : !llvm.ptr {
    %16 = llvm.mlir.zero : !llvm.ptr
    llvm.return %16 : !llvm.ptr
  }
  // Module static: d_rep3_log2
  llvm.mlir.global internal @d_rep3_log2() {addr_space = 0 : i32} : !llvm.ptr {
    %17 = llvm.mlir.zero : !llvm.ptr
    llvm.return %17 : !llvm.ptr
  }
  // Module static: d_rep3_off
  llvm.mlir.global internal @d_rep3_off() {addr_space = 0 : i32} : !llvm.ptr {
    %18 = llvm.mlir.zero : !llvm.ptr
    llvm.return %18 : !llvm.ptr
  }
  // Module static: d_count
  llvm.mlir.global internal @d_count(0 : i32) : i32
  // Module static: q_keys
  llvm.mlir.global internal @q_keys() {addr_space = 0 : i32} : !llvm.ptr {
    %19 = llvm.mlir.zero : !llvm.ptr
    llvm.return %19 : !llvm.ptr
  }
  // Module static: q_e2
  llvm.mlir.global internal @q_e2() {addr_space = 0 : i32} : !llvm.ptr {
    %20 = llvm.mlir.zero : !llvm.ptr
    llvm.return %20 : !llvm.ptr
  }
  // Module static: q_rep1_n
  llvm.mlir.global internal @q_rep1_n() {addr_space = 0 : i32} : !llvm.ptr {
    %21 = llvm.mlir.zero : !llvm.ptr
    llvm.return %21 : !llvm.ptr
  }
  // Module static: q_rep1_log2
  llvm.mlir.global internal @q_rep1_log2() {addr_space = 0 : i32} : !llvm.ptr {
    %22 = llvm.mlir.zero : !llvm.ptr
    llvm.return %22 : !llvm.ptr
  }
  // Module static: q_rep1_off
  llvm.mlir.global internal @q_rep1_off() {addr_space = 0 : i32} : !llvm.ptr {
    %23 = llvm.mlir.zero : !llvm.ptr
    llvm.return %23 : !llvm.ptr
  }
  // Module static: q_rep3_n
  llvm.mlir.global internal @q_rep3_n() {addr_space = 0 : i32} : !llvm.ptr {
    %24 = llvm.mlir.zero : !llvm.ptr
    llvm.return %24 : !llvm.ptr
  }
  // Module static: q_rep3_log2
  llvm.mlir.global internal @q_rep3_log2() {addr_space = 0 : i32} : !llvm.ptr {
    %25 = llvm.mlir.zero : !llvm.ptr
    llvm.return %25 : !llvm.ptr
  }
  // Module static: q_rep3_off
  llvm.mlir.global internal @q_rep3_off() {addr_space = 0 : i32} : !llvm.ptr {
    %26 = llvm.mlir.zero : !llvm.ptr
    llvm.return %26 : !llvm.ptr
  }
  // Module static: q_count
  llvm.mlir.global internal @q_count(0 : i32) : i32
  func.func @mulmod(%arg0: i64, %arg1: i64, %arg2: i64) -> i64 {
    %27 = arith.extsi %arg0 : i64 to i128
    %28 = arith.extsi %arg1 : i64 to i128
    %30 = arith.trunci %27 : i128 to i64
    %31 = arith.trunci %28 : i128 to i64
    %29 = arith.muli %30, %31 : i64
    %32 = arith.extsi %arg2 : i64 to i128
    %34 = arith.trunci %32 : i128 to i64
    %33 = arith.remsi %29, %34 : i64
    func.return %33 : i64
  }
  func.func @powmod(%arg0: i64, %arg1: i64, %arg2: i64) -> i64 {
    %35 = arith.constant 1 : i32
    %36 = arith.extsi %35 : i32 to i64
    %37 = llvm.mlir.constant(1 : i64) : i64
    %38 = llvm.alloca %37 x i64 : (i64) -> !llvm.ptr
    llvm.store %36, %38 : i64, !llvm.ptr
    %39 = arith.remsi %arg0, %arg2 : i64
    %40 = llvm.mlir.constant(1 : i64) : i64
    %41 = llvm.alloca %40 x i64 : (i64) -> !llvm.ptr
    llvm.store %39, %41 : i64, !llvm.ptr
    %42 = llvm.mlir.constant(1 : i64) : i64
    %43 = llvm.alloca %42 x i64 : (i64) -> !llvm.ptr
    llvm.store %arg1, %43 : i64, !llvm.ptr
    cf.br ^bb0
    ^bb0:
    %44 = llvm.load %43 : !llvm.ptr -> i64
    %45 = arith.constant 0 : i32
    %47 = arith.extsi %45 : i32 to i64
    %46 = arith.cmpi sgt, %44, %47 : i64
    cf.cond_br %46, ^bb1, ^bb2
    ^bb1:
      %48 = llvm.load %43 : !llvm.ptr -> i64
      %49 = arith.constant 1 : i32
      %51 = arith.extsi %49 : i32 to i64
      %50 = arith.andi %48, %51 : i64
      %52 = arith.constant 1 : i32
      %54 = arith.extsi %52 : i32 to i64
      %53 = arith.cmpi eq, %50, %54 : i64
      cf.cond_br %53, ^bb3, ^bb4
      ^bb3:
        %56 = llvm.load %38 : !llvm.ptr -> i64
        %57 = llvm.load %41 : !llvm.ptr -> i64
        %55 = func.call @mulmod(%56, %57, %arg2) : (i64, i64, i64) -> i64
        llvm.store %55, %38 : i64, !llvm.ptr
        cf.br ^bb5
      ^bb4:
        cf.br ^bb5
      ^bb5:
      %59 = llvm.load %41 : !llvm.ptr -> i64
      %60 = llvm.load %41 : !llvm.ptr -> i64
      %58 = func.call @mulmod(%59, %60, %arg2) : (i64, i64, i64) -> i64
      llvm.store %58, %41 : i64, !llvm.ptr
      %61 = llvm.load %43 : !llvm.ptr -> i64
      %62 = arith.constant 1 : i32
      %64 = arith.extsi %62 : i32 to i64
      %63 = arith.shrsi %61, %64 : i64
      llvm.store %63, %43 : i64, !llvm.ptr
      cf.br ^bb0
    ^bb2:
    %65 = llvm.load %38 : !llvm.ptr -> i64
    func.return %65 : i64
  }
  func.func @is_prime_u64(%arg0: i64) -> i32 {
    %66 = arith.constant 2 : i32
    %68 = arith.extsi %66 : i32 to i64
    %67 = arith.cmpi slt, %arg0, %68 : i64
    cf.cond_br %67, ^bb6, ^bb7
    ^bb6:
      %69 = arith.constant 0 : i32
      func.return %69 : i32
    ^bb7:
      cf.br ^bb8
    ^bb8:
    %70 = arith.constant 0 : i32
    %71 = llvm.mlir.constant(1 : i64) : i64
    %72 = llvm.alloca %71 x i32 : (i64) -> !llvm.ptr
    llvm.store %70, %72 : i32, !llvm.ptr
    cf.br ^bb9
    ^bb9:
    %73 = llvm.load %72 : !llvm.ptr -> i32
    %74 = arith.constant 12 : i32
    %75 = arith.cmpi slt, %73, %74 : i32
    cf.cond_br %75, ^bb10, ^bb11
    ^bb10:
      %76 = arith.constant 0 : i32
      %77 = arith.extsi %76 : i32 to i64
      %78 = llvm.load %72 : !llvm.ptr -> i32
      %79 = arith.constant 0 : i32
      %80 = arith.cmpi eq, %78, %79 : i32
      %81 = scf.if %80 -> (i64) {
        %82 = arith.constant 2 : i32
        %83 = arith.extsi %82 : i32 to i64
        scf.yield %83 : i64
      } else {
        scf.yield %77 : i64
      }
      %84 = llvm.load %72 : !llvm.ptr -> i32
      %85 = arith.constant 1 : i32
      %86 = arith.cmpi eq, %84, %85 : i32
      %87 = scf.if %86 -> (i64) {
        %88 = arith.constant 3 : i32
        %89 = arith.extsi %88 : i32 to i64
        scf.yield %89 : i64
      } else {
        scf.yield %81 : i64
      }
      %90 = llvm.load %72 : !llvm.ptr -> i32
      %91 = arith.constant 2 : i32
      %92 = arith.cmpi eq, %90, %91 : i32
      %93 = scf.if %92 -> (i64) {
        %94 = arith.constant 5 : i32
        %95 = arith.extsi %94 : i32 to i64
        scf.yield %95 : i64
      } else {
        scf.yield %87 : i64
      }
      %96 = llvm.load %72 : !llvm.ptr -> i32
      %97 = arith.constant 3 : i32
      %98 = arith.cmpi eq, %96, %97 : i32
      %99 = scf.if %98 -> (i64) {
        %100 = arith.constant 7 : i32
        %101 = arith.extsi %100 : i32 to i64
        scf.yield %101 : i64
      } else {
        scf.yield %93 : i64
      }
      %102 = llvm.load %72 : !llvm.ptr -> i32
      %103 = arith.constant 4 : i32
      %104 = arith.cmpi eq, %102, %103 : i32
      %105 = scf.if %104 -> (i64) {
        %106 = arith.constant 11 : i32
        %107 = arith.extsi %106 : i32 to i64
        scf.yield %107 : i64
      } else {
        scf.yield %99 : i64
      }
      %108 = llvm.load %72 : !llvm.ptr -> i32
      %109 = arith.constant 5 : i32
      %110 = arith.cmpi eq, %108, %109 : i32
      %111 = scf.if %110 -> (i64) {
        %112 = arith.constant 13 : i32
        %113 = arith.extsi %112 : i32 to i64
        scf.yield %113 : i64
      } else {
        scf.yield %105 : i64
      }
      %114 = llvm.load %72 : !llvm.ptr -> i32
      %115 = arith.constant 6 : i32
      %116 = arith.cmpi eq, %114, %115 : i32
      %117 = scf.if %116 -> (i64) {
        %118 = arith.constant 17 : i32
        %119 = arith.extsi %118 : i32 to i64
        scf.yield %119 : i64
      } else {
        scf.yield %111 : i64
      }
      %120 = llvm.load %72 : !llvm.ptr -> i32
      %121 = arith.constant 7 : i32
      %122 = arith.cmpi eq, %120, %121 : i32
      %123 = scf.if %122 -> (i64) {
        %124 = arith.constant 19 : i32
        %125 = arith.extsi %124 : i32 to i64
        scf.yield %125 : i64
      } else {
        scf.yield %117 : i64
      }
      %126 = llvm.load %72 : !llvm.ptr -> i32
      %127 = arith.constant 8 : i32
      %128 = arith.cmpi eq, %126, %127 : i32
      %129 = scf.if %128 -> (i64) {
        %130 = arith.constant 23 : i32
        %131 = arith.extsi %130 : i32 to i64
        scf.yield %131 : i64
      } else {
        scf.yield %123 : i64
      }
      %132 = llvm.load %72 : !llvm.ptr -> i32
      %133 = arith.constant 9 : i32
      %134 = arith.cmpi eq, %132, %133 : i32
      %135 = scf.if %134 -> (i64) {
        %136 = arith.constant 29 : i32
        %137 = arith.extsi %136 : i32 to i64
        scf.yield %137 : i64
      } else {
        scf.yield %129 : i64
      }
      %138 = llvm.load %72 : !llvm.ptr -> i32
      %139 = arith.constant 10 : i32
      %140 = arith.cmpi eq, %138, %139 : i32
      %141 = scf.if %140 -> (i64) {
        %142 = arith.constant 31 : i32
        %143 = arith.extsi %142 : i32 to i64
        scf.yield %143 : i64
      } else {
        scf.yield %135 : i64
      }
      %144 = llvm.load %72 : !llvm.ptr -> i32
      %145 = arith.constant 11 : i32
      %146 = arith.cmpi eq, %144, %145 : i32
      %147 = scf.if %146 -> (i64) {
        %148 = arith.constant 37 : i32
        %149 = arith.extsi %148 : i32 to i64
        scf.yield %149 : i64
      } else {
        scf.yield %141 : i64
      }
      %150 = arith.cmpi eq, %arg0, %147 : i64
      cf.cond_br %150, ^bb12, ^bb13
      ^bb12:
        %151 = arith.constant 1 : i32
        func.return %151 : i32
      ^bb13:
        cf.br ^bb14
      ^bb14:
      %152 = arith.remsi %arg0, %147 : i64
      %153 = arith.constant 0 : i32
      %155 = arith.extsi %153 : i32 to i64
      %154 = arith.cmpi eq, %152, %155 : i64
      cf.cond_br %154, ^bb15, ^bb16
      ^bb15:
        %156 = arith.constant 0 : i32
        func.return %156 : i32
      ^bb16:
        cf.br ^bb17
      ^bb17:
      %157 = llvm.load %72 : !llvm.ptr -> i32
      %158 = arith.constant 1 : i32
      %159 = arith.addi %157, %158 : i32
      llvm.store %159, %72 : i32, !llvm.ptr
      cf.br ^bb9
    ^bb11:
    %160 = arith.constant 1 : i32
    %162 = arith.extsi %160 : i32 to i64
    %161 = arith.subi %arg0, %162 : i64
    %163 = llvm.mlir.constant(1 : i64) : i64
    %164 = llvm.alloca %163 x i64 : (i64) -> !llvm.ptr
    llvm.store %161, %164 : i64, !llvm.ptr
    %165 = arith.constant 0 : i32
    %166 = llvm.mlir.constant(1 : i64) : i64
    %167 = llvm.alloca %166 x i32 : (i64) -> !llvm.ptr
    llvm.store %165, %167 : i32, !llvm.ptr
    cf.br ^bb18
    ^bb18:
    %168 = llvm.load %164 : !llvm.ptr -> i64
    %169 = arith.constant 2 : i32
    %171 = arith.extsi %169 : i32 to i64
    %170 = arith.remsi %168, %171 : i64
    %172 = arith.constant 0 : i32
    %174 = arith.extsi %172 : i32 to i64
    %173 = arith.cmpi eq, %170, %174 : i64
    cf.cond_br %173, ^bb19, ^bb20
    ^bb19:
      %175 = llvm.load %164 : !llvm.ptr -> i64
      %176 = arith.constant 2 : i32
      %178 = arith.extsi %176 : i32 to i64
      %177 = arith.divsi %175, %178 : i64
      llvm.store %177, %164 : i64, !llvm.ptr
      %179 = llvm.load %167 : !llvm.ptr -> i32
      %180 = arith.constant 1 : i32
      %181 = arith.addi %179, %180 : i32
      llvm.store %181, %167 : i32, !llvm.ptr
      cf.br ^bb18
    ^bb20:
    %182 = arith.constant 0 : i32
    %183 = llvm.mlir.constant(1 : i64) : i64
    %184 = llvm.alloca %183 x i32 : (i64) -> !llvm.ptr
    llvm.store %182, %184 : i32, !llvm.ptr
    cf.br ^bb21
    ^bb21:
    %185 = llvm.load %184 : !llvm.ptr -> i32
    %186 = arith.constant 7 : i32
    %187 = arith.cmpi slt, %185, %186 : i32
    cf.cond_br %187, ^bb22, ^bb23
    ^bb22:
      %188 = arith.constant 0 : i32
      %189 = arith.extsi %188 : i32 to i64
      %190 = llvm.load %184 : !llvm.ptr -> i32
      %191 = arith.constant 0 : i32
      %192 = arith.cmpi eq, %190, %191 : i32
      %193 = scf.if %192 -> (i64) {
        %194 = arith.constant 2 : i32
        %196 = arith.extsi %194 : i32 to i64
        %195 = arith.remsi %196, %arg0 : i64
        scf.yield %195 : i64
      } else {
        scf.yield %189 : i64
      }
      %197 = llvm.load %184 : !llvm.ptr -> i32
      %198 = arith.constant 1 : i32
      %199 = arith.cmpi eq, %197, %198 : i32
      %200 = scf.if %199 -> (i64) {
        %201 = arith.constant 325 : i32
        %203 = arith.extsi %201 : i32 to i64
        %202 = arith.remsi %203, %arg0 : i64
        scf.yield %202 : i64
      } else {
        scf.yield %193 : i64
      }
      %204 = llvm.load %184 : !llvm.ptr -> i32
      %205 = arith.constant 2 : i32
      %206 = arith.cmpi eq, %204, %205 : i32
      %207 = scf.if %206 -> (i64) {
        %208 = arith.constant 9375 : i32
        %210 = arith.extsi %208 : i32 to i64
        %209 = arith.remsi %210, %arg0 : i64
        scf.yield %209 : i64
      } else {
        scf.yield %200 : i64
      }
      %211 = llvm.load %184 : !llvm.ptr -> i32
      %212 = arith.constant 3 : i32
      %213 = arith.cmpi eq, %211, %212 : i32
      %214 = scf.if %213 -> (i64) {
        %215 = arith.constant 28178 : i32
        %217 = arith.extsi %215 : i32 to i64
        %216 = arith.remsi %217, %arg0 : i64
        scf.yield %216 : i64
      } else {
        scf.yield %207 : i64
      }
      %218 = llvm.load %184 : !llvm.ptr -> i32
      %219 = arith.constant 4 : i32
      %220 = arith.cmpi eq, %218, %219 : i32
      %221 = scf.if %220 -> (i64) {
        %222 = arith.constant 450775 : i32
        %224 = arith.extsi %222 : i32 to i64
        %223 = arith.remsi %224, %arg0 : i64
        scf.yield %223 : i64
      } else {
        scf.yield %214 : i64
      }
      %225 = llvm.load %184 : !llvm.ptr -> i32
      %226 = arith.constant 5 : i32
      %227 = arith.cmpi eq, %225, %226 : i32
      %228 = scf.if %227 -> (i64) {
        %229 = arith.constant 9780504 : i32
        %231 = arith.extsi %229 : i32 to i64
        %230 = arith.remsi %231, %arg0 : i64
        scf.yield %230 : i64
      } else {
        scf.yield %221 : i64
      }
      %232 = llvm.load %184 : !llvm.ptr -> i32
      %233 = arith.constant 6 : i32
      %234 = arith.cmpi eq, %232, %233 : i32
      %235 = scf.if %234 -> (i64) {
        %236 = arith.constant 1795265022 : i32
        %238 = arith.extsi %236 : i32 to i64
        %237 = arith.remsi %238, %arg0 : i64
        scf.yield %237 : i64
      } else {
        scf.yield %228 : i64
      }
      %239 = arith.constant 0 : i32
      %241 = arith.extsi %239 : i32 to i64
      %240 = arith.cmpi eq, %235, %241 : i64
      cf.cond_br %240, ^bb24, ^bb25
      ^bb24:
        %242 = llvm.load %184 : !llvm.ptr -> i32
        %243 = arith.constant 1 : i32
        %244 = arith.addi %242, %243 : i32
        llvm.store %244, %184 : i32, !llvm.ptr
        cf.br ^bb21
      ^bb25:
        cf.br ^bb26
      ^bb26:
      %246 = llvm.load %164 : !llvm.ptr -> i64
      %245 = func.call @powmod(%235, %246, %arg0) : (i64, i64, i64) -> i64
      %247 = llvm.mlir.constant(1 : i64) : i64
      %248 = llvm.alloca %247 x i64 : (i64) -> !llvm.ptr
      llvm.store %245, %248 : i64, !llvm.ptr
      %249 = llvm.load %248 : !llvm.ptr -> i64
      %250 = arith.constant 1 : i32
      %252 = arith.extsi %250 : i32 to i64
      %251 = arith.cmpi eq, %249, %252 : i64
      cf.cond_br %251, ^bb27, ^bb28
      ^bb27:
        %253 = llvm.load %184 : !llvm.ptr -> i32
        %254 = arith.constant 1 : i32
        %255 = arith.addi %253, %254 : i32
        llvm.store %255, %184 : i32, !llvm.ptr
        cf.br ^bb21
      ^bb28:
        cf.br ^bb29
      ^bb29:
      %256 = llvm.load %248 : !llvm.ptr -> i64
      %257 = arith.constant 1 : i32
      %259 = arith.extsi %257 : i32 to i64
      %258 = arith.subi %arg0, %259 : i64
      %260 = arith.cmpi eq, %256, %258 : i64
      cf.cond_br %260, ^bb30, ^bb31
      ^bb30:
        %261 = llvm.load %184 : !llvm.ptr -> i32
        %262 = arith.constant 1 : i32
        %263 = arith.addi %261, %262 : i32
        llvm.store %263, %184 : i32, !llvm.ptr
        cf.br ^bb21
      ^bb31:
        cf.br ^bb32
      ^bb32:
      %264 = arith.constant 0 : i32
      %265 = llvm.mlir.constant(1 : i64) : i64
      %266 = llvm.alloca %265 x i32 : (i64) -> !llvm.ptr
      llvm.store %264, %266 : i32, !llvm.ptr
      %267 = arith.constant 0 : i32
      %268 = llvm.mlir.constant(1 : i64) : i64
      %269 = llvm.alloca %268 x i32 : (i64) -> !llvm.ptr
      llvm.store %267, %269 : i32, !llvm.ptr
      cf.br ^bb33
      ^bb33:
      %270 = llvm.load %269 : !llvm.ptr -> i32
      %271 = llvm.load %167 : !llvm.ptr -> i32
      %272 = arith.constant 1 : i32
      %273 = arith.subi %271, %272 : i32
      %274 = arith.cmpi slt, %270, %273 : i32
      cf.cond_br %274, ^bb34, ^bb35
      ^bb34:
        %276 = llvm.load %248 : !llvm.ptr -> i64
        %277 = llvm.load %248 : !llvm.ptr -> i64
        %275 = func.call @mulmod(%276, %277, %arg0) : (i64, i64, i64) -> i64
        llvm.store %275, %248 : i64, !llvm.ptr
        %278 = llvm.load %248 : !llvm.ptr -> i64
        %279 = arith.constant 1 : i32
        %281 = arith.extsi %279 : i32 to i64
        %280 = arith.subi %arg0, %281 : i64
        %282 = arith.cmpi eq, %278, %280 : i64
        cf.cond_br %282, ^bb36, ^bb37
        ^bb36:
          %283 = arith.constant 1 : i32
          llvm.store %283, %266 : i32, !llvm.ptr
          cf.br ^bb35
        ^bb37:
          cf.br ^bb38
        ^bb38:
        %284 = llvm.load %269 : !llvm.ptr -> i32
        %285 = arith.constant 1 : i32
        %286 = arith.addi %284, %285 : i32
        llvm.store %286, %269 : i32, !llvm.ptr
        cf.br ^bb33
      ^bb35:
      %287 = llvm.load %266 : !llvm.ptr -> i32
      %288 = arith.constant 0 : i32
      %289 = arith.cmpi eq, %287, %288 : i32
      cf.cond_br %289, ^bb39, ^bb40
      ^bb39:
        %290 = arith.constant 0 : i32
        func.return %290 : i32
      ^bb40:
        cf.br ^bb41
      ^bb41:
      %291 = llvm.load %184 : !llvm.ptr -> i32
      %292 = arith.constant 1 : i32
      %293 = arith.addi %291, %292 : i32
      llvm.store %293, %184 : i32, !llvm.ptr
      cf.br ^bb21
    ^bb23:
    %294 = arith.constant 1 : i32
    func.return %294 : i32
  }
  func.func @gcd_u64(%arg0: i64, %arg1: i64) -> i64 {
    %295 = llvm.mlir.constant(1 : i64) : i64
    %296 = llvm.alloca %295 x i64 : (i64) -> !llvm.ptr
    llvm.store %arg0, %296 : i64, !llvm.ptr
    %297 = llvm.mlir.constant(1 : i64) : i64
    %298 = llvm.alloca %297 x i64 : (i64) -> !llvm.ptr
    llvm.store %arg1, %298 : i64, !llvm.ptr
    cf.br ^bb42
    ^bb42:
    %299 = llvm.load %298 : !llvm.ptr -> i64
    %300 = arith.constant 0 : i32
    %302 = arith.extsi %300 : i32 to i64
    %301 = arith.cmpi ne, %299, %302 : i64
    cf.cond_br %301, ^bb43, ^bb44
    ^bb43:
      %303 = llvm.load %296 : !llvm.ptr -> i64
      %304 = llvm.load %298 : !llvm.ptr -> i64
      %305 = arith.remsi %303, %304 : i64
      %306 = llvm.load %298 : !llvm.ptr -> i64
      llvm.store %306, %296 : i64, !llvm.ptr
      llvm.store %305, %298 : i64, !llvm.ptr
      cf.br ^bb42
    ^bb44:
    %307 = llvm.load %296 : !llvm.ptr -> i64
    func.return %307 : i64
  }
  func.func @pollard_rho(%arg0: i64) -> i64 {
    %308 = arith.constant 2 : i32
    %310 = arith.extsi %308 : i32 to i64
    %309 = arith.remsi %arg0, %310 : i64
    %311 = arith.constant 0 : i32
    %313 = arith.extsi %311 : i32 to i64
    %312 = arith.cmpi eq, %309, %313 : i64
    cf.cond_br %312, ^bb45, ^bb46
    ^bb45:
      %314 = arith.constant 2 : i32
      %315 = arith.extsi %314 : i32 to i64
      func.return %315 : i64
    ^bb46:
      cf.br ^bb47
    ^bb47:
    %316 = arith.constant 3 : i32
    %318 = arith.extsi %316 : i32 to i64
    %317 = arith.remsi %arg0, %318 : i64
    %319 = arith.constant 0 : i32
    %321 = arith.extsi %319 : i32 to i64
    %320 = arith.cmpi eq, %317, %321 : i64
    cf.cond_br %320, ^bb48, ^bb49
    ^bb48:
      %322 = arith.constant 3 : i32
      %323 = arith.extsi %322 : i32 to i64
      func.return %323 : i64
    ^bb49:
      cf.br ^bb50
    ^bb50:
    %324 = arith.constant 5 : i32
    %326 = arith.extsi %324 : i32 to i64
    %325 = arith.remsi %arg0, %326 : i64
    %327 = arith.constant 0 : i32
    %329 = arith.extsi %327 : i32 to i64
    %328 = arith.cmpi eq, %325, %329 : i64
    cf.cond_br %328, ^bb51, ^bb52
    ^bb51:
      %330 = arith.constant 5 : i32
      %331 = arith.extsi %330 : i32 to i64
      func.return %331 : i64
    ^bb52:
      cf.br ^bb53
    ^bb53:
    %332 = arith.constant 0 : i32
    %333 = llvm.mlir.constant(1 : i64) : i64
    %334 = llvm.alloca %333 x i32 : (i64) -> !llvm.ptr
    llvm.store %332, %334 : i32, !llvm.ptr
    cf.br ^bb54
    ^bb54:
    %335 = llvm.load %334 : !llvm.ptr -> i32
    %336 = arith.constant 12 : i32
    %337 = arith.cmpi slt, %335, %336 : i32
    cf.cond_br %337, ^bb55, ^bb56
    ^bb55:
      %338 = arith.constant 0 : i32
      %339 = arith.extsi %338 : i32 to i64
      %340 = llvm.load %334 : !llvm.ptr -> i32
      %341 = arith.constant 0 : i32
      %342 = arith.cmpi eq, %340, %341 : i32
      %343 = scf.if %342 -> (i64) {
        %344 = arith.constant 1 : i32
        %345 = arith.extsi %344 : i32 to i64
        scf.yield %345 : i64
      } else {
        scf.yield %339 : i64
      }
      %346 = llvm.load %334 : !llvm.ptr -> i32
      %347 = arith.constant 1 : i32
      %348 = arith.cmpi eq, %346, %347 : i32
      %349 = scf.if %348 -> (i64) {
        %350 = arith.constant 3 : i32
        %351 = arith.extsi %350 : i32 to i64
        scf.yield %351 : i64
      } else {
        scf.yield %343 : i64
      }
      %352 = llvm.load %334 : !llvm.ptr -> i32
      %353 = arith.constant 2 : i32
      %354 = arith.cmpi eq, %352, %353 : i32
      %355 = scf.if %354 -> (i64) {
        %356 = arith.constant 5 : i32
        %357 = arith.extsi %356 : i32 to i64
        scf.yield %357 : i64
      } else {
        scf.yield %349 : i64
      }
      %358 = llvm.load %334 : !llvm.ptr -> i32
      %359 = arith.constant 3 : i32
      %360 = arith.cmpi eq, %358, %359 : i32
      %361 = scf.if %360 -> (i64) {
        %362 = arith.constant 7 : i32
        %363 = arith.extsi %362 : i32 to i64
        scf.yield %363 : i64
      } else {
        scf.yield %355 : i64
      }
      %364 = llvm.load %334 : !llvm.ptr -> i32
      %365 = arith.constant 4 : i32
      %366 = arith.cmpi eq, %364, %365 : i32
      %367 = scf.if %366 -> (i64) {
        %368 = arith.constant 11 : i32
        %369 = arith.extsi %368 : i32 to i64
        scf.yield %369 : i64
      } else {
        scf.yield %361 : i64
      }
      %370 = llvm.load %334 : !llvm.ptr -> i32
      %371 = arith.constant 5 : i32
      %372 = arith.cmpi eq, %370, %371 : i32
      %373 = scf.if %372 -> (i64) {
        %374 = arith.constant 13 : i32
        %375 = arith.extsi %374 : i32 to i64
        scf.yield %375 : i64
      } else {
        scf.yield %367 : i64
      }
      %376 = llvm.load %334 : !llvm.ptr -> i32
      %377 = arith.constant 6 : i32
      %378 = arith.cmpi eq, %376, %377 : i32
      %379 = scf.if %378 -> (i64) {
        %380 = arith.constant 17 : i32
        %381 = arith.extsi %380 : i32 to i64
        scf.yield %381 : i64
      } else {
        scf.yield %373 : i64
      }
      %382 = llvm.load %334 : !llvm.ptr -> i32
      %383 = arith.constant 7 : i32
      %384 = arith.cmpi eq, %382, %383 : i32
      %385 = scf.if %384 -> (i64) {
        %386 = arith.constant 19 : i32
        %387 = arith.extsi %386 : i32 to i64
        scf.yield %387 : i64
      } else {
        scf.yield %379 : i64
      }
      %388 = llvm.load %334 : !llvm.ptr -> i32
      %389 = arith.constant 8 : i32
      %390 = arith.cmpi eq, %388, %389 : i32
      %391 = scf.if %390 -> (i64) {
        %392 = arith.constant 23 : i32
        %393 = arith.extsi %392 : i32 to i64
        scf.yield %393 : i64
      } else {
        scf.yield %385 : i64
      }
      %394 = llvm.load %334 : !llvm.ptr -> i32
      %395 = arith.constant 9 : i32
      %396 = arith.cmpi eq, %394, %395 : i32
      %397 = scf.if %396 -> (i64) {
        %398 = arith.constant 29 : i32
        %399 = arith.extsi %398 : i32 to i64
        scf.yield %399 : i64
      } else {
        scf.yield %391 : i64
      }
      %400 = llvm.load %334 : !llvm.ptr -> i32
      %401 = arith.constant 10 : i32
      %402 = arith.cmpi eq, %400, %401 : i32
      %403 = scf.if %402 -> (i64) {
        %404 = arith.constant 31 : i32
        %405 = arith.extsi %404 : i32 to i64
        scf.yield %405 : i64
      } else {
        scf.yield %397 : i64
      }
      %406 = llvm.load %334 : !llvm.ptr -> i32
      %407 = arith.constant 11 : i32
      %408 = arith.cmpi eq, %406, %407 : i32
      %409 = scf.if %408 -> (i64) {
        %410 = arith.constant 37 : i32
        %411 = arith.extsi %410 : i32 to i64
        scf.yield %411 : i64
      } else {
        scf.yield %403 : i64
      }
      %412 = arith.constant 3 : i32
      %413 = arith.extsi %412 : i32 to i64
      %414 = llvm.mlir.constant(1 : i64) : i64
      %415 = llvm.alloca %414 x i64 : (i64) -> !llvm.ptr
      llvm.store %413, %415 : i64, !llvm.ptr
      %416 = arith.constant 3 : i32
      %417 = arith.extsi %416 : i32 to i64
      %418 = llvm.mlir.constant(1 : i64) : i64
      %419 = llvm.alloca %418 x i64 : (i64) -> !llvm.ptr
      llvm.store %417, %419 : i64, !llvm.ptr
      %420 = arith.constant 1 : i32
      %421 = arith.extsi %420 : i32 to i64
      %422 = llvm.mlir.constant(1 : i64) : i64
      %423 = llvm.alloca %422 x i64 : (i64) -> !llvm.ptr
      llvm.store %421, %423 : i64, !llvm.ptr
      cf.br ^bb57
      ^bb57:
      %424 = llvm.load %423 : !llvm.ptr -> i64
      %425 = arith.constant 1 : i32
      %427 = arith.extsi %425 : i32 to i64
      %426 = arith.cmpi eq, %424, %427 : i64
      cf.cond_br %426, ^bb58, ^bb59
      ^bb58:
        %429 = llvm.load %415 : !llvm.ptr -> i64
        %430 = llvm.load %415 : !llvm.ptr -> i64
        %428 = func.call @mulmod(%429, %430, %arg0) : (i64, i64, i64) -> i64
        %431 = arith.addi %428, %409 : i64
        %432 = arith.remsi %431, %arg0 : i64
        llvm.store %432, %415 : i64, !llvm.ptr
        %434 = llvm.load %419 : !llvm.ptr -> i64
        %435 = llvm.load %419 : !llvm.ptr -> i64
        %433 = func.call @mulmod(%434, %435, %arg0) : (i64, i64, i64) -> i64
        %436 = arith.addi %433, %409 : i64
        %437 = arith.remsi %436, %arg0 : i64
        llvm.store %437, %419 : i64, !llvm.ptr
        %439 = llvm.load %419 : !llvm.ptr -> i64
        %440 = llvm.load %419 : !llvm.ptr -> i64
        %438 = func.call @mulmod(%439, %440, %arg0) : (i64, i64, i64) -> i64
        %441 = arith.addi %438, %409 : i64
        %442 = arith.remsi %441, %arg0 : i64
        llvm.store %442, %419 : i64, !llvm.ptr
        %443 = llvm.load %415 : !llvm.ptr -> i64
        %444 = llvm.load %419 : !llvm.ptr -> i64
        %445 = arith.cmpi sgt, %443, %444 : i64
        %446 = scf.if %445 -> (i64) {
          %447 = llvm.load %415 : !llvm.ptr -> i64
          %448 = llvm.load %419 : !llvm.ptr -> i64
          %449 = arith.subi %447, %448 : i64
          scf.yield %449 : i64
        } else {
          %450 = llvm.load %419 : !llvm.ptr -> i64
          %451 = llvm.load %415 : !llvm.ptr -> i64
          %452 = arith.subi %450, %451 : i64
          scf.yield %452 : i64
        }
        %453 = func.call @gcd_u64(%446, %arg0) : (i64, i64) -> i64
        llvm.store %453, %423 : i64, !llvm.ptr
        cf.br ^bb57
      ^bb59:
      %454 = llvm.load %423 : !llvm.ptr -> i64
      %455 = arith.cmpi ne, %454, %arg0 : i64
      cf.cond_br %455, ^bb60, ^bb61
      ^bb60:
        %456 = llvm.load %423 : !llvm.ptr -> i64
        func.return %456 : i64
      ^bb61:
        cf.br ^bb62
      ^bb62:
      %457 = llvm.load %334 : !llvm.ptr -> i32
      %458 = arith.constant 1 : i32
      %459 = arith.addi %457, %458 : i32
      llvm.store %459, %334 : i32, !llvm.ptr
      cf.br ^bb54
    ^bb56:
    func.return %arg0 : i64
  }
  func.func @factorize(%arg0: i64, %arg1: !llvm.ptr, %arg2: !llvm.ptr) -> i32 {
    %460 = llvm.mlir.constant(1 : i64) : i64
    %461 = llvm.alloca %460 x i64 : (i64) -> !llvm.ptr
    llvm.store %arg0, %461 : i64, !llvm.ptr
    %462 = arith.constant 0 : i32
    %463 = llvm.mlir.constant(1 : i64) : i64
    %464 = llvm.alloca %463 x i32 : (i64) -> !llvm.ptr
    llvm.store %462, %464 : i32, !llvm.ptr
    %465 = arith.constant 0 : i32
    %466 = llvm.mlir.constant(1 : i64) : i64
    %467 = llvm.alloca %466 x i32 : (i64) -> !llvm.ptr
    llvm.store %465, %467 : i32, !llvm.ptr
    cf.br ^bb63
    ^bb63:
    %468 = llvm.load %467 : !llvm.ptr -> i32
    %469 = arith.constant 12 : i32
    %470 = arith.cmpi slt, %468, %469 : i32
    cf.cond_br %470, ^bb64, ^bb65
    ^bb64:
      %471 = arith.constant 0 : i32
      %472 = arith.extsi %471 : i32 to i64
      %473 = llvm.load %467 : !llvm.ptr -> i32
      %474 = arith.constant 0 : i32
      %475 = arith.cmpi eq, %473, %474 : i32
      %476 = scf.if %475 -> (i64) {
        %477 = arith.constant 2 : i32
        %478 = arith.extsi %477 : i32 to i64
        scf.yield %478 : i64
      } else {
        scf.yield %472 : i64
      }
      %479 = llvm.load %467 : !llvm.ptr -> i32
      %480 = arith.constant 1 : i32
      %481 = arith.cmpi eq, %479, %480 : i32
      %482 = scf.if %481 -> (i64) {
        %483 = arith.constant 3 : i32
        %484 = arith.extsi %483 : i32 to i64
        scf.yield %484 : i64
      } else {
        scf.yield %476 : i64
      }
      %485 = llvm.load %467 : !llvm.ptr -> i32
      %486 = arith.constant 2 : i32
      %487 = arith.cmpi eq, %485, %486 : i32
      %488 = scf.if %487 -> (i64) {
        %489 = arith.constant 5 : i32
        %490 = arith.extsi %489 : i32 to i64
        scf.yield %490 : i64
      } else {
        scf.yield %482 : i64
      }
      %491 = llvm.load %467 : !llvm.ptr -> i32
      %492 = arith.constant 3 : i32
      %493 = arith.cmpi eq, %491, %492 : i32
      %494 = scf.if %493 -> (i64) {
        %495 = arith.constant 7 : i32
        %496 = arith.extsi %495 : i32 to i64
        scf.yield %496 : i64
      } else {
        scf.yield %488 : i64
      }
      %497 = llvm.load %467 : !llvm.ptr -> i32
      %498 = arith.constant 4 : i32
      %499 = arith.cmpi eq, %497, %498 : i32
      %500 = scf.if %499 -> (i64) {
        %501 = arith.constant 11 : i32
        %502 = arith.extsi %501 : i32 to i64
        scf.yield %502 : i64
      } else {
        scf.yield %494 : i64
      }
      %503 = llvm.load %467 : !llvm.ptr -> i32
      %504 = arith.constant 5 : i32
      %505 = arith.cmpi eq, %503, %504 : i32
      %506 = scf.if %505 -> (i64) {
        %507 = arith.constant 13 : i32
        %508 = arith.extsi %507 : i32 to i64
        scf.yield %508 : i64
      } else {
        scf.yield %500 : i64
      }
      %509 = llvm.load %467 : !llvm.ptr -> i32
      %510 = arith.constant 6 : i32
      %511 = arith.cmpi eq, %509, %510 : i32
      %512 = scf.if %511 -> (i64) {
        %513 = arith.constant 17 : i32
        %514 = arith.extsi %513 : i32 to i64
        scf.yield %514 : i64
      } else {
        scf.yield %506 : i64
      }
      %515 = llvm.load %467 : !llvm.ptr -> i32
      %516 = arith.constant 7 : i32
      %517 = arith.cmpi eq, %515, %516 : i32
      %518 = scf.if %517 -> (i64) {
        %519 = arith.constant 19 : i32
        %520 = arith.extsi %519 : i32 to i64
        scf.yield %520 : i64
      } else {
        scf.yield %512 : i64
      }
      %521 = llvm.load %467 : !llvm.ptr -> i32
      %522 = arith.constant 8 : i32
      %523 = arith.cmpi eq, %521, %522 : i32
      %524 = scf.if %523 -> (i64) {
        %525 = arith.constant 23 : i32
        %526 = arith.extsi %525 : i32 to i64
        scf.yield %526 : i64
      } else {
        scf.yield %518 : i64
      }
      %527 = llvm.load %467 : !llvm.ptr -> i32
      %528 = arith.constant 9 : i32
      %529 = arith.cmpi eq, %527, %528 : i32
      %530 = scf.if %529 -> (i64) {
        %531 = arith.constant 29 : i32
        %532 = arith.extsi %531 : i32 to i64
        scf.yield %532 : i64
      } else {
        scf.yield %524 : i64
      }
      %533 = llvm.load %467 : !llvm.ptr -> i32
      %534 = arith.constant 10 : i32
      %535 = arith.cmpi eq, %533, %534 : i32
      %536 = scf.if %535 -> (i64) {
        %537 = arith.constant 31 : i32
        %538 = arith.extsi %537 : i32 to i64
        scf.yield %538 : i64
      } else {
        scf.yield %530 : i64
      }
      %539 = llvm.load %467 : !llvm.ptr -> i32
      %540 = arith.constant 11 : i32
      %541 = arith.cmpi eq, %539, %540 : i32
      %542 = scf.if %541 -> (i64) {
        %543 = arith.constant 37 : i32
        %544 = arith.extsi %543 : i32 to i64
        scf.yield %544 : i64
      } else {
        scf.yield %536 : i64
      }
      %545 = llvm.load %461 : !llvm.ptr -> i64
      %546 = arith.remsi %545, %542 : i64
      %547 = arith.constant 0 : i32
      %549 = arith.extsi %547 : i32 to i64
      %548 = arith.cmpi eq, %546, %549 : i64
      cf.cond_br %548, ^bb66, ^bb67
      ^bb66:
        %550 = arith.constant 0 : i32
        %551 = llvm.mlir.constant(1 : i64) : i64
        %552 = llvm.alloca %551 x i32 : (i64) -> !llvm.ptr
        llvm.store %550, %552 : i32, !llvm.ptr
        cf.br ^bb69
        ^bb69:
        %553 = llvm.load %461 : !llvm.ptr -> i64
        %554 = arith.remsi %553, %542 : i64
        %555 = arith.constant 0 : i32
        %557 = arith.extsi %555 : i32 to i64
        %556 = arith.cmpi eq, %554, %557 : i64
        cf.cond_br %556, ^bb70, ^bb71
        ^bb70:
          %558 = llvm.load %461 : !llvm.ptr -> i64
          %559 = arith.divsi %558, %542 : i64
          llvm.store %559, %461 : i64, !llvm.ptr
          %560 = llvm.load %552 : !llvm.ptr -> i32
          %561 = arith.constant 1 : i32
          %562 = arith.addi %560, %561 : i32
          llvm.store %562, %552 : i32, !llvm.ptr
          cf.br ^bb69
        ^bb71:
        %563 = llvm.load %464 : !llvm.ptr -> i32
        %564 = arith.extsi %563 : i32 to i64
        %565 = llvm.getelementptr %arg1[%564] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %542, %565 : i64, !llvm.ptr
        %566 = llvm.load %552 : !llvm.ptr -> i32
        %567 = llvm.load %464 : !llvm.ptr -> i32
        %568 = arith.extsi %567 : i32 to i64
        %569 = llvm.getelementptr %arg2[%568] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %566, %569 : i32, !llvm.ptr
        %570 = llvm.load %464 : !llvm.ptr -> i32
        %571 = arith.constant 1 : i32
        %572 = arith.addi %570, %571 : i32
        llvm.store %572, %464 : i32, !llvm.ptr
        cf.br ^bb68
      ^bb67:
        cf.br ^bb68
      ^bb68:
      %573 = llvm.load %467 : !llvm.ptr -> i32
      %574 = arith.constant 1 : i32
      %575 = arith.addi %573, %574 : i32
      llvm.store %575, %467 : i32, !llvm.ptr
      cf.br ^bb63
    ^bb65:
    %577 = arith.constant 64 : i32
    %578 = arith.constant 8 : i32
    %579 = arith.extsi %577 : i32 to i64
    %580 = arith.extsi %578 : i32 to i64
    %576 = func.call @calloc(%579, %580) : (i64, i64) -> !llvm.ptr
    %581 = arith.constant 0 : i32
    %582 = llvm.mlir.constant(1 : i64) : i64
    %583 = llvm.alloca %582 x i32 : (i64) -> !llvm.ptr
    llvm.store %581, %583 : i32, !llvm.ptr
    %584 = llvm.load %461 : !llvm.ptr -> i64
    %585 = arith.constant 1 : i32
    %587 = arith.extsi %585 : i32 to i64
    %586 = arith.cmpi sgt, %584, %587 : i64
    cf.cond_br %586, ^bb72, ^bb73
    ^bb72:
      %588 = llvm.load %461 : !llvm.ptr -> i64
      %589 = llvm.load %583 : !llvm.ptr -> i32
      %590 = arith.extsi %589 : i32 to i64
      %591 = llvm.getelementptr %576[%590] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %588, %591 : i64, !llvm.ptr
      %592 = llvm.load %583 : !llvm.ptr -> i32
      %593 = arith.constant 1 : i32
      %594 = arith.addi %592, %593 : i32
      llvm.store %594, %583 : i32, !llvm.ptr
      cf.br ^bb74
    ^bb73:
      cf.br ^bb74
    ^bb74:
    cf.br ^bb75
    ^bb75:
    %595 = llvm.load %583 : !llvm.ptr -> i32
    %596 = arith.constant 0 : i32
    %597 = arith.cmpi sgt, %595, %596 : i32
    cf.cond_br %597, ^bb76, ^bb77
    ^bb76:
      %598 = llvm.load %583 : !llvm.ptr -> i32
      %599 = arith.constant 1 : i32
      %600 = arith.subi %598, %599 : i32
      llvm.store %600, %583 : i32, !llvm.ptr
      %602 = llvm.load %583 : !llvm.ptr -> i32
      %603 = arith.extsi %602 : i32 to i64
      %604 = llvm.getelementptr %576[%603] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %601 = llvm.load %604 : !llvm.ptr -> i64
      %605 = arith.constant 1 : i32
      %607 = arith.extsi %605 : i32 to i64
      %606 = arith.cmpi eq, %601, %607 : i64
      cf.cond_br %606, ^bb78, ^bb79
      ^bb78:
        cf.br ^bb75
      ^bb79:
        cf.br ^bb80
      ^bb80:
      %608 = func.call @is_prime_u64(%601) : (i64) -> i32
      %609 = arith.constant 1 : i32
      %610 = arith.cmpi eq, %608, %609 : i32
      cf.cond_br %610, ^bb81, ^bb82
      ^bb81:
        %611 = arith.constant 0 : i32
        %612 = llvm.mlir.constant(1 : i64) : i64
        %613 = llvm.alloca %612 x i32 : (i64) -> !llvm.ptr
        llvm.store %611, %613 : i32, !llvm.ptr
        %614 = arith.constant 0 : i32
        %615 = llvm.mlir.constant(1 : i64) : i64
        %616 = llvm.alloca %615 x i32 : (i64) -> !llvm.ptr
        llvm.store %614, %616 : i32, !llvm.ptr
        cf.br ^bb84
        ^bb84:
        %617 = llvm.load %616 : !llvm.ptr -> i32
        %618 = llvm.load %464 : !llvm.ptr -> i32
        %619 = arith.cmpi slt, %617, %618 : i32
        cf.cond_br %619, ^bb85, ^bb86
        ^bb85:
          %621 = llvm.load %616 : !llvm.ptr -> i32
          %622 = arith.extsi %621 : i32 to i64
          %623 = llvm.getelementptr %arg1[%622] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %620 = llvm.load %623 : !llvm.ptr -> i64
          %624 = arith.cmpi eq, %620, %601 : i64
          cf.cond_br %624, ^bb87, ^bb88
          ^bb87:
            %626 = llvm.load %616 : !llvm.ptr -> i32
            %627 = arith.extsi %626 : i32 to i64
            %628 = llvm.getelementptr %arg2[%627] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            %625 = llvm.load %628 : !llvm.ptr -> i32
            %629 = arith.constant 1 : i32
            %630 = arith.addi %625, %629 : i32
            %631 = llvm.load %616 : !llvm.ptr -> i32
            %632 = arith.extsi %631 : i32 to i64
            %633 = llvm.getelementptr %arg2[%632] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            llvm.store %630, %633 : i32, !llvm.ptr
            %634 = arith.constant 1 : i32
            llvm.store %634, %613 : i32, !llvm.ptr
            cf.br ^bb86
          ^bb88:
            cf.br ^bb89
          ^bb89:
          %635 = llvm.load %616 : !llvm.ptr -> i32
          %636 = arith.constant 1 : i32
          %637 = arith.addi %635, %636 : i32
          llvm.store %637, %616 : i32, !llvm.ptr
          cf.br ^bb84
        ^bb86:
        %638 = llvm.load %613 : !llvm.ptr -> i32
        %639 = arith.constant 0 : i32
        %640 = arith.cmpi eq, %638, %639 : i32
        cf.cond_br %640, ^bb90, ^bb91
        ^bb90:
          %641 = llvm.load %464 : !llvm.ptr -> i32
          %642 = arith.extsi %641 : i32 to i64
          %643 = llvm.getelementptr %arg1[%642] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %601, %643 : i64, !llvm.ptr
          %644 = arith.constant 1 : i32
          %645 = llvm.load %464 : !llvm.ptr -> i32
          %646 = arith.extsi %645 : i32 to i64
          %647 = llvm.getelementptr %arg2[%646] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %644, %647 : i32, !llvm.ptr
          %648 = llvm.load %464 : !llvm.ptr -> i32
          %649 = arith.constant 1 : i32
          %650 = arith.addi %648, %649 : i32
          llvm.store %650, %464 : i32, !llvm.ptr
          cf.br ^bb92
        ^bb91:
          cf.br ^bb92
        ^bb92:
        cf.br ^bb75
      ^bb82:
        cf.br ^bb83
      ^bb83:
      %651 = func.call @pollard_rho(%601) : (i64) -> i64
      %652 = arith.cmpi eq, %651, %601 : i64
      cf.cond_br %652, ^bb93, ^bb94
      ^bb93:
        %653 = arith.constant 0 : i32
        %654 = llvm.mlir.constant(1 : i64) : i64
        %655 = llvm.alloca %654 x i32 : (i64) -> !llvm.ptr
        llvm.store %653, %655 : i32, !llvm.ptr
        %656 = arith.constant 0 : i32
        %657 = llvm.mlir.constant(1 : i64) : i64
        %658 = llvm.alloca %657 x i32 : (i64) -> !llvm.ptr
        llvm.store %656, %658 : i32, !llvm.ptr
        cf.br ^bb96
        ^bb96:
        %659 = llvm.load %658 : !llvm.ptr -> i32
        %660 = llvm.load %464 : !llvm.ptr -> i32
        %661 = arith.cmpi slt, %659, %660 : i32
        cf.cond_br %661, ^bb97, ^bb98
        ^bb97:
          %663 = llvm.load %658 : !llvm.ptr -> i32
          %664 = arith.extsi %663 : i32 to i64
          %665 = llvm.getelementptr %arg1[%664] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %662 = llvm.load %665 : !llvm.ptr -> i64
          %666 = arith.cmpi eq, %662, %601 : i64
          cf.cond_br %666, ^bb99, ^bb100
          ^bb99:
            %668 = llvm.load %658 : !llvm.ptr -> i32
            %669 = arith.extsi %668 : i32 to i64
            %670 = llvm.getelementptr %arg2[%669] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            %667 = llvm.load %670 : !llvm.ptr -> i32
            %671 = arith.constant 1 : i32
            %672 = arith.addi %667, %671 : i32
            %673 = llvm.load %658 : !llvm.ptr -> i32
            %674 = arith.extsi %673 : i32 to i64
            %675 = llvm.getelementptr %arg2[%674] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            llvm.store %672, %675 : i32, !llvm.ptr
            %676 = arith.constant 1 : i32
            llvm.store %676, %655 : i32, !llvm.ptr
            cf.br ^bb98
          ^bb100:
            cf.br ^bb101
          ^bb101:
          %677 = llvm.load %658 : !llvm.ptr -> i32
          %678 = arith.constant 1 : i32
          %679 = arith.addi %677, %678 : i32
          llvm.store %679, %658 : i32, !llvm.ptr
          cf.br ^bb96
        ^bb98:
        %680 = llvm.load %655 : !llvm.ptr -> i32
        %681 = arith.constant 0 : i32
        %682 = arith.cmpi eq, %680, %681 : i32
        cf.cond_br %682, ^bb102, ^bb103
        ^bb102:
          %683 = llvm.load %464 : !llvm.ptr -> i32
          %684 = arith.extsi %683 : i32 to i64
          %685 = llvm.getelementptr %arg1[%684] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %601, %685 : i64, !llvm.ptr
          %686 = arith.constant 1 : i32
          %687 = llvm.load %464 : !llvm.ptr -> i32
          %688 = arith.extsi %687 : i32 to i64
          %689 = llvm.getelementptr %arg2[%688] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %686, %689 : i32, !llvm.ptr
          %690 = llvm.load %464 : !llvm.ptr -> i32
          %691 = arith.constant 1 : i32
          %692 = arith.addi %690, %691 : i32
          llvm.store %692, %464 : i32, !llvm.ptr
          cf.br ^bb104
        ^bb103:
          cf.br ^bb104
        ^bb104:
        cf.br ^bb75
      ^bb94:
        cf.br ^bb95
      ^bb95:
      %693 = llvm.load %583 : !llvm.ptr -> i32
      %694 = arith.extsi %693 : i32 to i64
      %695 = llvm.getelementptr %576[%694] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %651, %695 : i64, !llvm.ptr
      %696 = llvm.load %583 : !llvm.ptr -> i32
      %697 = arith.constant 1 : i32
      %698 = arith.addi %696, %697 : i32
      llvm.store %698, %583 : i32, !llvm.ptr
      %699 = arith.divsi %601, %651 : i64
      %700 = llvm.load %583 : !llvm.ptr -> i32
      %701 = arith.extsi %700 : i32 to i64
      %702 = llvm.getelementptr %576[%701] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %699, %702 : i64, !llvm.ptr
      %703 = llvm.load %583 : !llvm.ptr -> i32
      %704 = arith.constant 1 : i32
      %705 = arith.addi %703, %704 : i32
      llvm.store %705, %583 : i32, !llvm.ptr
      cf.br ^bb75
    ^bb77:
    func.call @free(%576) : (!llvm.ptr) -> ()
    %707 = llvm.load %464 : !llvm.ptr -> i32
    func.return %707 : i32
  }
  func.func @odd_divisors(%arg0: i64, %arg1: !llvm.ptr) -> i32 {
    %709 = arith.constant 20 : i32
    %710 = arith.constant 8 : i32
    %711 = arith.extsi %709 : i32 to i64
    %712 = arith.extsi %710 : i32 to i64
    %708 = func.call @calloc(%711, %712) : (i64, i64) -> !llvm.ptr
    %714 = arith.constant 20 : i32
    %715 = arith.constant 4 : i32
    %716 = arith.extsi %714 : i32 to i64
    %717 = arith.extsi %715 : i32 to i64
    %713 = func.call @calloc(%716, %717) : (i64, i64) -> !llvm.ptr
    %718 = func.call @factorize(%arg0, %708, %713) : (i64, !llvm.ptr, !llvm.ptr) -> i32
    %720 = arith.constant 20 : i32
    %721 = arith.constant 8 : i32
    %722 = arith.extsi %720 : i32 to i64
    %723 = arith.extsi %721 : i32 to i64
    %719 = func.call @calloc(%722, %723) : (i64, i64) -> !llvm.ptr
    %725 = arith.constant 20 : i32
    %726 = arith.constant 4 : i32
    %727 = arith.extsi %725 : i32 to i64
    %728 = arith.extsi %726 : i32 to i64
    %724 = func.call @calloc(%727, %728) : (i64, i64) -> !llvm.ptr
    %729 = arith.constant 0 : i32
    %730 = llvm.mlir.constant(1 : i64) : i64
    %731 = llvm.alloca %730 x i32 : (i64) -> !llvm.ptr
    llvm.store %729, %731 : i32, !llvm.ptr
    %732 = arith.constant 0 : i32
    %733 = llvm.mlir.constant(1 : i64) : i64
    %734 = llvm.alloca %733 x i32 : (i64) -> !llvm.ptr
    llvm.store %732, %734 : i32, !llvm.ptr
    cf.br ^bb105
    ^bb105:
    %735 = llvm.load %734 : !llvm.ptr -> i32
    %736 = arith.cmpi slt, %735, %718 : i32
    cf.cond_br %736, ^bb106, ^bb107
    ^bb106:
      %738 = llvm.load %734 : !llvm.ptr -> i32
      %739 = arith.extsi %738 : i32 to i64
      %740 = llvm.getelementptr %708[%739] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %737 = llvm.load %740 : !llvm.ptr -> i64
      %741 = arith.constant 2 : i32
      %743 = arith.extsi %741 : i32 to i64
      %742 = arith.cmpi ne, %737, %743 : i64
      cf.cond_br %742, ^bb108, ^bb109
      ^bb108:
        %745 = llvm.load %734 : !llvm.ptr -> i32
        %746 = arith.extsi %745 : i32 to i64
        %747 = llvm.getelementptr %708[%746] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %744 = llvm.load %747 : !llvm.ptr -> i64
        %748 = llvm.load %731 : !llvm.ptr -> i32
        %749 = arith.extsi %748 : i32 to i64
        %750 = llvm.getelementptr %719[%749] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %744, %750 : i64, !llvm.ptr
        %752 = llvm.load %734 : !llvm.ptr -> i32
        %753 = arith.extsi %752 : i32 to i64
        %754 = llvm.getelementptr %713[%753] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %751 = llvm.load %754 : !llvm.ptr -> i32
        %755 = llvm.load %731 : !llvm.ptr -> i32
        %756 = arith.extsi %755 : i32 to i64
        %757 = llvm.getelementptr %724[%756] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %751, %757 : i32, !llvm.ptr
        %758 = llvm.load %731 : !llvm.ptr -> i32
        %759 = arith.constant 1 : i32
        %760 = arith.addi %758, %759 : i32
        llvm.store %760, %731 : i32, !llvm.ptr
        cf.br ^bb110
      ^bb109:
        cf.br ^bb110
      ^bb110:
      %761 = llvm.load %734 : !llvm.ptr -> i32
      %762 = arith.constant 1 : i32
      %763 = arith.addi %761, %762 : i32
      llvm.store %763, %734 : i32, !llvm.ptr
      cf.br ^bb105
    ^bb107:
    %764 = arith.constant 1 : i32
    %765 = llvm.mlir.constant(1 : i64) : i64
    %766 = llvm.alloca %765 x i32 : (i64) -> !llvm.ptr
    llvm.store %764, %766 : i32, !llvm.ptr
    %767 = arith.constant 1 : i32
    %768 = arith.constant 0 : i32
    %769 = arith.extsi %767 : i32 to i64
    %770 = arith.extsi %768 : i32 to i64
    %771 = llvm.getelementptr %arg1[%770] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %769, %771 : i64, !llvm.ptr
    %772 = arith.constant 0 : i32
    %773 = llvm.mlir.constant(1 : i64) : i64
    %774 = llvm.alloca %773 x i32 : (i64) -> !llvm.ptr
    llvm.store %772, %774 : i32, !llvm.ptr
    cf.br ^bb111
    ^bb111:
    %775 = llvm.load %774 : !llvm.ptr -> i32
    %776 = llvm.load %731 : !llvm.ptr -> i32
    %777 = arith.cmpi slt, %775, %776 : i32
    cf.cond_br %777, ^bb112, ^bb113
    ^bb112:
      %778 = llvm.load %766 : !llvm.ptr -> i32
      %779 = arith.constant 1 : i32
      %780 = arith.extsi %779 : i32 to i64
      %781 = llvm.mlir.constant(1 : i64) : i64
      %782 = llvm.alloca %781 x i64 : (i64) -> !llvm.ptr
      llvm.store %780, %782 : i64, !llvm.ptr
      %783 = arith.constant 1 : i32
      %784 = llvm.mlir.constant(1 : i64) : i64
      %785 = llvm.alloca %784 x i32 : (i64) -> !llvm.ptr
      llvm.store %783, %785 : i32, !llvm.ptr
      cf.br ^bb114
      ^bb114:
      %786 = llvm.load %785 : !llvm.ptr -> i32
      %788 = llvm.load %774 : !llvm.ptr -> i32
      %789 = arith.extsi %788 : i32 to i64
      %790 = llvm.getelementptr %724[%789] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %787 = llvm.load %790 : !llvm.ptr -> i32
      %791 = arith.cmpi sle, %786, %787 : i32
      cf.cond_br %791, ^bb115, ^bb116
      ^bb115:
        %792 = llvm.load %782 : !llvm.ptr -> i64
        %794 = llvm.load %774 : !llvm.ptr -> i32
        %795 = arith.extsi %794 : i32 to i64
        %796 = llvm.getelementptr %719[%795] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %793 = llvm.load %796 : !llvm.ptr -> i64
        %797 = arith.muli %792, %793 : i64
        llvm.store %797, %782 : i64, !llvm.ptr
        %798 = arith.constant 0 : i32
        %799 = llvm.mlir.constant(1 : i64) : i64
        %800 = llvm.alloca %799 x i32 : (i64) -> !llvm.ptr
        llvm.store %798, %800 : i32, !llvm.ptr
        cf.br ^bb117
        ^bb117:
        %801 = llvm.load %800 : !llvm.ptr -> i32
        %802 = arith.cmpi slt, %801, %778 : i32
        cf.cond_br %802, ^bb118, ^bb119
        ^bb118:
          %804 = llvm.load %800 : !llvm.ptr -> i32
          %805 = arith.extsi %804 : i32 to i64
          %806 = llvm.getelementptr %arg1[%805] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %803 = llvm.load %806 : !llvm.ptr -> i64
          %807 = llvm.load %782 : !llvm.ptr -> i64
          %808 = arith.muli %803, %807 : i64
          %809 = llvm.load %766 : !llvm.ptr -> i32
          %810 = arith.extsi %809 : i32 to i64
          %811 = llvm.getelementptr %arg1[%810] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %808, %811 : i64, !llvm.ptr
          %812 = llvm.load %766 : !llvm.ptr -> i32
          %813 = arith.constant 1 : i32
          %814 = arith.addi %812, %813 : i32
          llvm.store %814, %766 : i32, !llvm.ptr
          %815 = llvm.load %800 : !llvm.ptr -> i32
          %816 = arith.constant 1 : i32
          %817 = arith.addi %815, %816 : i32
          llvm.store %817, %800 : i32, !llvm.ptr
          cf.br ^bb117
        ^bb119:
        %818 = llvm.load %785 : !llvm.ptr -> i32
        %819 = arith.constant 1 : i32
        %820 = arith.addi %818, %819 : i32
        llvm.store %820, %785 : i32, !llvm.ptr
        cf.br ^bb114
      ^bb116:
      %821 = llvm.load %774 : !llvm.ptr -> i32
      %822 = arith.constant 1 : i32
      %823 = arith.addi %821, %822 : i32
      llvm.store %823, %774 : i32, !llvm.ptr
      cf.br ^bb111
    ^bb113:
    %824 = arith.constant 1 : i32
    %825 = llvm.mlir.constant(1 : i64) : i64
    %826 = llvm.alloca %825 x i32 : (i64) -> !llvm.ptr
    llvm.store %824, %826 : i32, !llvm.ptr
    cf.br ^bb120
    ^bb120:
    %827 = llvm.load %826 : !llvm.ptr -> i32
    %828 = llvm.load %766 : !llvm.ptr -> i32
    %829 = arith.cmpi slt, %827, %828 : i32
    cf.cond_br %829, ^bb121, ^bb122
    ^bb121:
      %831 = llvm.load %826 : !llvm.ptr -> i32
      %832 = arith.extsi %831 : i32 to i64
      %833 = llvm.getelementptr %arg1[%832] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %830 = llvm.load %833 : !llvm.ptr -> i64
      %834 = llvm.load %826 : !llvm.ptr -> i32
      %835 = arith.constant 1 : i32
      %836 = arith.subi %834, %835 : i32
      %837 = llvm.mlir.constant(1 : i64) : i64
      %838 = llvm.alloca %837 x i32 : (i64) -> !llvm.ptr
      llvm.store %836, %838 : i32, !llvm.ptr
      cf.br ^bb123
      ^bb123:
      %839 = llvm.load %838 : !llvm.ptr -> i32
      %840 = arith.constant 0 : i32
      %841 = arith.cmpi sge, %839, %840 : i32
      %842 = scf.if %841 -> (i1) {
        %844 = llvm.load %838 : !llvm.ptr -> i32
        %845 = arith.extsi %844 : i32 to i64
        %846 = llvm.getelementptr %arg1[%845] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %843 = llvm.load %846 : !llvm.ptr -> i64
        %847 = arith.cmpi sgt, %843, %830 : i64
        scf.yield %847 : i1
      } else {
        %848 = arith.constant false
        scf.yield %848 : i1
      }
      cf.cond_br %842, ^bb124, ^bb125
      ^bb124:
        %850 = llvm.load %838 : !llvm.ptr -> i32
        %851 = arith.extsi %850 : i32 to i64
        %852 = llvm.getelementptr %arg1[%851] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %849 = llvm.load %852 : !llvm.ptr -> i64
        %853 = llvm.load %838 : !llvm.ptr -> i32
        %854 = arith.constant 1 : i32
        %855 = arith.addi %853, %854 : i32
        %856 = arith.extsi %855 : i32 to i64
        %857 = llvm.getelementptr %arg1[%856] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %849, %857 : i64, !llvm.ptr
        %858 = llvm.load %838 : !llvm.ptr -> i32
        %859 = arith.constant 1 : i32
        %860 = arith.subi %858, %859 : i32
        llvm.store %860, %838 : i32, !llvm.ptr
        cf.br ^bb123
      ^bb125:
      %861 = llvm.load %838 : !llvm.ptr -> i32
      %862 = arith.constant 1 : i32
      %863 = arith.addi %861, %862 : i32
      %864 = arith.extsi %863 : i32 to i64
      %865 = llvm.getelementptr %arg1[%864] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %830, %865 : i64, !llvm.ptr
      %866 = llvm.load %826 : !llvm.ptr -> i32
      %867 = arith.constant 1 : i32
      %868 = arith.addi %866, %867 : i32
      llvm.store %868, %826 : i32, !llvm.ptr
      cf.br ^bb120
    ^bb122:
    func.call @free(%708) : (!llvm.ptr) -> ()
    func.call @free(%713) : (!llvm.ptr) -> ()
    func.call @free(%719) : (!llvm.ptr) -> ()
    func.call @free(%724) : (!llvm.ptr) -> ()
    %873 = llvm.load %766 : !llvm.ptr -> i32
    func.return %873 : i32
  }
  func.func @gen_primes() -> () {
    %874 = arith.constant 2 : i32
    %875 = llvm.mlir.constant(1 : i64) : i64
    %876 = llvm.alloca %875 x i32 : (i64) -> !llvm.ptr
    llvm.store %874, %876 : i32, !llvm.ptr
    cf.br ^bb126
    ^bb126:
    %877 = llvm.mlir.addressof @np1 : !llvm.ptr
    %878 = llvm.load %877 : !llvm.ptr -> i32
    %879 = llvm.mlir.addressof @MAX_PRIMES : !llvm.ptr
    %880 = llvm.load %879 : !llvm.ptr -> i32
    %881 = arith.cmpi slt, %878, %880 : i32
    %882 = scf.if %881 -> (i1) {
      %883 = arith.constant true
      scf.yield %883 : i1
    } else {
      %884 = llvm.mlir.addressof @np3 : !llvm.ptr
      %885 = llvm.load %884 : !llvm.ptr -> i32
      %886 = llvm.mlir.addressof @MAX_PRIMES : !llvm.ptr
      %887 = llvm.load %886 : !llvm.ptr -> i32
      %888 = arith.cmpi slt, %885, %887 : i32
      scf.yield %888 : i1
    }
    cf.cond_br %882, ^bb127, ^bb128
    ^bb127:
      %889 = arith.constant 1 : i32
      %890 = llvm.mlir.constant(1 : i64) : i64
      %891 = llvm.alloca %890 x i32 : (i64) -> !llvm.ptr
      llvm.store %889, %891 : i32, !llvm.ptr
      %892 = arith.constant 2 : i32
      %893 = llvm.mlir.constant(1 : i64) : i64
      %894 = llvm.alloca %893 x i32 : (i64) -> !llvm.ptr
      llvm.store %892, %894 : i32, !llvm.ptr
      cf.br ^bb129
      ^bb129:
      %895 = llvm.load %894 : !llvm.ptr -> i32
      %896 = llvm.load %894 : !llvm.ptr -> i32
      %897 = arith.muli %895, %896 : i32
      %898 = llvm.load %876 : !llvm.ptr -> i32
      %899 = arith.cmpi sle, %897, %898 : i32
      cf.cond_br %899, ^bb130, ^bb131
      ^bb130:
        %900 = llvm.load %876 : !llvm.ptr -> i32
        %901 = llvm.load %894 : !llvm.ptr -> i32
        %902 = arith.remsi %900, %901 : i32
        %903 = arith.constant 0 : i32
        %904 = arith.cmpi eq, %902, %903 : i32
        cf.cond_br %904, ^bb132, ^bb133
        ^bb132:
          %905 = arith.constant 0 : i32
          llvm.store %905, %891 : i32, !llvm.ptr
          cf.br ^bb131
        ^bb133:
          cf.br ^bb134
        ^bb134:
        %906 = llvm.load %894 : !llvm.ptr -> i32
        %907 = arith.constant 1 : i32
        %908 = arith.addi %906, %907 : i32
        llvm.store %908, %894 : i32, !llvm.ptr
        cf.br ^bb129
      ^bb131:
      %909 = llvm.load %891 : !llvm.ptr -> i32
      %910 = arith.constant 1 : i32
      %911 = arith.cmpi eq, %909, %910 : i32
      cf.cond_br %911, ^bb135, ^bb136
      ^bb135:
        %912 = llvm.load %876 : !llvm.ptr -> i32
        %913 = arith.constant 4 : i32
        %914 = arith.remsi %912, %913 : i32
        %915 = arith.constant 1 : i32
        %916 = arith.cmpi eq, %914, %915 : i32
        %917 = scf.if %916 -> (i1) {
          %918 = llvm.mlir.addressof @np1 : !llvm.ptr
          %919 = llvm.load %918 : !llvm.ptr -> i32
          %920 = llvm.mlir.addressof @MAX_PRIMES : !llvm.ptr
          %921 = llvm.load %920 : !llvm.ptr -> i32
          %922 = arith.cmpi slt, %919, %921 : i32
          scf.yield %922 : i1
        } else {
          %923 = arith.constant false
          scf.yield %923 : i1
        }
        cf.cond_br %917, ^bb138, ^bb139
        ^bb138:
          %924 = llvm.load %876 : !llvm.ptr -> i32
          %925 = llvm.mlir.addressof @primes_p1 : !llvm.ptr
          %926 = llvm.load %925 : !llvm.ptr -> !llvm.ptr
          %927 = llvm.mlir.addressof @np1 : !llvm.ptr
          %928 = llvm.load %927 : !llvm.ptr -> i32
          %929 = arith.extsi %928 : i32 to i64
          %930 = llvm.getelementptr %926[%929] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %924, %930 : i32, !llvm.ptr
          %932 = llvm.load %876 : !llvm.ptr -> i32
          %933 = arith.sitofp %932 : i32 to f64
          %931 = func.call @log2(%933) : (f64) -> f64
          %934 = llvm.mlir.addressof @log2_p1 : !llvm.ptr
          %935 = llvm.load %934 : !llvm.ptr -> !llvm.ptr
          %936 = llvm.mlir.addressof @np1 : !llvm.ptr
          %937 = llvm.load %936 : !llvm.ptr -> i32
          %938 = arith.extsi %937 : i32 to i64
          %939 = llvm.getelementptr %935[%938] : (!llvm.ptr, i64) -> !llvm.ptr, f64
          llvm.store %931, %939 : f64, !llvm.ptr
          %940 = llvm.mlir.addressof @np1 : !llvm.ptr
          %941 = llvm.load %940 : !llvm.ptr -> i32
          %942 = arith.constant 1 : i32
          %943 = arith.addi %941, %942 : i32
          %944 = llvm.mlir.addressof @np1 : !llvm.ptr
          llvm.store %943, %944 : i32, !llvm.ptr
          cf.br ^bb140
        ^bb139:
          %945 = llvm.load %876 : !llvm.ptr -> i32
          %946 = arith.constant 4 : i32
          %947 = arith.remsi %945, %946 : i32
          %948 = arith.constant 3 : i32
          %949 = arith.cmpi eq, %947, %948 : i32
          %950 = scf.if %949 -> (i1) {
            %951 = llvm.mlir.addressof @np3 : !llvm.ptr
            %952 = llvm.load %951 : !llvm.ptr -> i32
            %953 = llvm.mlir.addressof @MAX_PRIMES : !llvm.ptr
            %954 = llvm.load %953 : !llvm.ptr -> i32
            %955 = arith.cmpi slt, %952, %954 : i32
            scf.yield %955 : i1
          } else {
            %956 = arith.constant false
            scf.yield %956 : i1
          }
          cf.cond_br %950, ^bb141, ^bb142
          ^bb141:
            %957 = llvm.load %876 : !llvm.ptr -> i32
            %958 = llvm.mlir.addressof @primes_p3 : !llvm.ptr
            %959 = llvm.load %958 : !llvm.ptr -> !llvm.ptr
            %960 = llvm.mlir.addressof @np3 : !llvm.ptr
            %961 = llvm.load %960 : !llvm.ptr -> i32
            %962 = arith.extsi %961 : i32 to i64
            %963 = llvm.getelementptr %959[%962] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            llvm.store %957, %963 : i32, !llvm.ptr
            %965 = llvm.load %876 : !llvm.ptr -> i32
            %966 = arith.sitofp %965 : i32 to f64
            %964 = func.call @log2(%966) : (f64) -> f64
            %967 = llvm.mlir.addressof @log2_p3 : !llvm.ptr
            %968 = llvm.load %967 : !llvm.ptr -> !llvm.ptr
            %969 = llvm.mlir.addressof @np3 : !llvm.ptr
            %970 = llvm.load %969 : !llvm.ptr -> i32
            %971 = arith.extsi %970 : i32 to i64
            %972 = llvm.getelementptr %968[%971] : (!llvm.ptr, i64) -> !llvm.ptr, f64
            llvm.store %964, %972 : f64, !llvm.ptr
            %973 = llvm.mlir.addressof @np3 : !llvm.ptr
            %974 = llvm.load %973 : !llvm.ptr -> i32
            %975 = arith.constant 1 : i32
            %976 = arith.addi %974, %975 : i32
            %977 = llvm.mlir.addressof @np3 : !llvm.ptr
            llvm.store %976, %977 : i32, !llvm.ptr
            cf.br ^bb143
          ^bb142:
            cf.br ^bb143
          ^bb143:
          cf.br ^bb140
        ^bb140:
        cf.br ^bb137
      ^bb136:
        cf.br ^bb137
      ^bb137:
      %978 = llvm.load %876 : !llvm.ptr -> i32
      %979 = arith.constant 1 : i32
      %980 = arith.addi %978, %979 : i32
      llvm.store %980, %876 : i32, !llvm.ptr
      cf.br ^bb126
    ^bb128:
    %982 = arith.constant 2.0 : f32
    %983 = arith.extf %982 : f32 to f64
    %981 = func.call @log2(%983) : (f64) -> f64
    %984 = llvm.mlir.addressof @log2_2 : !llvm.ptr
    llvm.store %981, %984 : f64, !llvm.ptr
    func.return
  }
  func.func @alloc_exps(%arg0: i32) -> i32 {
    %985 = llvm.mlir.addressof @exps_pool_next : !llvm.ptr
    %986 = llvm.load %985 : !llvm.ptr -> i32
    %987 = llvm.mlir.addressof @exps_pool_next : !llvm.ptr
    %988 = llvm.load %987 : !llvm.ptr -> i32
    %989 = arith.addi %988, %arg0 : i32
    %990 = llvm.mlir.addressof @exps_pool_next : !llvm.ptr
    llvm.store %989, %990 : i32, !llvm.ptr
    func.return %986 : i32
  }
  func.func @memo_lookup(%arg0: i64, %arg1: i32, %arg2: i32, %arg3: i32, %arg4: !llvm.ptr, %arg5: !llvm.ptr, %arg6: !llvm.ptr) -> i32 {
    %991 = arith.constant 0 : i32
    %992 = llvm.mlir.constant(1 : i64) : i64
    %993 = llvm.alloca %992 x i32 : (i64) -> !llvm.ptr
    llvm.store %991, %993 : i32, !llvm.ptr
    cf.br ^bb144
    ^bb144:
    %994 = llvm.load %993 : !llvm.ptr -> i32
    %995 = llvm.mlir.addressof @memo_count : !llvm.ptr
    %996 = llvm.load %995 : !llvm.ptr -> i32
    %997 = arith.cmpi slt, %994, %996 : i32
    cf.cond_br %997, ^bb145, ^bb146
    ^bb145:
      %999 = llvm.mlir.addressof @memo_rem : !llvm.ptr
      %1000 = llvm.load %999 : !llvm.ptr -> !llvm.ptr
      %1001 = llvm.load %993 : !llvm.ptr -> i32
      %1002 = arith.extsi %1001 : i32 to i64
      %1003 = llvm.getelementptr %1000[%1002] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %998 = llvm.load %1003 : !llvm.ptr -> i64
      %1004 = arith.cmpi eq, %998, %arg0 : i64
      %1005 = scf.if %1004 -> (i1) {
        %1007 = llvm.mlir.addressof @memo_idx : !llvm.ptr
        %1008 = llvm.load %1007 : !llvm.ptr -> !llvm.ptr
        %1009 = llvm.load %993 : !llvm.ptr -> i32
        %1010 = arith.extsi %1009 : i32 to i64
        %1011 = llvm.getelementptr %1008[%1010] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %1006 = llvm.load %1011 : !llvm.ptr -> i32
        %1012 = arith.cmpi eq, %1006, %arg1 : i32
        scf.yield %1012 : i1
      } else {
        %1013 = arith.constant false
        scf.yield %1013 : i1
      }
      %1014 = scf.if %1005 -> (i1) {
        %1016 = llvm.mlir.addressof @memo_prev_f : !llvm.ptr
        %1017 = llvm.load %1016 : !llvm.ptr -> !llvm.ptr
        %1018 = llvm.load %993 : !llvm.ptr -> i32
        %1019 = arith.extsi %1018 : i32 to i64
        %1020 = llvm.getelementptr %1017[%1019] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %1015 = llvm.load %1020 : !llvm.ptr -> i32
        %1021 = arith.cmpi eq, %1015, %arg2 : i32
        scf.yield %1021 : i1
      } else {
        %1022 = arith.constant false
        scf.yield %1022 : i1
      }
      %1023 = scf.if %1014 -> (i1) {
        %1025 = llvm.mlir.addressof @memo_pset : !llvm.ptr
        %1026 = llvm.load %1025 : !llvm.ptr -> !llvm.ptr
        %1027 = llvm.load %993 : !llvm.ptr -> i32
        %1028 = arith.extsi %1027 : i32 to i64
        %1029 = llvm.getelementptr %1026[%1028] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %1024 = llvm.load %1029 : !llvm.ptr -> i32
        %1030 = arith.cmpi eq, %1024, %arg3 : i32
        scf.yield %1030 : i1
      } else {
        %1031 = arith.constant false
        scf.yield %1031 : i1
      }
      cf.cond_br %1023, ^bb147, ^bb148
      ^bb147:
        %1033 = llvm.mlir.addressof @memo_valid : !llvm.ptr
        %1034 = llvm.load %1033 : !llvm.ptr -> !llvm.ptr
        %1035 = llvm.load %993 : !llvm.ptr -> i32
        %1036 = arith.extsi %1035 : i32 to i64
        %1037 = llvm.getelementptr %1034[%1036] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %1032 = llvm.load %1037 : !llvm.ptr -> i32
        %1038 = arith.constant 1 : i32
        %1039 = arith.cmpi eq, %1032, %1038 : i32
        cf.cond_br %1039, ^bb150, ^bb151
        ^bb150:
          %1041 = llvm.mlir.addressof @memo_n : !llvm.ptr
          %1042 = llvm.load %1041 : !llvm.ptr -> !llvm.ptr
          %1043 = llvm.load %993 : !llvm.ptr -> i32
          %1044 = arith.extsi %1043 : i32 to i64
          %1045 = llvm.getelementptr %1042[%1044] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %1040 = llvm.load %1045 : !llvm.ptr -> i32
          %1046 = arith.constant 0 : i32
          %1047 = arith.extsi %1046 : i32 to i64
          %1048 = llvm.getelementptr %arg4[%1047] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %1040, %1048 : i32, !llvm.ptr
          %1050 = llvm.mlir.addressof @memo_log2_val : !llvm.ptr
          %1051 = llvm.load %1050 : !llvm.ptr -> !llvm.ptr
          %1052 = llvm.load %993 : !llvm.ptr -> i32
          %1053 = arith.extsi %1052 : i32 to i64
          %1054 = llvm.getelementptr %1051[%1053] : (!llvm.ptr, i64) -> !llvm.ptr, f64
          %1049 = llvm.load %1054 : !llvm.ptr -> f64
          %1055 = arith.constant 0 : i32
          %1056 = arith.extsi %1055 : i32 to i64
          %1057 = llvm.getelementptr %arg5[%1056] : (!llvm.ptr, i64) -> !llvm.ptr, f64
          llvm.store %1049, %1057 : f64, !llvm.ptr
          %1059 = llvm.mlir.addressof @memo_exps_off : !llvm.ptr
          %1060 = llvm.load %1059 : !llvm.ptr -> !llvm.ptr
          %1061 = llvm.load %993 : !llvm.ptr -> i32
          %1062 = arith.extsi %1061 : i32 to i64
          %1063 = llvm.getelementptr %1060[%1062] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %1058 = llvm.load %1063 : !llvm.ptr -> i32
          %1064 = arith.constant 0 : i32
          %1065 = arith.extsi %1064 : i32 to i64
          %1066 = llvm.getelementptr %arg6[%1065] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %1058, %1066 : i32, !llvm.ptr
          %1067 = arith.constant 1 : i32
          func.return %1067 : i32
        ^bb151:
          cf.br ^bb152
        ^bb152:
        %1068 = arith.constant 0 : i32
        func.return %1068 : i32
      ^bb148:
        cf.br ^bb149
      ^bb149:
      %1069 = llvm.load %993 : !llvm.ptr -> i32
      %1070 = arith.constant 1 : i32
      %1071 = arith.addi %1069, %1070 : i32
      llvm.store %1071, %993 : i32, !llvm.ptr
      cf.br ^bb144
    ^bb146:
    %1072 = arith.constant 1 : i32
    %1074 = arith.constant 0 : i32
    %1073 = arith.subi %1074, %1072 : i32
    func.return %1073 : i32
  }
  func.func @memo_store(%arg0: i64, %arg1: i32, %arg2: i32, %arg3: i32, %arg4: i32, %arg5: i32, %arg6: f64, %arg7: i32) -> () {
    %1075 = llvm.mlir.addressof @memo_rem : !llvm.ptr
    %1076 = llvm.load %1075 : !llvm.ptr -> !llvm.ptr
    %1077 = llvm.mlir.addressof @memo_count : !llvm.ptr
    %1078 = llvm.load %1077 : !llvm.ptr -> i32
    %1079 = arith.extsi %1078 : i32 to i64
    %1080 = llvm.getelementptr %1076[%1079] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %arg0, %1080 : i64, !llvm.ptr
    %1081 = llvm.mlir.addressof @memo_idx : !llvm.ptr
    %1082 = llvm.load %1081 : !llvm.ptr -> !llvm.ptr
    %1083 = llvm.mlir.addressof @memo_count : !llvm.ptr
    %1084 = llvm.load %1083 : !llvm.ptr -> i32
    %1085 = arith.extsi %1084 : i32 to i64
    %1086 = llvm.getelementptr %1082[%1085] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %arg1, %1086 : i32, !llvm.ptr
    %1087 = llvm.mlir.addressof @memo_prev_f : !llvm.ptr
    %1088 = llvm.load %1087 : !llvm.ptr -> !llvm.ptr
    %1089 = llvm.mlir.addressof @memo_count : !llvm.ptr
    %1090 = llvm.load %1089 : !llvm.ptr -> i32
    %1091 = arith.extsi %1090 : i32 to i64
    %1092 = llvm.getelementptr %1088[%1091] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %arg2, %1092 : i32, !llvm.ptr
    %1093 = llvm.mlir.addressof @memo_pset : !llvm.ptr
    %1094 = llvm.load %1093 : !llvm.ptr -> !llvm.ptr
    %1095 = llvm.mlir.addressof @memo_count : !llvm.ptr
    %1096 = llvm.load %1095 : !llvm.ptr -> i32
    %1097 = arith.extsi %1096 : i32 to i64
    %1098 = llvm.getelementptr %1094[%1097] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %arg3, %1098 : i32, !llvm.ptr
    %1099 = llvm.mlir.addressof @memo_valid : !llvm.ptr
    %1100 = llvm.load %1099 : !llvm.ptr -> !llvm.ptr
    %1101 = llvm.mlir.addressof @memo_count : !llvm.ptr
    %1102 = llvm.load %1101 : !llvm.ptr -> i32
    %1103 = arith.extsi %1102 : i32 to i64
    %1104 = llvm.getelementptr %1100[%1103] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %arg4, %1104 : i32, !llvm.ptr
    %1105 = arith.constant 1 : i32
    %1106 = arith.cmpi eq, %arg4, %1105 : i32
    cf.cond_br %1106, ^bb153, ^bb154
    ^bb153:
      %1107 = llvm.mlir.addressof @memo_n : !llvm.ptr
      %1108 = llvm.load %1107 : !llvm.ptr -> !llvm.ptr
      %1109 = llvm.mlir.addressof @memo_count : !llvm.ptr
      %1110 = llvm.load %1109 : !llvm.ptr -> i32
      %1111 = arith.extsi %1110 : i32 to i64
      %1112 = llvm.getelementptr %1108[%1111] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %arg5, %1112 : i32, !llvm.ptr
      %1113 = llvm.mlir.addressof @memo_log2_val : !llvm.ptr
      %1114 = llvm.load %1113 : !llvm.ptr -> !llvm.ptr
      %1115 = llvm.mlir.addressof @memo_count : !llvm.ptr
      %1116 = llvm.load %1115 : !llvm.ptr -> i32
      %1117 = arith.extsi %1116 : i32 to i64
      %1118 = llvm.getelementptr %1114[%1117] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      llvm.store %arg6, %1118 : f64, !llvm.ptr
      %1119 = llvm.mlir.addressof @memo_exps_off : !llvm.ptr
      %1120 = llvm.load %1119 : !llvm.ptr -> !llvm.ptr
      %1121 = llvm.mlir.addressof @memo_count : !llvm.ptr
      %1122 = llvm.load %1121 : !llvm.ptr -> i32
      %1123 = arith.extsi %1122 : i32 to i64
      %1124 = llvm.getelementptr %1120[%1123] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %arg7, %1124 : i32, !llvm.ptr
      cf.br ^bb155
    ^bb154:
      cf.br ^bb155
    ^bb155:
    %1125 = llvm.mlir.addressof @memo_count : !llvm.ptr
    %1126 = llvm.load %1125 : !llvm.ptr -> i32
    %1127 = arith.constant 1 : i32
    %1128 = arith.addi %1126, %1127 : i32
    %1129 = llvm.mlir.addressof @memo_count : !llvm.ptr
    llvm.store %1128, %1129 : i32, !llvm.ptr
    func.return
  }
  func.func @dfs_min_rep(%arg0: i64, %arg1: i32, %arg2: i32, %arg3: !llvm.ptr, %arg4: !llvm.ptr, %arg5: i32, %arg6: i32, %arg7: !llvm.ptr, %arg8: !llvm.ptr, %arg9: !llvm.ptr) -> i32 {
    %1130 = arith.constant 1 : i32
    %1132 = arith.extsi %1130 : i32 to i64
    %1131 = arith.cmpi eq, %arg0, %1132 : i64
    cf.cond_br %1131, ^bb156, ^bb157
    ^bb156:
      %1133 = arith.constant 0 : i32
      %1134 = arith.constant 0 : i32
      %1135 = arith.extsi %1134 : i32 to i64
      %1136 = llvm.getelementptr %arg7[%1135] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1133, %1136 : i32, !llvm.ptr
      %1137 = arith.constant 0.0 : f32
      %1138 = arith.constant 0 : i32
      %1139 = arith.extf %1137 : f32 to f64
      %1140 = arith.extsi %1138 : i32 to i64
      %1141 = llvm.getelementptr %arg8[%1140] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      llvm.store %1139, %1141 : f64, !llvm.ptr
      %1142 = arith.constant 0 : i32
      %1143 = arith.constant 0 : i32
      %1144 = arith.extsi %1143 : i32 to i64
      %1145 = llvm.getelementptr %arg9[%1144] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1142, %1145 : i32, !llvm.ptr
      %1146 = arith.constant 1 : i32
      func.return %1146 : i32
    ^bb157:
      cf.br ^bb158
    ^bb158:
    %1147 = arith.cmpi sge, %arg1, %arg5 : i32
    cf.cond_br %1147, ^bb159, ^bb160
    ^bb159:
      %1148 = arith.constant 0 : i32
      func.return %1148 : i32
    ^bb160:
      cf.br ^bb161
    ^bb161:
    %1150 = arith.constant 1 : i32
    %1151 = arith.constant 4 : i32
    %1152 = arith.extsi %1150 : i32 to i64
    %1153 = arith.extsi %1151 : i32 to i64
    %1149 = func.call @calloc(%1152, %1153) : (i64, i64) -> !llvm.ptr
    %1155 = arith.constant 1 : i32
    %1156 = arith.constant 8 : i32
    %1157 = arith.extsi %1155 : i32 to i64
    %1158 = arith.extsi %1156 : i32 to i64
    %1154 = func.call @calloc(%1157, %1158) : (i64, i64) -> !llvm.ptr
    %1160 = arith.constant 1 : i32
    %1161 = arith.constant 4 : i32
    %1162 = arith.extsi %1160 : i32 to i64
    %1163 = arith.extsi %1161 : i32 to i64
    %1159 = func.call @calloc(%1162, %1163) : (i64, i64) -> !llvm.ptr
    %1164 = func.call @memo_lookup(%arg0, %arg1, %arg2, %arg6, %1149, %1154, %1159) : (i64, i32, i32, i32, !llvm.ptr, !llvm.ptr, !llvm.ptr) -> i32
    %1165 = arith.constant 0 : i32
    %1166 = arith.cmpi sge, %1164, %1165 : i32
    cf.cond_br %1166, ^bb162, ^bb163
    ^bb162:
      %1167 = arith.constant 1 : i32
      %1168 = arith.cmpi eq, %1164, %1167 : i32
      cf.cond_br %1168, ^bb165, ^bb166
      ^bb165:
        %1170 = arith.constant 0 : i32
        %1171 = arith.extsi %1170 : i32 to i64
        %1172 = llvm.getelementptr %1149[%1171] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %1169 = llvm.load %1172 : !llvm.ptr -> i32
        %1173 = arith.constant 0 : i32
        %1174 = arith.extsi %1173 : i32 to i64
        %1175 = llvm.getelementptr %arg7[%1174] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %1169, %1175 : i32, !llvm.ptr
        %1177 = arith.constant 0 : i32
        %1178 = arith.extsi %1177 : i32 to i64
        %1179 = llvm.getelementptr %1154[%1178] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        %1176 = llvm.load %1179 : !llvm.ptr -> f64
        %1180 = arith.constant 0 : i32
        %1181 = arith.extsi %1180 : i32 to i64
        %1182 = llvm.getelementptr %arg8[%1181] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        llvm.store %1176, %1182 : f64, !llvm.ptr
        %1184 = arith.constant 0 : i32
        %1185 = arith.extsi %1184 : i32 to i64
        %1186 = llvm.getelementptr %1159[%1185] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %1183 = llvm.load %1186 : !llvm.ptr -> i32
        %1187 = arith.constant 0 : i32
        %1188 = arith.extsi %1187 : i32 to i64
        %1189 = llvm.getelementptr %arg9[%1188] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %1183, %1189 : i32, !llvm.ptr
        cf.br ^bb167
      ^bb166:
        cf.br ^bb167
      ^bb167:
      func.call @free(%1149) : (!llvm.ptr) -> ()
      func.call @free(%1154) : (!llvm.ptr) -> ()
      func.call @free(%1159) : (!llvm.ptr) -> ()
      func.return %1164 : i32
    ^bb163:
      cf.br ^bb164
    ^bb164:
    func.call @free(%1149) : (!llvm.ptr) -> ()
    func.call @free(%1154) : (!llvm.ptr) -> ()
    func.call @free(%1159) : (!llvm.ptr) -> ()
    %1197 = arith.constant 20000 : i32
    %1198 = arith.constant 8 : i32
    %1199 = arith.extsi %1197 : i32 to i64
    %1200 = arith.extsi %1198 : i32 to i64
    %1196 = func.call @calloc(%1199, %1200) : (i64, i64) -> !llvm.ptr
    %1201 = func.call @odd_divisors(%arg0, %1196) : (i64, !llvm.ptr) -> i32
    %1202 = arith.constant 1 : i32
    %1204 = arith.constant 0 : i32
    %1203 = arith.subi %1204, %1202 : i32
    %1205 = llvm.mlir.constant(1 : i64) : i64
    %1206 = llvm.alloca %1205 x i32 : (i64) -> !llvm.ptr
    llvm.store %1203, %1206 : i32, !llvm.ptr
    %1207 = arith.constant 0.0 : f32
    %1208 = arith.extf %1207 : f32 to f64
    %1209 = llvm.mlir.constant(1 : i64) : i64
    %1210 = llvm.alloca %1209 x f64 : (i64) -> !llvm.ptr
    llvm.store %1208, %1210 : f64, !llvm.ptr
    %1211 = arith.constant 0 : i32
    %1212 = llvm.mlir.constant(1 : i64) : i64
    %1213 = llvm.alloca %1212 x i32 : (i64) -> !llvm.ptr
    llvm.store %1211, %1213 : i32, !llvm.ptr
    %1214 = arith.constant 0 : i32
    %1215 = llvm.mlir.constant(1 : i64) : i64
    %1216 = llvm.alloca %1215 x i32 : (i64) -> !llvm.ptr
    llvm.store %1214, %1216 : i32, !llvm.ptr
    %1217 = arith.constant 1 : i32
    %1218 = arith.subi %1201, %1217 : i32
    %1219 = llvm.mlir.constant(1 : i64) : i64
    %1220 = llvm.alloca %1219 x i32 : (i64) -> !llvm.ptr
    llvm.store %1218, %1220 : i32, !llvm.ptr
    cf.br ^bb168
    ^bb168:
    %1221 = llvm.load %1220 : !llvm.ptr -> i32
    %1222 = arith.constant 0 : i32
    %1223 = arith.cmpi sge, %1221, %1222 : i32
    cf.cond_br %1223, ^bb169, ^bb170
    ^bb169:
      %1225 = llvm.load %1220 : !llvm.ptr -> i32
      %1226 = arith.extsi %1225 : i32 to i64
      %1227 = llvm.getelementptr %1196[%1226] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %1224 = llvm.load %1227 : !llvm.ptr -> i64
      %1228 = arith.constant 1 : i32
      %1230 = arith.extsi %1228 : i32 to i64
      %1229 = arith.cmpi eq, %1224, %1230 : i64
      cf.cond_br %1229, ^bb171, ^bb172
      ^bb171:
        %1231 = llvm.load %1220 : !llvm.ptr -> i32
        %1232 = arith.constant 1 : i32
        %1233 = arith.subi %1231, %1232 : i32
        llvm.store %1233, %1220 : i32, !llvm.ptr
        cf.br ^bb168
      ^bb172:
        cf.br ^bb173
      ^bb173:
      %1234 = arith.extsi %arg2 : i32 to i64
      %1235 = arith.cmpi sgt, %1224, %1234 : i64
      cf.cond_br %1235, ^bb174, ^bb175
      ^bb174:
        %1236 = llvm.load %1220 : !llvm.ptr -> i32
        %1237 = arith.constant 1 : i32
        %1238 = arith.subi %1236, %1237 : i32
        llvm.store %1238, %1220 : i32, !llvm.ptr
        cf.br ^bb168
      ^bb175:
        cf.br ^bb176
      ^bb176:
      %1239 = arith.constant 1 : i32
      %1241 = arith.extsi %1239 : i32 to i64
      %1240 = arith.subi %1224, %1241 : i64
      %1242 = arith.constant 2 : i32
      %1244 = arith.extsi %1242 : i32 to i64
      %1243 = arith.divsi %1240, %1244 : i64
      %1245 = arith.trunci %1243 : i64 to i32
      %1246 = arith.constant 0 : i32
      %1247 = arith.cmpi sle, %1245, %1246 : i32
      cf.cond_br %1247, ^bb177, ^bb178
      ^bb177:
        %1248 = llvm.load %1220 : !llvm.ptr -> i32
        %1249 = arith.constant 1 : i32
        %1250 = arith.subi %1248, %1249 : i32
        llvm.store %1250, %1220 : i32, !llvm.ptr
        cf.br ^bb168
      ^bb178:
        cf.br ^bb179
      ^bb179:
      %1252 = arith.constant 1 : i32
      %1253 = arith.constant 4 : i32
      %1254 = arith.extsi %1252 : i32 to i64
      %1255 = arith.extsi %1253 : i32 to i64
      %1251 = func.call @calloc(%1254, %1255) : (i64, i64) -> !llvm.ptr
      %1257 = arith.constant 1 : i32
      %1258 = arith.constant 8 : i32
      %1259 = arith.extsi %1257 : i32 to i64
      %1260 = arith.extsi %1258 : i32 to i64
      %1256 = func.call @calloc(%1259, %1260) : (i64, i64) -> !llvm.ptr
      %1262 = arith.constant 1 : i32
      %1263 = arith.constant 4 : i32
      %1264 = arith.extsi %1262 : i32 to i64
      %1265 = arith.extsi %1263 : i32 to i64
      %1261 = func.call @calloc(%1264, %1265) : (i64, i64) -> !llvm.ptr
      %1267 = arith.divsi %arg0, %1224 : i64
      %1268 = arith.constant 1 : i32
      %1269 = arith.addi %arg1, %1268 : i32
      %1270 = arith.trunci %1224 : i64 to i32
      %1266 = func.call @dfs_min_rep(%1267, %1269, %1270, %arg3, %arg4, %arg5, %arg6, %1251, %1256, %1261) : (i64, i32, i32, !llvm.ptr, !llvm.ptr, i32, i32, !llvm.ptr, !llvm.ptr, !llvm.ptr) -> i32
      %1271 = arith.constant 1 : i32
      %1272 = arith.cmpi eq, %1266, %1271 : i32
      cf.cond_br %1272, ^bb180, ^bb181
      ^bb180:
        %1274 = arith.extsi %arg1 : i32 to i64
        %1275 = llvm.getelementptr %arg4[%1274] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        %1273 = llvm.load %1275 : !llvm.ptr -> f64
        %1276 = arith.sitofp %1245 : i32 to f64
        %1277 = arith.mulf %1273, %1276 : f64
        %1279 = arith.constant 0 : i32
        %1280 = arith.extsi %1279 : i32 to i64
        %1281 = llvm.getelementptr %1256[%1280] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        %1278 = llvm.load %1281 : !llvm.ptr -> f64
        %1282 = arith.addf %1277, %1278 : f64
        %1283 = llvm.load %1206 : !llvm.ptr -> i32
        %1284 = arith.constant 0 : i32
        %1285 = arith.cmpi slt, %1283, %1284 : i32
        %1286 = scf.if %1285 -> (i1) {
          %1287 = arith.constant true
          scf.yield %1287 : i1
        } else {
          %1288 = llvm.load %1210 : !llvm.ptr -> f64
          %1289 = arith.cmpf olt, %1282, %1288 : f64
          scf.yield %1289 : i1
        }
        cf.cond_br %1286, ^bb183, ^bb184
        ^bb183:
          %1291 = arith.constant 0 : i32
          %1292 = arith.extsi %1291 : i32 to i64
          %1293 = llvm.getelementptr %1251[%1292] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %1290 = llvm.load %1293 : !llvm.ptr -> i32
          %1294 = arith.constant 1 : i32
          %1295 = arith.addi %1290, %1294 : i32
          llvm.store %1295, %1206 : i32, !llvm.ptr
          %1297 = llvm.load %1206 : !llvm.ptr -> i32
          %1296 = func.call @alloc_exps(%1297) : (i32) -> i32
          %1298 = llvm.mlir.addressof @exps_pool : !llvm.ptr
          %1299 = llvm.load %1298 : !llvm.ptr -> !llvm.ptr
          %1300 = arith.extsi %1296 : i32 to i64
          %1301 = llvm.getelementptr %1299[%1300] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %1245, %1301 : i32, !llvm.ptr
          %1302 = arith.constant 0 : i32
          %1303 = llvm.mlir.constant(1 : i64) : i64
          %1304 = llvm.alloca %1303 x i32 : (i64) -> !llvm.ptr
          llvm.store %1302, %1304 : i32, !llvm.ptr
          cf.br ^bb186
          ^bb186:
          %1305 = llvm.load %1304 : !llvm.ptr -> i32
          %1307 = arith.constant 0 : i32
          %1308 = arith.extsi %1307 : i32 to i64
          %1309 = llvm.getelementptr %1251[%1308] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %1306 = llvm.load %1309 : !llvm.ptr -> i32
          %1310 = arith.cmpi slt, %1305, %1306 : i32
          cf.cond_br %1310, ^bb187, ^bb188
          ^bb187:
            %1312 = llvm.mlir.addressof @exps_pool : !llvm.ptr
            %1313 = llvm.load %1312 : !llvm.ptr -> !llvm.ptr
            %1315 = arith.constant 0 : i32
            %1316 = arith.extsi %1315 : i32 to i64
            %1317 = llvm.getelementptr %1261[%1316] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            %1314 = llvm.load %1317 : !llvm.ptr -> i32
            %1318 = llvm.load %1304 : !llvm.ptr -> i32
            %1319 = arith.addi %1314, %1318 : i32
            %1320 = arith.extsi %1319 : i32 to i64
            %1321 = llvm.getelementptr %1313[%1320] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            %1311 = llvm.load %1321 : !llvm.ptr -> i32
            %1322 = llvm.mlir.addressof @exps_pool : !llvm.ptr
            %1323 = llvm.load %1322 : !llvm.ptr -> !llvm.ptr
            %1324 = arith.constant 1 : i32
            %1325 = arith.addi %1296, %1324 : i32
            %1326 = llvm.load %1304 : !llvm.ptr -> i32
            %1327 = arith.addi %1325, %1326 : i32
            %1328 = arith.extsi %1327 : i32 to i64
            %1329 = llvm.getelementptr %1323[%1328] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            llvm.store %1311, %1329 : i32, !llvm.ptr
            %1330 = llvm.load %1304 : !llvm.ptr -> i32
            %1331 = arith.constant 1 : i32
            %1332 = arith.addi %1330, %1331 : i32
            llvm.store %1332, %1304 : i32, !llvm.ptr
            cf.br ^bb186
          ^bb188:
          llvm.store %1296, %1213 : i32, !llvm.ptr
          llvm.store %1282, %1210 : f64, !llvm.ptr
          cf.br ^bb185
        ^bb184:
          cf.br ^bb185
        ^bb185:
        %1333 = arith.constant 1 : i32
        llvm.store %1333, %1216 : i32, !llvm.ptr
        cf.br ^bb182
      ^bb181:
        cf.br ^bb182
      ^bb182:
      func.call @free(%1251) : (!llvm.ptr) -> ()
      func.call @free(%1256) : (!llvm.ptr) -> ()
      func.call @free(%1261) : (!llvm.ptr) -> ()
      %1337 = llvm.load %1220 : !llvm.ptr -> i32
      %1338 = arith.constant 1 : i32
      %1339 = arith.subi %1337, %1338 : i32
      llvm.store %1339, %1220 : i32, !llvm.ptr
      cf.br ^bb168
    ^bb170:
    func.call @free(%1196) : (!llvm.ptr) -> ()
    %1341 = llvm.load %1216 : !llvm.ptr -> i32
    %1342 = arith.constant 1 : i32
    %1343 = arith.cmpi eq, %1341, %1342 : i32
    cf.cond_br %1343, ^bb189, ^bb190
    ^bb189:
      %1344 = llvm.load %1206 : !llvm.ptr -> i32
      %1345 = arith.constant 0 : i32
      %1346 = arith.extsi %1345 : i32 to i64
      %1347 = llvm.getelementptr %arg7[%1346] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1344, %1347 : i32, !llvm.ptr
      %1348 = llvm.load %1210 : !llvm.ptr -> f64
      %1349 = arith.constant 0 : i32
      %1350 = arith.extsi %1349 : i32 to i64
      %1351 = llvm.getelementptr %arg8[%1350] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      llvm.store %1348, %1351 : f64, !llvm.ptr
      %1352 = llvm.load %1213 : !llvm.ptr -> i32
      %1353 = arith.constant 0 : i32
      %1354 = arith.extsi %1353 : i32 to i64
      %1355 = llvm.getelementptr %arg9[%1354] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1352, %1355 : i32, !llvm.ptr
      %1357 = arith.constant 1 : i32
      %1358 = llvm.load %1206 : !llvm.ptr -> i32
      %1359 = llvm.load %1210 : !llvm.ptr -> f64
      %1360 = llvm.load %1213 : !llvm.ptr -> i32
      func.call @memo_store(%arg0, %arg1, %arg2, %arg6, %1357, %1358, %1359, %1360) : (i64, i32, i32, i32, i32, i32, f64, i32) -> ()
      %1361 = arith.constant 1 : i32
      func.return %1361 : i32
    ^bb190:
      cf.br ^bb191
    ^bb191:
    %1363 = arith.constant 0 : i32
    %1364 = arith.constant 0 : i32
    %1365 = arith.constant 0.0 : f32
    %1366 = arith.constant 0 : i32
    %1367 = arith.extf %1365 : f32 to f64
    func.call @memo_store(%arg0, %arg1, %arg2, %arg6, %1363, %1364, %1367, %1366) : (i64, i32, i32, i32, i32, i32, f64, i32) -> ()
    %1368 = arith.constant 0 : i32
    func.return %1368 : i32
  }
  func.func @min_rep_for_product(%arg0: i64, %arg1: !llvm.ptr, %arg2: !llvm.ptr, %arg3: i32, %arg4: i32, %arg5: !llvm.ptr, %arg6: !llvm.ptr, %arg7: !llvm.ptr) -> () {
    %1369 = arith.constant 1 : i32
    %1371 = arith.constant 0 : i32
    %1370 = arith.subi %1371, %1369 : i32
    %1372 = arith.constant 0 : i32
    %1373 = arith.extsi %1372 : i32 to i64
    %1374 = llvm.getelementptr %arg5[%1373] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %1370, %1374 : i32, !llvm.ptr
    %1375 = arith.constant 1 : i32
    %1377 = arith.extsi %1375 : i32 to i64
    %1376 = arith.cmpi eq, %arg0, %1377 : i64
    cf.cond_br %1376, ^bb192, ^bb193
    ^bb192:
      %1378 = arith.constant 0 : i32
      %1379 = arith.constant 0 : i32
      %1380 = arith.extsi %1379 : i32 to i64
      %1381 = llvm.getelementptr %arg5[%1380] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1378, %1381 : i32, !llvm.ptr
      %1382 = arith.constant 0.0 : f32
      %1383 = arith.constant 0 : i32
      %1384 = arith.extf %1382 : f32 to f64
      %1385 = arith.extsi %1383 : i32 to i64
      %1386 = llvm.getelementptr %arg6[%1385] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      llvm.store %1384, %1386 : f64, !llvm.ptr
      %1387 = arith.constant 0 : i32
      %1388 = arith.constant 0 : i32
      %1389 = arith.extsi %1388 : i32 to i64
      %1390 = llvm.getelementptr %arg7[%1389] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1387, %1390 : i32, !llvm.ptr
      func.return
    ^bb193:
      cf.br ^bb194
    ^bb194:
    %1392 = arith.constant 0 : i32
    %1393 = arith.trunci %arg0 : i64 to i32
    %1391 = func.call @dfs_min_rep(%arg0, %1392, %1393, %arg1, %arg2, %arg3, %arg4, %arg5, %arg6, %arg7) : (i64, i32, i32, !llvm.ptr, !llvm.ptr, i32, i32, !llvm.ptr, !llvm.ptr, !llvm.ptr) -> i32
    func.return
  }
  func.func @best_rep_for_D(%arg0: i64, %arg1: !llvm.ptr, %arg2: !llvm.ptr, %arg3: !llvm.ptr, %arg4: !llvm.ptr, %arg5: !llvm.ptr) -> i32 {
    %1394 = arith.constant 1 : i32
    %1396 = arith.extsi %1394 : i32 to i64
    %1395 = arith.cmpi eq, %arg0, %1396 : i64
    cf.cond_br %1395, ^bb195, ^bb196
    ^bb195:
      %1397 = arith.constant 0 : i32
      %1398 = arith.constant 0 : i32
      %1399 = arith.extsi %1397 : i32 to i64
      %1400 = arith.extsi %1398 : i32 to i64
      %1401 = llvm.getelementptr %arg1[%1400] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %1399, %1401 : i64, !llvm.ptr
      %1402 = arith.constant 0 : i32
      %1403 = arith.constant 0 : i32
      %1404 = arith.extsi %1403 : i32 to i64
      %1405 = llvm.getelementptr %arg3[%1404] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1402, %1405 : i32, !llvm.ptr
      %1406 = arith.constant 0.0 : f32
      %1407 = arith.constant 0 : i32
      %1408 = arith.extf %1406 : f32 to f64
      %1409 = arith.extsi %1407 : i32 to i64
      %1410 = llvm.getelementptr %arg4[%1409] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      llvm.store %1408, %1410 : f64, !llvm.ptr
      %1411 = arith.constant 0 : i32
      %1412 = arith.constant 0 : i32
      %1413 = arith.extsi %1412 : i32 to i64
      %1414 = llvm.getelementptr %arg5[%1413] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1411, %1414 : i32, !llvm.ptr
      %1415 = arith.constant 0.0 : f32
      %1416 = arith.constant 0 : i32
      %1417 = arith.extf %1415 : f32 to f64
      %1418 = arith.extsi %1416 : i32 to i64
      %1419 = llvm.getelementptr %arg2[%1418] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      llvm.store %1417, %1419 : f64, !llvm.ptr
      %1420 = arith.constant 1 : i32
      func.return %1420 : i32
    ^bb196:
      cf.br ^bb197
    ^bb197:
    %1421 = arith.constant 0 : i32
    %1422 = llvm.mlir.constant(1 : i64) : i64
    %1423 = llvm.alloca %1422 x i32 : (i64) -> !llvm.ptr
    llvm.store %1421, %1423 : i32, !llvm.ptr
    cf.br ^bb198
    ^bb198:
    %1424 = llvm.load %1423 : !llvm.ptr -> i32
    %1425 = llvm.mlir.addressof @d_count : !llvm.ptr
    %1426 = llvm.load %1425 : !llvm.ptr -> i32
    %1427 = arith.cmpi slt, %1424, %1426 : i32
    cf.cond_br %1427, ^bb199, ^bb200
    ^bb199:
      %1429 = llvm.mlir.addressof @d_keys : !llvm.ptr
      %1430 = llvm.load %1429 : !llvm.ptr -> !llvm.ptr
      %1431 = llvm.load %1423 : !llvm.ptr -> i32
      %1432 = arith.extsi %1431 : i32 to i64
      %1433 = llvm.getelementptr %1430[%1432] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %1428 = llvm.load %1433 : !llvm.ptr -> i64
      %1434 = arith.cmpi eq, %1428, %arg0 : i64
      cf.cond_br %1434, ^bb201, ^bb202
      ^bb201:
        %1436 = llvm.mlir.addressof @d_e2 : !llvm.ptr
        %1437 = llvm.load %1436 : !llvm.ptr -> !llvm.ptr
        %1438 = llvm.load %1423 : !llvm.ptr -> i32
        %1439 = arith.extsi %1438 : i32 to i64
        %1440 = llvm.getelementptr %1437[%1439] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %1435 = llvm.load %1440 : !llvm.ptr -> i64
        %1441 = arith.constant 0 : i32
        %1442 = arith.extsi %1441 : i32 to i64
        %1443 = llvm.getelementptr %arg1[%1442] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %1435, %1443 : i64, !llvm.ptr
        %1445 = llvm.mlir.addressof @d_log2 : !llvm.ptr
        %1446 = llvm.load %1445 : !llvm.ptr -> !llvm.ptr
        %1447 = llvm.load %1423 : !llvm.ptr -> i32
        %1448 = arith.extsi %1447 : i32 to i64
        %1449 = llvm.getelementptr %1446[%1448] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        %1444 = llvm.load %1449 : !llvm.ptr -> f64
        %1450 = arith.constant 0 : i32
        %1451 = arith.extsi %1450 : i32 to i64
        %1452 = llvm.getelementptr %arg2[%1451] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        llvm.store %1444, %1452 : f64, !llvm.ptr
        %1454 = llvm.mlir.addressof @d_rep3_n : !llvm.ptr
        %1455 = llvm.load %1454 : !llvm.ptr -> !llvm.ptr
        %1456 = llvm.load %1423 : !llvm.ptr -> i32
        %1457 = arith.extsi %1456 : i32 to i64
        %1458 = llvm.getelementptr %1455[%1457] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %1453 = llvm.load %1458 : !llvm.ptr -> i32
        %1459 = arith.constant 0 : i32
        %1460 = arith.extsi %1459 : i32 to i64
        %1461 = llvm.getelementptr %arg3[%1460] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %1453, %1461 : i32, !llvm.ptr
        %1463 = llvm.mlir.addressof @d_rep3_log2 : !llvm.ptr
        %1464 = llvm.load %1463 : !llvm.ptr -> !llvm.ptr
        %1465 = llvm.load %1423 : !llvm.ptr -> i32
        %1466 = arith.extsi %1465 : i32 to i64
        %1467 = llvm.getelementptr %1464[%1466] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        %1462 = llvm.load %1467 : !llvm.ptr -> f64
        %1468 = arith.constant 0 : i32
        %1469 = arith.extsi %1468 : i32 to i64
        %1470 = llvm.getelementptr %arg4[%1469] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        llvm.store %1462, %1470 : f64, !llvm.ptr
        %1472 = llvm.mlir.addressof @d_rep3_off : !llvm.ptr
        %1473 = llvm.load %1472 : !llvm.ptr -> !llvm.ptr
        %1474 = llvm.load %1423 : !llvm.ptr -> i32
        %1475 = arith.extsi %1474 : i32 to i64
        %1476 = llvm.getelementptr %1473[%1475] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %1471 = llvm.load %1476 : !llvm.ptr -> i32
        %1477 = arith.constant 0 : i32
        %1478 = arith.extsi %1477 : i32 to i64
        %1479 = llvm.getelementptr %arg5[%1478] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %1471, %1479 : i32, !llvm.ptr
        %1480 = arith.constant 1 : i32
        func.return %1480 : i32
      ^bb202:
        cf.br ^bb203
      ^bb203:
      %1481 = llvm.load %1423 : !llvm.ptr -> i32
      %1482 = arith.constant 1 : i32
      %1483 = arith.addi %1481, %1482 : i32
      llvm.store %1483, %1423 : i32, !llvm.ptr
      cf.br ^bb198
    ^bb200:
    %1485 = arith.constant 20000 : i32
    %1486 = arith.constant 8 : i32
    %1487 = arith.extsi %1485 : i32 to i64
    %1488 = arith.extsi %1486 : i32 to i64
    %1484 = func.call @calloc(%1487, %1488) : (i64, i64) -> !llvm.ptr
    %1489 = func.call @odd_divisors(%arg0, %1484) : (i64, !llvm.ptr) -> i32
    %1490 = arith.constant 1 : i32
    %1492 = arith.constant 0 : i32
    %1491 = arith.subi %1492, %1490 : i32
    %1493 = arith.extsi %1491 : i32 to i64
    %1494 = llvm.mlir.constant(1 : i64) : i64
    %1495 = llvm.alloca %1494 x i64 : (i64) -> !llvm.ptr
    llvm.store %1493, %1495 : i64, !llvm.ptr
    %1496 = arith.constant 0.0 : f32
    %1497 = arith.extf %1496 : f32 to f64
    %1498 = llvm.mlir.constant(1 : i64) : i64
    %1499 = llvm.alloca %1498 x f64 : (i64) -> !llvm.ptr
    llvm.store %1497, %1499 : f64, !llvm.ptr
    %1500 = arith.constant 0 : i32
    %1501 = llvm.mlir.constant(1 : i64) : i64
    %1502 = llvm.alloca %1501 x i32 : (i64) -> !llvm.ptr
    llvm.store %1500, %1502 : i32, !llvm.ptr
    %1503 = arith.constant 0.0 : f32
    %1504 = arith.extf %1503 : f32 to f64
    %1505 = llvm.mlir.constant(1 : i64) : i64
    %1506 = llvm.alloca %1505 x f64 : (i64) -> !llvm.ptr
    llvm.store %1504, %1506 : f64, !llvm.ptr
    %1507 = arith.constant 0 : i32
    %1508 = llvm.mlir.constant(1 : i64) : i64
    %1509 = llvm.alloca %1508 x i32 : (i64) -> !llvm.ptr
    llvm.store %1507, %1509 : i32, !llvm.ptr
    %1510 = arith.constant 0 : i32
    %1511 = llvm.mlir.constant(1 : i64) : i64
    %1512 = llvm.alloca %1511 x i32 : (i64) -> !llvm.ptr
    llvm.store %1510, %1512 : i32, !llvm.ptr
    %1513 = arith.constant 0 : i32
    %1514 = llvm.mlir.constant(1 : i64) : i64
    %1515 = llvm.alloca %1514 x i32 : (i64) -> !llvm.ptr
    llvm.store %1513, %1515 : i32, !llvm.ptr
    cf.br ^bb204
    ^bb204:
    %1516 = llvm.load %1515 : !llvm.ptr -> i32
    %1517 = arith.cmpi slt, %1516, %1489 : i32
    cf.cond_br %1517, ^bb205, ^bb206
    ^bb205:
      %1519 = llvm.load %1515 : !llvm.ptr -> i32
      %1520 = arith.extsi %1519 : i32 to i64
      %1521 = llvm.getelementptr %1484[%1520] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %1518 = llvm.load %1521 : !llvm.ptr -> i64
      %1522 = arith.constant 1 : i32
      %1524 = arith.extsi %1522 : i32 to i64
      %1523 = arith.cmpi eq, %1518, %1524 : i64
      %1525 = scf.if %1523 -> (i32) {
        %1526 = arith.constant 0 : i32
        scf.yield %1526 : i32
      } else {
        %1527 = arith.constant 1 : i32
        %1529 = arith.extsi %1527 : i32 to i64
        %1528 = arith.addi %1518, %1529 : i64
        %1530 = arith.constant 2 : i32
        %1532 = arith.extsi %1530 : i32 to i64
        %1531 = arith.divsi %1528, %1532 : i64
        scf.yield %1531 : i64
      }
      %1533 = arith.extsi %1525 : i32 to i64
      %1534 = arith.divsi %arg0, %1518 : i64
      %1536 = arith.constant 1 : i32
      %1537 = arith.constant 4 : i32
      %1538 = arith.extsi %1536 : i32 to i64
      %1539 = arith.extsi %1537 : i32 to i64
      %1535 = func.call @calloc(%1538, %1539) : (i64, i64) -> !llvm.ptr
      %1541 = arith.constant 1 : i32
      %1542 = arith.constant 8 : i32
      %1543 = arith.extsi %1541 : i32 to i64
      %1544 = arith.extsi %1542 : i32 to i64
      %1540 = func.call @calloc(%1543, %1544) : (i64, i64) -> !llvm.ptr
      %1546 = arith.constant 1 : i32
      %1547 = arith.constant 4 : i32
      %1548 = arith.extsi %1546 : i32 to i64
      %1549 = arith.extsi %1547 : i32 to i64
      %1545 = func.call @calloc(%1548, %1549) : (i64, i64) -> !llvm.ptr
      %1551 = llvm.mlir.addressof @primes_p3 : !llvm.ptr
      %1552 = llvm.load %1551 : !llvm.ptr -> !llvm.ptr
      %1553 = llvm.mlir.addressof @log2_p3 : !llvm.ptr
      %1554 = llvm.load %1553 : !llvm.ptr -> !llvm.ptr
      %1555 = llvm.mlir.addressof @np3 : !llvm.ptr
      %1556 = llvm.load %1555 : !llvm.ptr -> i32
      %1557 = arith.constant 1 : i32
      func.call @min_rep_for_product(%1534, %1552, %1554, %1556, %1557, %1535, %1540, %1545) : (i64, !llvm.ptr, !llvm.ptr, i32, i32, !llvm.ptr, !llvm.ptr, !llvm.ptr) -> ()
      %1559 = arith.constant 0 : i32
      %1560 = arith.extsi %1559 : i32 to i64
      %1561 = llvm.getelementptr %1535[%1560] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %1558 = llvm.load %1561 : !llvm.ptr -> i32
      %1562 = arith.constant 0 : i32
      %1563 = arith.cmpi sge, %1558, %1562 : i32
      cf.cond_br %1563, ^bb207, ^bb208
      ^bb207:
        %1564 = llvm.mlir.addressof @log2_2 : !llvm.ptr
        %1565 = llvm.load %1564 : !llvm.ptr -> f64
        %1566 = arith.sitofp %1533 : i64 to f64
        %1567 = arith.mulf %1565, %1566 : f64
        %1569 = arith.constant 0 : i32
        %1570 = arith.extsi %1569 : i32 to i64
        %1571 = llvm.getelementptr %1540[%1570] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        %1568 = llvm.load %1571 : !llvm.ptr -> f64
        %1572 = arith.addf %1567, %1568 : f64
        %1573 = llvm.load %1512 : !llvm.ptr -> i32
        %1574 = arith.constant 0 : i32
        %1575 = arith.cmpi eq, %1573, %1574 : i32
        %1576 = scf.if %1575 -> (i1) {
          %1577 = arith.constant true
          scf.yield %1577 : i1
        } else {
          %1578 = llvm.load %1499 : !llvm.ptr -> f64
          %1579 = arith.cmpf olt, %1572, %1578 : f64
          scf.yield %1579 : i1
        }
        cf.cond_br %1576, ^bb210, ^bb211
        ^bb210:
          llvm.store %1533, %1495 : i64, !llvm.ptr
          %1581 = arith.constant 0 : i32
          %1582 = arith.extsi %1581 : i32 to i64
          %1583 = llvm.getelementptr %1535[%1582] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %1580 = llvm.load %1583 : !llvm.ptr -> i32
          llvm.store %1580, %1502 : i32, !llvm.ptr
          %1585 = arith.constant 0 : i32
          %1586 = arith.extsi %1585 : i32 to i64
          %1587 = llvm.getelementptr %1540[%1586] : (!llvm.ptr, i64) -> !llvm.ptr, f64
          %1584 = llvm.load %1587 : !llvm.ptr -> f64
          llvm.store %1584, %1506 : f64, !llvm.ptr
          %1589 = arith.constant 0 : i32
          %1590 = arith.extsi %1589 : i32 to i64
          %1591 = llvm.getelementptr %1545[%1590] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %1588 = llvm.load %1591 : !llvm.ptr -> i32
          llvm.store %1588, %1509 : i32, !llvm.ptr
          llvm.store %1572, %1499 : f64, !llvm.ptr
          %1592 = arith.constant 1 : i32
          llvm.store %1592, %1512 : i32, !llvm.ptr
          cf.br ^bb212
        ^bb211:
          cf.br ^bb212
        ^bb212:
        cf.br ^bb209
      ^bb208:
        cf.br ^bb209
      ^bb209:
      func.call @free(%1535) : (!llvm.ptr) -> ()
      func.call @free(%1540) : (!llvm.ptr) -> ()
      func.call @free(%1545) : (!llvm.ptr) -> ()
      %1596 = llvm.load %1515 : !llvm.ptr -> i32
      %1597 = arith.constant 1 : i32
      %1598 = arith.addi %1596, %1597 : i32
      llvm.store %1598, %1515 : i32, !llvm.ptr
      cf.br ^bb204
    ^bb206:
    func.call @free(%1484) : (!llvm.ptr) -> ()
    %1600 = llvm.load %1512 : !llvm.ptr -> i32
    %1601 = arith.constant 1 : i32
    %1602 = arith.cmpi eq, %1600, %1601 : i32
    cf.cond_br %1602, ^bb213, ^bb214
    ^bb213:
      %1603 = llvm.load %1495 : !llvm.ptr -> i64
      %1604 = arith.constant 0 : i32
      %1605 = arith.extsi %1604 : i32 to i64
      %1606 = llvm.getelementptr %arg1[%1605] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %1603, %1606 : i64, !llvm.ptr
      %1607 = llvm.load %1499 : !llvm.ptr -> f64
      %1608 = arith.constant 0 : i32
      %1609 = arith.extsi %1608 : i32 to i64
      %1610 = llvm.getelementptr %arg2[%1609] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      llvm.store %1607, %1610 : f64, !llvm.ptr
      %1611 = llvm.load %1502 : !llvm.ptr -> i32
      %1612 = arith.constant 0 : i32
      %1613 = arith.extsi %1612 : i32 to i64
      %1614 = llvm.getelementptr %arg3[%1613] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1611, %1614 : i32, !llvm.ptr
      %1615 = llvm.load %1506 : !llvm.ptr -> f64
      %1616 = arith.constant 0 : i32
      %1617 = arith.extsi %1616 : i32 to i64
      %1618 = llvm.getelementptr %arg4[%1617] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      llvm.store %1615, %1618 : f64, !llvm.ptr
      %1619 = llvm.load %1509 : !llvm.ptr -> i32
      %1620 = arith.constant 0 : i32
      %1621 = arith.extsi %1620 : i32 to i64
      %1622 = llvm.getelementptr %arg5[%1621] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1619, %1622 : i32, !llvm.ptr
      %1623 = llvm.mlir.addressof @d_keys : !llvm.ptr
      %1624 = llvm.load %1623 : !llvm.ptr -> !llvm.ptr
      %1625 = llvm.mlir.addressof @d_count : !llvm.ptr
      %1626 = llvm.load %1625 : !llvm.ptr -> i32
      %1627 = arith.extsi %1626 : i32 to i64
      %1628 = llvm.getelementptr %1624[%1627] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %arg0, %1628 : i64, !llvm.ptr
      %1629 = llvm.load %1495 : !llvm.ptr -> i64
      %1630 = llvm.mlir.addressof @d_e2 : !llvm.ptr
      %1631 = llvm.load %1630 : !llvm.ptr -> !llvm.ptr
      %1632 = llvm.mlir.addressof @d_count : !llvm.ptr
      %1633 = llvm.load %1632 : !llvm.ptr -> i32
      %1634 = arith.extsi %1633 : i32 to i64
      %1635 = llvm.getelementptr %1631[%1634] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %1629, %1635 : i64, !llvm.ptr
      %1636 = llvm.load %1499 : !llvm.ptr -> f64
      %1637 = llvm.mlir.addressof @d_log2 : !llvm.ptr
      %1638 = llvm.load %1637 : !llvm.ptr -> !llvm.ptr
      %1639 = llvm.mlir.addressof @d_count : !llvm.ptr
      %1640 = llvm.load %1639 : !llvm.ptr -> i32
      %1641 = arith.extsi %1640 : i32 to i64
      %1642 = llvm.getelementptr %1638[%1641] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      llvm.store %1636, %1642 : f64, !llvm.ptr
      %1643 = llvm.load %1502 : !llvm.ptr -> i32
      %1644 = llvm.mlir.addressof @d_rep3_n : !llvm.ptr
      %1645 = llvm.load %1644 : !llvm.ptr -> !llvm.ptr
      %1646 = llvm.mlir.addressof @d_count : !llvm.ptr
      %1647 = llvm.load %1646 : !llvm.ptr -> i32
      %1648 = arith.extsi %1647 : i32 to i64
      %1649 = llvm.getelementptr %1645[%1648] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1643, %1649 : i32, !llvm.ptr
      %1650 = llvm.load %1506 : !llvm.ptr -> f64
      %1651 = llvm.mlir.addressof @d_rep3_log2 : !llvm.ptr
      %1652 = llvm.load %1651 : !llvm.ptr -> !llvm.ptr
      %1653 = llvm.mlir.addressof @d_count : !llvm.ptr
      %1654 = llvm.load %1653 : !llvm.ptr -> i32
      %1655 = arith.extsi %1654 : i32 to i64
      %1656 = llvm.getelementptr %1652[%1655] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      llvm.store %1650, %1656 : f64, !llvm.ptr
      %1657 = llvm.load %1509 : !llvm.ptr -> i32
      %1658 = llvm.mlir.addressof @d_rep3_off : !llvm.ptr
      %1659 = llvm.load %1658 : !llvm.ptr -> !llvm.ptr
      %1660 = llvm.mlir.addressof @d_count : !llvm.ptr
      %1661 = llvm.load %1660 : !llvm.ptr -> i32
      %1662 = arith.extsi %1661 : i32 to i64
      %1663 = llvm.getelementptr %1659[%1662] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1657, %1663 : i32, !llvm.ptr
      %1664 = llvm.mlir.addressof @d_count : !llvm.ptr
      %1665 = llvm.load %1664 : !llvm.ptr -> i32
      %1666 = arith.constant 1 : i32
      %1667 = arith.addi %1665, %1666 : i32
      %1668 = llvm.mlir.addressof @d_count : !llvm.ptr
      llvm.store %1667, %1668 : i32, !llvm.ptr
      %1669 = arith.constant 1 : i32
      func.return %1669 : i32
    ^bb214:
      cf.br ^bb215
    ^bb215:
    %1670 = arith.constant 0 : i32
    func.return %1670 : i32
  }
  func.func @Q_rep(%arg0: i64, %arg1: !llvm.ptr, %arg2: !llvm.ptr, %arg3: !llvm.ptr, %arg4: !llvm.ptr, %arg5: !llvm.ptr, %arg6: !llvm.ptr, %arg7: !llvm.ptr) -> i32 {
    %1671 = arith.constant 0 : i32
    %1672 = llvm.mlir.constant(1 : i64) : i64
    %1673 = llvm.alloca %1672 x i32 : (i64) -> !llvm.ptr
    llvm.store %1671, %1673 : i32, !llvm.ptr
    cf.br ^bb216
    ^bb216:
    %1674 = llvm.load %1673 : !llvm.ptr -> i32
    %1675 = llvm.mlir.addressof @q_count : !llvm.ptr
    %1676 = llvm.load %1675 : !llvm.ptr -> i32
    %1677 = arith.cmpi slt, %1674, %1676 : i32
    cf.cond_br %1677, ^bb217, ^bb218
    ^bb217:
      %1679 = llvm.mlir.addressof @q_keys : !llvm.ptr
      %1680 = llvm.load %1679 : !llvm.ptr -> !llvm.ptr
      %1681 = llvm.load %1673 : !llvm.ptr -> i32
      %1682 = arith.extsi %1681 : i32 to i64
      %1683 = llvm.getelementptr %1680[%1682] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %1678 = llvm.load %1683 : !llvm.ptr -> i64
      %1684 = arith.cmpi eq, %1678, %arg0 : i64
      cf.cond_br %1684, ^bb219, ^bb220
      ^bb219:
        %1686 = llvm.mlir.addressof @q_e2 : !llvm.ptr
        %1687 = llvm.load %1686 : !llvm.ptr -> !llvm.ptr
        %1688 = llvm.load %1673 : !llvm.ptr -> i32
        %1689 = arith.extsi %1688 : i32 to i64
        %1690 = llvm.getelementptr %1687[%1689] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %1685 = llvm.load %1690 : !llvm.ptr -> i64
        %1691 = arith.constant 0 : i32
        %1692 = arith.extsi %1691 : i32 to i64
        %1693 = llvm.getelementptr %arg1[%1692] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %1685, %1693 : i64, !llvm.ptr
        %1695 = llvm.mlir.addressof @q_rep1_n : !llvm.ptr
        %1696 = llvm.load %1695 : !llvm.ptr -> !llvm.ptr
        %1697 = llvm.load %1673 : !llvm.ptr -> i32
        %1698 = arith.extsi %1697 : i32 to i64
        %1699 = llvm.getelementptr %1696[%1698] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %1694 = llvm.load %1699 : !llvm.ptr -> i32
        %1700 = arith.constant 0 : i32
        %1701 = arith.extsi %1700 : i32 to i64
        %1702 = llvm.getelementptr %arg2[%1701] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %1694, %1702 : i32, !llvm.ptr
        %1704 = llvm.mlir.addressof @q_rep1_log2 : !llvm.ptr
        %1705 = llvm.load %1704 : !llvm.ptr -> !llvm.ptr
        %1706 = llvm.load %1673 : !llvm.ptr -> i32
        %1707 = arith.extsi %1706 : i32 to i64
        %1708 = llvm.getelementptr %1705[%1707] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        %1703 = llvm.load %1708 : !llvm.ptr -> f64
        %1709 = arith.constant 0 : i32
        %1710 = arith.extsi %1709 : i32 to i64
        %1711 = llvm.getelementptr %arg3[%1710] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        llvm.store %1703, %1711 : f64, !llvm.ptr
        %1713 = llvm.mlir.addressof @q_rep1_off : !llvm.ptr
        %1714 = llvm.load %1713 : !llvm.ptr -> !llvm.ptr
        %1715 = llvm.load %1673 : !llvm.ptr -> i32
        %1716 = arith.extsi %1715 : i32 to i64
        %1717 = llvm.getelementptr %1714[%1716] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %1712 = llvm.load %1717 : !llvm.ptr -> i32
        %1718 = arith.constant 0 : i32
        %1719 = arith.extsi %1718 : i32 to i64
        %1720 = llvm.getelementptr %arg4[%1719] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %1712, %1720 : i32, !llvm.ptr
        %1722 = llvm.mlir.addressof @q_rep3_n : !llvm.ptr
        %1723 = llvm.load %1722 : !llvm.ptr -> !llvm.ptr
        %1724 = llvm.load %1673 : !llvm.ptr -> i32
        %1725 = arith.extsi %1724 : i32 to i64
        %1726 = llvm.getelementptr %1723[%1725] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %1721 = llvm.load %1726 : !llvm.ptr -> i32
        %1727 = arith.constant 0 : i32
        %1728 = arith.extsi %1727 : i32 to i64
        %1729 = llvm.getelementptr %arg5[%1728] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %1721, %1729 : i32, !llvm.ptr
        %1731 = llvm.mlir.addressof @q_rep3_log2 : !llvm.ptr
        %1732 = llvm.load %1731 : !llvm.ptr -> !llvm.ptr
        %1733 = llvm.load %1673 : !llvm.ptr -> i32
        %1734 = arith.extsi %1733 : i32 to i64
        %1735 = llvm.getelementptr %1732[%1734] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        %1730 = llvm.load %1735 : !llvm.ptr -> f64
        %1736 = arith.constant 0 : i32
        %1737 = arith.extsi %1736 : i32 to i64
        %1738 = llvm.getelementptr %arg6[%1737] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        llvm.store %1730, %1738 : f64, !llvm.ptr
        %1740 = llvm.mlir.addressof @q_rep3_off : !llvm.ptr
        %1741 = llvm.load %1740 : !llvm.ptr -> !llvm.ptr
        %1742 = llvm.load %1673 : !llvm.ptr -> i32
        %1743 = arith.extsi %1742 : i32 to i64
        %1744 = llvm.getelementptr %1741[%1743] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %1739 = llvm.load %1744 : !llvm.ptr -> i32
        %1745 = arith.constant 0 : i32
        %1746 = arith.extsi %1745 : i32 to i64
        %1747 = llvm.getelementptr %arg7[%1746] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %1739, %1747 : i32, !llvm.ptr
        %1748 = arith.constant 1 : i32
        func.return %1748 : i32
      ^bb220:
        cf.br ^bb221
      ^bb221:
      %1749 = llvm.load %1673 : !llvm.ptr -> i32
      %1750 = arith.constant 1 : i32
      %1751 = arith.addi %1749, %1750 : i32
      llvm.store %1751, %1673 : i32, !llvm.ptr
      cf.br ^bb216
    ^bb218:
    %1752 = arith.constant 1 : i32
    %1754 = arith.extsi %1752 : i32 to i64
    %1753 = arith.addi %arg0, %1754 : i64
    %1756 = arith.constant 20000 : i32
    %1757 = arith.constant 8 : i32
    %1758 = arith.extsi %1756 : i32 to i64
    %1759 = arith.extsi %1757 : i32 to i64
    %1755 = func.call @calloc(%1758, %1759) : (i64, i64) -> !llvm.ptr
    %1760 = func.call @odd_divisors(%1753, %1755) : (i64, !llvm.ptr) -> i32
    %1761 = arith.constant 1 : i32
    %1763 = arith.constant 0 : i32
    %1762 = arith.subi %1763, %1761 : i32
    %1764 = arith.extsi %1762 : i32 to i64
    %1765 = llvm.mlir.constant(1 : i64) : i64
    %1766 = llvm.alloca %1765 x i64 : (i64) -> !llvm.ptr
    llvm.store %1764, %1766 : i64, !llvm.ptr
    %1767 = arith.constant 0.0 : f32
    %1768 = arith.extf %1767 : f32 to f64
    %1769 = llvm.mlir.constant(1 : i64) : i64
    %1770 = llvm.alloca %1769 x f64 : (i64) -> !llvm.ptr
    llvm.store %1768, %1770 : f64, !llvm.ptr
    %1771 = arith.constant 0 : i32
    %1772 = llvm.mlir.constant(1 : i64) : i64
    %1773 = llvm.alloca %1772 x i32 : (i64) -> !llvm.ptr
    llvm.store %1771, %1773 : i32, !llvm.ptr
    %1774 = arith.constant 0.0 : f32
    %1775 = arith.extf %1774 : f32 to f64
    %1776 = llvm.mlir.constant(1 : i64) : i64
    %1777 = llvm.alloca %1776 x f64 : (i64) -> !llvm.ptr
    llvm.store %1775, %1777 : f64, !llvm.ptr
    %1778 = arith.constant 0 : i32
    %1779 = llvm.mlir.constant(1 : i64) : i64
    %1780 = llvm.alloca %1779 x i32 : (i64) -> !llvm.ptr
    llvm.store %1778, %1780 : i32, !llvm.ptr
    %1781 = arith.constant 0 : i32
    %1782 = llvm.mlir.constant(1 : i64) : i64
    %1783 = llvm.alloca %1782 x i32 : (i64) -> !llvm.ptr
    llvm.store %1781, %1783 : i32, !llvm.ptr
    %1784 = arith.constant 0.0 : f32
    %1785 = arith.extf %1784 : f32 to f64
    %1786 = llvm.mlir.constant(1 : i64) : i64
    %1787 = llvm.alloca %1786 x f64 : (i64) -> !llvm.ptr
    llvm.store %1785, %1787 : f64, !llvm.ptr
    %1788 = arith.constant 0 : i32
    %1789 = llvm.mlir.constant(1 : i64) : i64
    %1790 = llvm.alloca %1789 x i32 : (i64) -> !llvm.ptr
    llvm.store %1788, %1790 : i32, !llvm.ptr
    %1791 = arith.constant 0 : i32
    %1792 = llvm.mlir.constant(1 : i64) : i64
    %1793 = llvm.alloca %1792 x i32 : (i64) -> !llvm.ptr
    llvm.store %1791, %1793 : i32, !llvm.ptr
    %1794 = arith.constant 0 : i32
    %1795 = llvm.mlir.constant(1 : i64) : i64
    %1796 = llvm.alloca %1795 x i32 : (i64) -> !llvm.ptr
    llvm.store %1794, %1796 : i32, !llvm.ptr
    cf.br ^bb222
    ^bb222:
    %1797 = llvm.load %1796 : !llvm.ptr -> i32
    %1798 = arith.cmpi slt, %1797, %1760 : i32
    cf.cond_br %1798, ^bb223, ^bb224
    ^bb223:
      %1800 = llvm.load %1796 : !llvm.ptr -> i32
      %1801 = arith.extsi %1800 : i32 to i64
      %1802 = llvm.getelementptr %1755[%1801] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %1799 = llvm.load %1802 : !llvm.ptr -> i64
      %1804 = arith.constant 1 : i32
      %1805 = arith.constant 4 : i32
      %1806 = arith.extsi %1804 : i32 to i64
      %1807 = arith.extsi %1805 : i32 to i64
      %1803 = func.call @calloc(%1806, %1807) : (i64, i64) -> !llvm.ptr
      %1809 = arith.constant 1 : i32
      %1810 = arith.constant 8 : i32
      %1811 = arith.extsi %1809 : i32 to i64
      %1812 = arith.extsi %1810 : i32 to i64
      %1808 = func.call @calloc(%1811, %1812) : (i64, i64) -> !llvm.ptr
      %1814 = arith.constant 1 : i32
      %1815 = arith.constant 4 : i32
      %1816 = arith.extsi %1814 : i32 to i64
      %1817 = arith.extsi %1815 : i32 to i64
      %1813 = func.call @calloc(%1816, %1817) : (i64, i64) -> !llvm.ptr
      %1819 = llvm.mlir.addressof @primes_p1 : !llvm.ptr
      %1820 = llvm.load %1819 : !llvm.ptr -> !llvm.ptr
      %1821 = llvm.mlir.addressof @log2_p1 : !llvm.ptr
      %1822 = llvm.load %1821 : !llvm.ptr -> !llvm.ptr
      %1823 = llvm.mlir.addressof @np1 : !llvm.ptr
      %1824 = llvm.load %1823 : !llvm.ptr -> i32
      %1825 = arith.constant 0 : i32
      func.call @min_rep_for_product(%1799, %1820, %1822, %1824, %1825, %1803, %1808, %1813) : (i64, !llvm.ptr, !llvm.ptr, i32, i32, !llvm.ptr, !llvm.ptr, !llvm.ptr) -> ()
      %1827 = arith.constant 0 : i32
      %1828 = arith.extsi %1827 : i32 to i64
      %1829 = llvm.getelementptr %1803[%1828] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %1826 = llvm.load %1829 : !llvm.ptr -> i32
      %1830 = arith.constant 0 : i32
      %1831 = arith.cmpi sge, %1826, %1830 : i32
      cf.cond_br %1831, ^bb225, ^bb226
      ^bb225:
        %1832 = arith.constant 2 : i32
        %1834 = arith.extsi %1832 : i32 to i64
        %1833 = arith.muli %1834, %1753 : i64
        %1835 = arith.divsi %1833, %1799 : i64
        %1836 = arith.constant 1 : i32
        %1838 = arith.extsi %1836 : i32 to i64
        %1837 = arith.subi %1835, %1838 : i64
        %1840 = arith.constant 1 : i32
        %1841 = arith.constant 8 : i32
        %1842 = arith.extsi %1840 : i32 to i64
        %1843 = arith.extsi %1841 : i32 to i64
        %1839 = func.call @calloc(%1842, %1843) : (i64, i64) -> !llvm.ptr
        %1845 = arith.constant 1 : i32
        %1846 = arith.constant 8 : i32
        %1847 = arith.extsi %1845 : i32 to i64
        %1848 = arith.extsi %1846 : i32 to i64
        %1844 = func.call @calloc(%1847, %1848) : (i64, i64) -> !llvm.ptr
        %1850 = arith.constant 1 : i32
        %1851 = arith.constant 4 : i32
        %1852 = arith.extsi %1850 : i32 to i64
        %1853 = arith.extsi %1851 : i32 to i64
        %1849 = func.call @calloc(%1852, %1853) : (i64, i64) -> !llvm.ptr
        %1855 = arith.constant 1 : i32
        %1856 = arith.constant 8 : i32
        %1857 = arith.extsi %1855 : i32 to i64
        %1858 = arith.extsi %1856 : i32 to i64
        %1854 = func.call @calloc(%1857, %1858) : (i64, i64) -> !llvm.ptr
        %1860 = arith.constant 1 : i32
        %1861 = arith.constant 4 : i32
        %1862 = arith.extsi %1860 : i32 to i64
        %1863 = arith.extsi %1861 : i32 to i64
        %1859 = func.call @calloc(%1862, %1863) : (i64, i64) -> !llvm.ptr
        %1864 = func.call @best_rep_for_D(%1837, %1839, %1844, %1849, %1854, %1859) : (i64, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr) -> i32
        %1865 = arith.constant 1 : i32
        %1866 = arith.cmpi eq, %1864, %1865 : i32
        cf.cond_br %1866, ^bb228, ^bb229
        ^bb228:
          %1868 = arith.constant 0 : i32
          %1869 = arith.extsi %1868 : i32 to i64
          %1870 = llvm.getelementptr %1808[%1869] : (!llvm.ptr, i64) -> !llvm.ptr, f64
          %1867 = llvm.load %1870 : !llvm.ptr -> f64
          %1872 = arith.constant 0 : i32
          %1873 = arith.extsi %1872 : i32 to i64
          %1874 = llvm.getelementptr %1844[%1873] : (!llvm.ptr, i64) -> !llvm.ptr, f64
          %1871 = llvm.load %1874 : !llvm.ptr -> f64
          %1875 = arith.addf %1867, %1871 : f64
          %1876 = llvm.load %1793 : !llvm.ptr -> i32
          %1877 = arith.constant 0 : i32
          %1878 = arith.cmpi eq, %1876, %1877 : i32
          %1879 = scf.if %1878 -> (i1) {
            %1880 = arith.constant true
            scf.yield %1880 : i1
          } else {
            %1881 = llvm.load %1770 : !llvm.ptr -> f64
            %1882 = arith.cmpf olt, %1875, %1881 : f64
            scf.yield %1882 : i1
          }
          cf.cond_br %1879, ^bb231, ^bb232
          ^bb231:
            %1883 = arith.constant 1 : i32
            llvm.store %1883, %1793 : i32, !llvm.ptr
            %1885 = arith.constant 0 : i32
            %1886 = arith.extsi %1885 : i32 to i64
            %1887 = llvm.getelementptr %1803[%1886] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            %1884 = llvm.load %1887 : !llvm.ptr -> i32
            llvm.store %1884, %1773 : i32, !llvm.ptr
            %1889 = arith.constant 0 : i32
            %1890 = arith.extsi %1889 : i32 to i64
            %1891 = llvm.getelementptr %1808[%1890] : (!llvm.ptr, i64) -> !llvm.ptr, f64
            %1888 = llvm.load %1891 : !llvm.ptr -> f64
            llvm.store %1888, %1777 : f64, !llvm.ptr
            %1893 = arith.constant 0 : i32
            %1894 = arith.extsi %1893 : i32 to i64
            %1895 = llvm.getelementptr %1813[%1894] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            %1892 = llvm.load %1895 : !llvm.ptr -> i32
            llvm.store %1892, %1780 : i32, !llvm.ptr
            %1897 = arith.constant 0 : i32
            %1898 = arith.extsi %1897 : i32 to i64
            %1899 = llvm.getelementptr %1839[%1898] : (!llvm.ptr, i64) -> !llvm.ptr, i64
            %1896 = llvm.load %1899 : !llvm.ptr -> i64
            llvm.store %1896, %1766 : i64, !llvm.ptr
            %1901 = arith.constant 0 : i32
            %1902 = arith.extsi %1901 : i32 to i64
            %1903 = llvm.getelementptr %1849[%1902] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            %1900 = llvm.load %1903 : !llvm.ptr -> i32
            llvm.store %1900, %1783 : i32, !llvm.ptr
            %1905 = arith.constant 0 : i32
            %1906 = arith.extsi %1905 : i32 to i64
            %1907 = llvm.getelementptr %1854[%1906] : (!llvm.ptr, i64) -> !llvm.ptr, f64
            %1904 = llvm.load %1907 : !llvm.ptr -> f64
            llvm.store %1904, %1787 : f64, !llvm.ptr
            %1909 = arith.constant 0 : i32
            %1910 = arith.extsi %1909 : i32 to i64
            %1911 = llvm.getelementptr %1859[%1910] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            %1908 = llvm.load %1911 : !llvm.ptr -> i32
            llvm.store %1908, %1790 : i32, !llvm.ptr
            llvm.store %1875, %1770 : f64, !llvm.ptr
            cf.br ^bb233
          ^bb232:
            cf.br ^bb233
          ^bb233:
          cf.br ^bb230
        ^bb229:
          cf.br ^bb230
        ^bb230:
        func.call @free(%1839) : (!llvm.ptr) -> ()
        func.call @free(%1844) : (!llvm.ptr) -> ()
        func.call @free(%1849) : (!llvm.ptr) -> ()
        func.call @free(%1854) : (!llvm.ptr) -> ()
        func.call @free(%1859) : (!llvm.ptr) -> ()
        cf.br ^bb227
      ^bb226:
        cf.br ^bb227
      ^bb227:
      func.call @free(%1803) : (!llvm.ptr) -> ()
      func.call @free(%1808) : (!llvm.ptr) -> ()
      func.call @free(%1813) : (!llvm.ptr) -> ()
      %1920 = llvm.load %1796 : !llvm.ptr -> i32
      %1921 = arith.constant 1 : i32
      %1922 = arith.addi %1920, %1921 : i32
      llvm.store %1922, %1796 : i32, !llvm.ptr
      cf.br ^bb222
    ^bb224:
    func.call @free(%1755) : (!llvm.ptr) -> ()
    %1924 = llvm.load %1793 : !llvm.ptr -> i32
    %1925 = arith.constant 1 : i32
    %1926 = arith.cmpi eq, %1924, %1925 : i32
    cf.cond_br %1926, ^bb234, ^bb235
    ^bb234:
      %1927 = llvm.load %1766 : !llvm.ptr -> i64
      %1928 = arith.constant 0 : i32
      %1929 = arith.extsi %1928 : i32 to i64
      %1930 = llvm.getelementptr %arg1[%1929] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %1927, %1930 : i64, !llvm.ptr
      %1931 = llvm.load %1773 : !llvm.ptr -> i32
      %1932 = arith.constant 0 : i32
      %1933 = arith.extsi %1932 : i32 to i64
      %1934 = llvm.getelementptr %arg2[%1933] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1931, %1934 : i32, !llvm.ptr
      %1935 = llvm.load %1777 : !llvm.ptr -> f64
      %1936 = arith.constant 0 : i32
      %1937 = arith.extsi %1936 : i32 to i64
      %1938 = llvm.getelementptr %arg3[%1937] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      llvm.store %1935, %1938 : f64, !llvm.ptr
      %1939 = llvm.load %1780 : !llvm.ptr -> i32
      %1940 = arith.constant 0 : i32
      %1941 = arith.extsi %1940 : i32 to i64
      %1942 = llvm.getelementptr %arg4[%1941] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1939, %1942 : i32, !llvm.ptr
      %1943 = llvm.load %1783 : !llvm.ptr -> i32
      %1944 = arith.constant 0 : i32
      %1945 = arith.extsi %1944 : i32 to i64
      %1946 = llvm.getelementptr %arg5[%1945] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1943, %1946 : i32, !llvm.ptr
      %1947 = llvm.load %1787 : !llvm.ptr -> f64
      %1948 = arith.constant 0 : i32
      %1949 = arith.extsi %1948 : i32 to i64
      %1950 = llvm.getelementptr %arg6[%1949] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      llvm.store %1947, %1950 : f64, !llvm.ptr
      %1951 = llvm.load %1790 : !llvm.ptr -> i32
      %1952 = arith.constant 0 : i32
      %1953 = arith.extsi %1952 : i32 to i64
      %1954 = llvm.getelementptr %arg7[%1953] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1951, %1954 : i32, !llvm.ptr
      %1955 = llvm.mlir.addressof @q_keys : !llvm.ptr
      %1956 = llvm.load %1955 : !llvm.ptr -> !llvm.ptr
      %1957 = llvm.mlir.addressof @q_count : !llvm.ptr
      %1958 = llvm.load %1957 : !llvm.ptr -> i32
      %1959 = arith.extsi %1958 : i32 to i64
      %1960 = llvm.getelementptr %1956[%1959] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %arg0, %1960 : i64, !llvm.ptr
      %1961 = llvm.load %1766 : !llvm.ptr -> i64
      %1962 = llvm.mlir.addressof @q_e2 : !llvm.ptr
      %1963 = llvm.load %1962 : !llvm.ptr -> !llvm.ptr
      %1964 = llvm.mlir.addressof @q_count : !llvm.ptr
      %1965 = llvm.load %1964 : !llvm.ptr -> i32
      %1966 = arith.extsi %1965 : i32 to i64
      %1967 = llvm.getelementptr %1963[%1966] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %1961, %1967 : i64, !llvm.ptr
      %1968 = llvm.load %1773 : !llvm.ptr -> i32
      %1969 = llvm.mlir.addressof @q_rep1_n : !llvm.ptr
      %1970 = llvm.load %1969 : !llvm.ptr -> !llvm.ptr
      %1971 = llvm.mlir.addressof @q_count : !llvm.ptr
      %1972 = llvm.load %1971 : !llvm.ptr -> i32
      %1973 = arith.extsi %1972 : i32 to i64
      %1974 = llvm.getelementptr %1970[%1973] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1968, %1974 : i32, !llvm.ptr
      %1975 = llvm.load %1777 : !llvm.ptr -> f64
      %1976 = llvm.mlir.addressof @q_rep1_log2 : !llvm.ptr
      %1977 = llvm.load %1976 : !llvm.ptr -> !llvm.ptr
      %1978 = llvm.mlir.addressof @q_count : !llvm.ptr
      %1979 = llvm.load %1978 : !llvm.ptr -> i32
      %1980 = arith.extsi %1979 : i32 to i64
      %1981 = llvm.getelementptr %1977[%1980] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      llvm.store %1975, %1981 : f64, !llvm.ptr
      %1982 = llvm.load %1780 : !llvm.ptr -> i32
      %1983 = llvm.mlir.addressof @q_rep1_off : !llvm.ptr
      %1984 = llvm.load %1983 : !llvm.ptr -> !llvm.ptr
      %1985 = llvm.mlir.addressof @q_count : !llvm.ptr
      %1986 = llvm.load %1985 : !llvm.ptr -> i32
      %1987 = arith.extsi %1986 : i32 to i64
      %1988 = llvm.getelementptr %1984[%1987] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1982, %1988 : i32, !llvm.ptr
      %1989 = llvm.load %1783 : !llvm.ptr -> i32
      %1990 = llvm.mlir.addressof @q_rep3_n : !llvm.ptr
      %1991 = llvm.load %1990 : !llvm.ptr -> !llvm.ptr
      %1992 = llvm.mlir.addressof @q_count : !llvm.ptr
      %1993 = llvm.load %1992 : !llvm.ptr -> i32
      %1994 = arith.extsi %1993 : i32 to i64
      %1995 = llvm.getelementptr %1991[%1994] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1989, %1995 : i32, !llvm.ptr
      %1996 = llvm.load %1787 : !llvm.ptr -> f64
      %1997 = llvm.mlir.addressof @q_rep3_log2 : !llvm.ptr
      %1998 = llvm.load %1997 : !llvm.ptr -> !llvm.ptr
      %1999 = llvm.mlir.addressof @q_count : !llvm.ptr
      %2000 = llvm.load %1999 : !llvm.ptr -> i32
      %2001 = arith.extsi %2000 : i32 to i64
      %2002 = llvm.getelementptr %1998[%2001] : (!llvm.ptr, i64) -> !llvm.ptr, f64
      llvm.store %1996, %2002 : f64, !llvm.ptr
      %2003 = llvm.load %1790 : !llvm.ptr -> i32
      %2004 = llvm.mlir.addressof @q_rep3_off : !llvm.ptr
      %2005 = llvm.load %2004 : !llvm.ptr -> !llvm.ptr
      %2006 = llvm.mlir.addressof @q_count : !llvm.ptr
      %2007 = llvm.load %2006 : !llvm.ptr -> i32
      %2008 = arith.extsi %2007 : i32 to i64
      %2009 = llvm.getelementptr %2005[%2008] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %2003, %2009 : i32, !llvm.ptr
      %2010 = llvm.mlir.addressof @q_count : !llvm.ptr
      %2011 = llvm.load %2010 : !llvm.ptr -> i32
      %2012 = arith.constant 1 : i32
      %2013 = arith.addi %2011, %2012 : i32
      %2014 = llvm.mlir.addressof @q_count : !llvm.ptr
      llvm.store %2013, %2014 : i32, !llvm.ptr
      %2015 = arith.constant 1 : i32
      func.return %2015 : i32
    ^bb235:
      cf.br ^bb236
    ^bb236:
    %2016 = arith.constant 0 : i32
    func.return %2016 : i32
  }
  func.func @Q_mod(%arg0: i64) -> i64 {
    %2018 = arith.constant 1 : i32
    %2019 = arith.constant 8 : i32
    %2020 = arith.extsi %2018 : i32 to i64
    %2021 = arith.extsi %2019 : i32 to i64
    %2017 = func.call @calloc(%2020, %2021) : (i64, i64) -> !llvm.ptr
    %2023 = arith.constant 1 : i32
    %2024 = arith.constant 4 : i32
    %2025 = arith.extsi %2023 : i32 to i64
    %2026 = arith.extsi %2024 : i32 to i64
    %2022 = func.call @calloc(%2025, %2026) : (i64, i64) -> !llvm.ptr
    %2028 = arith.constant 1 : i32
    %2029 = arith.constant 8 : i32
    %2030 = arith.extsi %2028 : i32 to i64
    %2031 = arith.extsi %2029 : i32 to i64
    %2027 = func.call @calloc(%2030, %2031) : (i64, i64) -> !llvm.ptr
    %2033 = arith.constant 1 : i32
    %2034 = arith.constant 4 : i32
    %2035 = arith.extsi %2033 : i32 to i64
    %2036 = arith.extsi %2034 : i32 to i64
    %2032 = func.call @calloc(%2035, %2036) : (i64, i64) -> !llvm.ptr
    %2038 = arith.constant 1 : i32
    %2039 = arith.constant 4 : i32
    %2040 = arith.extsi %2038 : i32 to i64
    %2041 = arith.extsi %2039 : i32 to i64
    %2037 = func.call @calloc(%2040, %2041) : (i64, i64) -> !llvm.ptr
    %2043 = arith.constant 1 : i32
    %2044 = arith.constant 8 : i32
    %2045 = arith.extsi %2043 : i32 to i64
    %2046 = arith.extsi %2044 : i32 to i64
    %2042 = func.call @calloc(%2045, %2046) : (i64, i64) -> !llvm.ptr
    %2048 = arith.constant 1 : i32
    %2049 = arith.constant 4 : i32
    %2050 = arith.extsi %2048 : i32 to i64
    %2051 = arith.extsi %2049 : i32 to i64
    %2047 = func.call @calloc(%2050, %2051) : (i64, i64) -> !llvm.ptr
    %2052 = func.call @Q_rep(%arg0, %2017, %2022, %2027, %2032, %2037, %2042, %2047) : (i64, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr) -> i32
    %2053 = arith.constant 1 : i32
    %2054 = arith.extsi %2053 : i32 to i64
    %2055 = llvm.mlir.constant(1 : i64) : i64
    %2056 = llvm.alloca %2055 x i64 : (i64) -> !llvm.ptr
    llvm.store %2054, %2056 : i64, !llvm.ptr
    %2057 = arith.constant 0 : i32
    %2058 = llvm.mlir.constant(1 : i64) : i64
    %2059 = llvm.alloca %2058 x i32 : (i64) -> !llvm.ptr
    llvm.store %2057, %2059 : i32, !llvm.ptr
    cf.br ^bb237
    ^bb237:
    %2060 = llvm.load %2059 : !llvm.ptr -> i32
    %2062 = arith.constant 0 : i32
    %2063 = arith.extsi %2062 : i32 to i64
    %2064 = llvm.getelementptr %2022[%2063] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %2061 = llvm.load %2064 : !llvm.ptr -> i32
    %2065 = arith.cmpi slt, %2060, %2061 : i32
    cf.cond_br %2065, ^bb238, ^bb239
    ^bb238:
      %2068 = llvm.mlir.addressof @primes_p1 : !llvm.ptr
      %2069 = llvm.load %2068 : !llvm.ptr -> !llvm.ptr
      %2070 = llvm.load %2059 : !llvm.ptr -> i32
      %2071 = arith.extsi %2070 : i32 to i64
      %2072 = llvm.getelementptr %2069[%2071] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %2067 = llvm.load %2072 : !llvm.ptr -> i32
      %2073 = arith.extsi %2067 : i32 to i64
      %2075 = llvm.mlir.addressof @exps_pool : !llvm.ptr
      %2076 = llvm.load %2075 : !llvm.ptr -> !llvm.ptr
      %2078 = arith.constant 0 : i32
      %2079 = arith.extsi %2078 : i32 to i64
      %2080 = llvm.getelementptr %2032[%2079] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %2077 = llvm.load %2080 : !llvm.ptr -> i32
      %2081 = llvm.load %2059 : !llvm.ptr -> i32
      %2082 = arith.addi %2077, %2081 : i32
      %2083 = arith.extsi %2082 : i32 to i64
      %2084 = llvm.getelementptr %2076[%2083] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %2074 = llvm.load %2084 : !llvm.ptr -> i32
      %2085 = arith.extsi %2074 : i32 to i64
      %2086 = llvm.mlir.addressof @MOD : !llvm.ptr
      %2087 = llvm.load %2086 : !llvm.ptr -> i64
      %2066 = func.call @powmod(%2073, %2085, %2087) : (i64, i64, i64) -> i64
      %2088 = llvm.load %2056 : !llvm.ptr -> i64
      %2089 = arith.muli %2088, %2066 : i64
      %2090 = llvm.mlir.addressof @MOD : !llvm.ptr
      %2091 = llvm.load %2090 : !llvm.ptr -> i64
      %2092 = arith.remsi %2089, %2091 : i64
      llvm.store %2092, %2056 : i64, !llvm.ptr
      %2093 = llvm.load %2059 : !llvm.ptr -> i32
      %2094 = arith.constant 1 : i32
      %2095 = arith.addi %2093, %2094 : i32
      llvm.store %2095, %2059 : i32, !llvm.ptr
      cf.br ^bb237
    ^bb239:
    %2097 = arith.constant 2 : i32
    %2099 = arith.constant 0 : i32
    %2100 = arith.extsi %2099 : i32 to i64
    %2101 = llvm.getelementptr %2017[%2100] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    %2098 = llvm.load %2101 : !llvm.ptr -> i64
    %2102 = llvm.mlir.addressof @MOD : !llvm.ptr
    %2103 = llvm.load %2102 : !llvm.ptr -> i64
    %2104 = arith.extsi %2097 : i32 to i64
    %2096 = func.call @powmod(%2104, %2098, %2103) : (i64, i64, i64) -> i64
    %2105 = llvm.load %2056 : !llvm.ptr -> i64
    %2106 = arith.muli %2105, %2096 : i64
    %2107 = llvm.mlir.addressof @MOD : !llvm.ptr
    %2108 = llvm.load %2107 : !llvm.ptr -> i64
    %2109 = arith.remsi %2106, %2108 : i64
    llvm.store %2109, %2056 : i64, !llvm.ptr
    %2110 = arith.constant 0 : i32
    %2111 = llvm.mlir.constant(1 : i64) : i64
    %2112 = llvm.alloca %2111 x i32 : (i64) -> !llvm.ptr
    llvm.store %2110, %2112 : i32, !llvm.ptr
    cf.br ^bb240
    ^bb240:
    %2113 = llvm.load %2112 : !llvm.ptr -> i32
    %2115 = arith.constant 0 : i32
    %2116 = arith.extsi %2115 : i32 to i64
    %2117 = llvm.getelementptr %2037[%2116] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %2114 = llvm.load %2117 : !llvm.ptr -> i32
    %2118 = arith.cmpi slt, %2113, %2114 : i32
    cf.cond_br %2118, ^bb241, ^bb242
    ^bb241:
      %2121 = llvm.mlir.addressof @primes_p3 : !llvm.ptr
      %2122 = llvm.load %2121 : !llvm.ptr -> !llvm.ptr
      %2123 = llvm.load %2112 : !llvm.ptr -> i32
      %2124 = arith.extsi %2123 : i32 to i64
      %2125 = llvm.getelementptr %2122[%2124] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %2120 = llvm.load %2125 : !llvm.ptr -> i32
      %2126 = arith.extsi %2120 : i32 to i64
      %2128 = llvm.mlir.addressof @exps_pool : !llvm.ptr
      %2129 = llvm.load %2128 : !llvm.ptr -> !llvm.ptr
      %2131 = arith.constant 0 : i32
      %2132 = arith.extsi %2131 : i32 to i64
      %2133 = llvm.getelementptr %2047[%2132] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %2130 = llvm.load %2133 : !llvm.ptr -> i32
      %2134 = llvm.load %2112 : !llvm.ptr -> i32
      %2135 = arith.addi %2130, %2134 : i32
      %2136 = arith.extsi %2135 : i32 to i64
      %2137 = llvm.getelementptr %2129[%2136] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %2127 = llvm.load %2137 : !llvm.ptr -> i32
      %2138 = arith.extsi %2127 : i32 to i64
      %2139 = llvm.mlir.addressof @MOD : !llvm.ptr
      %2140 = llvm.load %2139 : !llvm.ptr -> i64
      %2119 = func.call @powmod(%2126, %2138, %2140) : (i64, i64, i64) -> i64
      %2141 = llvm.load %2056 : !llvm.ptr -> i64
      %2142 = arith.muli %2141, %2119 : i64
      %2143 = llvm.mlir.addressof @MOD : !llvm.ptr
      %2144 = llvm.load %2143 : !llvm.ptr -> i64
      %2145 = arith.remsi %2142, %2144 : i64
      llvm.store %2145, %2056 : i64, !llvm.ptr
      %2146 = llvm.load %2112 : !llvm.ptr -> i32
      %2147 = arith.constant 1 : i32
      %2148 = arith.addi %2146, %2147 : i32
      llvm.store %2148, %2112 : i32, !llvm.ptr
      cf.br ^bb240
    ^bb242:
    func.call @free(%2017) : (!llvm.ptr) -> ()
    func.call @free(%2022) : (!llvm.ptr) -> ()
    func.call @free(%2027) : (!llvm.ptr) -> ()
    func.call @free(%2032) : (!llvm.ptr) -> ()
    func.call @free(%2037) : (!llvm.ptr) -> ()
    func.call @free(%2042) : (!llvm.ptr) -> ()
    func.call @free(%2047) : (!llvm.ptr) -> ()
    %2156 = llvm.load %2056 : !llvm.ptr -> i64
    func.return %2156 : i64
  }
  func.func @init_globals() -> () {
    %2158 = arith.constant 200 : i32
    %2159 = arith.constant 4 : i32
    %2160 = arith.extsi %2158 : i32 to i64
    %2161 = arith.extsi %2159 : i32 to i64
    %2157 = func.call @calloc(%2160, %2161) : (i64, i64) -> !llvm.ptr
    %2162 = llvm.mlir.addressof @primes_p1 : !llvm.ptr
    llvm.store %2157, %2162 : !llvm.ptr, !llvm.ptr
    %2164 = arith.constant 200 : i32
    %2165 = arith.constant 4 : i32
    %2166 = arith.extsi %2164 : i32 to i64
    %2167 = arith.extsi %2165 : i32 to i64
    %2163 = func.call @calloc(%2166, %2167) : (i64, i64) -> !llvm.ptr
    %2168 = llvm.mlir.addressof @primes_p3 : !llvm.ptr
    llvm.store %2163, %2168 : !llvm.ptr, !llvm.ptr
    %2170 = arith.constant 200 : i32
    %2171 = arith.constant 8 : i32
    %2172 = arith.extsi %2170 : i32 to i64
    %2173 = arith.extsi %2171 : i32 to i64
    %2169 = func.call @calloc(%2172, %2173) : (i64, i64) -> !llvm.ptr
    %2174 = llvm.mlir.addressof @log2_p1 : !llvm.ptr
    llvm.store %2169, %2174 : !llvm.ptr, !llvm.ptr
    %2176 = arith.constant 200 : i32
    %2177 = arith.constant 8 : i32
    %2178 = arith.extsi %2176 : i32 to i64
    %2179 = arith.extsi %2177 : i32 to i64
    %2175 = func.call @calloc(%2178, %2179) : (i64, i64) -> !llvm.ptr
    %2180 = llvm.mlir.addressof @log2_p3 : !llvm.ptr
    llvm.store %2175, %2180 : !llvm.ptr, !llvm.ptr
    %2182 = arith.constant 500000 : i32
    %2183 = arith.constant 8 : i32
    %2184 = arith.extsi %2182 : i32 to i64
    %2185 = arith.extsi %2183 : i32 to i64
    %2181 = func.call @calloc(%2184, %2185) : (i64, i64) -> !llvm.ptr
    %2186 = llvm.mlir.addressof @memo_rem : !llvm.ptr
    llvm.store %2181, %2186 : !llvm.ptr, !llvm.ptr
    %2188 = arith.constant 500000 : i32
    %2189 = arith.constant 4 : i32
    %2190 = arith.extsi %2188 : i32 to i64
    %2191 = arith.extsi %2189 : i32 to i64
    %2187 = func.call @calloc(%2190, %2191) : (i64, i64) -> !llvm.ptr
    %2192 = llvm.mlir.addressof @memo_idx : !llvm.ptr
    llvm.store %2187, %2192 : !llvm.ptr, !llvm.ptr
    %2194 = arith.constant 500000 : i32
    %2195 = arith.constant 4 : i32
    %2196 = arith.extsi %2194 : i32 to i64
    %2197 = arith.extsi %2195 : i32 to i64
    %2193 = func.call @calloc(%2196, %2197) : (i64, i64) -> !llvm.ptr
    %2198 = llvm.mlir.addressof @memo_prev_f : !llvm.ptr
    llvm.store %2193, %2198 : !llvm.ptr, !llvm.ptr
    %2200 = arith.constant 500000 : i32
    %2201 = arith.constant 4 : i32
    %2202 = arith.extsi %2200 : i32 to i64
    %2203 = arith.extsi %2201 : i32 to i64
    %2199 = func.call @calloc(%2202, %2203) : (i64, i64) -> !llvm.ptr
    %2204 = llvm.mlir.addressof @memo_pset : !llvm.ptr
    llvm.store %2199, %2204 : !llvm.ptr, !llvm.ptr
    %2206 = arith.constant 500000 : i32
    %2207 = arith.constant 4 : i32
    %2208 = arith.extsi %2206 : i32 to i64
    %2209 = arith.extsi %2207 : i32 to i64
    %2205 = func.call @calloc(%2208, %2209) : (i64, i64) -> !llvm.ptr
    %2210 = llvm.mlir.addressof @memo_valid : !llvm.ptr
    llvm.store %2205, %2210 : !llvm.ptr, !llvm.ptr
    %2212 = arith.constant 500000 : i32
    %2213 = arith.constant 4 : i32
    %2214 = arith.extsi %2212 : i32 to i64
    %2215 = arith.extsi %2213 : i32 to i64
    %2211 = func.call @calloc(%2214, %2215) : (i64, i64) -> !llvm.ptr
    %2216 = llvm.mlir.addressof @memo_n : !llvm.ptr
    llvm.store %2211, %2216 : !llvm.ptr, !llvm.ptr
    %2218 = arith.constant 500000 : i32
    %2219 = arith.constant 8 : i32
    %2220 = arith.extsi %2218 : i32 to i64
    %2221 = arith.extsi %2219 : i32 to i64
    %2217 = func.call @calloc(%2220, %2221) : (i64, i64) -> !llvm.ptr
    %2222 = llvm.mlir.addressof @memo_log2_val : !llvm.ptr
    llvm.store %2217, %2222 : !llvm.ptr, !llvm.ptr
    %2224 = arith.constant 500000 : i32
    %2225 = arith.constant 4 : i32
    %2226 = arith.extsi %2224 : i32 to i64
    %2227 = arith.extsi %2225 : i32 to i64
    %2223 = func.call @calloc(%2226, %2227) : (i64, i64) -> !llvm.ptr
    %2228 = llvm.mlir.addressof @memo_exps_off : !llvm.ptr
    llvm.store %2223, %2228 : !llvm.ptr, !llvm.ptr
    %2230 = arith.constant 10000000 : i32
    %2231 = arith.constant 4 : i32
    %2232 = arith.extsi %2230 : i32 to i64
    %2233 = arith.extsi %2231 : i32 to i64
    %2229 = func.call @calloc(%2232, %2233) : (i64, i64) -> !llvm.ptr
    %2234 = llvm.mlir.addressof @exps_pool : !llvm.ptr
    llvm.store %2229, %2234 : !llvm.ptr, !llvm.ptr
    %2236 = arith.constant 65536 : i32
    %2237 = arith.constant 8 : i32
    %2238 = arith.extsi %2236 : i32 to i64
    %2239 = arith.extsi %2237 : i32 to i64
    %2235 = func.call @calloc(%2238, %2239) : (i64, i64) -> !llvm.ptr
    %2240 = llvm.mlir.addressof @d_keys : !llvm.ptr
    llvm.store %2235, %2240 : !llvm.ptr, !llvm.ptr
    %2242 = arith.constant 65536 : i32
    %2243 = arith.constant 8 : i32
    %2244 = arith.extsi %2242 : i32 to i64
    %2245 = arith.extsi %2243 : i32 to i64
    %2241 = func.call @calloc(%2244, %2245) : (i64, i64) -> !llvm.ptr
    %2246 = llvm.mlir.addressof @d_e2 : !llvm.ptr
    llvm.store %2241, %2246 : !llvm.ptr, !llvm.ptr
    %2248 = arith.constant 65536 : i32
    %2249 = arith.constant 8 : i32
    %2250 = arith.extsi %2248 : i32 to i64
    %2251 = arith.extsi %2249 : i32 to i64
    %2247 = func.call @calloc(%2250, %2251) : (i64, i64) -> !llvm.ptr
    %2252 = llvm.mlir.addressof @d_log2 : !llvm.ptr
    llvm.store %2247, %2252 : !llvm.ptr, !llvm.ptr
    %2254 = arith.constant 65536 : i32
    %2255 = arith.constant 4 : i32
    %2256 = arith.extsi %2254 : i32 to i64
    %2257 = arith.extsi %2255 : i32 to i64
    %2253 = func.call @calloc(%2256, %2257) : (i64, i64) -> !llvm.ptr
    %2258 = llvm.mlir.addressof @d_rep3_n : !llvm.ptr
    llvm.store %2253, %2258 : !llvm.ptr, !llvm.ptr
    %2260 = arith.constant 65536 : i32
    %2261 = arith.constant 8 : i32
    %2262 = arith.extsi %2260 : i32 to i64
    %2263 = arith.extsi %2261 : i32 to i64
    %2259 = func.call @calloc(%2262, %2263) : (i64, i64) -> !llvm.ptr
    %2264 = llvm.mlir.addressof @d_rep3_log2 : !llvm.ptr
    llvm.store %2259, %2264 : !llvm.ptr, !llvm.ptr
    %2266 = arith.constant 65536 : i32
    %2267 = arith.constant 4 : i32
    %2268 = arith.extsi %2266 : i32 to i64
    %2269 = arith.extsi %2267 : i32 to i64
    %2265 = func.call @calloc(%2268, %2269) : (i64, i64) -> !llvm.ptr
    %2270 = llvm.mlir.addressof @d_rep3_off : !llvm.ptr
    llvm.store %2265, %2270 : !llvm.ptr, !llvm.ptr
    %2272 = arith.constant 256 : i32
    %2273 = arith.constant 8 : i32
    %2274 = arith.extsi %2272 : i32 to i64
    %2275 = arith.extsi %2273 : i32 to i64
    %2271 = func.call @calloc(%2274, %2275) : (i64, i64) -> !llvm.ptr
    %2276 = llvm.mlir.addressof @q_keys : !llvm.ptr
    llvm.store %2271, %2276 : !llvm.ptr, !llvm.ptr
    %2278 = arith.constant 256 : i32
    %2279 = arith.constant 8 : i32
    %2280 = arith.extsi %2278 : i32 to i64
    %2281 = arith.extsi %2279 : i32 to i64
    %2277 = func.call @calloc(%2280, %2281) : (i64, i64) -> !llvm.ptr
    %2282 = llvm.mlir.addressof @q_e2 : !llvm.ptr
    llvm.store %2277, %2282 : !llvm.ptr, !llvm.ptr
    %2284 = arith.constant 256 : i32
    %2285 = arith.constant 4 : i32
    %2286 = arith.extsi %2284 : i32 to i64
    %2287 = arith.extsi %2285 : i32 to i64
    %2283 = func.call @calloc(%2286, %2287) : (i64, i64) -> !llvm.ptr
    %2288 = llvm.mlir.addressof @q_rep1_n : !llvm.ptr
    llvm.store %2283, %2288 : !llvm.ptr, !llvm.ptr
    %2290 = arith.constant 256 : i32
    %2291 = arith.constant 8 : i32
    %2292 = arith.extsi %2290 : i32 to i64
    %2293 = arith.extsi %2291 : i32 to i64
    %2289 = func.call @calloc(%2292, %2293) : (i64, i64) -> !llvm.ptr
    %2294 = llvm.mlir.addressof @q_rep1_log2 : !llvm.ptr
    llvm.store %2289, %2294 : !llvm.ptr, !llvm.ptr
    %2296 = arith.constant 256 : i32
    %2297 = arith.constant 4 : i32
    %2298 = arith.extsi %2296 : i32 to i64
    %2299 = arith.extsi %2297 : i32 to i64
    %2295 = func.call @calloc(%2298, %2299) : (i64, i64) -> !llvm.ptr
    %2300 = llvm.mlir.addressof @q_rep1_off : !llvm.ptr
    llvm.store %2295, %2300 : !llvm.ptr, !llvm.ptr
    %2302 = arith.constant 256 : i32
    %2303 = arith.constant 4 : i32
    %2304 = arith.extsi %2302 : i32 to i64
    %2305 = arith.extsi %2303 : i32 to i64
    %2301 = func.call @calloc(%2304, %2305) : (i64, i64) -> !llvm.ptr
    %2306 = llvm.mlir.addressof @q_rep3_n : !llvm.ptr
    llvm.store %2301, %2306 : !llvm.ptr, !llvm.ptr
    %2308 = arith.constant 256 : i32
    %2309 = arith.constant 8 : i32
    %2310 = arith.extsi %2308 : i32 to i64
    %2311 = arith.extsi %2309 : i32 to i64
    %2307 = func.call @calloc(%2310, %2311) : (i64, i64) -> !llvm.ptr
    %2312 = llvm.mlir.addressof @q_rep3_log2 : !llvm.ptr
    llvm.store %2307, %2312 : !llvm.ptr, !llvm.ptr
    %2314 = arith.constant 256 : i32
    %2315 = arith.constant 4 : i32
    %2316 = arith.extsi %2314 : i32 to i64
    %2317 = arith.extsi %2315 : i32 to i64
    %2313 = func.call @calloc(%2316, %2317) : (i64, i64) -> !llvm.ptr
    %2318 = llvm.mlir.addressof @q_rep3_off : !llvm.ptr
    llvm.store %2313, %2318 : !llvm.ptr, !llvm.ptr
    func.return
  }
  func.func @main() -> i32 {
    func.call @init_globals() : () -> ()
    func.call @gen_primes() : () -> ()
    %2321 = arith.constant 0 : i32
    %2322 = arith.extsi %2321 : i32 to i64
    %2323 = llvm.mlir.constant(1 : i64) : i64
    %2324 = llvm.alloca %2323 x i64 : (i64) -> !llvm.ptr
    llvm.store %2322, %2324 : i64, !llvm.ptr
    %2325 = arith.constant 1 : i32
    %2326 = llvm.mlir.constant(1 : i64) : i64
    %2327 = llvm.alloca %2326 x i32 : (i64) -> !llvm.ptr
    llvm.store %2325, %2327 : i32, !llvm.ptr
    cf.br ^bb243
    ^bb243:
    %2328 = llvm.load %2327 : !llvm.ptr -> i32
    %2329 = arith.constant 18 : i32
    %2330 = arith.cmpi sle, %2328, %2329 : i32
    cf.cond_br %2330, ^bb244, ^bb245
    ^bb244:
      %2331 = arith.constant 1 : i32
      %2332 = arith.extsi %2331 : i32 to i64
      %2333 = llvm.mlir.constant(1 : i64) : i64
      %2334 = llvm.alloca %2333 x i64 : (i64) -> !llvm.ptr
      llvm.store %2332, %2334 : i64, !llvm.ptr
      %2335 = arith.constant 0 : i32
      %2336 = llvm.mlir.constant(1 : i64) : i64
      %2337 = llvm.alloca %2336 x i32 : (i64) -> !llvm.ptr
      llvm.store %2335, %2337 : i32, !llvm.ptr
      cf.br ^bb246
      ^bb246:
      %2338 = llvm.load %2337 : !llvm.ptr -> i32
      %2339 = llvm.load %2327 : !llvm.ptr -> i32
      %2340 = arith.cmpi slt, %2338, %2339 : i32
      cf.cond_br %2340, ^bb247, ^bb248
      ^bb247:
        %2341 = llvm.load %2334 : !llvm.ptr -> i64
        %2342 = arith.constant 10 : i32
        %2344 = arith.extsi %2342 : i32 to i64
        %2343 = arith.muli %2341, %2344 : i64
        llvm.store %2343, %2334 : i64, !llvm.ptr
        %2345 = llvm.load %2337 : !llvm.ptr -> i32
        %2346 = arith.constant 1 : i32
        %2347 = arith.addi %2345, %2346 : i32
        llvm.store %2347, %2337 : i32, !llvm.ptr
        cf.br ^bb246
      ^bb248:
      %2349 = llvm.load %2334 : !llvm.ptr -> i64
      %2348 = func.call @Q_mod(%2349) : (i64) -> i64
      %2350 = llvm.load %2324 : !llvm.ptr -> i64
      %2351 = arith.addi %2350, %2348 : i64
      %2352 = llvm.mlir.addressof @MOD : !llvm.ptr
      %2353 = llvm.load %2352 : !llvm.ptr -> i64
      %2354 = arith.remsi %2351, %2353 : i64
      llvm.store %2354, %2324 : i64, !llvm.ptr
      %2355 = llvm.load %2327 : !llvm.ptr -> i32
      %2356 = arith.constant 1 : i32
      %2357 = arith.addi %2355, %2356 : i32
      llvm.store %2357, %2327 : i32, !llvm.ptr
      cf.br ^bb243
    ^bb245:
    %2358 = llvm.mlir.addressof @str_0 : !llvm.ptr
    %2359 = llvm.load %2324 : !llvm.ptr -> i64
    %2360 = llvm.call @printf(%2358, %2359) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i64) -> i32
    %2361 = arith.constant 0 : i32
    func.return %2361 : i32
  }
}