Problem 687

Shuffling cards: P(#perfect ranks is prime) to 10 decimals. Uses base-10^9 bignum for exact integer arithmetic.

Answer0.3285320869
Output0.3285320869
StatusPASS
Native helperno
Runtime0 ms
Peak memory1136 KB
Time complexityO(n^3) (estimated)
Space complexityO(n^2) (estimated)

Performance comparison

MetricOur solutionBest known
Time complexityO(n^3)O(n)
Space complexityO(n^2)O(1)
ApproachFlow solutionDirect hand evaluation or enumeration
VerdictSuboptimal

Flow source

# Project Euler 687
# Shuffling cards: P(#perfect ranks is prime) to 10 decimals.
# Uses base-10^9 bignum for exact integer arithmetic.

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

const B: i64 = 1000000000
const RANKS: i32 = 13
const N: i32 = 52
const CB: i32 = 24
const MAXD: i32 = 40

# Bignum: ptr<i64>, base 10^9, little-endian. Length tracked explicitly.

function bn_zero(a: ptr<i64>, cap: i32) -> void {
    let mut i: i32 = 0
    while i < cap { a[i] = 0; i = i + 1 }
}

# a += b * v (v >= 0). Returns new length.
function bn_addmul_small(a: ptr<i64>, a_len: i32, b: ptr<i64>, b_len: i32, v: i64) -> i32 {
    if v == 0 { return a_len }
    let mut carry: i64 = 0
    let mut i: i32 = 0
    let mut n: i32 = a_len
    if b_len > n { n = b_len }
    while i < n {
        let ai: i64 = if i < a_len { a[i] } else { 0 }
        let bi: i64 = if i < b_len { b[i] } else { 0 }
        let s: i128 = (carry as i128) + (ai as i128) + (bi as i128) * (v as i128)
        a[i] = (s % (B as i128)) as i64
        carry = (s / (B as i128)) as i64
        i = i + 1
    }
    while carry > 0 {
        a[n] = carry % B
        carry = carry / B
        n = n + 1
    }
    while n > 0 && a[n - 1] == 0 { n = n - 1 }
    return n
}

# a += b * v (v >= 0, i128). Returns new length.
function bn_addmul_i128(a: ptr<i64>, a_len: i32, b: ptr<i64>, b_len: i32, v: i128) -> i32 {
    if v == 0 { return a_len }
    # Split v into high and low 32-bit parts to avoid overflow
    let vh: i64 = (v >> 32) as i64
    let vl: i64 = (v & 0xFFFFFFFF) as i64
    # a += b * vl
    let tmp: ptr<i64> = calloc(40, 8)
    let tl: i32 = bn_addmul_small(tmp, 0, b, b_len, vl)
    # tmp *= 2^32 (shift left by 32 bits = multiply by 4294967296)
    # tmp = tmp * vh * 2^32 + tmp * vl... no, this is wrong.
    # Actually: b * v = b * (vh * 2^32 + vl) = b * vh * 2^32 + b * vl
    # We already have tmp = b * vl. Now compute b * vh, shift left 32, and add.
    # But shifting a bignum left by 32 bits is complex.
    # Simpler: just do the multiplication directly with i128 arithmetic.
    free(tmp as ptr<void>)
    let mut carry: i128 = 0
    let mut i: i32 = 0
    let mut n: i32 = a_len
    if b_len > n { n = b_len }
    while i < n {
        let ai: i128 = if i < a_len { a[i] as i128 } else { 0 }
        let bi: i128 = if i < b_len { b[i] as i128 } else { 0 }
        let s: i128 = carry + ai + bi * v
        a[i] = (s % (B as i128)) as i64
        carry = s / (B as i128)
        i = i + 1
    }
    while carry > 0 {
        a[n] = (carry % (B as i128)) as i64
        carry = carry / (B as i128)
        n = n + 1
    }
    while n > 0 && a[n - 1] == 0 { n = n - 1 }
    return n
}
function bn_mul_small(dst: ptr<i64>, a: ptr<i64>, a_len: i32, v: i64) -> i32 {
    let mut carry: i64 = 0
    let mut i: i32 = 0
    let mut n: i32 = a_len
    while i < n {
        let prod: i128 = (a[i] as i128) * (v as i128) + carry
        dst[i] = (prod % (B as i128)) as i64
        carry = (prod / (B as i128)) as i64
        i = i + 1
    }
    while carry > 0 {
        dst[n] = carry % B
        carry = carry / B
        n = n + 1
    }
    return n
}

# q = a / v (v > 0). Returns quotient length. rem in *rem_ptr.
function bn_div_small(q: ptr<i64>, a: ptr<i64>, a_len: i32, v: i64) -> i32 {
    let mut rem: i64 = 0
    let mut n: i32 = a_len
    let mut i: i32 = a_len - 1
    while i >= 0 {
        let cur: i128 = (rem as i128) * (B as i128) + (a[i] as i128)
        q[i] = (cur / (v as i128)) as i64
        rem = (cur % (v as i128)) as i64
        i = i - 1
    }
    while n > 0 && q[n - 1] == 0 { n = n - 1 }
    return n
}

# dst = a - b (a >= b). Returns length.
function bn_sub(dst: ptr<i64>, a: ptr<i64>, a_len: i32, b: ptr<i64>, b_len: i32) -> i32 {
    let mut borrow: i64 = 0
    let mut i: i32 = 0
    let mut n: i32 = a_len
    while i < n {
        let mut s: i64 = a[i] - borrow
        if i < b_len { s = s - b[i] }
        if s < 0 { s = s + B; borrow = 1 } else { borrow = 0 }
        dst[i] = s
        i = i + 1
    }
    while n > 0 && dst[n - 1] == 0 { n = n - 1 }
    return n
}

# Compare a and b. Returns 1 if a > b, -1 if a < b, 0 if equal.
function bn_cmp(a: ptr<i64>, a_len: i32, b: ptr<i64>, b_len: i32) -> i32 {
    if a_len != b_len {
        if a_len > b_len { return 1 }
        return -1
    }
    let mut i: i32 = a_len - 1
    while i >= 0 {
        if a[i] != b[i] {
            if a[i] > b[i] { return 1 }
            return -1
        }
        i = i - 1
    }
    return 0
}

# Copy a to dst, zero rest up to cap.
function bn_copy(dst: ptr<i64>, a: ptr<i64>, a_len: i32, cap: i32) -> void {
    let mut i: i32 = 0
    while i < a_len { dst[i] = a[i]; i = i + 1 }
    while i < cap { dst[i] = 0; i = i + 1 }
}

# Convert to f64 (for final output).
function bn_to_f64(a: ptr<i64>, a_len: i32) -> f64 {
    if a_len == 0 { return 0.0 }
    let mut result: f64 = 0.0
    let mut i: i32 = a_len - 1
    while i >= 0 {
        result = result * 1000000000.0 + (a[i] as f64)
        i = i - 1
    }
    return result
}

function comb_l(n: i64, k: i64) -> i64 {
    if k < 0 || k > n { return 0 }
    let mut kk: i64 = k
    if kk > n - kk { kk = n - kk }
    let mut r: i64 = 1
    let mut i: i64 = 1
    while i <= kk {
        r = r * (n - kk + i) / i
        i = i + 1
    }
    return r
}

function main() -> i32 {
    # Build Qpow[m] polynomial coefficients (i128, can be large)
    let Qpow: ptr<ptr<i128> > = calloc(14, 8)
    let deg: ptr<i32> = calloc(14, 4)
    let mut m: i32 = 0
    while m <= RANKS {
        Qpow[m] = calloc(MAXD, 16)
        m = m + 1
    }
    Qpow[0][0] = 1
    deg[0] = 0
    let Q: ptr<i64> = calloc(4, 8)
    Q[0] = 1
    Q[1] = -12
    Q[2] = 36
    Q[3] = -24
    m = 1
    while m <= RANKS {
        let pd: i32 = deg[m - 1]
        deg[m] = pd + 3
        let mut i: i32 = 0
        while i <= pd {
            let mut j: i32 = 0
            while j < 4 {
                Qpow[m][i + j] = Qpow[m][i + j] + Qpow[m - 1][i] * (Q[j] as i128)
                j = j + 1
            }
            i = i + 1
        }
        m = m + 1
    }

    # Compute factorials as bignums (base 10^9)
    # 52! has about 68 digits, so 8 base-10^9 digits
    let fact: ptr<ptr<i64> > = calloc((N + 1) as i64, 8)
    let fact_len: ptr<i32> = calloc((N + 1) as i64, 4)
    fact[0] = calloc(20, 8)
    fact[0][0] = 1
    fact_len[0] = 1
    let mut i: i32 = 1
    while i <= N {
        fact[i] = calloc(20, 8)
        fact_len[i] = bn_mul_small(fact[i], fact[i - 1], fact_len[i - 1], (i as i64))
        i = i + 1
    }

    # denom = 24^13 as bignum
    let denom: ptr<i64> = calloc(20, 8)
    denom[0] = 1
    let mut dn: i32 = 1
    let mut i2: i32 = 0
    while i2 < RANKS {
        let tmp: ptr<i64> = calloc(20, 8)
        let nl: i32 = bn_mul_small(tmp, denom, dn, (CB as i64))
        bn_copy(denom, tmp, nl, 20)
        dn = nl
        free(tmp as ptr<void>)
        i2 = i2 + 1
    }

    # nval[m] = sum_{B} fact[N-B] * Qpow[m][B] / denom
    # Split into positive and negative parts, then subtract.
    let nval: ptr<ptr<i64> > = calloc(14, 8)
    let nval_len: ptr<i32> = calloc(14, 4)
    m = 0
    while m <= RANKS {
        let pos: ptr<i64> = calloc(30, 8)
        let mut plen: i32 = 0
        let neg: ptr<i64> = calloc(30, 8)
        let mut nlen: i32 = 0
        let mut B2: i32 = 0
        while B2 <= deg[m] {
            let coef: i128 = Qpow[m][B2]
            if coef > 0 {
                plen = bn_addmul_i128(pos, plen, fact[N - B2], fact_len[N - B2], coef)
            } else {
                if coef < 0 {
                    nlen = bn_addmul_i128(neg, nlen, fact[N - B2], fact_len[N - B2], 0 - coef)
                }
            }
            B2 = B2 + 1
        }
        # num = pos - neg (should be >= 0)
        let num: ptr<i64> = calloc(30, 8)
        let num_len: i32 = bn_sub(num, pos, plen, neg, nlen)
        # nval[m] = num / denom = num / 24^13
        # Divide by 24 thirteen times.
        nval[m] = calloc(20, 8)
        let mut remaining: ptr<i64> = calloc(30, 8)
        bn_copy(remaining, num, num_len, 30)
        let mut rlen: i32 = num_len
        let mut d: i32 = 0
        while d < RANKS {
            let tmp2: ptr<i64> = calloc(30, 8)
            rlen = bn_div_small(tmp2, remaining, rlen, (CB as i64))
            bn_copy(remaining, tmp2, rlen, 30)
            free(tmp2 as ptr<void>)
            d = d + 1
        }
        bn_copy(nval[m], remaining, rlen, 20)
        nval_len[m] = rlen
        free(pos as ptr<void>)
        free(neg as ptr<void>)
        free(num as ptr<void>)
        free(remaining as ptr<void>)
        m = m + 1
    }

    # total = nval[0]
    let total: ptr<i64> = calloc(20, 8)
    let mut total_len: i32 = nval_len[0]
    bn_copy(total, nval[0], total_len, 20)

    # good = sum over primes k of C(13,k) * z_k
    # z_k = sum_{m=k..13} (-1)^(m-k) C(13-k, m-k) * nval[m]
    # nval[m] are bignums, C(13,k) and C(13-k,m-k) are small i64.
    let good: ptr<i64> = calloc(30, 8)
    let mut good_len: i32 = 0
    let primes: ptr<i32> = calloc(6, 4)
    primes[0] = 2
    primes[1] = 3
    primes[2] = 5
    primes[3] = 7
    primes[4] = 11
    primes[5] = 13
    let mut ki: i32 = 0
    while ki < 6 {
        let k: i32 = primes[ki]
        # z = sum_{m=k..13} (-1)^(m-k) C(13-k, m-k) * nval[m]
        # Split into pos and neg since cc can be negative
        let z: ptr<i64> = calloc(30, 8)
        let mut zlen: i32 = 0
        let zneg: ptr<i64> = calloc(30, 8)
        let mut znlen: i32 = 0
        let mut m3: i32 = k
        while m3 <= RANKS {
            let c: i64 = comb_l((RANKS - k) as i64, (m3 - k) as i64)
            if ((m3 - k) & 1) != 0 {
                znlen = bn_addmul_small(zneg, znlen, nval[m3], nval_len[m3], c)
            } else {
                zlen = bn_addmul_small(z, zlen, nval[m3], nval_len[m3], c)
            }
            m3 = m3 + 1
        }
        # z = zpos - zneg
        let zfinal: ptr<i64> = calloc(30, 8)
        let zf_len: i32 = bn_sub(zfinal, z, zlen, zneg, znlen)
        # good += zfinal * C(13, k)
        let ck: i64 = comb_l((RANKS as i64), (k as i64))
        good_len = bn_addmul_small(good, good_len, zfinal, zf_len, ck)
        free(z as ptr<void>)
        free(zneg as ptr<void>)
        free(zfinal as ptr<void>)
        ki = ki + 1
    }

    # q = (good * 10^11 + total/2) / total + 5, then / 10
    # good * 10^11
    let good_scaled: ptr<i64> = calloc(30, 8)
    let gs_len: i32 = bn_mul_small(good_scaled, good, good_len, 100000000000)
    # total / 2
    let half_total: ptr<i64> = calloc(20, 8)
    let ht_len: i32 = bn_div_small(half_total, total, total_len, 2)
    # good_scaled + half_total
    let numerator: ptr<i64> = calloc(30, 8)
    let num_len: i32 = bn_addmul_small(numerator, 0, good_scaled, gs_len, 1)
    let num_len2: i32 = bn_addmul_small(numerator, num_len, half_total, ht_len, 1)
    # numerator / total = integer quotient q
    # Then ans = (q + 5) / 10 / 10^10
    # We need exact integer division. Use long division.
    # numerator and total are bignums. The quotient fits in ~20 digits.
    # Convert both to f64 for an approximate quotient, then adjust.
    # Actually, let's do proper bignum division.
    # Since the quotient is small (~10 digits), we can compute it digit by digit.
    # Or: convert numerator and total to high-precision f64 and divide.
    # The issue is f64 has ~15.9 significant digits, but we need 11.
    # Let's use the top 2-3 digits of each for the division.
    # numerator has ~25 digits, total has ~50 digits.
    # quotient = numerator / total ~ 3.28 * 10^10
    # We need 11 significant digits.
    # Use long division: find q such that q * total <= numerator < (q+1) * total
    # q fits in i64 (it's ~3.28 * 10^10).
    # Approximate with f64, then adjust by multiplying back.
    let num_f: f64 = bn_to_f64(numerator, num_len2)
    let total_f: f64 = bn_to_f64(total, total_len)
    let q_approx: i64 = (num_f / total_f) as i64
    # Adjust: check q_approx * total vs numerator
    # q * total
    let qprod: ptr<i64> = calloc(30, 8)
    let qp_len: i32 = bn_mul_small(qprod, total, total_len, q_approx)
    let cmp: i32 = bn_cmp(qprod, qp_len, numerator, num_len2)
    let mut q_final: i64 = q_approx
    if cmp < 0 {
        # qprod < numerator, might need to increase q
        # Try q+1, q+2, etc.
        let mut q_try: i64 = q_approx + 1
        let mut found: i32 = 0
        while found == 0 {
            let qp2: ptr<i64> = calloc(30, 8)
            let qp2_len: i32 = bn_mul_small(qp2, total, total_len, q_try)
            let cmp2: i32 = bn_cmp(qp2, qp2_len, numerator, num_len2)
            free(qp2 as ptr<void>)
            if cmp2 > 0 {
                found = 1
            } else {
                q_try = q_try + 1
                if q_try > q_approx + 100 { found = 1 }
            }
        }
        q_final = q_try - 1
    } else {
        if cmp > 0 {
            # qprod > numerator, need to decrease q
            let mut q_try: i64 = q_approx - 1
            let mut found: i32 = 0
            while found == 0 && q_try >= 0 {
                let qp2: ptr<i64> = calloc(30, 8)
                let qp2_len: i32 = bn_mul_small(qp2, total, total_len, q_try)
                let cmp2: i32 = bn_cmp(qp2, qp2_len, numerator, num_len2)
                free(qp2 as ptr<void>)
                if cmp2 <= 0 {
                    found = 1
                } else {
                    q_try = q_try - 1
                    if q_try < q_approx - 100 { found = 1 }
                }
            }
            q_final = q_try
        }
    }
    # ans = (q_final + 5) / 10 / 10^10
    let q_with_5: i64 = q_final + 5
    let q_div_10: i64 = q_with_5 / 10
    let ans: f64 = (q_div_10 as f64) / 10000000000.0

    printf("%.10f\n", ans)

    # Cleanup
    let mut m4: i32 = 0
    while m4 <= RANKS {
        free(Qpow[m4] as ptr<void>)
        free(nval[m4] as ptr<void>)
        m4 = m4 + 1
    }
    free(Qpow as ptr<void>)
    free(deg as ptr<void>)
    free(Q as ptr<void>)
    let mut i3: i32 = 0
    while i3 <= N {
        free(fact[i3] as ptr<void>)
        i3 = i3 + 1
    }
    free(fact as ptr<void>)
    free(fact_len as ptr<void>)
    free(denom as ptr<void>)
    free(nval_len as ptr<void>)
    free(total as ptr<void>)
    free(good as ptr<void>)
    free(primes as ptr<void>)
    free(good_scaled as ptr<void>)
    free(half_total as ptr<void>)
    free(numerator as ptr<void>)
    free(qprod as ptr<void>)
    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; }

void bn_zero_ptr_i64_i32(int64_t* a, int32_t cap);
int32_t bn_addmul_small_ptr_i64_i32_ptr_i64_i32_i64(int64_t* a, int32_t a_len, int64_t* b, int32_t b_len, int64_t v);
int32_t bn_addmul_i128_ptr_i64_i32_ptr_i64_i32_i128(int64_t* a, int32_t a_len, int64_t* b, int32_t b_len, __int128 v);
int32_t bn_mul_small_ptr_i64_ptr_i64_i32_i64(int64_t* dst, int64_t* a, int32_t a_len, int64_t v);
int32_t bn_div_small_ptr_i64_ptr_i64_i32_i64(int64_t* q, int64_t* a, int32_t a_len, int64_t v);
int32_t bn_sub_ptr_i64_ptr_i64_i32_ptr_i64_i32(int64_t* dst, int64_t* a, int32_t a_len, int64_t* b, int32_t b_len);
int32_t bn_cmp_ptr_i64_i32_ptr_i64_i32(int64_t* a, int32_t a_len, int64_t* b, int32_t b_len);
void bn_copy_ptr_i64_ptr_i64_i32_i32(int64_t* dst, int64_t* a, int32_t a_len, int32_t cap);
double bn_to_f64_ptr_i64_i32(int64_t* a, int32_t a_len);
int64_t comb_l_i64_i64(int64_t n, int64_t k);
int32_t main(void);

static const int64_t B = 1000000000;
static const int32_t RANKS = 13;
static const int32_t N = 52;
static const int32_t CB = 24;
static const int32_t MAXD = 40;




void bn_zero_ptr_i64_i32(int64_t* a, int32_t cap) {
    int32_t i = 0;
    while (i < cap) {
        a[i] = 0;
        i = (i + 1);
    }
}

int32_t bn_addmul_small_ptr_i64_i32_ptr_i64_i32_i64(int64_t* a, int32_t a_len, int64_t* b, int32_t b_len, int64_t v) {
    if (v == 0) {
        return a_len;
    }
    int64_t carry = 0;
    int32_t i = 0;
    int32_t n = a_len;
    if (b_len > n) {
        n = b_len;
    }
    while (i < n) {
        int64_t ai = ((i < a_len) ? (a[i]) : (0));
        int64_t bi = ((i < b_len) ? (b[i]) : (0));
        __int128 s = ((((__int128)(carry)) + ((__int128)(ai))) + (((__int128)(bi)) * ((__int128)(v))));
        a[i] = ((int64_t)(FLOW_CHECKED_MOD((s), (((__int128)(B))))));
        carry = ((int64_t)(FLOW_CHECKED_DIV((s), (((__int128)(B))))));
        i = (i + 1);
    }
    while (carry > 0) {
        a[n] = FLOW_CHECKED_MOD((carry), (B));
        carry = FLOW_CHECKED_DIV((carry), (B));
        n = (n + 1);
    }
    while ((n > 0 && a[(n - 1)] == 0)) {
        n = (n - 1);
    }
    return n;
}

int32_t bn_addmul_i128_ptr_i64_i32_ptr_i64_i32_i128(int64_t* a, int32_t a_len, int64_t* b, int32_t b_len, __int128 v) {
    if (v == 0) {
        return a_len;
    }
    int64_t vh = ((int64_t)(FLOW_CHECKED_SHR((v), (32))));
    int64_t vl = ((int64_t)((v & 4294967295)));
    int64_t* tmp = (int64_t*)(calloc(40, 8));
    int32_t tl = bn_addmul_small_ptr_i64_i32_ptr_i64_i32_i64(tmp, 0, b, b_len, vl);
    free(((void*)(tmp)));
    __int128 carry = 0;
    int32_t i = 0;
    int32_t n = a_len;
    if (b_len > n) {
        n = b_len;
    }
    while (i < n) {
        __int128 ai = ((i < a_len) ? (((__int128)(a[i]))) : (0));
        __int128 bi = ((i < b_len) ? (((__int128)(b[i]))) : (0));
        __int128 s = ((carry + ai) + (bi * v));
        a[i] = ((int64_t)(FLOW_CHECKED_MOD((s), (((__int128)(B))))));
        carry = FLOW_CHECKED_DIV((s), (((__int128)(B))));
        i = (i + 1);
    }
    while (carry > 0) {
        a[n] = ((int64_t)(FLOW_CHECKED_MOD((carry), (((__int128)(B))))));
        carry = FLOW_CHECKED_DIV((carry), (((__int128)(B))));
        n = (n + 1);
    }
    while ((n > 0 && a[(n - 1)] == 0)) {
        n = (n - 1);
    }
    return n;
}

int32_t bn_mul_small_ptr_i64_ptr_i64_i32_i64(int64_t* dst, int64_t* a, int32_t a_len, int64_t v) {
    int64_t carry = 0;
    int32_t i = 0;
    int32_t n = a_len;
    while (i < n) {
        __int128 prod = ((((__int128)(a[i])) * ((__int128)(v))) + carry);
        dst[i] = ((int64_t)(FLOW_CHECKED_MOD((prod), (((__int128)(B))))));
        carry = ((int64_t)(FLOW_CHECKED_DIV((prod), (((__int128)(B))))));
        i = (i + 1);
    }
    while (carry > 0) {
        dst[n] = FLOW_CHECKED_MOD((carry), (B));
        carry = FLOW_CHECKED_DIV((carry), (B));
        n = (n + 1);
    }
    return n;
}

int32_t bn_div_small_ptr_i64_ptr_i64_i32_i64(int64_t* q, int64_t* a, int32_t a_len, int64_t v) {
    int64_t rem = 0;
    int32_t n = a_len;
    int32_t i = (a_len - 1);
    while (i >= 0) {
        __int128 cur = ((((__int128)(rem)) * ((__int128)(B))) + ((__int128)(a[i])));
        q[i] = ((int64_t)(FLOW_CHECKED_DIV((cur), (((__int128)(v))))));
        rem = ((int64_t)(FLOW_CHECKED_MOD((cur), (((__int128)(v))))));
        i = (i - 1);
    }
    while ((n > 0 && q[(n - 1)] == 0)) {
        n = (n - 1);
    }
    return n;
}

int32_t bn_sub_ptr_i64_ptr_i64_i32_ptr_i64_i32(int64_t* dst, int64_t* a, int32_t a_len, int64_t* b, int32_t b_len) {
    int64_t borrow = 0;
    int32_t i = 0;
    int32_t n = a_len;
    while (i < n) {
        int64_t s = (a[i] - borrow);
        if (i < b_len) {
            s = (s - b[i]);
        }
        if (s < 0) {
            s = (s + B);
            borrow = 1;
        } else {
            borrow = 0;
        }
        dst[i] = s;
        i = (i + 1);
    }
    while ((n > 0 && dst[(n - 1)] == 0)) {
        n = (n - 1);
    }
    return n;
}

int32_t bn_cmp_ptr_i64_i32_ptr_i64_i32(int64_t* a, int32_t a_len, int64_t* b, int32_t b_len) {
    if (a_len != b_len) {
        if (a_len > b_len) {
            return 1;
        }
        return (-1);
    }
    int32_t i = (a_len - 1);
    while (i >= 0) {
        if (a[i] != b[i]) {
            if (a[i] > b[i]) {
                return 1;
            }
            return (-1);
        }
        i = (i - 1);
    }
    return 0;
}

void bn_copy_ptr_i64_ptr_i64_i32_i32(int64_t* dst, int64_t* a, int32_t a_len, int32_t cap) {
    int32_t i = 0;
    while (i < a_len) {
        dst[i] = a[i];
        i = (i + 1);
    }
    while (i < cap) {
        dst[i] = 0;
        i = (i + 1);
    }
}

double bn_to_f64_ptr_i64_i32(int64_t* a, int32_t a_len) {
    if (a_len == 0) {
        return 0.0;
    }
    double result = 0.0;
    int32_t i = (a_len - 1);
    while (i >= 0) {
        result = ((result * 1000000000.0) + ((double)(a[i])));
        i = (i - 1);
    }
    return result;
}

int64_t comb_l_i64_i64(int64_t n, int64_t k) {
    if ((k < 0 || k > n)) {
        return 0;
    }
    int64_t kk = k;
    if (kk > (n - kk)) {
        kk = (n - kk);
    }
    int64_t r = 1;
    int64_t i = 1;
    while (i <= kk) {
        r = FLOW_CHECKED_DIV(((r * ((n - kk) + i))), (i));
        i = (i + 1);
    }
    return r;
}

int32_t main(void) {
    __int128** Qpow = (__int128**)(calloc(14, 8));
    int32_t* deg = (int32_t*)(calloc(14, 4));
    int32_t m = 0;
    while (m <= RANKS) {
        Qpow[m] = calloc(MAXD, 16);
        m = (m + 1);
    }
    Qpow[0][0] = 1;
    deg[0] = 0;
    int64_t* Q = (int64_t*)(calloc(4, 8));
    Q[0] = 1;
    Q[1] = (-12);
    Q[2] = 36;
    Q[3] = (-24);
    m = 1;
    while (m <= RANKS) {
        int32_t pd = deg[(m - 1)];
        deg[m] = (pd + 3);
        int32_t i = 0;
        while (i <= pd) {
            int32_t j = 0;
            while (j < 4) {
                Qpow[m][(i + j)] = (Qpow[m][(i + j)] + (Qpow[(m - 1)][i] * ((__int128)(Q[j]))));
                j = (j + 1);
            }
            i = (i + 1);
        }
        m = (m + 1);
    }
    int64_t** fact = (int64_t**)(calloc(((int64_t)((N + 1))), 8));
    int32_t* fact_len = (int32_t*)(calloc(((int64_t)((N + 1))), 4));
    fact[0] = calloc(20, 8);
    fact[0][0] = 1;
    fact_len[0] = 1;
    int32_t i = 1;
    while (i <= N) {
        fact[i] = calloc(20, 8);
        fact_len[i] = bn_mul_small_ptr_i64_ptr_i64_i32_i64(fact[i], fact[(i - 1)], fact_len[(i - 1)], ((int64_t)(i)));
        i = (i + 1);
    }
    int64_t* denom = (int64_t*)(calloc(20, 8));
    denom[0] = 1;
    int32_t dn = 1;
    int32_t i2 = 0;
    while (i2 < RANKS) {
        int64_t* tmp = (int64_t*)(calloc(20, 8));
        int32_t nl = bn_mul_small_ptr_i64_ptr_i64_i32_i64(tmp, denom, dn, ((int64_t)(CB)));
        bn_copy_ptr_i64_ptr_i64_i32_i32(denom, tmp, nl, 20);
        dn = nl;
        free(((void*)(tmp)));
        i2 = (i2 + 1);
    }
    int64_t** nval = (int64_t**)(calloc(14, 8));
    int32_t* nval_len = (int32_t*)(calloc(14, 4));
    m = 0;
    while (m <= RANKS) {
        int64_t* pos = (int64_t*)(calloc(30, 8));
        int32_t plen = 0;
        int64_t* neg = (int64_t*)(calloc(30, 8));
        int32_t nlen = 0;
        int32_t B2 = 0;
        while (B2 <= deg[m]) {
            __int128 coef = Qpow[m][B2];
            if (coef > 0) {
                plen = bn_addmul_i128_ptr_i64_i32_ptr_i64_i32_i128(pos, plen, fact[(N - B2)], fact_len[(N - B2)], coef);
            } else {
                if (coef < 0) {
                    nlen = bn_addmul_i128_ptr_i64_i32_ptr_i64_i32_i128(neg, nlen, fact[(N - B2)], fact_len[(N - B2)], (0 - coef));
                }
            }
            B2 = (B2 + 1);
        }
        int64_t* num = (int64_t*)(calloc(30, 8));
        int32_t num_len = bn_sub_ptr_i64_ptr_i64_i32_ptr_i64_i32(num, pos, plen, neg, nlen);
        nval[m] = calloc(20, 8);
        int64_t* remaining = (int64_t*)(calloc(30, 8));
        bn_copy_ptr_i64_ptr_i64_i32_i32(remaining, num, num_len, 30);
        int32_t rlen = num_len;
        int32_t d = 0;
        while (d < RANKS) {
            int64_t* tmp2 = (int64_t*)(calloc(30, 8));
            rlen = bn_div_small_ptr_i64_ptr_i64_i32_i64(tmp2, remaining, rlen, ((int64_t)(CB)));
            bn_copy_ptr_i64_ptr_i64_i32_i32(remaining, tmp2, rlen, 30);
            free(((void*)(tmp2)));
            d = (d + 1);
        }
        bn_copy_ptr_i64_ptr_i64_i32_i32(nval[m], remaining, rlen, 20);
        nval_len[m] = rlen;
        free(((void*)(pos)));
        free(((void*)(neg)));
        free(((void*)(num)));
        free(((void*)(remaining)));
        m = (m + 1);
    }
    int64_t* total = (int64_t*)(calloc(20, 8));
    int32_t total_len = nval_len[0];
    bn_copy_ptr_i64_ptr_i64_i32_i32(total, nval[0], total_len, 20);
    int64_t* good = (int64_t*)(calloc(30, 8));
    int32_t good_len = 0;
    int32_t* primes = (int32_t*)(calloc(6, 4));
    primes[0] = 2;
    primes[1] = 3;
    primes[2] = 5;
    primes[3] = 7;
    primes[4] = 11;
    primes[5] = 13;
    int32_t ki = 0;
    while (ki < 6) {
        int32_t k = primes[ki];
        int64_t* z = (int64_t*)(calloc(30, 8));
        int32_t zlen = 0;
        int64_t* zneg = (int64_t*)(calloc(30, 8));
        int32_t znlen = 0;
        int32_t m3 = k;
        while (m3 <= RANKS) {
            int64_t c = comb_l_i64_i64(((int64_t)((RANKS - k))), ((int64_t)((m3 - k))));
            if (((m3 - k) & 1) != 0) {
                znlen = bn_addmul_small_ptr_i64_i32_ptr_i64_i32_i64(zneg, znlen, nval[m3], nval_len[m3], c);
            } else {
                zlen = bn_addmul_small_ptr_i64_i32_ptr_i64_i32_i64(z, zlen, nval[m3], nval_len[m3], c);
            }
            m3 = (m3 + 1);
        }
        int64_t* zfinal = (int64_t*)(calloc(30, 8));
        int32_t zf_len = bn_sub_ptr_i64_ptr_i64_i32_ptr_i64_i32(zfinal, z, zlen, zneg, znlen);
        int64_t ck = comb_l_i64_i64(((int64_t)(RANKS)), ((int64_t)(k)));
        good_len = bn_addmul_small_ptr_i64_i32_ptr_i64_i32_i64(good, good_len, zfinal, zf_len, ck);
        free(((void*)(z)));
        free(((void*)(zneg)));
        free(((void*)(zfinal)));
        ki = (ki + 1);
    }
    int64_t* good_scaled = (int64_t*)(calloc(30, 8));
    int32_t gs_len = bn_mul_small_ptr_i64_ptr_i64_i32_i64(good_scaled, good, good_len, 100000000000);
    int64_t* half_total = (int64_t*)(calloc(20, 8));
    int32_t ht_len = bn_div_small_ptr_i64_ptr_i64_i32_i64(half_total, total, total_len, 2);
    int64_t* numerator = (int64_t*)(calloc(30, 8));
    int32_t num_len = bn_addmul_small_ptr_i64_i32_ptr_i64_i32_i64(numerator, 0, good_scaled, gs_len, 1);
    int32_t num_len2 = bn_addmul_small_ptr_i64_i32_ptr_i64_i32_i64(numerator, num_len, half_total, ht_len, 1);
    double num_f = bn_to_f64_ptr_i64_i32(numerator, num_len2);
    double total_f = bn_to_f64_ptr_i64_i32(total, total_len);
    int64_t q_approx = ((int64_t)((num_f / total_f)));
    int64_t* qprod = (int64_t*)(calloc(30, 8));
    int32_t qp_len = bn_mul_small_ptr_i64_ptr_i64_i32_i64(qprod, total, total_len, q_approx);
    int32_t cmp = bn_cmp_ptr_i64_i32_ptr_i64_i32(qprod, qp_len, numerator, num_len2);
    int64_t q_final = q_approx;
    if (cmp < 0) {
        int64_t q_try = (q_approx + 1);
        int32_t found = 0;
        while (found == 0) {
            int64_t* qp2 = (int64_t*)(calloc(30, 8));
            int32_t qp2_len = bn_mul_small_ptr_i64_ptr_i64_i32_i64(qp2, total, total_len, q_try);
            int32_t cmp2 = bn_cmp_ptr_i64_i32_ptr_i64_i32(qp2, qp2_len, numerator, num_len2);
            free(((void*)(qp2)));
            if (cmp2 > 0) {
                found = 1;
            } else {
                q_try = (q_try + 1);
                if (q_try > (q_approx + 100)) {
                    found = 1;
                }
            }
        }
        q_final = (q_try - 1);
    } else {
        if (cmp > 0) {
            int64_t q_try = (q_approx - 1);
            int32_t found = 0;
            while ((found == 0 && q_try >= 0)) {
                int64_t* qp2 = (int64_t*)(calloc(30, 8));
                int32_t qp2_len = bn_mul_small_ptr_i64_ptr_i64_i32_i64(qp2, total, total_len, q_try);
                int32_t cmp2 = bn_cmp_ptr_i64_i32_ptr_i64_i32(qp2, qp2_len, numerator, num_len2);
                free(((void*)(qp2)));
                if (cmp2 <= 0) {
                    found = 1;
                } else {
                    q_try = (q_try - 1);
                    if (q_try < (q_approx - 100)) {
                        found = 1;
                    }
                }
            }
            q_final = q_try;
        }
    }
    int64_t q_with_5 = (q_final + 5);
    int64_t q_div_10 = FLOW_CHECKED_DIV((q_with_5), (10));
    double ans = (((double)(q_div_10)) / 10000000000.0);
    printf("%.10f\n", ans);
    int32_t m4 = 0;
    while (m4 <= RANKS) {
        free(((void*)(Qpow[m4])));
        free(((void*)(nval[m4])));
        m4 = (m4 + 1);
    }
    free(((void*)(Qpow)));
    free(((void*)(deg)));
    free(((void*)(Q)));
    int32_t i3 = 0;
    while (i3 <= N) {
        free(((void*)(fact[i3])));
        i3 = (i3 + 1);
    }
    free(((void*)(fact)));
    free(((void*)(fact_len)));
    free(((void*)(denom)));
    free(((void*)(nval_len)));
    free(((void*)(total)));
    free(((void*)(good)));
    free(((void*)(primes)));
    free(((void*)(good_scaled)));
    free(((void*)(half_total)));
    free(((void*)(numerator)));
    free(((void*)(qprod)));
    return 0;
}

Generated MLIR

module {
  llvm.func @printf(!llvm.ptr, ...) -> i32
  llvm.mlir.global internal constant @str_0("%.10f\n\00") {addr_space = 0 : i32} : !llvm.array<7 x i8>
  func.func private @calloc(i64, i64) -> !llvm.ptr
  func.func private @free(!llvm.ptr) -> ()

  // Constant: B
  llvm.mlir.global internal constant @B(1000000000 : i64) : i64
  // Constant: RANKS
  llvm.mlir.global internal constant @RANKS(13 : i32) : i32
  // Constant: N
  llvm.mlir.global internal constant @N(52 : i32) : i32
  // Constant: CB
  llvm.mlir.global internal constant @CB(24 : i32) : i32
  // Constant: MAXD
  llvm.mlir.global internal constant @MAXD(40 : i32) : i32
  func.func @bn_zero(%arg0: !llvm.ptr, %arg1: i32) -> () {
    %0 = arith.constant 0 : i32
    %1 = llvm.mlir.constant(1 : i64) : i64
    %2 = llvm.alloca %1 x i32 : (i64) -> !llvm.ptr
    llvm.store %0, %2 : i32, !llvm.ptr
    cf.br ^bb0
    ^bb0:
    %3 = llvm.load %2 : !llvm.ptr -> i32
    %4 = arith.cmpi slt, %3, %arg1 : i32
    cf.cond_br %4, ^bb1, ^bb2
    ^bb1:
      %5 = arith.constant 0 : i32
      %6 = llvm.load %2 : !llvm.ptr -> i32
      %7 = arith.extsi %5 : i32 to i64
      %8 = arith.extsi %6 : i32 to i64
      %9 = llvm.getelementptr %arg0[%8] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %7, %9 : i64, !llvm.ptr
      %10 = llvm.load %2 : !llvm.ptr -> i32
      %11 = arith.constant 1 : i32
      %12 = arith.addi %10, %11 : i32
      llvm.store %12, %2 : i32, !llvm.ptr
      cf.br ^bb0
    ^bb2:
    func.return
  }
  func.func @bn_addmul_small(%arg0: !llvm.ptr, %arg1: i32, %arg2: !llvm.ptr, %arg3: i32, %arg4: i64) -> i32 {
    %13 = arith.constant 0 : i32
    %15 = arith.extsi %13 : i32 to i64
    %14 = arith.cmpi eq, %arg4, %15 : i64
    cf.cond_br %14, ^bb3, ^bb4
    ^bb3:
      func.return %arg1 : i32
    ^bb4:
      cf.br ^bb5
    ^bb5:
    %16 = arith.constant 0 : i32
    %17 = arith.extsi %16 : i32 to i64
    %18 = llvm.mlir.constant(1 : i64) : i64
    %19 = llvm.alloca %18 x i64 : (i64) -> !llvm.ptr
    llvm.store %17, %19 : i64, !llvm.ptr
    %20 = arith.constant 0 : i32
    %21 = llvm.mlir.constant(1 : i64) : i64
    %22 = llvm.alloca %21 x i32 : (i64) -> !llvm.ptr
    llvm.store %20, %22 : i32, !llvm.ptr
    %23 = llvm.mlir.constant(1 : i64) : i64
    %24 = llvm.alloca %23 x i32 : (i64) -> !llvm.ptr
    llvm.store %arg1, %24 : i32, !llvm.ptr
    %25 = llvm.load %24 : !llvm.ptr -> i32
    %26 = arith.cmpi sgt, %arg3, %25 : i32
    cf.cond_br %26, ^bb6, ^bb7
    ^bb6:
      llvm.store %arg3, %24 : i32, !llvm.ptr
      cf.br ^bb8
    ^bb7:
      cf.br ^bb8
    ^bb8:
    cf.br ^bb9
    ^bb9:
    %27 = llvm.load %22 : !llvm.ptr -> i32
    %28 = llvm.load %24 : !llvm.ptr -> i32
    %29 = arith.cmpi slt, %27, %28 : i32
    cf.cond_br %29, ^bb10, ^bb11
    ^bb10:
      %30 = llvm.load %22 : !llvm.ptr -> i32
      %31 = arith.cmpi slt, %30, %arg1 : i32
      %32 = scf.if %31 -> (i64) {
        %34 = llvm.load %22 : !llvm.ptr -> i32
        %35 = arith.extsi %34 : i32 to i64
        %36 = llvm.getelementptr %arg0[%35] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %33 = llvm.load %36 : !llvm.ptr -> i64
        scf.yield %33 : i64
      } else {
        %37 = arith.constant 0 : i32
        scf.yield %37 : i32
      }
      %38 = llvm.load %22 : !llvm.ptr -> i32
      %39 = arith.cmpi slt, %38, %arg3 : i32
      %40 = scf.if %39 -> (i64) {
        %42 = llvm.load %22 : !llvm.ptr -> i32
        %43 = arith.extsi %42 : i32 to i64
        %44 = llvm.getelementptr %arg2[%43] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %41 = llvm.load %44 : !llvm.ptr -> i64
        scf.yield %41 : i64
      } else {
        %45 = arith.constant 0 : i32
        scf.yield %45 : i32
      }
      %46 = llvm.load %19 : !llvm.ptr -> i64
      %47 = arith.extsi %46 : i64 to i128
      %48 = arith.extsi %32 : i64 to i128
      %50 = arith.trunci %47 : i128 to i64
      %51 = arith.trunci %48 : i128 to i64
      %49 = arith.addi %50, %51 : i64
      %52 = arith.extsi %40 : i64 to i128
      %53 = arith.extsi %arg4 : i64 to i128
      %55 = arith.trunci %52 : i128 to i64
      %56 = arith.trunci %53 : i128 to i64
      %54 = arith.muli %55, %56 : i64
      %57 = arith.addi %49, %54 : i64
      %58 = arith.extsi %57 : i64 to i128
      %59 = llvm.mlir.addressof @B : !llvm.ptr
      %60 = llvm.load %59 : !llvm.ptr -> i64
      %61 = arith.extsi %60 : i64 to i128
      %63 = arith.trunci %58 : i128 to i64
      %64 = arith.trunci %61 : i128 to i64
      %62 = arith.remsi %63, %64 : i64
      %65 = llvm.load %22 : !llvm.ptr -> i32
      %66 = arith.extsi %65 : i32 to i64
      %67 = llvm.getelementptr %arg0[%66] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %62, %67 : i64, !llvm.ptr
      %68 = llvm.mlir.addressof @B : !llvm.ptr
      %69 = llvm.load %68 : !llvm.ptr -> i64
      %70 = arith.extsi %69 : i64 to i128
      %72 = arith.trunci %58 : i128 to i64
      %73 = arith.trunci %70 : i128 to i64
      %71 = arith.divsi %72, %73 : i64
      llvm.store %71, %19 : i64, !llvm.ptr
      %74 = llvm.load %22 : !llvm.ptr -> i32
      %75 = arith.constant 1 : i32
      %76 = arith.addi %74, %75 : i32
      llvm.store %76, %22 : i32, !llvm.ptr
      cf.br ^bb9
    ^bb11:
    cf.br ^bb12
    ^bb12:
    %77 = llvm.load %19 : !llvm.ptr -> i64
    %78 = arith.constant 0 : i32
    %80 = arith.extsi %78 : i32 to i64
    %79 = arith.cmpi sgt, %77, %80 : i64
    cf.cond_br %79, ^bb13, ^bb14
    ^bb13:
      %81 = llvm.load %19 : !llvm.ptr -> i64
      %82 = llvm.mlir.addressof @B : !llvm.ptr
      %83 = llvm.load %82 : !llvm.ptr -> i64
      %84 = arith.remsi %81, %83 : i64
      %85 = llvm.load %24 : !llvm.ptr -> i32
      %86 = arith.extsi %85 : i32 to i64
      %87 = llvm.getelementptr %arg0[%86] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %84, %87 : i64, !llvm.ptr
      %88 = llvm.load %19 : !llvm.ptr -> i64
      %89 = llvm.mlir.addressof @B : !llvm.ptr
      %90 = llvm.load %89 : !llvm.ptr -> i64
      %91 = arith.divsi %88, %90 : i64
      llvm.store %91, %19 : i64, !llvm.ptr
      %92 = llvm.load %24 : !llvm.ptr -> i32
      %93 = arith.constant 1 : i32
      %94 = arith.addi %92, %93 : i32
      llvm.store %94, %24 : i32, !llvm.ptr
      cf.br ^bb12
    ^bb14:
    cf.br ^bb15
    ^bb15:
    %95 = llvm.load %24 : !llvm.ptr -> i32
    %96 = arith.constant 0 : i32
    %97 = arith.cmpi sgt, %95, %96 : i32
    %98 = scf.if %97 -> (i1) {
      %100 = llvm.load %24 : !llvm.ptr -> i32
      %101 = arith.constant 1 : i32
      %102 = arith.subi %100, %101 : i32
      %103 = arith.extsi %102 : i32 to i64
      %104 = llvm.getelementptr %arg0[%103] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %99 = llvm.load %104 : !llvm.ptr -> i64
      %105 = arith.constant 0 : i32
      %107 = arith.extsi %105 : i32 to i64
      %106 = arith.cmpi eq, %99, %107 : i64
      scf.yield %106 : i1
    } else {
      %108 = arith.constant false
      scf.yield %108 : i1
    }
    cf.cond_br %98, ^bb16, ^bb17
    ^bb16:
      %109 = llvm.load %24 : !llvm.ptr -> i32
      %110 = arith.constant 1 : i32
      %111 = arith.subi %109, %110 : i32
      llvm.store %111, %24 : i32, !llvm.ptr
      cf.br ^bb15
    ^bb17:
    %112 = llvm.load %24 : !llvm.ptr -> i32
    func.return %112 : i32
  }
  func.func @bn_addmul_i128(%arg0: !llvm.ptr, %arg1: i32, %arg2: !llvm.ptr, %arg3: i32, %arg4: i128) -> i32 {
    %113 = arith.constant 0 : i32
    %115 = arith.trunci %arg4 : i128 to i64
    %116 = arith.extsi %113 : i32 to i64
    %114 = arith.cmpi eq, %115, %116 : i64
    cf.cond_br %114, ^bb18, ^bb19
    ^bb18:
      func.return %arg1 : i32
    ^bb19:
      cf.br ^bb20
    ^bb20:
    %117 = arith.constant 32 : i32
    %119 = arith.trunci %arg4 : i128 to i64
    %120 = arith.extsi %117 : i32 to i64
    %118 = arith.shrsi %119, %120 : i64
    %121 = arith.constant -1 : i32
    %123 = arith.trunci %arg4 : i128 to i64
    %124 = arith.extsi %121 : i32 to i64
    %122 = arith.andi %123, %124 : i64
    %126 = arith.constant 40 : i32
    %127 = arith.constant 8 : i32
    %128 = arith.extsi %126 : i32 to i64
    %129 = arith.extsi %127 : i32 to i64
    %125 = func.call @calloc(%128, %129) : (i64, i64) -> !llvm.ptr
    %131 = arith.constant 0 : i32
    %130 = func.call @bn_addmul_small(%125, %131, %arg2, %arg3, %122) : (!llvm.ptr, i32, !llvm.ptr, i32, i64) -> i32
    func.call @free(%125) : (!llvm.ptr) -> ()
    %133 = arith.constant 0 : i32
    %134 = arith.extsi %133 : i32 to i128
    %135 = llvm.mlir.constant(1 : i64) : i64
    %136 = llvm.alloca %135 x i128 : (i64) -> !llvm.ptr
    llvm.store %134, %136 : i128, !llvm.ptr
    %137 = arith.constant 0 : i32
    %138 = llvm.mlir.constant(1 : i64) : i64
    %139 = llvm.alloca %138 x i32 : (i64) -> !llvm.ptr
    llvm.store %137, %139 : i32, !llvm.ptr
    %140 = llvm.mlir.constant(1 : i64) : i64
    %141 = llvm.alloca %140 x i32 : (i64) -> !llvm.ptr
    llvm.store %arg1, %141 : i32, !llvm.ptr
    %142 = llvm.load %141 : !llvm.ptr -> i32
    %143 = arith.cmpi sgt, %arg3, %142 : i32
    cf.cond_br %143, ^bb21, ^bb22
    ^bb21:
      llvm.store %arg3, %141 : i32, !llvm.ptr
      cf.br ^bb23
    ^bb22:
      cf.br ^bb23
    ^bb23:
    cf.br ^bb24
    ^bb24:
    %144 = llvm.load %139 : !llvm.ptr -> i32
    %145 = llvm.load %141 : !llvm.ptr -> i32
    %146 = arith.cmpi slt, %144, %145 : i32
    cf.cond_br %146, ^bb25, ^bb26
    ^bb25:
      %147 = llvm.load %139 : !llvm.ptr -> i32
      %148 = arith.cmpi slt, %147, %arg1 : i32
      %149 = scf.if %148 -> (i128) {
        %151 = llvm.load %139 : !llvm.ptr -> i32
        %152 = arith.extsi %151 : i32 to i64
        %153 = llvm.getelementptr %arg0[%152] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %150 = llvm.load %153 : !llvm.ptr -> i64
        %154 = arith.extsi %150 : i64 to i128
        scf.yield %154 : i128
      } else {
        %155 = arith.constant 0 : i32
        scf.yield %155 : i32
      }
      %156 = llvm.load %139 : !llvm.ptr -> i32
      %157 = arith.cmpi slt, %156, %arg3 : i32
      %158 = scf.if %157 -> (i128) {
        %160 = llvm.load %139 : !llvm.ptr -> i32
        %161 = arith.extsi %160 : i32 to i64
        %162 = llvm.getelementptr %arg2[%161] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %159 = llvm.load %162 : !llvm.ptr -> i64
        %163 = arith.extsi %159 : i64 to i128
        scf.yield %163 : i128
      } else {
        %164 = arith.constant 0 : i32
        scf.yield %164 : i32
      }
      %165 = llvm.load %136 : !llvm.ptr -> i128
      %167 = arith.trunci %165 : i128 to i64
      %168 = arith.trunci %149 : i128 to i64
      %166 = arith.addi %167, %168 : i64
      %170 = arith.trunci %158 : i128 to i64
      %171 = arith.trunci %arg4 : i128 to i64
      %169 = arith.muli %170, %171 : i64
      %172 = arith.addi %166, %169 : i64
      %173 = arith.extsi %172 : i64 to i128
      %174 = llvm.mlir.addressof @B : !llvm.ptr
      %175 = llvm.load %174 : !llvm.ptr -> i64
      %176 = arith.extsi %175 : i64 to i128
      %178 = arith.trunci %173 : i128 to i64
      %179 = arith.trunci %176 : i128 to i64
      %177 = arith.remsi %178, %179 : i64
      %180 = llvm.load %139 : !llvm.ptr -> i32
      %181 = arith.extsi %180 : i32 to i64
      %182 = llvm.getelementptr %arg0[%181] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %177, %182 : i64, !llvm.ptr
      %183 = llvm.mlir.addressof @B : !llvm.ptr
      %184 = llvm.load %183 : !llvm.ptr -> i64
      %185 = arith.extsi %184 : i64 to i128
      %187 = arith.trunci %173 : i128 to i64
      %188 = arith.trunci %185 : i128 to i64
      %186 = arith.divsi %187, %188 : i64
      %189 = arith.extsi %186 : i64 to i128
      llvm.store %189, %136 : i128, !llvm.ptr
      %190 = llvm.load %139 : !llvm.ptr -> i32
      %191 = arith.constant 1 : i32
      %192 = arith.addi %190, %191 : i32
      llvm.store %192, %139 : i32, !llvm.ptr
      cf.br ^bb24
    ^bb26:
    cf.br ^bb27
    ^bb27:
    %193 = llvm.load %136 : !llvm.ptr -> i128
    %194 = arith.constant 0 : i32
    %196 = arith.trunci %193 : i128 to i64
    %197 = arith.extsi %194 : i32 to i64
    %195 = arith.cmpi sgt, %196, %197 : i64
    cf.cond_br %195, ^bb28, ^bb29
    ^bb28:
      %198 = llvm.load %136 : !llvm.ptr -> i128
      %199 = llvm.mlir.addressof @B : !llvm.ptr
      %200 = llvm.load %199 : !llvm.ptr -> i64
      %201 = arith.extsi %200 : i64 to i128
      %203 = arith.trunci %198 : i128 to i64
      %204 = arith.trunci %201 : i128 to i64
      %202 = arith.remsi %203, %204 : i64
      %205 = llvm.load %141 : !llvm.ptr -> i32
      %206 = arith.extsi %205 : i32 to i64
      %207 = llvm.getelementptr %arg0[%206] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %202, %207 : i64, !llvm.ptr
      %208 = llvm.load %136 : !llvm.ptr -> i128
      %209 = llvm.mlir.addressof @B : !llvm.ptr
      %210 = llvm.load %209 : !llvm.ptr -> i64
      %211 = arith.extsi %210 : i64 to i128
      %213 = arith.trunci %208 : i128 to i64
      %214 = arith.trunci %211 : i128 to i64
      %212 = arith.divsi %213, %214 : i64
      %215 = arith.extsi %212 : i64 to i128
      llvm.store %215, %136 : i128, !llvm.ptr
      %216 = llvm.load %141 : !llvm.ptr -> i32
      %217 = arith.constant 1 : i32
      %218 = arith.addi %216, %217 : i32
      llvm.store %218, %141 : i32, !llvm.ptr
      cf.br ^bb27
    ^bb29:
    cf.br ^bb30
    ^bb30:
    %219 = llvm.load %141 : !llvm.ptr -> i32
    %220 = arith.constant 0 : i32
    %221 = arith.cmpi sgt, %219, %220 : i32
    %222 = scf.if %221 -> (i1) {
      %224 = llvm.load %141 : !llvm.ptr -> i32
      %225 = arith.constant 1 : i32
      %226 = arith.subi %224, %225 : i32
      %227 = arith.extsi %226 : i32 to i64
      %228 = llvm.getelementptr %arg0[%227] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %223 = llvm.load %228 : !llvm.ptr -> i64
      %229 = arith.constant 0 : i32
      %231 = arith.extsi %229 : i32 to i64
      %230 = arith.cmpi eq, %223, %231 : i64
      scf.yield %230 : i1
    } else {
      %232 = arith.constant false
      scf.yield %232 : i1
    }
    cf.cond_br %222, ^bb31, ^bb32
    ^bb31:
      %233 = llvm.load %141 : !llvm.ptr -> i32
      %234 = arith.constant 1 : i32
      %235 = arith.subi %233, %234 : i32
      llvm.store %235, %141 : i32, !llvm.ptr
      cf.br ^bb30
    ^bb32:
    %236 = llvm.load %141 : !llvm.ptr -> i32
    func.return %236 : i32
  }
  func.func @bn_mul_small(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: i32, %arg3: i64) -> i32 {
    %237 = arith.constant 0 : i32
    %238 = arith.extsi %237 : i32 to i64
    %239 = llvm.mlir.constant(1 : i64) : i64
    %240 = llvm.alloca %239 x i64 : (i64) -> !llvm.ptr
    llvm.store %238, %240 : i64, !llvm.ptr
    %241 = arith.constant 0 : i32
    %242 = llvm.mlir.constant(1 : i64) : i64
    %243 = llvm.alloca %242 x i32 : (i64) -> !llvm.ptr
    llvm.store %241, %243 : i32, !llvm.ptr
    %244 = llvm.mlir.constant(1 : i64) : i64
    %245 = llvm.alloca %244 x i32 : (i64) -> !llvm.ptr
    llvm.store %arg2, %245 : i32, !llvm.ptr
    cf.br ^bb33
    ^bb33:
    %246 = llvm.load %243 : !llvm.ptr -> i32
    %247 = llvm.load %245 : !llvm.ptr -> i32
    %248 = arith.cmpi slt, %246, %247 : i32
    cf.cond_br %248, ^bb34, ^bb35
    ^bb34:
      %250 = llvm.load %243 : !llvm.ptr -> i32
      %251 = arith.extsi %250 : i32 to i64
      %252 = llvm.getelementptr %arg1[%251] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %249 = llvm.load %252 : !llvm.ptr -> i64
      %253 = arith.extsi %249 : i64 to i128
      %254 = arith.extsi %arg3 : i64 to i128
      %256 = arith.trunci %253 : i128 to i64
      %257 = arith.trunci %254 : i128 to i64
      %255 = arith.muli %256, %257 : i64
      %258 = llvm.load %240 : !llvm.ptr -> i64
      %259 = arith.addi %255, %258 : i64
      %260 = arith.extsi %259 : i64 to i128
      %261 = llvm.mlir.addressof @B : !llvm.ptr
      %262 = llvm.load %261 : !llvm.ptr -> i64
      %263 = arith.extsi %262 : i64 to i128
      %265 = arith.trunci %260 : i128 to i64
      %266 = arith.trunci %263 : i128 to i64
      %264 = arith.remsi %265, %266 : i64
      %267 = llvm.load %243 : !llvm.ptr -> i32
      %268 = arith.extsi %267 : i32 to i64
      %269 = llvm.getelementptr %arg0[%268] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %264, %269 : i64, !llvm.ptr
      %270 = llvm.mlir.addressof @B : !llvm.ptr
      %271 = llvm.load %270 : !llvm.ptr -> i64
      %272 = arith.extsi %271 : i64 to i128
      %274 = arith.trunci %260 : i128 to i64
      %275 = arith.trunci %272 : i128 to i64
      %273 = arith.divsi %274, %275 : i64
      llvm.store %273, %240 : i64, !llvm.ptr
      %276 = llvm.load %243 : !llvm.ptr -> i32
      %277 = arith.constant 1 : i32
      %278 = arith.addi %276, %277 : i32
      llvm.store %278, %243 : i32, !llvm.ptr
      cf.br ^bb33
    ^bb35:
    cf.br ^bb36
    ^bb36:
    %279 = llvm.load %240 : !llvm.ptr -> i64
    %280 = arith.constant 0 : i32
    %282 = arith.extsi %280 : i32 to i64
    %281 = arith.cmpi sgt, %279, %282 : i64
    cf.cond_br %281, ^bb37, ^bb38
    ^bb37:
      %283 = llvm.load %240 : !llvm.ptr -> i64
      %284 = llvm.mlir.addressof @B : !llvm.ptr
      %285 = llvm.load %284 : !llvm.ptr -> i64
      %286 = arith.remsi %283, %285 : i64
      %287 = llvm.load %245 : !llvm.ptr -> i32
      %288 = arith.extsi %287 : i32 to i64
      %289 = llvm.getelementptr %arg0[%288] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %286, %289 : i64, !llvm.ptr
      %290 = llvm.load %240 : !llvm.ptr -> i64
      %291 = llvm.mlir.addressof @B : !llvm.ptr
      %292 = llvm.load %291 : !llvm.ptr -> i64
      %293 = arith.divsi %290, %292 : i64
      llvm.store %293, %240 : i64, !llvm.ptr
      %294 = llvm.load %245 : !llvm.ptr -> i32
      %295 = arith.constant 1 : i32
      %296 = arith.addi %294, %295 : i32
      llvm.store %296, %245 : i32, !llvm.ptr
      cf.br ^bb36
    ^bb38:
    %297 = llvm.load %245 : !llvm.ptr -> i32
    func.return %297 : i32
  }
  func.func @bn_div_small(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: i32, %arg3: i64) -> i32 {
    %298 = arith.constant 0 : i32
    %299 = arith.extsi %298 : i32 to i64
    %300 = llvm.mlir.constant(1 : i64) : i64
    %301 = llvm.alloca %300 x i64 : (i64) -> !llvm.ptr
    llvm.store %299, %301 : i64, !llvm.ptr
    %302 = llvm.mlir.constant(1 : i64) : i64
    %303 = llvm.alloca %302 x i32 : (i64) -> !llvm.ptr
    llvm.store %arg2, %303 : i32, !llvm.ptr
    %304 = arith.constant 1 : i32
    %305 = arith.subi %arg2, %304 : i32
    %306 = llvm.mlir.constant(1 : i64) : i64
    %307 = llvm.alloca %306 x i32 : (i64) -> !llvm.ptr
    llvm.store %305, %307 : i32, !llvm.ptr
    cf.br ^bb39
    ^bb39:
    %308 = llvm.load %307 : !llvm.ptr -> i32
    %309 = arith.constant 0 : i32
    %310 = arith.cmpi sge, %308, %309 : i32
    cf.cond_br %310, ^bb40, ^bb41
    ^bb40:
      %311 = llvm.load %301 : !llvm.ptr -> i64
      %312 = arith.extsi %311 : i64 to i128
      %313 = llvm.mlir.addressof @B : !llvm.ptr
      %314 = llvm.load %313 : !llvm.ptr -> i64
      %315 = arith.extsi %314 : i64 to i128
      %317 = arith.trunci %312 : i128 to i64
      %318 = arith.trunci %315 : i128 to i64
      %316 = arith.muli %317, %318 : i64
      %320 = llvm.load %307 : !llvm.ptr -> i32
      %321 = arith.extsi %320 : i32 to i64
      %322 = llvm.getelementptr %arg1[%321] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %319 = llvm.load %322 : !llvm.ptr -> i64
      %323 = arith.extsi %319 : i64 to i128
      %325 = arith.trunci %323 : i128 to i64
      %324 = arith.addi %316, %325 : i64
      %326 = arith.extsi %324 : i64 to i128
      %327 = arith.extsi %arg3 : i64 to i128
      %329 = arith.trunci %326 : i128 to i64
      %330 = arith.trunci %327 : i128 to i64
      %328 = arith.divsi %329, %330 : i64
      %331 = llvm.load %307 : !llvm.ptr -> i32
      %332 = arith.extsi %331 : i32 to i64
      %333 = llvm.getelementptr %arg0[%332] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %328, %333 : i64, !llvm.ptr
      %334 = arith.extsi %arg3 : i64 to i128
      %336 = arith.trunci %326 : i128 to i64
      %337 = arith.trunci %334 : i128 to i64
      %335 = arith.remsi %336, %337 : i64
      llvm.store %335, %301 : i64, !llvm.ptr
      %338 = llvm.load %307 : !llvm.ptr -> i32
      %339 = arith.constant 1 : i32
      %340 = arith.subi %338, %339 : i32
      llvm.store %340, %307 : i32, !llvm.ptr
      cf.br ^bb39
    ^bb41:
    cf.br ^bb42
    ^bb42:
    %341 = llvm.load %303 : !llvm.ptr -> i32
    %342 = arith.constant 0 : i32
    %343 = arith.cmpi sgt, %341, %342 : i32
    %344 = scf.if %343 -> (i1) {
      %346 = llvm.load %303 : !llvm.ptr -> i32
      %347 = arith.constant 1 : i32
      %348 = arith.subi %346, %347 : i32
      %349 = arith.extsi %348 : i32 to i64
      %350 = llvm.getelementptr %arg0[%349] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %345 = llvm.load %350 : !llvm.ptr -> i64
      %351 = arith.constant 0 : i32
      %353 = arith.extsi %351 : i32 to i64
      %352 = arith.cmpi eq, %345, %353 : i64
      scf.yield %352 : i1
    } else {
      %354 = arith.constant false
      scf.yield %354 : i1
    }
    cf.cond_br %344, ^bb43, ^bb44
    ^bb43:
      %355 = llvm.load %303 : !llvm.ptr -> i32
      %356 = arith.constant 1 : i32
      %357 = arith.subi %355, %356 : i32
      llvm.store %357, %303 : i32, !llvm.ptr
      cf.br ^bb42
    ^bb44:
    %358 = llvm.load %303 : !llvm.ptr -> i32
    func.return %358 : i32
  }
  func.func @bn_sub(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: i32, %arg3: !llvm.ptr, %arg4: i32) -> i32 {
    %359 = arith.constant 0 : i32
    %360 = arith.extsi %359 : i32 to i64
    %361 = llvm.mlir.constant(1 : i64) : i64
    %362 = llvm.alloca %361 x i64 : (i64) -> !llvm.ptr
    llvm.store %360, %362 : i64, !llvm.ptr
    %363 = arith.constant 0 : i32
    %364 = llvm.mlir.constant(1 : i64) : i64
    %365 = llvm.alloca %364 x i32 : (i64) -> !llvm.ptr
    llvm.store %363, %365 : i32, !llvm.ptr
    %366 = llvm.mlir.constant(1 : i64) : i64
    %367 = llvm.alloca %366 x i32 : (i64) -> !llvm.ptr
    llvm.store %arg2, %367 : i32, !llvm.ptr
    cf.br ^bb45
    ^bb45:
    %368 = llvm.load %365 : !llvm.ptr -> i32
    %369 = llvm.load %367 : !llvm.ptr -> i32
    %370 = arith.cmpi slt, %368, %369 : i32
    cf.cond_br %370, ^bb46, ^bb47
    ^bb46:
      %372 = llvm.load %365 : !llvm.ptr -> i32
      %373 = arith.extsi %372 : i32 to i64
      %374 = llvm.getelementptr %arg1[%373] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %371 = llvm.load %374 : !llvm.ptr -> i64
      %375 = llvm.load %362 : !llvm.ptr -> i64
      %376 = arith.subi %371, %375 : i64
      %377 = llvm.mlir.constant(1 : i64) : i64
      %378 = llvm.alloca %377 x i64 : (i64) -> !llvm.ptr
      llvm.store %376, %378 : i64, !llvm.ptr
      %379 = llvm.load %365 : !llvm.ptr -> i32
      %380 = arith.cmpi slt, %379, %arg4 : i32
      cf.cond_br %380, ^bb48, ^bb49
      ^bb48:
        %381 = llvm.load %378 : !llvm.ptr -> i64
        %383 = llvm.load %365 : !llvm.ptr -> i32
        %384 = arith.extsi %383 : i32 to i64
        %385 = llvm.getelementptr %arg3[%384] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %382 = llvm.load %385 : !llvm.ptr -> i64
        %386 = arith.subi %381, %382 : i64
        llvm.store %386, %378 : i64, !llvm.ptr
        cf.br ^bb50
      ^bb49:
        cf.br ^bb50
      ^bb50:
      %387 = llvm.load %378 : !llvm.ptr -> i64
      %388 = arith.constant 0 : i32
      %390 = arith.extsi %388 : i32 to i64
      %389 = arith.cmpi slt, %387, %390 : i64
      cf.cond_br %389, ^bb51, ^bb52
      ^bb51:
        %391 = llvm.load %378 : !llvm.ptr -> i64
        %392 = llvm.mlir.addressof @B : !llvm.ptr
        %393 = llvm.load %392 : !llvm.ptr -> i64
        %394 = arith.addi %391, %393 : i64
        llvm.store %394, %378 : i64, !llvm.ptr
        %395 = arith.constant 1 : i32
        %396 = arith.extsi %395 : i32 to i64
        llvm.store %396, %362 : i64, !llvm.ptr
        cf.br ^bb53
      ^bb52:
        %397 = arith.constant 0 : i32
        %398 = arith.extsi %397 : i32 to i64
        llvm.store %398, %362 : i64, !llvm.ptr
        cf.br ^bb53
      ^bb53:
      %399 = llvm.load %378 : !llvm.ptr -> i64
      %400 = llvm.load %365 : !llvm.ptr -> i32
      %401 = arith.extsi %400 : i32 to i64
      %402 = llvm.getelementptr %arg0[%401] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %399, %402 : i64, !llvm.ptr
      %403 = llvm.load %365 : !llvm.ptr -> i32
      %404 = arith.constant 1 : i32
      %405 = arith.addi %403, %404 : i32
      llvm.store %405, %365 : i32, !llvm.ptr
      cf.br ^bb45
    ^bb47:
    cf.br ^bb54
    ^bb54:
    %406 = llvm.load %367 : !llvm.ptr -> i32
    %407 = arith.constant 0 : i32
    %408 = arith.cmpi sgt, %406, %407 : i32
    %409 = scf.if %408 -> (i1) {
      %411 = llvm.load %367 : !llvm.ptr -> i32
      %412 = arith.constant 1 : i32
      %413 = arith.subi %411, %412 : i32
      %414 = arith.extsi %413 : i32 to i64
      %415 = llvm.getelementptr %arg0[%414] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %410 = llvm.load %415 : !llvm.ptr -> i64
      %416 = arith.constant 0 : i32
      %418 = arith.extsi %416 : i32 to i64
      %417 = arith.cmpi eq, %410, %418 : i64
      scf.yield %417 : i1
    } else {
      %419 = arith.constant false
      scf.yield %419 : i1
    }
    cf.cond_br %409, ^bb55, ^bb56
    ^bb55:
      %420 = llvm.load %367 : !llvm.ptr -> i32
      %421 = arith.constant 1 : i32
      %422 = arith.subi %420, %421 : i32
      llvm.store %422, %367 : i32, !llvm.ptr
      cf.br ^bb54
    ^bb56:
    %423 = llvm.load %367 : !llvm.ptr -> i32
    func.return %423 : i32
  }
  func.func @bn_cmp(%arg0: !llvm.ptr, %arg1: i32, %arg2: !llvm.ptr, %arg3: i32) -> i32 {
    %424 = arith.cmpi ne, %arg1, %arg3 : i32
    cf.cond_br %424, ^bb57, ^bb58
    ^bb57:
      %425 = arith.cmpi sgt, %arg1, %arg3 : i32
      cf.cond_br %425, ^bb60, ^bb61
      ^bb60:
        %426 = arith.constant 1 : i32
        func.return %426 : i32
      ^bb61:
        cf.br ^bb62
      ^bb62:
      %427 = arith.constant 1 : i32
      %429 = arith.constant 0 : i32
      %428 = arith.subi %429, %427 : i32
      func.return %428 : i32
    ^bb58:
      cf.br ^bb59
    ^bb59:
    %430 = arith.constant 1 : i32
    %431 = arith.subi %arg1, %430 : i32
    %432 = llvm.mlir.constant(1 : i64) : i64
    %433 = llvm.alloca %432 x i32 : (i64) -> !llvm.ptr
    llvm.store %431, %433 : i32, !llvm.ptr
    cf.br ^bb63
    ^bb63:
    %434 = llvm.load %433 : !llvm.ptr -> i32
    %435 = arith.constant 0 : i32
    %436 = arith.cmpi sge, %434, %435 : i32
    cf.cond_br %436, ^bb64, ^bb65
    ^bb64:
      %438 = llvm.load %433 : !llvm.ptr -> i32
      %439 = arith.extsi %438 : i32 to i64
      %440 = llvm.getelementptr %arg0[%439] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %437 = llvm.load %440 : !llvm.ptr -> i64
      %442 = llvm.load %433 : !llvm.ptr -> i32
      %443 = arith.extsi %442 : i32 to i64
      %444 = llvm.getelementptr %arg2[%443] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %441 = llvm.load %444 : !llvm.ptr -> i64
      %445 = arith.cmpi ne, %437, %441 : i64
      cf.cond_br %445, ^bb66, ^bb67
      ^bb66:
        %447 = llvm.load %433 : !llvm.ptr -> i32
        %448 = arith.extsi %447 : i32 to i64
        %449 = llvm.getelementptr %arg0[%448] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %446 = llvm.load %449 : !llvm.ptr -> i64
        %451 = llvm.load %433 : !llvm.ptr -> i32
        %452 = arith.extsi %451 : i32 to i64
        %453 = llvm.getelementptr %arg2[%452] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %450 = llvm.load %453 : !llvm.ptr -> i64
        %454 = arith.cmpi sgt, %446, %450 : i64
        cf.cond_br %454, ^bb69, ^bb70
        ^bb69:
          %455 = arith.constant 1 : i32
          func.return %455 : i32
        ^bb70:
          cf.br ^bb71
        ^bb71:
        %456 = arith.constant 1 : i32
        %458 = arith.constant 0 : i32
        %457 = arith.subi %458, %456 : i32
        func.return %457 : i32
      ^bb67:
        cf.br ^bb68
      ^bb68:
      %459 = llvm.load %433 : !llvm.ptr -> i32
      %460 = arith.constant 1 : i32
      %461 = arith.subi %459, %460 : i32
      llvm.store %461, %433 : i32, !llvm.ptr
      cf.br ^bb63
    ^bb65:
    %462 = arith.constant 0 : i32
    func.return %462 : i32
  }
  func.func @bn_copy(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: i32, %arg3: i32) -> () {
    %463 = arith.constant 0 : i32
    %464 = llvm.mlir.constant(1 : i64) : i64
    %465 = llvm.alloca %464 x i32 : (i64) -> !llvm.ptr
    llvm.store %463, %465 : i32, !llvm.ptr
    cf.br ^bb72
    ^bb72:
    %466 = llvm.load %465 : !llvm.ptr -> i32
    %467 = arith.cmpi slt, %466, %arg2 : i32
    cf.cond_br %467, ^bb73, ^bb74
    ^bb73:
      %469 = llvm.load %465 : !llvm.ptr -> i32
      %470 = arith.extsi %469 : i32 to i64
      %471 = llvm.getelementptr %arg1[%470] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %468 = llvm.load %471 : !llvm.ptr -> i64
      %472 = llvm.load %465 : !llvm.ptr -> i32
      %473 = arith.extsi %472 : i32 to i64
      %474 = llvm.getelementptr %arg0[%473] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %468, %474 : i64, !llvm.ptr
      %475 = llvm.load %465 : !llvm.ptr -> i32
      %476 = arith.constant 1 : i32
      %477 = arith.addi %475, %476 : i32
      llvm.store %477, %465 : i32, !llvm.ptr
      cf.br ^bb72
    ^bb74:
    cf.br ^bb75
    ^bb75:
    %478 = llvm.load %465 : !llvm.ptr -> i32
    %479 = arith.cmpi slt, %478, %arg3 : i32
    cf.cond_br %479, ^bb76, ^bb77
    ^bb76:
      %480 = arith.constant 0 : i32
      %481 = llvm.load %465 : !llvm.ptr -> i32
      %482 = arith.extsi %480 : i32 to i64
      %483 = arith.extsi %481 : i32 to i64
      %484 = llvm.getelementptr %arg0[%483] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %482, %484 : i64, !llvm.ptr
      %485 = llvm.load %465 : !llvm.ptr -> i32
      %486 = arith.constant 1 : i32
      %487 = arith.addi %485, %486 : i32
      llvm.store %487, %465 : i32, !llvm.ptr
      cf.br ^bb75
    ^bb77:
    func.return
  }
  func.func @bn_to_f64(%arg0: !llvm.ptr, %arg1: i32) -> f64 {
    %488 = arith.constant 0 : i32
    %489 = arith.cmpi eq, %arg1, %488 : i32
    cf.cond_br %489, ^bb78, ^bb79
    ^bb78:
      %490 = arith.constant 0.0 : f32
      %491 = arith.extf %490 : f32 to f64
      func.return %491 : f64
    ^bb79:
      cf.br ^bb80
    ^bb80:
    %492 = arith.constant 0.0 : f32
    %493 = arith.extf %492 : f32 to f64
    %494 = llvm.mlir.constant(1 : i64) : i64
    %495 = llvm.alloca %494 x f64 : (i64) -> !llvm.ptr
    llvm.store %493, %495 : f64, !llvm.ptr
    %496 = arith.constant 1 : i32
    %497 = arith.subi %arg1, %496 : i32
    %498 = llvm.mlir.constant(1 : i64) : i64
    %499 = llvm.alloca %498 x i32 : (i64) -> !llvm.ptr
    llvm.store %497, %499 : i32, !llvm.ptr
    cf.br ^bb81
    ^bb81:
    %500 = llvm.load %499 : !llvm.ptr -> i32
    %501 = arith.constant 0 : i32
    %502 = arith.cmpi sge, %500, %501 : i32
    cf.cond_br %502, ^bb82, ^bb83
    ^bb82:
      %503 = llvm.load %495 : !llvm.ptr -> f64
      %504 = arith.constant 1000000000.0 : f32
      %506 = arith.extf %504 : f32 to f64
      %505 = arith.mulf %503, %506 : f64
      %508 = llvm.load %499 : !llvm.ptr -> i32
      %509 = arith.extsi %508 : i32 to i64
      %510 = llvm.getelementptr %arg0[%509] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %507 = llvm.load %510 : !llvm.ptr -> i64
      %511 = arith.sitofp %507 : i64 to f64
      %512 = arith.addf %505, %511 : f64
      llvm.store %512, %495 : f64, !llvm.ptr
      %513 = llvm.load %499 : !llvm.ptr -> i32
      %514 = arith.constant 1 : i32
      %515 = arith.subi %513, %514 : i32
      llvm.store %515, %499 : i32, !llvm.ptr
      cf.br ^bb81
    ^bb83:
    %516 = llvm.load %495 : !llvm.ptr -> f64
    func.return %516 : f64
  }
  func.func @comb_l(%arg0: i64, %arg1: i64) -> i64 {
    %517 = arith.constant 0 : i32
    %519 = arith.extsi %517 : i32 to i64
    %518 = arith.cmpi slt, %arg1, %519 : i64
    %520 = scf.if %518 -> (i1) {
      %521 = arith.constant true
      scf.yield %521 : i1
    } else {
      %522 = arith.cmpi sgt, %arg1, %arg0 : i64
      scf.yield %522 : i1
    }
    cf.cond_br %520, ^bb84, ^bb85
    ^bb84:
      %523 = arith.constant 0 : i32
      %524 = arith.extsi %523 : i32 to i64
      func.return %524 : i64
    ^bb85:
      cf.br ^bb86
    ^bb86:
    %525 = llvm.mlir.constant(1 : i64) : i64
    %526 = llvm.alloca %525 x i64 : (i64) -> !llvm.ptr
    llvm.store %arg1, %526 : i64, !llvm.ptr
    %527 = llvm.load %526 : !llvm.ptr -> i64
    %528 = llvm.load %526 : !llvm.ptr -> i64
    %529 = arith.subi %arg0, %528 : i64
    %530 = arith.cmpi sgt, %527, %529 : i64
    cf.cond_br %530, ^bb87, ^bb88
    ^bb87:
      %531 = llvm.load %526 : !llvm.ptr -> i64
      %532 = arith.subi %arg0, %531 : i64
      llvm.store %532, %526 : i64, !llvm.ptr
      cf.br ^bb89
    ^bb88:
      cf.br ^bb89
    ^bb89:
    %533 = arith.constant 1 : i32
    %534 = arith.extsi %533 : i32 to i64
    %535 = llvm.mlir.constant(1 : i64) : i64
    %536 = llvm.alloca %535 x i64 : (i64) -> !llvm.ptr
    llvm.store %534, %536 : i64, !llvm.ptr
    %537 = arith.constant 1 : i32
    %538 = arith.extsi %537 : i32 to i64
    %539 = llvm.mlir.constant(1 : i64) : i64
    %540 = llvm.alloca %539 x i64 : (i64) -> !llvm.ptr
    llvm.store %538, %540 : i64, !llvm.ptr
    cf.br ^bb90
    ^bb90:
    %541 = llvm.load %540 : !llvm.ptr -> i64
    %542 = llvm.load %526 : !llvm.ptr -> i64
    %543 = arith.cmpi sle, %541, %542 : i64
    cf.cond_br %543, ^bb91, ^bb92
    ^bb91:
      %544 = llvm.load %536 : !llvm.ptr -> i64
      %545 = llvm.load %526 : !llvm.ptr -> i64
      %546 = arith.subi %arg0, %545 : i64
      %547 = llvm.load %540 : !llvm.ptr -> i64
      %548 = arith.addi %546, %547 : i64
      %549 = arith.muli %544, %548 : i64
      %550 = llvm.load %540 : !llvm.ptr -> i64
      %551 = arith.divsi %549, %550 : i64
      llvm.store %551, %536 : i64, !llvm.ptr
      %552 = llvm.load %540 : !llvm.ptr -> i64
      %553 = arith.constant 1 : i32
      %555 = arith.extsi %553 : i32 to i64
      %554 = arith.addi %552, %555 : i64
      llvm.store %554, %540 : i64, !llvm.ptr
      cf.br ^bb90
    ^bb92:
    %556 = llvm.load %536 : !llvm.ptr -> i64
    func.return %556 : i64
  }
  func.func @main() -> i32 {
    %558 = arith.constant 14 : i32
    %559 = arith.constant 8 : i32
    %560 = arith.extsi %558 : i32 to i64
    %561 = arith.extsi %559 : i32 to i64
    %557 = func.call @calloc(%560, %561) : (i64, i64) -> !llvm.ptr
    %563 = arith.constant 14 : i32
    %564 = arith.constant 4 : i32
    %565 = arith.extsi %563 : i32 to i64
    %566 = arith.extsi %564 : i32 to i64
    %562 = func.call @calloc(%565, %566) : (i64, i64) -> !llvm.ptr
    %567 = arith.constant 0 : i32
    %568 = llvm.mlir.constant(1 : i64) : i64
    %569 = llvm.alloca %568 x i32 : (i64) -> !llvm.ptr
    llvm.store %567, %569 : i32, !llvm.ptr
    cf.br ^bb93
    ^bb93:
    %570 = llvm.load %569 : !llvm.ptr -> i32
    %571 = llvm.mlir.addressof @RANKS : !llvm.ptr
    %572 = llvm.load %571 : !llvm.ptr -> i32
    %573 = arith.cmpi sle, %570, %572 : i32
    cf.cond_br %573, ^bb94, ^bb95
    ^bb94:
      %575 = llvm.mlir.addressof @MAXD : !llvm.ptr
      %576 = llvm.load %575 : !llvm.ptr -> i32
      %577 = arith.constant 16 : i32
      %578 = arith.extsi %576 : i32 to i64
      %579 = arith.extsi %577 : i32 to i64
      %574 = func.call @calloc(%578, %579) : (i64, i64) -> !llvm.ptr
      %580 = llvm.load %569 : !llvm.ptr -> i32
      %581 = arith.extsi %580 : i32 to i64
      %582 = llvm.getelementptr %557[%581] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.ptr
      llvm.store %574, %582 : !llvm.ptr, !llvm.ptr
      %583 = llvm.load %569 : !llvm.ptr -> i32
      %584 = arith.constant 1 : i32
      %585 = arith.addi %583, %584 : i32
      llvm.store %585, %569 : i32, !llvm.ptr
      cf.br ^bb93
    ^bb95:
    %586 = arith.constant 1 : i32
    %588 = arith.constant 0 : i32
    %589 = arith.extsi %588 : i32 to i64
    %590 = llvm.getelementptr %557[%589] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.ptr
    %587 = llvm.load %590 : !llvm.ptr -> !llvm.ptr
    %591 = arith.constant 0 : i32
    %592 = arith.extsi %586 : i32 to i128
    %593 = arith.extsi %591 : i32 to i64
    %594 = llvm.getelementptr %587[%593] : (!llvm.ptr, i64) -> !llvm.ptr, i128
    llvm.store %592, %594 : i128, !llvm.ptr
    %595 = arith.constant 0 : i32
    %596 = arith.constant 0 : i32
    %597 = arith.extsi %596 : i32 to i64
    %598 = llvm.getelementptr %562[%597] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %595, %598 : i32, !llvm.ptr
    %600 = arith.constant 4 : i32
    %601 = arith.constant 8 : i32
    %602 = arith.extsi %600 : i32 to i64
    %603 = arith.extsi %601 : i32 to i64
    %599 = func.call @calloc(%602, %603) : (i64, i64) -> !llvm.ptr
    %604 = arith.constant 1 : i32
    %605 = arith.constant 0 : i32
    %606 = arith.extsi %604 : i32 to i64
    %607 = arith.extsi %605 : i32 to i64
    %608 = llvm.getelementptr %599[%607] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %606, %608 : i64, !llvm.ptr
    %609 = arith.constant 12 : i32
    %611 = arith.constant 0 : i32
    %610 = arith.subi %611, %609 : i32
    %612 = arith.constant 1 : i32
    %613 = arith.extsi %610 : i32 to i64
    %614 = arith.extsi %612 : i32 to i64
    %615 = llvm.getelementptr %599[%614] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %613, %615 : i64, !llvm.ptr
    %616 = arith.constant 36 : i32
    %617 = arith.constant 2 : i32
    %618 = arith.extsi %616 : i32 to i64
    %619 = arith.extsi %617 : i32 to i64
    %620 = llvm.getelementptr %599[%619] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %618, %620 : i64, !llvm.ptr
    %621 = arith.constant 24 : i32
    %623 = arith.constant 0 : i32
    %622 = arith.subi %623, %621 : i32
    %624 = arith.constant 3 : i32
    %625 = arith.extsi %622 : i32 to i64
    %626 = arith.extsi %624 : i32 to i64
    %627 = llvm.getelementptr %599[%626] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %625, %627 : i64, !llvm.ptr
    %628 = arith.constant 1 : i32
    llvm.store %628, %569 : i32, !llvm.ptr
    cf.br ^bb96
    ^bb96:
    %629 = llvm.load %569 : !llvm.ptr -> i32
    %630 = llvm.mlir.addressof @RANKS : !llvm.ptr
    %631 = llvm.load %630 : !llvm.ptr -> i32
    %632 = arith.cmpi sle, %629, %631 : i32
    cf.cond_br %632, ^bb97, ^bb98
    ^bb97:
      %634 = llvm.load %569 : !llvm.ptr -> i32
      %635 = arith.constant 1 : i32
      %636 = arith.subi %634, %635 : i32
      %637 = arith.extsi %636 : i32 to i64
      %638 = llvm.getelementptr %562[%637] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %633 = llvm.load %638 : !llvm.ptr -> i32
      %639 = arith.constant 3 : i32
      %640 = arith.addi %633, %639 : i32
      %641 = llvm.load %569 : !llvm.ptr -> i32
      %642 = arith.extsi %641 : i32 to i64
      %643 = llvm.getelementptr %562[%642] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %640, %643 : i32, !llvm.ptr
      %644 = arith.constant 0 : i32
      %645 = llvm.mlir.constant(1 : i64) : i64
      %646 = llvm.alloca %645 x i32 : (i64) -> !llvm.ptr
      llvm.store %644, %646 : i32, !llvm.ptr
      cf.br ^bb99
      ^bb99:
      %647 = llvm.load %646 : !llvm.ptr -> i32
      %648 = arith.cmpi sle, %647, %633 : i32
      cf.cond_br %648, ^bb100, ^bb101
      ^bb100:
        %649 = arith.constant 0 : i32
        %650 = llvm.mlir.constant(1 : i64) : i64
        %651 = llvm.alloca %650 x i32 : (i64) -> !llvm.ptr
        llvm.store %649, %651 : i32, !llvm.ptr
        cf.br ^bb102
        ^bb102:
        %652 = llvm.load %651 : !llvm.ptr -> i32
        %653 = arith.constant 4 : i32
        %654 = arith.cmpi slt, %652, %653 : i32
        cf.cond_br %654, ^bb103, ^bb104
        ^bb103:
          %657 = llvm.load %569 : !llvm.ptr -> i32
          %658 = arith.extsi %657 : i32 to i64
          %659 = llvm.getelementptr %557[%658] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.ptr
          %656 = llvm.load %659 : !llvm.ptr -> !llvm.ptr
          %660 = llvm.load %646 : !llvm.ptr -> i32
          %661 = llvm.load %651 : !llvm.ptr -> i32
          %662 = arith.addi %660, %661 : i32
          %663 = arith.extsi %662 : i32 to i64
          %664 = llvm.getelementptr %656[%663] : (!llvm.ptr, i64) -> !llvm.ptr, i128
          %655 = llvm.load %664 : !llvm.ptr -> i128
          %667 = llvm.load %569 : !llvm.ptr -> i32
          %668 = arith.constant 1 : i32
          %669 = arith.subi %667, %668 : i32
          %670 = arith.extsi %669 : i32 to i64
          %671 = llvm.getelementptr %557[%670] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.ptr
          %666 = llvm.load %671 : !llvm.ptr -> !llvm.ptr
          %672 = llvm.load %646 : !llvm.ptr -> i32
          %673 = arith.extsi %672 : i32 to i64
          %674 = llvm.getelementptr %666[%673] : (!llvm.ptr, i64) -> !llvm.ptr, i128
          %665 = llvm.load %674 : !llvm.ptr -> i128
          %676 = llvm.load %651 : !llvm.ptr -> i32
          %677 = arith.extsi %676 : i32 to i64
          %678 = llvm.getelementptr %599[%677] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %675 = llvm.load %678 : !llvm.ptr -> i64
          %679 = arith.extsi %675 : i64 to i128
          %681 = arith.trunci %665 : i128 to i64
          %682 = arith.trunci %679 : i128 to i64
          %680 = arith.muli %681, %682 : i64
          %684 = arith.trunci %655 : i128 to i64
          %683 = arith.addi %684, %680 : i64
          %686 = llvm.load %569 : !llvm.ptr -> i32
          %687 = arith.extsi %686 : i32 to i64
          %688 = llvm.getelementptr %557[%687] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.ptr
          %685 = llvm.load %688 : !llvm.ptr -> !llvm.ptr
          %689 = llvm.load %646 : !llvm.ptr -> i32
          %690 = llvm.load %651 : !llvm.ptr -> i32
          %691 = arith.addi %689, %690 : i32
          %692 = arith.extsi %683 : i64 to i128
          %693 = arith.extsi %691 : i32 to i64
          %694 = llvm.getelementptr %685[%693] : (!llvm.ptr, i64) -> !llvm.ptr, i128
          llvm.store %692, %694 : i128, !llvm.ptr
          %695 = llvm.load %651 : !llvm.ptr -> i32
          %696 = arith.constant 1 : i32
          %697 = arith.addi %695, %696 : i32
          llvm.store %697, %651 : i32, !llvm.ptr
          cf.br ^bb102
        ^bb104:
        %698 = llvm.load %646 : !llvm.ptr -> i32
        %699 = arith.constant 1 : i32
        %700 = arith.addi %698, %699 : i32
        llvm.store %700, %646 : i32, !llvm.ptr
        cf.br ^bb99
      ^bb101:
      %701 = llvm.load %569 : !llvm.ptr -> i32
      %702 = arith.constant 1 : i32
      %703 = arith.addi %701, %702 : i32
      llvm.store %703, %569 : i32, !llvm.ptr
      cf.br ^bb96
    ^bb98:
    %705 = llvm.mlir.addressof @N : !llvm.ptr
    %706 = llvm.load %705 : !llvm.ptr -> i32
    %707 = arith.constant 1 : i32
    %708 = arith.addi %706, %707 : i32
    %709 = arith.extsi %708 : i32 to i64
    %710 = arith.constant 8 : i32
    %711 = arith.extsi %710 : i32 to i64
    %704 = func.call @calloc(%709, %711) : (i64, i64) -> !llvm.ptr
    %713 = llvm.mlir.addressof @N : !llvm.ptr
    %714 = llvm.load %713 : !llvm.ptr -> i32
    %715 = arith.constant 1 : i32
    %716 = arith.addi %714, %715 : i32
    %717 = arith.extsi %716 : i32 to i64
    %718 = arith.constant 4 : i32
    %719 = arith.extsi %718 : i32 to i64
    %712 = func.call @calloc(%717, %719) : (i64, i64) -> !llvm.ptr
    %721 = arith.constant 20 : i32
    %722 = arith.constant 8 : i32
    %723 = arith.extsi %721 : i32 to i64
    %724 = arith.extsi %722 : i32 to i64
    %720 = func.call @calloc(%723, %724) : (i64, i64) -> !llvm.ptr
    %725 = arith.constant 0 : i32
    %726 = arith.extsi %725 : i32 to i64
    %727 = llvm.getelementptr %704[%726] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.ptr
    llvm.store %720, %727 : !llvm.ptr, !llvm.ptr
    %728 = arith.constant 1 : i32
    %730 = arith.constant 0 : i32
    %731 = arith.extsi %730 : i32 to i64
    %732 = llvm.getelementptr %704[%731] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.ptr
    %729 = llvm.load %732 : !llvm.ptr -> !llvm.ptr
    %733 = arith.constant 0 : i32
    %734 = arith.extsi %728 : i32 to i64
    %735 = arith.extsi %733 : i32 to i64
    %736 = llvm.getelementptr %729[%735] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %734, %736 : i64, !llvm.ptr
    %737 = arith.constant 1 : i32
    %738 = arith.constant 0 : i32
    %739 = arith.extsi %738 : i32 to i64
    %740 = llvm.getelementptr %712[%739] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %737, %740 : i32, !llvm.ptr
    %741 = arith.constant 1 : i32
    %742 = llvm.mlir.constant(1 : i64) : i64
    %743 = llvm.alloca %742 x i32 : (i64) -> !llvm.ptr
    llvm.store %741, %743 : i32, !llvm.ptr
    cf.br ^bb105
    ^bb105:
    %744 = llvm.load %743 : !llvm.ptr -> i32
    %745 = llvm.mlir.addressof @N : !llvm.ptr
    %746 = llvm.load %745 : !llvm.ptr -> i32
    %747 = arith.cmpi sle, %744, %746 : i32
    cf.cond_br %747, ^bb106, ^bb107
    ^bb106:
      %749 = arith.constant 20 : i32
      %750 = arith.constant 8 : i32
      %751 = arith.extsi %749 : i32 to i64
      %752 = arith.extsi %750 : i32 to i64
      %748 = func.call @calloc(%751, %752) : (i64, i64) -> !llvm.ptr
      %753 = llvm.load %743 : !llvm.ptr -> i32
      %754 = arith.extsi %753 : i32 to i64
      %755 = llvm.getelementptr %704[%754] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.ptr
      llvm.store %748, %755 : !llvm.ptr, !llvm.ptr
      %758 = llvm.load %743 : !llvm.ptr -> i32
      %759 = arith.extsi %758 : i32 to i64
      %760 = llvm.getelementptr %704[%759] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.ptr
      %757 = llvm.load %760 : !llvm.ptr -> !llvm.ptr
      %762 = llvm.load %743 : !llvm.ptr -> i32
      %763 = arith.constant 1 : i32
      %764 = arith.subi %762, %763 : i32
      %765 = arith.extsi %764 : i32 to i64
      %766 = llvm.getelementptr %704[%765] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.ptr
      %761 = llvm.load %766 : !llvm.ptr -> !llvm.ptr
      %768 = llvm.load %743 : !llvm.ptr -> i32
      %769 = arith.constant 1 : i32
      %770 = arith.subi %768, %769 : i32
      %771 = arith.extsi %770 : i32 to i64
      %772 = llvm.getelementptr %712[%771] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %767 = llvm.load %772 : !llvm.ptr -> i32
      %773 = llvm.load %743 : !llvm.ptr -> i32
      %774 = arith.extsi %773 : i32 to i64
      %756 = func.call @bn_mul_small(%757, %761, %767, %774) : (!llvm.ptr, !llvm.ptr, i32, i64) -> i32
      %775 = llvm.load %743 : !llvm.ptr -> i32
      %776 = arith.extsi %775 : i32 to i64
      %777 = llvm.getelementptr %712[%776] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %756, %777 : i32, !llvm.ptr
      %778 = llvm.load %743 : !llvm.ptr -> i32
      %779 = arith.constant 1 : i32
      %780 = arith.addi %778, %779 : i32
      llvm.store %780, %743 : i32, !llvm.ptr
      cf.br ^bb105
    ^bb107:
    %782 = arith.constant 20 : i32
    %783 = arith.constant 8 : i32
    %784 = arith.extsi %782 : i32 to i64
    %785 = arith.extsi %783 : i32 to i64
    %781 = func.call @calloc(%784, %785) : (i64, i64) -> !llvm.ptr
    %786 = arith.constant 1 : i32
    %787 = arith.constant 0 : i32
    %788 = arith.extsi %786 : i32 to i64
    %789 = arith.extsi %787 : i32 to i64
    %790 = llvm.getelementptr %781[%789] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %788, %790 : i64, !llvm.ptr
    %791 = arith.constant 1 : i32
    %792 = llvm.mlir.constant(1 : i64) : i64
    %793 = llvm.alloca %792 x i32 : (i64) -> !llvm.ptr
    llvm.store %791, %793 : i32, !llvm.ptr
    %794 = arith.constant 0 : i32
    %795 = llvm.mlir.constant(1 : i64) : i64
    %796 = llvm.alloca %795 x i32 : (i64) -> !llvm.ptr
    llvm.store %794, %796 : i32, !llvm.ptr
    cf.br ^bb108
    ^bb108:
    %797 = llvm.load %796 : !llvm.ptr -> i32
    %798 = llvm.mlir.addressof @RANKS : !llvm.ptr
    %799 = llvm.load %798 : !llvm.ptr -> i32
    %800 = arith.cmpi slt, %797, %799 : i32
    cf.cond_br %800, ^bb109, ^bb110
    ^bb109:
      %802 = arith.constant 20 : i32
      %803 = arith.constant 8 : i32
      %804 = arith.extsi %802 : i32 to i64
      %805 = arith.extsi %803 : i32 to i64
      %801 = func.call @calloc(%804, %805) : (i64, i64) -> !llvm.ptr
      %807 = llvm.load %793 : !llvm.ptr -> i32
      %808 = llvm.mlir.addressof @CB : !llvm.ptr
      %809 = llvm.load %808 : !llvm.ptr -> i32
      %810 = arith.extsi %809 : i32 to i64
      %806 = func.call @bn_mul_small(%801, %781, %807, %810) : (!llvm.ptr, !llvm.ptr, i32, i64) -> i32
      %812 = arith.constant 20 : i32
      func.call @bn_copy(%781, %801, %806, %812) : (!llvm.ptr, !llvm.ptr, i32, i32) -> ()
      llvm.store %806, %793 : i32, !llvm.ptr
      func.call @free(%801) : (!llvm.ptr) -> ()
      %814 = llvm.load %796 : !llvm.ptr -> i32
      %815 = arith.constant 1 : i32
      %816 = arith.addi %814, %815 : i32
      llvm.store %816, %796 : i32, !llvm.ptr
      cf.br ^bb108
    ^bb110:
    %818 = arith.constant 14 : i32
    %819 = arith.constant 8 : i32
    %820 = arith.extsi %818 : i32 to i64
    %821 = arith.extsi %819 : i32 to i64
    %817 = func.call @calloc(%820, %821) : (i64, i64) -> !llvm.ptr
    %823 = arith.constant 14 : i32
    %824 = arith.constant 4 : i32
    %825 = arith.extsi %823 : i32 to i64
    %826 = arith.extsi %824 : i32 to i64
    %822 = func.call @calloc(%825, %826) : (i64, i64) -> !llvm.ptr
    %827 = arith.constant 0 : i32
    llvm.store %827, %569 : i32, !llvm.ptr
    cf.br ^bb111
    ^bb111:
    %828 = llvm.load %569 : !llvm.ptr -> i32
    %829 = llvm.mlir.addressof @RANKS : !llvm.ptr
    %830 = llvm.load %829 : !llvm.ptr -> i32
    %831 = arith.cmpi sle, %828, %830 : i32
    cf.cond_br %831, ^bb112, ^bb113
    ^bb112:
      %833 = arith.constant 30 : i32
      %834 = arith.constant 8 : i32
      %835 = arith.extsi %833 : i32 to i64
      %836 = arith.extsi %834 : i32 to i64
      %832 = func.call @calloc(%835, %836) : (i64, i64) -> !llvm.ptr
      %837 = arith.constant 0 : i32
      %838 = llvm.mlir.constant(1 : i64) : i64
      %839 = llvm.alloca %838 x i32 : (i64) -> !llvm.ptr
      llvm.store %837, %839 : i32, !llvm.ptr
      %841 = arith.constant 30 : i32
      %842 = arith.constant 8 : i32
      %843 = arith.extsi %841 : i32 to i64
      %844 = arith.extsi %842 : i32 to i64
      %840 = func.call @calloc(%843, %844) : (i64, i64) -> !llvm.ptr
      %845 = arith.constant 0 : i32
      %846 = llvm.mlir.constant(1 : i64) : i64
      %847 = llvm.alloca %846 x i32 : (i64) -> !llvm.ptr
      llvm.store %845, %847 : i32, !llvm.ptr
      %848 = arith.constant 0 : i32
      %849 = llvm.mlir.constant(1 : i64) : i64
      %850 = llvm.alloca %849 x i32 : (i64) -> !llvm.ptr
      llvm.store %848, %850 : i32, !llvm.ptr
      cf.br ^bb114
      ^bb114:
      %851 = llvm.load %850 : !llvm.ptr -> i32
      %853 = llvm.load %569 : !llvm.ptr -> i32
      %854 = arith.extsi %853 : i32 to i64
      %855 = llvm.getelementptr %562[%854] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %852 = llvm.load %855 : !llvm.ptr -> i32
      %856 = arith.cmpi sle, %851, %852 : i32
      cf.cond_br %856, ^bb115, ^bb116
      ^bb115:
        %859 = llvm.load %569 : !llvm.ptr -> i32
        %860 = arith.extsi %859 : i32 to i64
        %861 = llvm.getelementptr %557[%860] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.ptr
        %858 = llvm.load %861 : !llvm.ptr -> !llvm.ptr
        %862 = llvm.load %850 : !llvm.ptr -> i32
        %863 = arith.extsi %862 : i32 to i64
        %864 = llvm.getelementptr %858[%863] : (!llvm.ptr, i64) -> !llvm.ptr, i128
        %857 = llvm.load %864 : !llvm.ptr -> i128
        %865 = arith.constant 0 : i32
        %867 = arith.trunci %857 : i128 to i64
        %868 = arith.extsi %865 : i32 to i64
        %866 = arith.cmpi sgt, %867, %868 : i64
        cf.cond_br %866, ^bb117, ^bb118
        ^bb117:
          %870 = llvm.load %839 : !llvm.ptr -> i32
          %872 = llvm.mlir.addressof @N : !llvm.ptr
          %873 = llvm.load %872 : !llvm.ptr -> i32
          %874 = llvm.load %850 : !llvm.ptr -> i32
          %875 = arith.subi %873, %874 : i32
          %876 = arith.extsi %875 : i32 to i64
          %877 = llvm.getelementptr %704[%876] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.ptr
          %871 = llvm.load %877 : !llvm.ptr -> !llvm.ptr
          %879 = llvm.mlir.addressof @N : !llvm.ptr
          %880 = llvm.load %879 : !llvm.ptr -> i32
          %881 = llvm.load %850 : !llvm.ptr -> i32
          %882 = arith.subi %880, %881 : i32
          %883 = arith.extsi %882 : i32 to i64
          %884 = llvm.getelementptr %712[%883] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %878 = llvm.load %884 : !llvm.ptr -> i32
          %869 = func.call @bn_addmul_i128(%832, %870, %871, %878, %857) : (!llvm.ptr, i32, !llvm.ptr, i32, i128) -> i32
          llvm.store %869, %839 : i32, !llvm.ptr
          cf.br ^bb119
        ^bb118:
          %885 = arith.constant 0 : i32
          %887 = arith.trunci %857 : i128 to i64
          %888 = arith.extsi %885 : i32 to i64
          %886 = arith.cmpi slt, %887, %888 : i64
          cf.cond_br %886, ^bb120, ^bb121
          ^bb120:
            %890 = llvm.load %847 : !llvm.ptr -> i32
            %892 = llvm.mlir.addressof @N : !llvm.ptr
            %893 = llvm.load %892 : !llvm.ptr -> i32
            %894 = llvm.load %850 : !llvm.ptr -> i32
            %895 = arith.subi %893, %894 : i32
            %896 = arith.extsi %895 : i32 to i64
            %897 = llvm.getelementptr %704[%896] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.ptr
            %891 = llvm.load %897 : !llvm.ptr -> !llvm.ptr
            %899 = llvm.mlir.addressof @N : !llvm.ptr
            %900 = llvm.load %899 : !llvm.ptr -> i32
            %901 = llvm.load %850 : !llvm.ptr -> i32
            %902 = arith.subi %900, %901 : i32
            %903 = arith.extsi %902 : i32 to i64
            %904 = llvm.getelementptr %712[%903] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            %898 = llvm.load %904 : !llvm.ptr -> i32
            %905 = arith.constant 0 : i32
            %907 = arith.extsi %905 : i32 to i64
            %908 = arith.trunci %857 : i128 to i64
            %906 = arith.subi %907, %908 : i64
            %909 = arith.extsi %906 : i64 to i128
            %889 = func.call @bn_addmul_i128(%840, %890, %891, %898, %909) : (!llvm.ptr, i32, !llvm.ptr, i32, i128) -> i32
            llvm.store %889, %847 : i32, !llvm.ptr
            cf.br ^bb122
          ^bb121:
            cf.br ^bb122
          ^bb122:
          cf.br ^bb119
        ^bb119:
        %910 = llvm.load %850 : !llvm.ptr -> i32
        %911 = arith.constant 1 : i32
        %912 = arith.addi %910, %911 : i32
        llvm.store %912, %850 : i32, !llvm.ptr
        cf.br ^bb114
      ^bb116:
      %914 = arith.constant 30 : i32
      %915 = arith.constant 8 : i32
      %916 = arith.extsi %914 : i32 to i64
      %917 = arith.extsi %915 : i32 to i64
      %913 = func.call @calloc(%916, %917) : (i64, i64) -> !llvm.ptr
      %919 = llvm.load %839 : !llvm.ptr -> i32
      %920 = llvm.load %847 : !llvm.ptr -> i32
      %918 = func.call @bn_sub(%913, %832, %919, %840, %920) : (!llvm.ptr, !llvm.ptr, i32, !llvm.ptr, i32) -> i32
      %922 = arith.constant 20 : i32
      %923 = arith.constant 8 : i32
      %924 = arith.extsi %922 : i32 to i64
      %925 = arith.extsi %923 : i32 to i64
      %921 = func.call @calloc(%924, %925) : (i64, i64) -> !llvm.ptr
      %926 = llvm.load %569 : !llvm.ptr -> i32
      %927 = arith.extsi %926 : i32 to i64
      %928 = llvm.getelementptr %817[%927] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.ptr
      llvm.store %921, %928 : !llvm.ptr, !llvm.ptr
      %930 = arith.constant 30 : i32
      %931 = arith.constant 8 : i32
      %932 = arith.extsi %930 : i32 to i64
      %933 = arith.extsi %931 : i32 to i64
      %929 = func.call @calloc(%932, %933) : (i64, i64) -> !llvm.ptr
      %934 = llvm.mlir.constant(1 : i64) : i64
      %935 = llvm.alloca %934 x !llvm.ptr : (i64) -> !llvm.ptr
      llvm.store %929, %935 : !llvm.ptr, !llvm.ptr
      %937 = llvm.load %935 : !llvm.ptr -> !llvm.ptr
      %938 = arith.constant 30 : i32
      func.call @bn_copy(%937, %913, %918, %938) : (!llvm.ptr, !llvm.ptr, i32, i32) -> ()
      %939 = llvm.mlir.constant(1 : i64) : i64
      %940 = llvm.alloca %939 x i32 : (i64) -> !llvm.ptr
      llvm.store %918, %940 : i32, !llvm.ptr
      %941 = arith.constant 0 : i32
      %942 = llvm.mlir.constant(1 : i64) : i64
      %943 = llvm.alloca %942 x i32 : (i64) -> !llvm.ptr
      llvm.store %941, %943 : i32, !llvm.ptr
      cf.br ^bb123
      ^bb123:
      %944 = llvm.load %943 : !llvm.ptr -> i32
      %945 = llvm.mlir.addressof @RANKS : !llvm.ptr
      %946 = llvm.load %945 : !llvm.ptr -> i32
      %947 = arith.cmpi slt, %944, %946 : i32
      cf.cond_br %947, ^bb124, ^bb125
      ^bb124:
        %949 = arith.constant 30 : i32
        %950 = arith.constant 8 : i32
        %951 = arith.extsi %949 : i32 to i64
        %952 = arith.extsi %950 : i32 to i64
        %948 = func.call @calloc(%951, %952) : (i64, i64) -> !llvm.ptr
        %954 = llvm.load %935 : !llvm.ptr -> !llvm.ptr
        %955 = llvm.load %940 : !llvm.ptr -> i32
        %956 = llvm.mlir.addressof @CB : !llvm.ptr
        %957 = llvm.load %956 : !llvm.ptr -> i32
        %958 = arith.extsi %957 : i32 to i64
        %953 = func.call @bn_div_small(%948, %954, %955, %958) : (!llvm.ptr, !llvm.ptr, i32, i64) -> i32
        llvm.store %953, %940 : i32, !llvm.ptr
        %960 = llvm.load %935 : !llvm.ptr -> !llvm.ptr
        %961 = llvm.load %940 : !llvm.ptr -> i32
        %962 = arith.constant 30 : i32
        func.call @bn_copy(%960, %948, %961, %962) : (!llvm.ptr, !llvm.ptr, i32, i32) -> ()
        func.call @free(%948) : (!llvm.ptr) -> ()
        %964 = llvm.load %943 : !llvm.ptr -> i32
        %965 = arith.constant 1 : i32
        %966 = arith.addi %964, %965 : i32
        llvm.store %966, %943 : i32, !llvm.ptr
        cf.br ^bb123
      ^bb125:
      %969 = llvm.load %569 : !llvm.ptr -> i32
      %970 = arith.extsi %969 : i32 to i64
      %971 = llvm.getelementptr %817[%970] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.ptr
      %968 = llvm.load %971 : !llvm.ptr -> !llvm.ptr
      %972 = llvm.load %935 : !llvm.ptr -> !llvm.ptr
      %973 = llvm.load %940 : !llvm.ptr -> i32
      %974 = arith.constant 20 : i32
      func.call @bn_copy(%968, %972, %973, %974) : (!llvm.ptr, !llvm.ptr, i32, i32) -> ()
      %975 = llvm.load %940 : !llvm.ptr -> i32
      %976 = llvm.load %569 : !llvm.ptr -> i32
      %977 = arith.extsi %976 : i32 to i64
      %978 = llvm.getelementptr %822[%977] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %975, %978 : i32, !llvm.ptr
      func.call @free(%832) : (!llvm.ptr) -> ()
      func.call @free(%840) : (!llvm.ptr) -> ()
      func.call @free(%913) : (!llvm.ptr) -> ()
      %983 = llvm.load %935 : !llvm.ptr -> !llvm.ptr
      func.call @free(%983) : (!llvm.ptr) -> ()
      %984 = llvm.load %569 : !llvm.ptr -> i32
      %985 = arith.constant 1 : i32
      %986 = arith.addi %984, %985 : i32
      llvm.store %986, %569 : i32, !llvm.ptr
      cf.br ^bb111
    ^bb113:
    %988 = arith.constant 20 : i32
    %989 = arith.constant 8 : i32
    %990 = arith.extsi %988 : i32 to i64
    %991 = arith.extsi %989 : i32 to i64
    %987 = func.call @calloc(%990, %991) : (i64, i64) -> !llvm.ptr
    %993 = arith.constant 0 : i32
    %994 = arith.extsi %993 : i32 to i64
    %995 = llvm.getelementptr %822[%994] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %992 = llvm.load %995 : !llvm.ptr -> i32
    %996 = llvm.mlir.constant(1 : i64) : i64
    %997 = llvm.alloca %996 x i32 : (i64) -> !llvm.ptr
    llvm.store %992, %997 : i32, !llvm.ptr
    %1000 = arith.constant 0 : i32
    %1001 = arith.extsi %1000 : i32 to i64
    %1002 = llvm.getelementptr %817[%1001] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.ptr
    %999 = llvm.load %1002 : !llvm.ptr -> !llvm.ptr
    %1003 = llvm.load %997 : !llvm.ptr -> i32
    %1004 = arith.constant 20 : i32
    func.call @bn_copy(%987, %999, %1003, %1004) : (!llvm.ptr, !llvm.ptr, i32, i32) -> ()
    %1006 = arith.constant 30 : i32
    %1007 = arith.constant 8 : i32
    %1008 = arith.extsi %1006 : i32 to i64
    %1009 = arith.extsi %1007 : i32 to i64
    %1005 = func.call @calloc(%1008, %1009) : (i64, i64) -> !llvm.ptr
    %1010 = arith.constant 0 : i32
    %1011 = llvm.mlir.constant(1 : i64) : i64
    %1012 = llvm.alloca %1011 x i32 : (i64) -> !llvm.ptr
    llvm.store %1010, %1012 : i32, !llvm.ptr
    %1014 = arith.constant 6 : i32
    %1015 = arith.constant 4 : i32
    %1016 = arith.extsi %1014 : i32 to i64
    %1017 = arith.extsi %1015 : i32 to i64
    %1013 = func.call @calloc(%1016, %1017) : (i64, i64) -> !llvm.ptr
    %1018 = arith.constant 2 : i32
    %1019 = arith.constant 0 : i32
    %1020 = arith.extsi %1019 : i32 to i64
    %1021 = llvm.getelementptr %1013[%1020] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %1018, %1021 : i32, !llvm.ptr
    %1022 = arith.constant 3 : i32
    %1023 = arith.constant 1 : i32
    %1024 = arith.extsi %1023 : i32 to i64
    %1025 = llvm.getelementptr %1013[%1024] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %1022, %1025 : i32, !llvm.ptr
    %1026 = arith.constant 5 : i32
    %1027 = arith.constant 2 : i32
    %1028 = arith.extsi %1027 : i32 to i64
    %1029 = llvm.getelementptr %1013[%1028] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %1026, %1029 : i32, !llvm.ptr
    %1030 = arith.constant 7 : i32
    %1031 = arith.constant 3 : i32
    %1032 = arith.extsi %1031 : i32 to i64
    %1033 = llvm.getelementptr %1013[%1032] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %1030, %1033 : i32, !llvm.ptr
    %1034 = arith.constant 11 : i32
    %1035 = arith.constant 4 : i32
    %1036 = arith.extsi %1035 : i32 to i64
    %1037 = llvm.getelementptr %1013[%1036] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %1034, %1037 : i32, !llvm.ptr
    %1038 = arith.constant 13 : i32
    %1039 = arith.constant 5 : i32
    %1040 = arith.extsi %1039 : i32 to i64
    %1041 = llvm.getelementptr %1013[%1040] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %1038, %1041 : i32, !llvm.ptr
    %1042 = arith.constant 0 : i32
    %1043 = llvm.mlir.constant(1 : i64) : i64
    %1044 = llvm.alloca %1043 x i32 : (i64) -> !llvm.ptr
    llvm.store %1042, %1044 : i32, !llvm.ptr
    cf.br ^bb126
    ^bb126:
    %1045 = llvm.load %1044 : !llvm.ptr -> i32
    %1046 = arith.constant 6 : i32
    %1047 = arith.cmpi slt, %1045, %1046 : i32
    cf.cond_br %1047, ^bb127, ^bb128
    ^bb127:
      %1049 = llvm.load %1044 : !llvm.ptr -> i32
      %1050 = arith.extsi %1049 : i32 to i64
      %1051 = llvm.getelementptr %1013[%1050] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %1048 = llvm.load %1051 : !llvm.ptr -> i32
      %1053 = arith.constant 30 : i32
      %1054 = arith.constant 8 : i32
      %1055 = arith.extsi %1053 : i32 to i64
      %1056 = arith.extsi %1054 : i32 to i64
      %1052 = func.call @calloc(%1055, %1056) : (i64, i64) -> !llvm.ptr
      %1057 = arith.constant 0 : i32
      %1058 = llvm.mlir.constant(1 : i64) : i64
      %1059 = llvm.alloca %1058 x i32 : (i64) -> !llvm.ptr
      llvm.store %1057, %1059 : i32, !llvm.ptr
      %1061 = arith.constant 30 : i32
      %1062 = arith.constant 8 : i32
      %1063 = arith.extsi %1061 : i32 to i64
      %1064 = arith.extsi %1062 : i32 to i64
      %1060 = func.call @calloc(%1063, %1064) : (i64, i64) -> !llvm.ptr
      %1065 = arith.constant 0 : i32
      %1066 = llvm.mlir.constant(1 : i64) : i64
      %1067 = llvm.alloca %1066 x i32 : (i64) -> !llvm.ptr
      llvm.store %1065, %1067 : i32, !llvm.ptr
      %1068 = llvm.mlir.constant(1 : i64) : i64
      %1069 = llvm.alloca %1068 x i32 : (i64) -> !llvm.ptr
      llvm.store %1048, %1069 : i32, !llvm.ptr
      cf.br ^bb129
      ^bb129:
      %1070 = llvm.load %1069 : !llvm.ptr -> i32
      %1071 = llvm.mlir.addressof @RANKS : !llvm.ptr
      %1072 = llvm.load %1071 : !llvm.ptr -> i32
      %1073 = arith.cmpi sle, %1070, %1072 : i32
      cf.cond_br %1073, ^bb130, ^bb131
      ^bb130:
        %1075 = llvm.mlir.addressof @RANKS : !llvm.ptr
        %1076 = llvm.load %1075 : !llvm.ptr -> i32
        %1077 = arith.subi %1076, %1048 : i32
        %1078 = arith.extsi %1077 : i32 to i64
        %1079 = llvm.load %1069 : !llvm.ptr -> i32
        %1080 = arith.subi %1079, %1048 : i32
        %1081 = arith.extsi %1080 : i32 to i64
        %1074 = func.call @comb_l(%1078, %1081) : (i64, i64) -> i64
        %1082 = llvm.load %1069 : !llvm.ptr -> i32
        %1083 = arith.subi %1082, %1048 : i32
        %1084 = arith.constant 1 : i32
        %1085 = arith.andi %1083, %1084 : i32
        %1086 = arith.constant 0 : i32
        %1087 = arith.cmpi ne, %1085, %1086 : i32
        cf.cond_br %1087, ^bb132, ^bb133
        ^bb132:
          %1089 = llvm.load %1067 : !llvm.ptr -> i32
          %1091 = llvm.load %1069 : !llvm.ptr -> i32
          %1092 = arith.extsi %1091 : i32 to i64
          %1093 = llvm.getelementptr %817[%1092] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.ptr
          %1090 = llvm.load %1093 : !llvm.ptr -> !llvm.ptr
          %1095 = llvm.load %1069 : !llvm.ptr -> i32
          %1096 = arith.extsi %1095 : i32 to i64
          %1097 = llvm.getelementptr %822[%1096] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %1094 = llvm.load %1097 : !llvm.ptr -> i32
          %1088 = func.call @bn_addmul_small(%1060, %1089, %1090, %1094, %1074) : (!llvm.ptr, i32, !llvm.ptr, i32, i64) -> i32
          llvm.store %1088, %1067 : i32, !llvm.ptr
          cf.br ^bb134
        ^bb133:
          %1099 = llvm.load %1059 : !llvm.ptr -> i32
          %1101 = llvm.load %1069 : !llvm.ptr -> i32
          %1102 = arith.extsi %1101 : i32 to i64
          %1103 = llvm.getelementptr %817[%1102] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.ptr
          %1100 = llvm.load %1103 : !llvm.ptr -> !llvm.ptr
          %1105 = llvm.load %1069 : !llvm.ptr -> i32
          %1106 = arith.extsi %1105 : i32 to i64
          %1107 = llvm.getelementptr %822[%1106] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %1104 = llvm.load %1107 : !llvm.ptr -> i32
          %1098 = func.call @bn_addmul_small(%1052, %1099, %1100, %1104, %1074) : (!llvm.ptr, i32, !llvm.ptr, i32, i64) -> i32
          llvm.store %1098, %1059 : i32, !llvm.ptr
          cf.br ^bb134
        ^bb134:
        %1108 = llvm.load %1069 : !llvm.ptr -> i32
        %1109 = arith.constant 1 : i32
        %1110 = arith.addi %1108, %1109 : i32
        llvm.store %1110, %1069 : i32, !llvm.ptr
        cf.br ^bb129
      ^bb131:
      %1112 = arith.constant 30 : i32
      %1113 = arith.constant 8 : i32
      %1114 = arith.extsi %1112 : i32 to i64
      %1115 = arith.extsi %1113 : i32 to i64
      %1111 = func.call @calloc(%1114, %1115) : (i64, i64) -> !llvm.ptr
      %1117 = llvm.load %1059 : !llvm.ptr -> i32
      %1118 = llvm.load %1067 : !llvm.ptr -> i32
      %1116 = func.call @bn_sub(%1111, %1052, %1117, %1060, %1118) : (!llvm.ptr, !llvm.ptr, i32, !llvm.ptr, i32) -> i32
      %1120 = llvm.mlir.addressof @RANKS : !llvm.ptr
      %1121 = llvm.load %1120 : !llvm.ptr -> i32
      %1122 = arith.extsi %1121 : i32 to i64
      %1123 = arith.extsi %1048 : i32 to i64
      %1119 = func.call @comb_l(%1122, %1123) : (i64, i64) -> i64
      %1125 = llvm.load %1012 : !llvm.ptr -> i32
      %1124 = func.call @bn_addmul_small(%1005, %1125, %1111, %1116, %1119) : (!llvm.ptr, i32, !llvm.ptr, i32, i64) -> i32
      llvm.store %1124, %1012 : i32, !llvm.ptr
      func.call @free(%1052) : (!llvm.ptr) -> ()
      func.call @free(%1060) : (!llvm.ptr) -> ()
      func.call @free(%1111) : (!llvm.ptr) -> ()
      %1129 = llvm.load %1044 : !llvm.ptr -> i32
      %1130 = arith.constant 1 : i32
      %1131 = arith.addi %1129, %1130 : i32
      llvm.store %1131, %1044 : i32, !llvm.ptr
      cf.br ^bb126
    ^bb128:
    %1133 = arith.constant 30 : i32
    %1134 = arith.constant 8 : i32
    %1135 = arith.extsi %1133 : i32 to i64
    %1136 = arith.extsi %1134 : i32 to i64
    %1132 = func.call @calloc(%1135, %1136) : (i64, i64) -> !llvm.ptr
    %1138 = llvm.load %1012 : !llvm.ptr -> i32
    %1139 = arith.constant 95705032704 : i32
    %1140 = arith.extsi %1139 : i32 to i64
    %1137 = func.call @bn_mul_small(%1132, %1005, %1138, %1140) : (!llvm.ptr, !llvm.ptr, i32, i64) -> i32
    %1142 = arith.constant 20 : i32
    %1143 = arith.constant 8 : i32
    %1144 = arith.extsi %1142 : i32 to i64
    %1145 = arith.extsi %1143 : i32 to i64
    %1141 = func.call @calloc(%1144, %1145) : (i64, i64) -> !llvm.ptr
    %1147 = llvm.load %997 : !llvm.ptr -> i32
    %1148 = arith.constant 2 : i32
    %1149 = arith.extsi %1148 : i32 to i64
    %1146 = func.call @bn_div_small(%1141, %987, %1147, %1149) : (!llvm.ptr, !llvm.ptr, i32, i64) -> i32
    %1151 = arith.constant 30 : i32
    %1152 = arith.constant 8 : i32
    %1153 = arith.extsi %1151 : i32 to i64
    %1154 = arith.extsi %1152 : i32 to i64
    %1150 = func.call @calloc(%1153, %1154) : (i64, i64) -> !llvm.ptr
    %1156 = arith.constant 0 : i32
    %1157 = arith.constant 1 : i32
    %1158 = arith.extsi %1157 : i32 to i64
    %1155 = func.call @bn_addmul_small(%1150, %1156, %1132, %1137, %1158) : (!llvm.ptr, i32, !llvm.ptr, i32, i64) -> i32
    %1160 = arith.constant 1 : i32
    %1161 = arith.extsi %1160 : i32 to i64
    %1159 = func.call @bn_addmul_small(%1150, %1155, %1141, %1146, %1161) : (!llvm.ptr, i32, !llvm.ptr, i32, i64) -> i32
    %1162 = func.call @bn_to_f64(%1150, %1159) : (!llvm.ptr, i32) -> f64
    %1164 = llvm.load %997 : !llvm.ptr -> i32
    %1163 = func.call @bn_to_f64(%987, %1164) : (!llvm.ptr, i32) -> f64
    %1165 = arith.divf %1162, %1163 : f64
    %1166 = arith.fptosi %1165 : f64 to i64
    %1168 = arith.constant 30 : i32
    %1169 = arith.constant 8 : i32
    %1170 = arith.extsi %1168 : i32 to i64
    %1171 = arith.extsi %1169 : i32 to i64
    %1167 = func.call @calloc(%1170, %1171) : (i64, i64) -> !llvm.ptr
    %1173 = llvm.load %997 : !llvm.ptr -> i32
    %1172 = func.call @bn_mul_small(%1167, %987, %1173, %1166) : (!llvm.ptr, !llvm.ptr, i32, i64) -> i32
    %1174 = func.call @bn_cmp(%1167, %1172, %1150, %1159) : (!llvm.ptr, i32, !llvm.ptr, i32) -> i32
    %1175 = llvm.mlir.constant(1 : i64) : i64
    %1176 = llvm.alloca %1175 x i64 : (i64) -> !llvm.ptr
    llvm.store %1166, %1176 : i64, !llvm.ptr
    %1177 = arith.constant 0 : i32
    %1178 = arith.cmpi slt, %1174, %1177 : i32
    cf.cond_br %1178, ^bb135, ^bb136
    ^bb135:
      %1179 = arith.constant 1 : i32
      %1181 = arith.extsi %1179 : i32 to i64
      %1180 = arith.addi %1166, %1181 : i64
      %1182 = llvm.mlir.constant(1 : i64) : i64
      %1183 = llvm.alloca %1182 x i64 : (i64) -> !llvm.ptr
      llvm.store %1180, %1183 : i64, !llvm.ptr
      %1184 = arith.constant 0 : i32
      %1185 = llvm.mlir.constant(1 : i64) : i64
      %1186 = llvm.alloca %1185 x i32 : (i64) -> !llvm.ptr
      llvm.store %1184, %1186 : i32, !llvm.ptr
      cf.br ^bb138
      ^bb138:
      %1187 = llvm.load %1186 : !llvm.ptr -> i32
      %1188 = arith.constant 0 : i32
      %1189 = arith.cmpi eq, %1187, %1188 : i32
      cf.cond_br %1189, ^bb139, ^bb140
      ^bb139:
        %1191 = arith.constant 30 : i32
        %1192 = arith.constant 8 : i32
        %1193 = arith.extsi %1191 : i32 to i64
        %1194 = arith.extsi %1192 : i32 to i64
        %1190 = func.call @calloc(%1193, %1194) : (i64, i64) -> !llvm.ptr
        %1196 = llvm.load %997 : !llvm.ptr -> i32
        %1197 = llvm.load %1183 : !llvm.ptr -> i64
        %1195 = func.call @bn_mul_small(%1190, %987, %1196, %1197) : (!llvm.ptr, !llvm.ptr, i32, i64) -> i32
        %1198 = func.call @bn_cmp(%1190, %1195, %1150, %1159) : (!llvm.ptr, i32, !llvm.ptr, i32) -> i32
        func.call @free(%1190) : (!llvm.ptr) -> ()
        %1200 = arith.constant 0 : i32
        %1201 = arith.cmpi sgt, %1198, %1200 : i32
        cf.cond_br %1201, ^bb141, ^bb142
        ^bb141:
          %1202 = arith.constant 1 : i32
          llvm.store %1202, %1186 : i32, !llvm.ptr
          cf.br ^bb143
        ^bb142:
          %1203 = llvm.load %1183 : !llvm.ptr -> i64
          %1204 = arith.constant 1 : i32
          %1206 = arith.extsi %1204 : i32 to i64
          %1205 = arith.addi %1203, %1206 : i64
          llvm.store %1205, %1183 : i64, !llvm.ptr
          %1207 = llvm.load %1183 : !llvm.ptr -> i64
          %1208 = arith.constant 100 : i32
          %1210 = arith.extsi %1208 : i32 to i64
          %1209 = arith.addi %1166, %1210 : i64
          %1211 = arith.cmpi sgt, %1207, %1209 : i64
          cf.cond_br %1211, ^bb144, ^bb145
          ^bb144:
            %1212 = arith.constant 1 : i32
            llvm.store %1212, %1186 : i32, !llvm.ptr
            cf.br ^bb146
          ^bb145:
            cf.br ^bb146
          ^bb146:
          cf.br ^bb143
        ^bb143:
        cf.br ^bb138
      ^bb140:
      %1213 = llvm.load %1183 : !llvm.ptr -> i64
      %1214 = arith.constant 1 : i32
      %1216 = arith.extsi %1214 : i32 to i64
      %1215 = arith.subi %1213, %1216 : i64
      llvm.store %1215, %1176 : i64, !llvm.ptr
      cf.br ^bb137
    ^bb136:
      %1217 = arith.constant 0 : i32
      %1218 = arith.cmpi sgt, %1174, %1217 : i32
      cf.cond_br %1218, ^bb147, ^bb148
      ^bb147:
        %1219 = arith.constant 1 : i32
        %1221 = arith.extsi %1219 : i32 to i64
        %1220 = arith.subi %1166, %1221 : i64
        %1222 = llvm.mlir.constant(1 : i64) : i64
        %1223 = llvm.alloca %1222 x i64 : (i64) -> !llvm.ptr
        llvm.store %1220, %1223 : i64, !llvm.ptr
        %1224 = arith.constant 0 : i32
        %1225 = llvm.mlir.constant(1 : i64) : i64
        %1226 = llvm.alloca %1225 x i32 : (i64) -> !llvm.ptr
        llvm.store %1224, %1226 : i32, !llvm.ptr
        cf.br ^bb150
        ^bb150:
        %1227 = llvm.load %1226 : !llvm.ptr -> i32
        %1228 = arith.constant 0 : i32
        %1229 = arith.cmpi eq, %1227, %1228 : i32
        %1230 = scf.if %1229 -> (i1) {
          %1231 = llvm.load %1223 : !llvm.ptr -> i64
          %1232 = arith.constant 0 : i32
          %1234 = arith.extsi %1232 : i32 to i64
          %1233 = arith.cmpi sge, %1231, %1234 : i64
          scf.yield %1233 : i1
        } else {
          %1235 = arith.constant false
          scf.yield %1235 : i1
        }
        cf.cond_br %1230, ^bb151, ^bb152
        ^bb151:
          %1237 = arith.constant 30 : i32
          %1238 = arith.constant 8 : i32
          %1239 = arith.extsi %1237 : i32 to i64
          %1240 = arith.extsi %1238 : i32 to i64
          %1236 = func.call @calloc(%1239, %1240) : (i64, i64) -> !llvm.ptr
          %1242 = llvm.load %997 : !llvm.ptr -> i32
          %1243 = llvm.load %1223 : !llvm.ptr -> i64
          %1241 = func.call @bn_mul_small(%1236, %987, %1242, %1243) : (!llvm.ptr, !llvm.ptr, i32, i64) -> i32
          %1244 = func.call @bn_cmp(%1236, %1241, %1150, %1159) : (!llvm.ptr, i32, !llvm.ptr, i32) -> i32
          func.call @free(%1236) : (!llvm.ptr) -> ()
          %1246 = arith.constant 0 : i32
          %1247 = arith.cmpi sle, %1244, %1246 : i32
          cf.cond_br %1247, ^bb153, ^bb154
          ^bb153:
            %1248 = arith.constant 1 : i32
            llvm.store %1248, %1226 : i32, !llvm.ptr
            cf.br ^bb155
          ^bb154:
            %1249 = llvm.load %1223 : !llvm.ptr -> i64
            %1250 = arith.constant 1 : i32
            %1252 = arith.extsi %1250 : i32 to i64
            %1251 = arith.subi %1249, %1252 : i64
            llvm.store %1251, %1223 : i64, !llvm.ptr
            %1253 = llvm.load %1223 : !llvm.ptr -> i64
            %1254 = arith.constant 100 : i32
            %1256 = arith.extsi %1254 : i32 to i64
            %1255 = arith.subi %1166, %1256 : i64
            %1257 = arith.cmpi slt, %1253, %1255 : i64
            cf.cond_br %1257, ^bb156, ^bb157
            ^bb156:
              %1258 = arith.constant 1 : i32
              llvm.store %1258, %1226 : i32, !llvm.ptr
              cf.br ^bb158
            ^bb157:
              cf.br ^bb158
            ^bb158:
            cf.br ^bb155
          ^bb155:
          cf.br ^bb150
        ^bb152:
        %1259 = llvm.load %1223 : !llvm.ptr -> i64
        llvm.store %1259, %1176 : i64, !llvm.ptr
        cf.br ^bb149
      ^bb148:
        cf.br ^bb149
      ^bb149:
      cf.br ^bb137
    ^bb137:
    %1260 = llvm.load %1176 : !llvm.ptr -> i64
    %1261 = arith.constant 5 : i32
    %1263 = arith.extsi %1261 : i32 to i64
    %1262 = arith.addi %1260, %1263 : i64
    %1264 = arith.constant 10 : i32
    %1266 = arith.extsi %1264 : i32 to i64
    %1265 = arith.divsi %1262, %1266 : i64
    %1267 = arith.sitofp %1265 : i64 to f64
    %1268 = arith.constant 10000000000.0 : f32
    %1270 = arith.extf %1268 : f32 to f64
    %1269 = arith.divf %1267, %1270 : f64
    %1271 = llvm.mlir.addressof @str_0 : !llvm.ptr
    %1272 = llvm.call @printf(%1271, %1269) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, f64) -> i32
    %1273 = arith.constant 0 : i32
    %1274 = llvm.mlir.constant(1 : i64) : i64
    %1275 = llvm.alloca %1274 x i32 : (i64) -> !llvm.ptr
    llvm.store %1273, %1275 : i32, !llvm.ptr
    cf.br ^bb159
    ^bb159:
    %1276 = llvm.load %1275 : !llvm.ptr -> i32
    %1277 = llvm.mlir.addressof @RANKS : !llvm.ptr
    %1278 = llvm.load %1277 : !llvm.ptr -> i32
    %1279 = arith.cmpi sle, %1276, %1278 : i32
    cf.cond_br %1279, ^bb160, ^bb161
    ^bb160:
      %1282 = llvm.load %1275 : !llvm.ptr -> i32
      %1283 = arith.extsi %1282 : i32 to i64
      %1284 = llvm.getelementptr %557[%1283] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.ptr
      %1281 = llvm.load %1284 : !llvm.ptr -> !llvm.ptr
      func.call @free(%1281) : (!llvm.ptr) -> ()
      %1287 = llvm.load %1275 : !llvm.ptr -> i32
      %1288 = arith.extsi %1287 : i32 to i64
      %1289 = llvm.getelementptr %817[%1288] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.ptr
      %1286 = llvm.load %1289 : !llvm.ptr -> !llvm.ptr
      func.call @free(%1286) : (!llvm.ptr) -> ()
      %1290 = llvm.load %1275 : !llvm.ptr -> i32
      %1291 = arith.constant 1 : i32
      %1292 = arith.addi %1290, %1291 : i32
      llvm.store %1292, %1275 : i32, !llvm.ptr
      cf.br ^bb159
    ^bb161:
    func.call @free(%557) : (!llvm.ptr) -> ()
    func.call @free(%562) : (!llvm.ptr) -> ()
    func.call @free(%599) : (!llvm.ptr) -> ()
    %1296 = arith.constant 0 : i32
    %1297 = llvm.mlir.constant(1 : i64) : i64
    %1298 = llvm.alloca %1297 x i32 : (i64) -> !llvm.ptr
    llvm.store %1296, %1298 : i32, !llvm.ptr
    cf.br ^bb162
    ^bb162:
    %1299 = llvm.load %1298 : !llvm.ptr -> i32
    %1300 = llvm.mlir.addressof @N : !llvm.ptr
    %1301 = llvm.load %1300 : !llvm.ptr -> i32
    %1302 = arith.cmpi sle, %1299, %1301 : i32
    cf.cond_br %1302, ^bb163, ^bb164
    ^bb163:
      %1305 = llvm.load %1298 : !llvm.ptr -> i32
      %1306 = arith.extsi %1305 : i32 to i64
      %1307 = llvm.getelementptr %704[%1306] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.ptr
      %1304 = llvm.load %1307 : !llvm.ptr -> !llvm.ptr
      func.call @free(%1304) : (!llvm.ptr) -> ()
      %1308 = llvm.load %1298 : !llvm.ptr -> i32
      %1309 = arith.constant 1 : i32
      %1310 = arith.addi %1308, %1309 : i32
      llvm.store %1310, %1298 : i32, !llvm.ptr
      cf.br ^bb162
    ^bb164:
    func.call @free(%704) : (!llvm.ptr) -> ()
    func.call @free(%712) : (!llvm.ptr) -> ()
    func.call @free(%781) : (!llvm.ptr) -> ()
    func.call @free(%822) : (!llvm.ptr) -> ()
    func.call @free(%987) : (!llvm.ptr) -> ()
    func.call @free(%1005) : (!llvm.ptr) -> ()
    func.call @free(%1013) : (!llvm.ptr) -> ()
    func.call @free(%1132) : (!llvm.ptr) -> ()
    func.call @free(%1141) : (!llvm.ptr) -> ()
    func.call @free(%1150) : (!llvm.ptr) -> ()
    func.call @free(%1167) : (!llvm.ptr) -> ()
    %1322 = arith.constant 0 : i32
    func.return %1322 : i32
  }
}