Problem 964

P(k) for k=7 using exact rational arithmetic with i128. P = (1/n!) * sum_{m=0}^{n-1} (-1)^m * prod_i mult_i / dim^(k-1)

Answer4.7126135532e-29
Output4.7126135532e-29
StatusPASS
Native helperno
Runtime0 ms
Peak memory27600 KB
Time complexityO(n log n) (estimated)
Space complexityO(n^2) (estimated)

Performance comparison

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

Flow source

# Project Euler 964
# P(k) for k=7 using exact rational arithmetic with i128.
# P = (1/n!) * sum_{m=0}^{n-1} (-1)^m * prod_i mult_i / dim^(k-1)

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

const K: i32 = 7
const N: i32 = 22
const TBITS: i32 = 524288
const TMASK: i32 = 524287

# Hash table for memoization of count_paths
# Keys stored as flat byte array: ht_keydata[h*64 .. h*64+63]
let mut ht_keydata: ptr<i8> = 0 as ptr<i8>
let mut ht_vals: ptr<i128> = 0 as ptr<i128>
let mut ht_used: ptr<i32> = 0 as ptr<i32>

function init_globals() -> void {
    ht_keydata = calloc(TBITS * 64, 1)
    ht_vals = calloc(TBITS, 16)
    ht_used = calloc(TBITS, 4)
}

function hash_str(s: ptr<i8>) -> i64 {
    let mut h: i64 = 1469598103934665603
    let mut i: i32 = 0
    while s[i] != 0 {
        h = h ^ (s[i] as i64)
        h = h * 1099511628211
        i = i + 1
    }
    return h
}

function key_eq(a: ptr<i8>, b: ptr<i8>) -> i32 {
    let mut i: i32 = 0
    while a[i] != 0 || b[i] != 0 {
        if a[i] != b[i] { return 0 }
        i = i + 1
    }
    return 1
}

function lookup(key: ptr<i8>, out: ptr<i128>) -> i32 {
    let mut h: i32 = (hash_str(key) & TMASK as i64) as i32
    while ht_used[h] != 0 {
        let slot_key: ptr<i8> = ht_keydata + h * 64
        if key_eq(key, slot_key) == 1 {
            out[0] = ht_vals[h]
            return 1
        }
        h = (h + 1) & TMASK
    }
    return 0
}

function insert(key: ptr<i8>, val: i128) -> void {
    let mut h: i32 = (hash_str(key) & TMASK as i64) as i32
    while ht_used[h] != 0 {
        let slot_key: ptr<i8> = ht_keydata + h * 64
        if key_eq(key, slot_key) == 1 {
            ht_vals[h] = val
            return
        }
        h = (h + 1) & TMASK
    }
    # Copy key into slot
    let slot_key: ptr<i8> = ht_keydata + h * 64
    let mut i: i32 = 0
    while key[i] != 0 {
        slot_key[i] = key[i]
        i = i + 1
    }
    slot_key[i] = 0
    ht_vals[h] = val
    ht_used[h] = 1
}

function make_key(buf: ptr<i8>, start: ptr<i32>, len: i32, i: i32) -> void {
    buf[0] = i as i8
    let mut j: i32 = 0
    while j < len {
        buf[1 + j] = start[j] as i8
        j = j + 1
    }
    buf[1 + len] = 0
}

function count_paths(start: ptr<i32>, len: i32, i: i32) -> i128 {
    let mut sum: i32 = 0
    let mut j: i32 = 0
    while j < len {
        sum = sum + start[j]
        j = j + 1
    }
    if sum < i { return 0 }
    if len == 1 && start[0] == i { return 1 }

    let keybuf: ptr<i8> = calloc(64, 1)
    make_key(keybuf, start, len, i)
    let out: ptr<i128> = calloc(1, 16)
    if lookup(keybuf, out) == 1 {
        let result: i128 = out[0]
        free(keybuf as ptr<void>)
        free(out as ptr<void>)
        return result
    }
    free(out as ptr<void>)

    let mut total: i128 = 0
    let newp: ptr<i32> = calloc(32, 4)
    let mut r: i32 = 0
    while r < len {
        let is_corner: i32 = if r == len - 1 { 1 } else { if start[r + 1] < start[r] { 1 } else { 0 } }
        if is_corner == 1 {
            let mut nlen: i32 = len
            let mut j2: i32 = 0
            while j2 < len {
                newp[j2] = start[j2]
                j2 = j2 + 1
            }
            newp[r] = newp[r] - 1
            if newp[r] == 0 {
                let mut j3: i32 = r
                while j3 < nlen - 1 {
                    newp[j3] = newp[j3 + 1]
                    j3 = j3 + 1
                }
                nlen = nlen - 1
            }
            if nlen == 0 { r = r + 1; continue }
            if newp[0] < i { r = r + 1; continue }
            total = total + count_paths(newp, nlen, i)
        }
        r = r + 1
    }
    free(newp as ptr<void>)

    insert(keybuf, total)
    free(keybuf as ptr<void>)
    return total
}

function binom(n: i32, k: i32) -> i128 {
    if k < 0 || k > n { return 0 }
    if k == 0 || k == n { return 1 }
    let kk: i32 = if k > n - k { n - k } else { k }
    let mut r: i128 = 1
    let mut i: i32 = 0
    while i < kk {
        r = r * ((n - i) as i128) / ((i + 1) as i128)
        i = i + 1
    }
    return r
}

function gcd128(a: i128, b: i128) -> i128 {
    let mut x: i128 = a
    if x < 0 { x = 0 - x }
    let mut y: i128 = b
    if y < 0 { y = 0 - y }
    while y != 0 {
        let t: i128 = x % y
        x = y
        y = t
    }
    return x
}

function i128_to_f64(x: i128) -> f64 {
    if x == 0 { return 0.0 }
    let neg: i32 = 0
    let mut v: i128 = x
    if v < 0 { neg = 1; v = 0 - v }
    let lo: i64 = v as i64
    let hi: i64 = (v >> 64) as i64
    let mut result: f64 = 0.0
    if hi != 0 {
        result = (hi as f64) * 18446744073709551616.0 + (lo as f64)
    } else {
        result = lo as f64
    }
    if neg == 1 { result = 0 - result }
    return result
}

function main() -> i32 {
    init_globals()

    let mut sum_num: i128 = 0
    let mut sum_den: i128 = 1

    let mut m: i32 = 0
    while m < N {
        let lam: ptr<i32> = calloc(32, 4)
        let lamlen: i32 = 0
        if m == 0 {
            lam[0] = N
            lamlen = 1
        } else {
            lam[0] = N - m
            let mut j: i32 = 1
            while j <= m {
                lam[j] = 1
                j = j + 1
            }
            lamlen = m + 1
        }

        let mut prod: i128 = 1
        let mut prod_zero: i32 = 0
        let mut i: i32 = 1
        while i <= K {
            let mult: i128 = count_paths(lam, lamlen, i)
            if mult == 0 { prod_zero = 1; break }
            prod = prod * mult
            i = i + 1
        }
        free(lam as ptr<void>)

        if prod_zero == 1 {
            m = m + 1
            continue
        }

        let dim: i128 = binom(N - 1, m)
        let mut d6: i128 = 1
        let mut e: i32 = 0
        while e < K - 1 {
            d6 = d6 * dim
            e = e + 1
        }

        let mut term_num: i128 = prod
        if m % 2 == 1 { term_num = 0 - term_num }
        let term_den: i128 = d6

        # Reduce term
        let mut g: i128 = gcd128(term_num, term_den)
        if g > 1 {
            term_num = term_num / g
            term_den = term_den / g
        }

        # sum = sum + term
        let new_num: i128 = sum_num * term_den + term_num * sum_den
        let new_den: i128 = sum_den * term_den

        sum_num = new_num
        sum_den = new_den

        # Reduce
        g = gcd128(sum_num, sum_den)
        if g > 1 {
            sum_num = sum_num / g
            sum_den = sum_den / g
        }

        m = m + 1
    }

    # P = sum_num / (sum_den * n!)
    let mut nfact: i128 = 1
    let mut i2: i32 = 2
    while i2 <= N {
        nfact = nfact * (i2 as i128)
        i2 = i2 + 1
    }

    let p_den: i128 = sum_den * nfact
    let mut g2: i128 = gcd128(sum_num, p_den)
    if g2 > 1 {
        sum_num = sum_num / g2
    }
    let mut p_den_reduced: i128 = p_den
    if g2 > 1 {
        p_den_reduced = p_den / g2
    }

    let P: f64 = i128_to_f64(sum_num) / i128_to_f64(p_den_reduced)
    printf("%.10e\n", P)
    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 init_globals(void);
int64_t hash_str_ptr_i8(int8_t* s);
int32_t key_eq_ptr_i8_ptr_i8(int8_t* a, int8_t* b);
int32_t lookup_ptr_i8_ptr_i128(int8_t* key, __int128* out);
void insert_ptr_i8_i128(int8_t* key, __int128 val);
void make_key_ptr_i8_ptr_i32_i32_i32(int8_t* buf, int32_t* start, int32_t len, int32_t i);
__int128 count_paths_ptr_i32_i32_i32(int32_t* start, int32_t len, int32_t i);
__int128 binom_i32_i32(int32_t n, int32_t k);
__int128 gcd128_i128_i128(__int128 a, __int128 b);
double i128_to_f64_i128(__int128 x);
int32_t main(void);

static const int32_t K = 7;
static const int32_t N = 22;
static const int32_t TBITS = 524288;
static const int32_t TMASK = 524287;

/* Module statics */
static int8_t* ht_keydata = ((int8_t*)(0));
static __int128* ht_vals = ((__int128*)(0));
static int32_t* ht_used = ((int32_t*)(0));




void init_globals(void) {
    ht_keydata = calloc((TBITS * 64), 1);
    ht_vals = calloc(TBITS, 16);
    ht_used = calloc(TBITS, 4);
}

int64_t hash_str_ptr_i8(int8_t* s) {
    int64_t h = 1469598103934665603;
    int32_t i = 0;
    while (s[i] != 0) {
        h = (h ^ ((int64_t)(s[i])));
        h = (h * 1099511628211);
        i = (i + 1);
    }
    return h;
}

int32_t key_eq_ptr_i8_ptr_i8(int8_t* a, int8_t* b) {
    int32_t i = 0;
    while ((a[i] != 0 || b[i] != 0)) {
        if (a[i] != b[i]) {
            return 0;
        }
        i = (i + 1);
    }
    return 1;
}

int32_t lookup_ptr_i8_ptr_i128(int8_t* key, __int128* out) {
    int32_t h = ((int32_t)((hash_str_ptr_i8(key) & ((int64_t)(TMASK)))));
    while (ht_used[h] != 0) {
        int8_t* slot_key = (int8_t*)((ht_keydata + (h * 64)));
        if (key_eq_ptr_i8_ptr_i8(key, slot_key) == 1) {
            out[0] = ht_vals[h];
            return 1;
        }
        h = ((h + 1) & TMASK);
    }
    return 0;
}

void insert_ptr_i8_i128(int8_t* key, __int128 val) {
    int32_t h = ((int32_t)((hash_str_ptr_i8(key) & ((int64_t)(TMASK)))));
    while (ht_used[h] != 0) {
        int8_t* slot_key = (int8_t*)((ht_keydata + (h * 64)));
        if (key_eq_ptr_i8_ptr_i8(key, slot_key) == 1) {
            ht_vals[h] = val;
            return;
        }
        h = ((h + 1) & TMASK);
    }
    int8_t* slot_key = (int8_t*)((ht_keydata + (h * 64)));
    int32_t i = 0;
    while (key[i] != 0) {
        slot_key[i] = key[i];
        i = (i + 1);
    }
    slot_key[i] = 0;
    ht_vals[h] = val;
    ht_used[h] = 1;
}

void make_key_ptr_i8_ptr_i32_i32_i32(int8_t* buf, int32_t* start, int32_t len, int32_t i) {
    buf[0] = ((int8_t)(i));
    int32_t j = 0;
    while (j < len) {
        buf[(1 + j)] = ((int8_t)(start[j]));
        j = (j + 1);
    }
    buf[(1 + len)] = 0;
}

__int128 count_paths_ptr_i32_i32_i32(int32_t* start, int32_t len, int32_t i) {
    int32_t sum = 0;
    int32_t j = 0;
    while (j < len) {
        sum = (sum + start[j]);
        j = (j + 1);
    }
    if (sum < i) {
        return 0;
    }
    if ((len == 1 && start[0] == i)) {
        return 1;
    }
    int8_t* keybuf = (int8_t*)(calloc(64, 1));
    make_key_ptr_i8_ptr_i32_i32_i32(keybuf, start, len, i);
    __int128* out = (__int128*)(calloc(1, 16));
    if (lookup_ptr_i8_ptr_i128(keybuf, out) == 1) {
        __int128 result = out[0];
        free(((void*)(keybuf)));
        free(((void*)(out)));
        return result;
    }
    free(((void*)(out)));
    __int128 total = 0;
    int32_t* newp = (int32_t*)(calloc(32, 4));
    int32_t r = 0;
    while (r < len) {
        int32_t is_corner = ((r == (len - 1)) ? (1) : (((start[(r + 1)] < start[r]) ? (1) : (0))));
        if (is_corner == 1) {
            int32_t nlen = len;
            int32_t j2 = 0;
            while (j2 < len) {
                newp[j2] = start[j2];
                j2 = (j2 + 1);
            }
            newp[r] = (newp[r] - 1);
            if (newp[r] == 0) {
                int32_t j3 = r;
                while (j3 < (nlen - 1)) {
                    newp[j3] = newp[(j3 + 1)];
                    j3 = (j3 + 1);
                }
                nlen = (nlen - 1);
            }
            if (nlen == 0) {
                r = (r + 1);
                continue;
            }
            if (newp[0] < i) {
                r = (r + 1);
                continue;
            }
            total = (total + count_paths_ptr_i32_i32_i32(newp, nlen, i));
        }
        r = (r + 1);
    }
    free(((void*)(newp)));
    insert_ptr_i8_i128(keybuf, total);
    free(((void*)(keybuf)));
    return total;
}

__int128 binom_i32_i32(int32_t n, int32_t k) {
    if ((k < 0 || k > n)) {
        return 0;
    }
    if ((k == 0 || k == n)) {
        return 1;
    }
    int32_t kk = ((k > (n - k)) ? ((n - k)) : (k));
    __int128 r = 1;
    int32_t i = 0;
    while (i < kk) {
        r = FLOW_CHECKED_DIV(((r * ((__int128)((n - i))))), (((__int128)((i + 1)))));
        i = (i + 1);
    }
    return r;
}

__int128 gcd128_i128_i128(__int128 a, __int128 b) {
    __int128 x = a;
    if (x < 0) {
        x = (0 - x);
    }
    __int128 y = b;
    if (y < 0) {
        y = (0 - y);
    }
    while (y != 0) {
        __int128 t = FLOW_CHECKED_MOD((x), (y));
        x = y;
        y = t;
    }
    return x;
}

double i128_to_f64_i128(__int128 x) {
    if (x == 0) {
        return 0.0;
    }
    int32_t neg = 0;
    __int128 v = x;
    if (v < 0) {
        neg = 1;
        v = (0 - v);
    }
    int64_t lo = ((int64_t)(v));
    int64_t hi = ((int64_t)(FLOW_CHECKED_SHR((v), (64))));
    double result = 0.0;
    if (hi != 0) {
        result = ((((double)(hi)) * 18446744073709551616.0) + ((double)(lo)));
    } else {
        result = ((double)(lo));
    }
    if (neg == 1) {
        result = (0 - result);
    }
    return result;
}

int32_t main(void) {
    init_globals();
    __int128 sum_num = 0;
    __int128 sum_den = 1;
    int32_t m = 0;
    while (m < N) {
        int32_t* lam = (int32_t*)(calloc(32, 4));
        int32_t lamlen = 0;
        if (m == 0) {
            lam[0] = N;
            lamlen = 1;
        } else {
            lam[0] = (N - m);
            int32_t j = 1;
            while (j <= m) {
                lam[j] = 1;
                j = (j + 1);
            }
            lamlen = (m + 1);
        }
        __int128 prod = 1;
        int32_t prod_zero = 0;
        int32_t i = 1;
        while (i <= K) {
            __int128 mult = count_paths_ptr_i32_i32_i32(lam, lamlen, i);
            if (mult == 0) {
                prod_zero = 1;
                break;
            }
            prod = (prod * mult);
            i = (i + 1);
        }
        free(((void*)(lam)));
        if (prod_zero == 1) {
            m = (m + 1);
            continue;
        }
        __int128 dim = binom_i32_i32((N - 1), m);
        __int128 d6 = 1;
        int32_t e = 0;
        while (e < (K - 1)) {
            d6 = (d6 * dim);
            e = (e + 1);
        }
        __int128 term_num = prod;
        if (FLOW_CHECKED_MOD((m), (2)) == 1) {
            term_num = (0 - term_num);
        }
        __int128 term_den = d6;
        __int128 g = gcd128_i128_i128(term_num, term_den);
        if (g > 1) {
            term_num = FLOW_CHECKED_DIV((term_num), (g));
            term_den = FLOW_CHECKED_DIV((term_den), (g));
        }
        __int128 new_num = ((sum_num * term_den) + (term_num * sum_den));
        __int128 new_den = (sum_den * term_den);
        sum_num = new_num;
        sum_den = new_den;
        g = gcd128_i128_i128(sum_num, sum_den);
        if (g > 1) {
            sum_num = FLOW_CHECKED_DIV((sum_num), (g));
            sum_den = FLOW_CHECKED_DIV((sum_den), (g));
        }
        m = (m + 1);
    }
    __int128 nfact = 1;
    int32_t i2 = 2;
    while (i2 <= N) {
        nfact = (nfact * ((__int128)(i2)));
        i2 = (i2 + 1);
    }
    __int128 p_den = (sum_den * nfact);
    __int128 g2 = gcd128_i128_i128(sum_num, p_den);
    if (g2 > 1) {
        sum_num = FLOW_CHECKED_DIV((sum_num), (g2));
    }
    __int128 p_den_reduced = p_den;
    if (g2 > 1) {
        p_den_reduced = FLOW_CHECKED_DIV((p_den), (g2));
    }
    double P = (i128_to_f64_i128(sum_num) / i128_to_f64_i128(p_den_reduced));
    printf("%.10e\n", P);
    return 0;
}

Generated MLIR

module {
  llvm.func @printf(!llvm.ptr, ...) -> i32
  llvm.mlir.global internal constant @str_0("%.10e\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: K
  llvm.mlir.global internal constant @K(7 : i32) : i32
  // Constant: N
  llvm.mlir.global internal constant @N(22 : i32) : i32
  // Constant: TBITS
  llvm.mlir.global internal constant @TBITS(524288 : i32) : i32
  // Constant: TMASK
  llvm.mlir.global internal constant @TMASK(524287 : i32) : i32
  // Module static: ht_keydata
  llvm.mlir.global internal @ht_keydata() {addr_space = 0 : i32} : !llvm.ptr {
    %0 = llvm.mlir.zero : !llvm.ptr
    llvm.return %0 : !llvm.ptr
  }
  // Module static: ht_vals
  llvm.mlir.global internal @ht_vals() {addr_space = 0 : i32} : !llvm.ptr {
    %1 = llvm.mlir.zero : !llvm.ptr
    llvm.return %1 : !llvm.ptr
  }
  // Module static: ht_used
  llvm.mlir.global internal @ht_used() {addr_space = 0 : i32} : !llvm.ptr {
    %2 = llvm.mlir.zero : !llvm.ptr
    llvm.return %2 : !llvm.ptr
  }
  func.func @init_globals() -> () {
    %4 = llvm.mlir.addressof @TBITS : !llvm.ptr
    %5 = llvm.load %4 : !llvm.ptr -> i32
    %6 = arith.constant 64 : i32
    %7 = arith.muli %5, %6 : i32
    %8 = arith.constant 1 : i32
    %9 = arith.extsi %7 : i32 to i64
    %10 = arith.extsi %8 : i32 to i64
    %3 = func.call @calloc(%9, %10) : (i64, i64) -> !llvm.ptr
    %11 = llvm.mlir.addressof @ht_keydata : !llvm.ptr
    llvm.store %3, %11 : !llvm.ptr, !llvm.ptr
    %13 = llvm.mlir.addressof @TBITS : !llvm.ptr
    %14 = llvm.load %13 : !llvm.ptr -> i32
    %15 = arith.constant 16 : i32
    %16 = arith.extsi %14 : i32 to i64
    %17 = arith.extsi %15 : i32 to i64
    %12 = func.call @calloc(%16, %17) : (i64, i64) -> !llvm.ptr
    %18 = llvm.mlir.addressof @ht_vals : !llvm.ptr
    llvm.store %12, %18 : !llvm.ptr, !llvm.ptr
    %20 = llvm.mlir.addressof @TBITS : !llvm.ptr
    %21 = llvm.load %20 : !llvm.ptr -> i32
    %22 = arith.constant 4 : i32
    %23 = arith.extsi %21 : i32 to i64
    %24 = arith.extsi %22 : i32 to i64
    %19 = func.call @calloc(%23, %24) : (i64, i64) -> !llvm.ptr
    %25 = llvm.mlir.addressof @ht_used : !llvm.ptr
    llvm.store %19, %25 : !llvm.ptr, !llvm.ptr
    func.return
  }
  func.func @hash_str(%arg0: !llvm.ptr) -> i64 {
    %26 = arith.constant 1469598099639698307 : i32
    %27 = arith.extsi %26 : i32 to i64
    %28 = llvm.mlir.constant(1 : i64) : i64
    %29 = llvm.alloca %28 x i64 : (i64) -> !llvm.ptr
    llvm.store %27, %29 : i64, !llvm.ptr
    %30 = arith.constant 0 : i32
    %31 = llvm.mlir.constant(1 : i64) : i64
    %32 = llvm.alloca %31 x i32 : (i64) -> !llvm.ptr
    llvm.store %30, %32 : i32, !llvm.ptr
    cf.br ^bb0
    ^bb0:
    %34 = llvm.load %32 : !llvm.ptr -> i32
    %35 = arith.extsi %34 : i32 to i64
    %36 = llvm.getelementptr %arg0[%35] : (!llvm.ptr, i64) -> !llvm.ptr, i8
    %33 = llvm.load %36 : !llvm.ptr -> i8
    %37 = arith.constant 0 : i32
    %39 = arith.extsi %33 : i8 to i32
    %38 = arith.cmpi ne, %39, %37 : i32
    cf.cond_br %38, ^bb1, ^bb2
    ^bb1:
      %40 = llvm.load %29 : !llvm.ptr -> i64
      %42 = llvm.load %32 : !llvm.ptr -> i32
      %43 = arith.extsi %42 : i32 to i64
      %44 = llvm.getelementptr %arg0[%43] : (!llvm.ptr, i64) -> !llvm.ptr, i8
      %41 = llvm.load %44 : !llvm.ptr -> i8
      %45 = arith.extsi %41 : i8 to i64
      %46 = arith.xori %40, %45 : i64
      llvm.store %46, %29 : i64, !llvm.ptr
      %47 = llvm.load %29 : !llvm.ptr -> i64
      %48 = arith.constant 1095216660915 : i32
      %50 = arith.extsi %48 : i32 to i64
      %49 = arith.muli %47, %50 : i64
      llvm.store %49, %29 : i64, !llvm.ptr
      %51 = llvm.load %32 : !llvm.ptr -> i32
      %52 = arith.constant 1 : i32
      %53 = arith.addi %51, %52 : i32
      llvm.store %53, %32 : i32, !llvm.ptr
      cf.br ^bb0
    ^bb2:
    %54 = llvm.load %29 : !llvm.ptr -> i64
    func.return %54 : i64
  }
  func.func @key_eq(%arg0: !llvm.ptr, %arg1: !llvm.ptr) -> i32 {
    %55 = arith.constant 0 : i32
    %56 = llvm.mlir.constant(1 : i64) : i64
    %57 = llvm.alloca %56 x i32 : (i64) -> !llvm.ptr
    llvm.store %55, %57 : i32, !llvm.ptr
    cf.br ^bb3
    ^bb3:
    %59 = llvm.load %57 : !llvm.ptr -> i32
    %60 = arith.extsi %59 : i32 to i64
    %61 = llvm.getelementptr %arg0[%60] : (!llvm.ptr, i64) -> !llvm.ptr, i8
    %58 = llvm.load %61 : !llvm.ptr -> i8
    %62 = arith.constant 0 : i32
    %64 = arith.extsi %58 : i8 to i32
    %63 = arith.cmpi ne, %64, %62 : i32
    %65 = scf.if %63 -> (i1) {
      %66 = arith.constant true
      scf.yield %66 : i1
    } else {
      %68 = llvm.load %57 : !llvm.ptr -> i32
      %69 = arith.extsi %68 : i32 to i64
      %70 = llvm.getelementptr %arg1[%69] : (!llvm.ptr, i64) -> !llvm.ptr, i8
      %67 = llvm.load %70 : !llvm.ptr -> i8
      %71 = arith.constant 0 : i32
      %73 = arith.extsi %67 : i8 to i32
      %72 = arith.cmpi ne, %73, %71 : i32
      scf.yield %72 : i1
    }
    cf.cond_br %65, ^bb4, ^bb5
    ^bb4:
      %75 = llvm.load %57 : !llvm.ptr -> i32
      %76 = arith.extsi %75 : i32 to i64
      %77 = llvm.getelementptr %arg0[%76] : (!llvm.ptr, i64) -> !llvm.ptr, i8
      %74 = llvm.load %77 : !llvm.ptr -> i8
      %79 = llvm.load %57 : !llvm.ptr -> i32
      %80 = arith.extsi %79 : i32 to i64
      %81 = llvm.getelementptr %arg1[%80] : (!llvm.ptr, i64) -> !llvm.ptr, i8
      %78 = llvm.load %81 : !llvm.ptr -> i8
      %83 = arith.extsi %74 : i8 to i32
      %84 = arith.extsi %78 : i8 to i32
      %82 = arith.cmpi ne, %83, %84 : i32
      cf.cond_br %82, ^bb6, ^bb7
      ^bb6:
        %85 = arith.constant 0 : i32
        func.return %85 : i32
      ^bb7:
        cf.br ^bb8
      ^bb8:
      %86 = llvm.load %57 : !llvm.ptr -> i32
      %87 = arith.constant 1 : i32
      %88 = arith.addi %86, %87 : i32
      llvm.store %88, %57 : i32, !llvm.ptr
      cf.br ^bb3
    ^bb5:
    %89 = arith.constant 1 : i32
    func.return %89 : i32
  }
  func.func @lookup(%arg0: !llvm.ptr, %arg1: !llvm.ptr) -> i32 {
    %90 = func.call @hash_str(%arg0) : (!llvm.ptr) -> i64
    %91 = llvm.mlir.addressof @TMASK : !llvm.ptr
    %92 = llvm.load %91 : !llvm.ptr -> i32
    %93 = arith.extsi %92 : i32 to i64
    %94 = arith.andi %90, %93 : i64
    %95 = arith.trunci %94 : i64 to i32
    %96 = llvm.mlir.constant(1 : i64) : i64
    %97 = llvm.alloca %96 x i32 : (i64) -> !llvm.ptr
    llvm.store %95, %97 : i32, !llvm.ptr
    cf.br ^bb9
    ^bb9:
    %99 = llvm.mlir.addressof @ht_used : !llvm.ptr
    %100 = llvm.load %99 : !llvm.ptr -> !llvm.ptr
    %101 = llvm.load %97 : !llvm.ptr -> i32
    %102 = arith.extsi %101 : i32 to i64
    %103 = llvm.getelementptr %100[%102] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %98 = llvm.load %103 : !llvm.ptr -> i32
    %104 = arith.constant 0 : i32
    %105 = arith.cmpi ne, %98, %104 : i32
    cf.cond_br %105, ^bb10, ^bb11
    ^bb10:
      # String concatenation: !llvm.ptr + i32
      %107 = func.call @key_eq(%arg0, %106) : (!llvm.ptr, !llvm.ptr) -> i32
      %108 = arith.constant 1 : i32
      %109 = arith.cmpi eq, %107, %108 : i32
      cf.cond_br %109, ^bb12, ^bb13
      ^bb12:
        %111 = llvm.mlir.addressof @ht_vals : !llvm.ptr
        %112 = llvm.load %111 : !llvm.ptr -> !llvm.ptr
        %113 = llvm.load %97 : !llvm.ptr -> i32
        %114 = arith.extsi %113 : i32 to i64
        %115 = llvm.getelementptr %112[%114] : (!llvm.ptr, i64) -> !llvm.ptr, i128
        %110 = llvm.load %115 : !llvm.ptr -> i128
        %116 = arith.constant 0 : i32
        %117 = arith.extsi %116 : i32 to i64
        %118 = llvm.getelementptr %arg1[%117] : (!llvm.ptr, i64) -> !llvm.ptr, i128
        llvm.store %110, %118 : i128, !llvm.ptr
        %119 = arith.constant 1 : i32
        func.return %119 : i32
      ^bb13:
        cf.br ^bb14
      ^bb14:
      %120 = llvm.load %97 : !llvm.ptr -> i32
      %121 = arith.constant 1 : i32
      %122 = arith.addi %120, %121 : i32
      %123 = llvm.mlir.addressof @TMASK : !llvm.ptr
      %124 = llvm.load %123 : !llvm.ptr -> i32
      %125 = arith.andi %122, %124 : i32
      llvm.store %125, %97 : i32, !llvm.ptr
      cf.br ^bb9
    ^bb11:
    %126 = arith.constant 0 : i32
    func.return %126 : i32
  }
  func.func @insert(%arg0: !llvm.ptr, %arg1: i128) -> () {
    %127 = func.call @hash_str(%arg0) : (!llvm.ptr) -> i64
    %128 = llvm.mlir.addressof @TMASK : !llvm.ptr
    %129 = llvm.load %128 : !llvm.ptr -> i32
    %130 = arith.extsi %129 : i32 to i64
    %131 = arith.andi %127, %130 : i64
    %132 = arith.trunci %131 : i64 to i32
    %133 = llvm.mlir.constant(1 : i64) : i64
    %134 = llvm.alloca %133 x i32 : (i64) -> !llvm.ptr
    llvm.store %132, %134 : i32, !llvm.ptr
    cf.br ^bb15
    ^bb15:
    %136 = llvm.mlir.addressof @ht_used : !llvm.ptr
    %137 = llvm.load %136 : !llvm.ptr -> !llvm.ptr
    %138 = llvm.load %134 : !llvm.ptr -> i32
    %139 = arith.extsi %138 : i32 to i64
    %140 = llvm.getelementptr %137[%139] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %135 = llvm.load %140 : !llvm.ptr -> i32
    %141 = arith.constant 0 : i32
    %142 = arith.cmpi ne, %135, %141 : i32
    cf.cond_br %142, ^bb16, ^bb17
    ^bb16:
      # String concatenation: !llvm.ptr + i32
      %144 = func.call @key_eq(%arg0, %143) : (!llvm.ptr, !llvm.ptr) -> i32
      %145 = arith.constant 1 : i32
      %146 = arith.cmpi eq, %144, %145 : i32
      cf.cond_br %146, ^bb18, ^bb19
      ^bb18:
        %147 = llvm.mlir.addressof @ht_vals : !llvm.ptr
        %148 = llvm.load %147 : !llvm.ptr -> !llvm.ptr
        %149 = llvm.load %134 : !llvm.ptr -> i32
        %150 = arith.extsi %149 : i32 to i64
        %151 = llvm.getelementptr %148[%150] : (!llvm.ptr, i64) -> !llvm.ptr, i128
        llvm.store %arg1, %151 : i128, !llvm.ptr
        func.return
      ^bb19:
        cf.br ^bb20
      ^bb20:
      %152 = llvm.load %134 : !llvm.ptr -> i32
      %153 = arith.constant 1 : i32
      %154 = arith.addi %152, %153 : i32
      %155 = llvm.mlir.addressof @TMASK : !llvm.ptr
      %156 = llvm.load %155 : !llvm.ptr -> i32
      %157 = arith.andi %154, %156 : i32
      llvm.store %157, %134 : i32, !llvm.ptr
      cf.br ^bb15
    ^bb17:
    # String concatenation: !llvm.ptr + i32
    %159 = arith.constant 0 : i32
    %160 = llvm.mlir.constant(1 : i64) : i64
    %161 = llvm.alloca %160 x i32 : (i64) -> !llvm.ptr
    llvm.store %159, %161 : i32, !llvm.ptr
    cf.br ^bb21
    ^bb21:
    %163 = llvm.load %161 : !llvm.ptr -> i32
    %164 = arith.extsi %163 : i32 to i64
    %165 = llvm.getelementptr %arg0[%164] : (!llvm.ptr, i64) -> !llvm.ptr, i8
    %162 = llvm.load %165 : !llvm.ptr -> i8
    %166 = arith.constant 0 : i32
    %168 = arith.extsi %162 : i8 to i32
    %167 = arith.cmpi ne, %168, %166 : i32
    cf.cond_br %167, ^bb22, ^bb23
    ^bb22:
      %170 = llvm.load %161 : !llvm.ptr -> i32
      %171 = arith.extsi %170 : i32 to i64
      %172 = llvm.getelementptr %arg0[%171] : (!llvm.ptr, i64) -> !llvm.ptr, i8
      %169 = llvm.load %172 : !llvm.ptr -> i8
      %173 = llvm.load %161 : !llvm.ptr -> i32
      %174 = arith.extsi %173 : i32 to i64
      %175 = llvm.getelementptr %158[%174] : (!llvm.ptr, i64) -> !llvm.ptr, i8
      llvm.store %169, %175 : i8, !llvm.ptr
      %176 = llvm.load %161 : !llvm.ptr -> i32
      %177 = arith.constant 1 : i32
      %178 = arith.addi %176, %177 : i32
      llvm.store %178, %161 : i32, !llvm.ptr
      cf.br ^bb21
    ^bb23:
    %179 = arith.constant 0 : i32
    %180 = llvm.load %161 : !llvm.ptr -> i32
    %181 = arith.trunci %179 : i32 to i8
    %182 = arith.extsi %180 : i32 to i64
    %183 = llvm.getelementptr %158[%182] : (!llvm.ptr, i64) -> !llvm.ptr, i8
    llvm.store %181, %183 : i8, !llvm.ptr
    %184 = llvm.mlir.addressof @ht_vals : !llvm.ptr
    %185 = llvm.load %184 : !llvm.ptr -> !llvm.ptr
    %186 = llvm.load %134 : !llvm.ptr -> i32
    %187 = arith.extsi %186 : i32 to i64
    %188 = llvm.getelementptr %185[%187] : (!llvm.ptr, i64) -> !llvm.ptr, i128
    llvm.store %arg1, %188 : i128, !llvm.ptr
    %189 = arith.constant 1 : i32
    %190 = llvm.mlir.addressof @ht_used : !llvm.ptr
    %191 = llvm.load %190 : !llvm.ptr -> !llvm.ptr
    %192 = llvm.load %134 : !llvm.ptr -> i32
    %193 = arith.extsi %192 : i32 to i64
    %194 = llvm.getelementptr %191[%193] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %189, %194 : i32, !llvm.ptr
    func.return
  }
  func.func @make_key(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: i32, %arg3: i32) -> () {
    %195 = arith.trunci %arg3 : i32 to i8
    %196 = arith.constant 0 : i32
    %197 = arith.extsi %196 : i32 to i64
    %198 = llvm.getelementptr %arg0[%197] : (!llvm.ptr, i64) -> !llvm.ptr, i8
    llvm.store %195, %198 : i8, !llvm.ptr
    %199 = arith.constant 0 : i32
    %200 = llvm.mlir.constant(1 : i64) : i64
    %201 = llvm.alloca %200 x i32 : (i64) -> !llvm.ptr
    llvm.store %199, %201 : i32, !llvm.ptr
    cf.br ^bb24
    ^bb24:
    %202 = llvm.load %201 : !llvm.ptr -> i32
    %203 = arith.cmpi slt, %202, %arg2 : i32
    cf.cond_br %203, ^bb25, ^bb26
    ^bb25:
      %205 = llvm.load %201 : !llvm.ptr -> i32
      %206 = arith.extsi %205 : i32 to i64
      %207 = llvm.getelementptr %arg1[%206] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %204 = llvm.load %207 : !llvm.ptr -> i32
      %208 = arith.trunci %204 : i32 to i8
      %209 = arith.constant 1 : i32
      %210 = llvm.load %201 : !llvm.ptr -> i32
      %211 = arith.addi %209, %210 : i32
      %212 = arith.extsi %211 : i32 to i64
      %213 = llvm.getelementptr %arg0[%212] : (!llvm.ptr, i64) -> !llvm.ptr, i8
      llvm.store %208, %213 : i8, !llvm.ptr
      %214 = llvm.load %201 : !llvm.ptr -> i32
      %215 = arith.constant 1 : i32
      %216 = arith.addi %214, %215 : i32
      llvm.store %216, %201 : i32, !llvm.ptr
      cf.br ^bb24
    ^bb26:
    %217 = arith.constant 0 : i32
    %218 = arith.constant 1 : i32
    %219 = arith.addi %218, %arg2 : i32
    %220 = arith.trunci %217 : i32 to i8
    %221 = arith.extsi %219 : i32 to i64
    %222 = llvm.getelementptr %arg0[%221] : (!llvm.ptr, i64) -> !llvm.ptr, i8
    llvm.store %220, %222 : i8, !llvm.ptr
    func.return
  }
  func.func @count_paths(%arg0: !llvm.ptr, %arg1: i32, %arg2: i32) -> i128 {
    %223 = arith.constant 0 : i32
    %224 = llvm.mlir.constant(1 : i64) : i64
    %225 = llvm.alloca %224 x i32 : (i64) -> !llvm.ptr
    llvm.store %223, %225 : i32, !llvm.ptr
    %226 = arith.constant 0 : i32
    %227 = llvm.mlir.constant(1 : i64) : i64
    %228 = llvm.alloca %227 x i32 : (i64) -> !llvm.ptr
    llvm.store %226, %228 : i32, !llvm.ptr
    cf.br ^bb27
    ^bb27:
    %229 = llvm.load %228 : !llvm.ptr -> i32
    %230 = arith.cmpi slt, %229, %arg1 : i32
    cf.cond_br %230, ^bb28, ^bb29
    ^bb28:
      %231 = llvm.load %225 : !llvm.ptr -> i32
      %233 = llvm.load %228 : !llvm.ptr -> i32
      %234 = arith.extsi %233 : i32 to i64
      %235 = llvm.getelementptr %arg0[%234] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %232 = llvm.load %235 : !llvm.ptr -> i32
      %236 = arith.addi %231, %232 : i32
      llvm.store %236, %225 : i32, !llvm.ptr
      %237 = llvm.load %228 : !llvm.ptr -> i32
      %238 = arith.constant 1 : i32
      %239 = arith.addi %237, %238 : i32
      llvm.store %239, %228 : i32, !llvm.ptr
      cf.br ^bb27
    ^bb29:
    %240 = llvm.load %225 : !llvm.ptr -> i32
    %241 = arith.cmpi slt, %240, %arg2 : i32
    cf.cond_br %241, ^bb30, ^bb31
    ^bb30:
      %242 = arith.constant 0 : i32
      %243 = arith.extsi %242 : i32 to i128
      func.return %243 : i128
    ^bb31:
      cf.br ^bb32
    ^bb32:
    %244 = arith.constant 1 : i32
    %245 = arith.cmpi eq, %arg1, %244 : i32
    %246 = scf.if %245 -> (i1) {
      %248 = arith.constant 0 : i32
      %249 = arith.extsi %248 : i32 to i64
      %250 = llvm.getelementptr %arg0[%249] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %247 = llvm.load %250 : !llvm.ptr -> i32
      %251 = arith.cmpi eq, %247, %arg2 : i32
      scf.yield %251 : i1
    } else {
      %252 = arith.constant false
      scf.yield %252 : i1
    }
    cf.cond_br %246, ^bb33, ^bb34
    ^bb33:
      %253 = arith.constant 1 : i32
      %254 = arith.extsi %253 : i32 to i128
      func.return %254 : i128
    ^bb34:
      cf.br ^bb35
    ^bb35:
    %256 = arith.constant 64 : i32
    %257 = arith.constant 1 : i32
    %258 = arith.extsi %256 : i32 to i64
    %259 = arith.extsi %257 : i32 to i64
    %255 = func.call @calloc(%258, %259) : (i64, i64) -> !llvm.ptr
    func.call @make_key(%255, %arg0, %arg1, %arg2) : (!llvm.ptr, !llvm.ptr, i32, i32) -> ()
    %262 = arith.constant 1 : i32
    %263 = arith.constant 16 : i32
    %264 = arith.extsi %262 : i32 to i64
    %265 = arith.extsi %263 : i32 to i64
    %261 = func.call @calloc(%264, %265) : (i64, i64) -> !llvm.ptr
    %266 = func.call @lookup(%255, %261) : (!llvm.ptr, !llvm.ptr) -> i32
    %267 = arith.constant 1 : i32
    %268 = arith.cmpi eq, %266, %267 : i32
    cf.cond_br %268, ^bb36, ^bb37
    ^bb36:
      %270 = arith.constant 0 : i32
      %271 = arith.extsi %270 : i32 to i64
      %272 = llvm.getelementptr %261[%271] : (!llvm.ptr, i64) -> !llvm.ptr, i128
      %269 = llvm.load %272 : !llvm.ptr -> i128
      func.call @free(%255) : (!llvm.ptr) -> ()
      func.call @free(%261) : (!llvm.ptr) -> ()
      func.return %269 : i128
    ^bb37:
      cf.br ^bb38
    ^bb38:
    func.call @free(%261) : (!llvm.ptr) -> ()
    %276 = arith.constant 0 : i32
    %277 = arith.extsi %276 : i32 to i128
    %278 = llvm.mlir.constant(1 : i64) : i64
    %279 = llvm.alloca %278 x i128 : (i64) -> !llvm.ptr
    llvm.store %277, %279 : i128, !llvm.ptr
    %281 = arith.constant 32 : i32
    %282 = arith.constant 4 : i32
    %283 = arith.extsi %281 : i32 to i64
    %284 = arith.extsi %282 : i32 to i64
    %280 = func.call @calloc(%283, %284) : (i64, i64) -> !llvm.ptr
    %285 = arith.constant 0 : i32
    %286 = llvm.mlir.constant(1 : i64) : i64
    %287 = llvm.alloca %286 x i32 : (i64) -> !llvm.ptr
    llvm.store %285, %287 : i32, !llvm.ptr
    cf.br ^bb39
    ^bb39:
    %288 = llvm.load %287 : !llvm.ptr -> i32
    %289 = arith.cmpi slt, %288, %arg1 : i32
    cf.cond_br %289, ^bb40, ^bb41
    ^bb40:
      %290 = llvm.load %287 : !llvm.ptr -> i32
      %291 = arith.constant 1 : i32
      %292 = arith.subi %arg1, %291 : i32
      %293 = arith.cmpi eq, %290, %292 : i32
      %294 = scf.if %293 -> (i32) {
        %295 = arith.constant 1 : i32
        scf.yield %295 : i32
      } else {
        %297 = llvm.load %287 : !llvm.ptr -> i32
        %298 = arith.constant 1 : i32
        %299 = arith.addi %297, %298 : i32
        %300 = arith.extsi %299 : i32 to i64
        %301 = llvm.getelementptr %arg0[%300] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %296 = llvm.load %301 : !llvm.ptr -> i32
        %303 = llvm.load %287 : !llvm.ptr -> i32
        %304 = arith.extsi %303 : i32 to i64
        %305 = llvm.getelementptr %arg0[%304] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %302 = llvm.load %305 : !llvm.ptr -> i32
        %306 = arith.cmpi slt, %296, %302 : i32
        %307 = scf.if %306 -> (i32) {
          %308 = arith.constant 1 : i32
          scf.yield %308 : i32
        } else {
          %309 = arith.constant 0 : i32
          scf.yield %309 : i32
        }
        scf.yield %307 : i32
      }
      %310 = arith.constant 1 : i32
      %311 = arith.cmpi eq, %294, %310 : i32
      cf.cond_br %311, ^bb42, ^bb43
      ^bb42:
        %312 = llvm.mlir.constant(1 : i64) : i64
        %313 = llvm.alloca %312 x i32 : (i64) -> !llvm.ptr
        llvm.store %arg1, %313 : i32, !llvm.ptr
        %314 = arith.constant 0 : i32
        %315 = llvm.mlir.constant(1 : i64) : i64
        %316 = llvm.alloca %315 x i32 : (i64) -> !llvm.ptr
        llvm.store %314, %316 : i32, !llvm.ptr
        cf.br ^bb45
        ^bb45:
        %317 = llvm.load %316 : !llvm.ptr -> i32
        %318 = arith.cmpi slt, %317, %arg1 : i32
        cf.cond_br %318, ^bb46, ^bb47
        ^bb46:
          %320 = llvm.load %316 : !llvm.ptr -> i32
          %321 = arith.extsi %320 : i32 to i64
          %322 = llvm.getelementptr %arg0[%321] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %319 = llvm.load %322 : !llvm.ptr -> i32
          %323 = llvm.load %316 : !llvm.ptr -> i32
          %324 = arith.extsi %323 : i32 to i64
          %325 = llvm.getelementptr %280[%324] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %319, %325 : i32, !llvm.ptr
          %326 = llvm.load %316 : !llvm.ptr -> i32
          %327 = arith.constant 1 : i32
          %328 = arith.addi %326, %327 : i32
          llvm.store %328, %316 : i32, !llvm.ptr
          cf.br ^bb45
        ^bb47:
        %330 = llvm.load %287 : !llvm.ptr -> i32
        %331 = arith.extsi %330 : i32 to i64
        %332 = llvm.getelementptr %280[%331] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %329 = llvm.load %332 : !llvm.ptr -> i32
        %333 = arith.constant 1 : i32
        %334 = arith.subi %329, %333 : i32
        %335 = llvm.load %287 : !llvm.ptr -> i32
        %336 = arith.extsi %335 : i32 to i64
        %337 = llvm.getelementptr %280[%336] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %334, %337 : i32, !llvm.ptr
        %339 = llvm.load %287 : !llvm.ptr -> i32
        %340 = arith.extsi %339 : i32 to i64
        %341 = llvm.getelementptr %280[%340] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %338 = llvm.load %341 : !llvm.ptr -> i32
        %342 = arith.constant 0 : i32
        %343 = arith.cmpi eq, %338, %342 : i32
        cf.cond_br %343, ^bb48, ^bb49
        ^bb48:
          %344 = llvm.load %287 : !llvm.ptr -> i32
          %345 = llvm.mlir.constant(1 : i64) : i64
          %346 = llvm.alloca %345 x i32 : (i64) -> !llvm.ptr
          llvm.store %344, %346 : i32, !llvm.ptr
          cf.br ^bb51
          ^bb51:
          %347 = llvm.load %346 : !llvm.ptr -> i32
          %348 = llvm.load %313 : !llvm.ptr -> i32
          %349 = arith.constant 1 : i32
          %350 = arith.subi %348, %349 : i32
          %351 = arith.cmpi slt, %347, %350 : i32
          cf.cond_br %351, ^bb52, ^bb53
          ^bb52:
            %353 = llvm.load %346 : !llvm.ptr -> i32
            %354 = arith.constant 1 : i32
            %355 = arith.addi %353, %354 : i32
            %356 = arith.extsi %355 : i32 to i64
            %357 = llvm.getelementptr %280[%356] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            %352 = llvm.load %357 : !llvm.ptr -> i32
            %358 = llvm.load %346 : !llvm.ptr -> i32
            %359 = arith.extsi %358 : i32 to i64
            %360 = llvm.getelementptr %280[%359] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            llvm.store %352, %360 : i32, !llvm.ptr
            %361 = llvm.load %346 : !llvm.ptr -> i32
            %362 = arith.constant 1 : i32
            %363 = arith.addi %361, %362 : i32
            llvm.store %363, %346 : i32, !llvm.ptr
            cf.br ^bb51
          ^bb53:
          %364 = llvm.load %313 : !llvm.ptr -> i32
          %365 = arith.constant 1 : i32
          %366 = arith.subi %364, %365 : i32
          llvm.store %366, %313 : i32, !llvm.ptr
          cf.br ^bb50
        ^bb49:
          cf.br ^bb50
        ^bb50:
        %367 = llvm.load %313 : !llvm.ptr -> i32
        %368 = arith.constant 0 : i32
        %369 = arith.cmpi eq, %367, %368 : i32
        cf.cond_br %369, ^bb54, ^bb55
        ^bb54:
          %370 = llvm.load %287 : !llvm.ptr -> i32
          %371 = arith.constant 1 : i32
          %372 = arith.addi %370, %371 : i32
          llvm.store %372, %287 : i32, !llvm.ptr
          cf.br ^bb39
        ^bb55:
          cf.br ^bb56
        ^bb56:
        %374 = arith.constant 0 : i32
        %375 = arith.extsi %374 : i32 to i64
        %376 = llvm.getelementptr %280[%375] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %373 = llvm.load %376 : !llvm.ptr -> i32
        %377 = arith.cmpi slt, %373, %arg2 : i32
        cf.cond_br %377, ^bb57, ^bb58
        ^bb57:
          %378 = llvm.load %287 : !llvm.ptr -> i32
          %379 = arith.constant 1 : i32
          %380 = arith.addi %378, %379 : i32
          llvm.store %380, %287 : i32, !llvm.ptr
          cf.br ^bb39
        ^bb58:
          cf.br ^bb59
        ^bb59:
        %381 = llvm.load %279 : !llvm.ptr -> i128
        %383 = llvm.load %313 : !llvm.ptr -> i32
        %382 = func.call @count_paths(%280, %383, %arg2) : (!llvm.ptr, i32, i32) -> i128
        %385 = arith.trunci %381 : i128 to i64
        %386 = arith.trunci %382 : i128 to i64
        %384 = arith.addi %385, %386 : i64
        %387 = arith.extsi %384 : i64 to i128
        llvm.store %387, %279 : i128, !llvm.ptr
        cf.br ^bb44
      ^bb43:
        cf.br ^bb44
      ^bb44:
      %388 = llvm.load %287 : !llvm.ptr -> i32
      %389 = arith.constant 1 : i32
      %390 = arith.addi %388, %389 : i32
      llvm.store %390, %287 : i32, !llvm.ptr
      cf.br ^bb39
    ^bb41:
    func.call @free(%280) : (!llvm.ptr) -> ()
    %393 = llvm.load %279 : !llvm.ptr -> i128
    func.call @insert(%255, %393) : (!llvm.ptr, i128) -> ()
    func.call @free(%255) : (!llvm.ptr) -> ()
    %395 = llvm.load %279 : !llvm.ptr -> i128
    func.return %395 : i128
  }
  func.func @binom(%arg0: i32, %arg1: i32) -> i128 {
    %396 = arith.constant 0 : i32
    %397 = arith.cmpi slt, %arg1, %396 : i32
    %398 = scf.if %397 -> (i1) {
      %399 = arith.constant true
      scf.yield %399 : i1
    } else {
      %400 = arith.cmpi sgt, %arg1, %arg0 : i32
      scf.yield %400 : i1
    }
    cf.cond_br %398, ^bb60, ^bb61
    ^bb60:
      %401 = arith.constant 0 : i32
      %402 = arith.extsi %401 : i32 to i128
      func.return %402 : i128
    ^bb61:
      cf.br ^bb62
    ^bb62:
    %403 = arith.constant 0 : i32
    %404 = arith.cmpi eq, %arg1, %403 : i32
    %405 = scf.if %404 -> (i1) {
      %406 = arith.constant true
      scf.yield %406 : i1
    } else {
      %407 = arith.cmpi eq, %arg1, %arg0 : i32
      scf.yield %407 : i1
    }
    cf.cond_br %405, ^bb63, ^bb64
    ^bb63:
      %408 = arith.constant 1 : i32
      %409 = arith.extsi %408 : i32 to i128
      func.return %409 : i128
    ^bb64:
      cf.br ^bb65
    ^bb65:
    %410 = arith.subi %arg0, %arg1 : i32
    %411 = arith.cmpi sgt, %arg1, %410 : i32
    %412 = scf.if %411 -> (i32) {
      %413 = arith.subi %arg0, %arg1 : i32
      scf.yield %413 : i32
    } else {
      scf.yield %arg1 : i32
    }
    %414 = arith.constant 1 : i32
    %415 = arith.extsi %414 : i32 to i128
    %416 = llvm.mlir.constant(1 : i64) : i64
    %417 = llvm.alloca %416 x i128 : (i64) -> !llvm.ptr
    llvm.store %415, %417 : i128, !llvm.ptr
    %418 = arith.constant 0 : i32
    %419 = llvm.mlir.constant(1 : i64) : i64
    %420 = llvm.alloca %419 x i32 : (i64) -> !llvm.ptr
    llvm.store %418, %420 : i32, !llvm.ptr
    cf.br ^bb66
    ^bb66:
    %421 = llvm.load %420 : !llvm.ptr -> i32
    %422 = arith.cmpi slt, %421, %412 : i32
    cf.cond_br %422, ^bb67, ^bb68
    ^bb67:
      %423 = llvm.load %417 : !llvm.ptr -> i128
      %424 = llvm.load %420 : !llvm.ptr -> i32
      %425 = arith.subi %arg0, %424 : i32
      %426 = arith.extsi %425 : i32 to i128
      %428 = arith.trunci %423 : i128 to i64
      %429 = arith.trunci %426 : i128 to i64
      %427 = arith.muli %428, %429 : i64
      %430 = llvm.load %420 : !llvm.ptr -> i32
      %431 = arith.constant 1 : i32
      %432 = arith.addi %430, %431 : i32
      %433 = arith.extsi %432 : i32 to i128
      %435 = arith.trunci %433 : i128 to i64
      %434 = arith.divsi %427, %435 : i64
      %436 = arith.extsi %434 : i64 to i128
      llvm.store %436, %417 : i128, !llvm.ptr
      %437 = llvm.load %420 : !llvm.ptr -> i32
      %438 = arith.constant 1 : i32
      %439 = arith.addi %437, %438 : i32
      llvm.store %439, %420 : i32, !llvm.ptr
      cf.br ^bb66
    ^bb68:
    %440 = llvm.load %417 : !llvm.ptr -> i128
    func.return %440 : i128
  }
  func.func @gcd128(%arg0: i128, %arg1: i128) -> i128 {
    %441 = llvm.mlir.constant(1 : i64) : i64
    %442 = llvm.alloca %441 x i128 : (i64) -> !llvm.ptr
    llvm.store %arg0, %442 : i128, !llvm.ptr
    %443 = llvm.load %442 : !llvm.ptr -> i128
    %444 = arith.constant 0 : i32
    %446 = arith.trunci %443 : i128 to i64
    %447 = arith.extsi %444 : i32 to i64
    %445 = arith.cmpi slt, %446, %447 : i64
    cf.cond_br %445, ^bb69, ^bb70
    ^bb69:
      %448 = arith.constant 0 : i32
      %449 = llvm.load %442 : !llvm.ptr -> i128
      %451 = arith.extsi %448 : i32 to i64
      %452 = arith.trunci %449 : i128 to i64
      %450 = arith.subi %451, %452 : i64
      %453 = arith.extsi %450 : i64 to i128
      llvm.store %453, %442 : i128, !llvm.ptr
      cf.br ^bb71
    ^bb70:
      cf.br ^bb71
    ^bb71:
    %454 = llvm.mlir.constant(1 : i64) : i64
    %455 = llvm.alloca %454 x i128 : (i64) -> !llvm.ptr
    llvm.store %arg1, %455 : i128, !llvm.ptr
    %456 = llvm.load %455 : !llvm.ptr -> i128
    %457 = arith.constant 0 : i32
    %459 = arith.trunci %456 : i128 to i64
    %460 = arith.extsi %457 : i32 to i64
    %458 = arith.cmpi slt, %459, %460 : i64
    cf.cond_br %458, ^bb72, ^bb73
    ^bb72:
      %461 = arith.constant 0 : i32
      %462 = llvm.load %455 : !llvm.ptr -> i128
      %464 = arith.extsi %461 : i32 to i64
      %465 = arith.trunci %462 : i128 to i64
      %463 = arith.subi %464, %465 : i64
      %466 = arith.extsi %463 : i64 to i128
      llvm.store %466, %455 : i128, !llvm.ptr
      cf.br ^bb74
    ^bb73:
      cf.br ^bb74
    ^bb74:
    cf.br ^bb75
    ^bb75:
    %467 = llvm.load %455 : !llvm.ptr -> i128
    %468 = arith.constant 0 : i32
    %470 = arith.trunci %467 : i128 to i64
    %471 = arith.extsi %468 : i32 to i64
    %469 = arith.cmpi ne, %470, %471 : i64
    cf.cond_br %469, ^bb76, ^bb77
    ^bb76:
      %472 = llvm.load %442 : !llvm.ptr -> i128
      %473 = llvm.load %455 : !llvm.ptr -> i128
      %475 = arith.trunci %472 : i128 to i64
      %476 = arith.trunci %473 : i128 to i64
      %474 = arith.remsi %475, %476 : i64
      %477 = arith.extsi %474 : i64 to i128
      %478 = llvm.load %455 : !llvm.ptr -> i128
      llvm.store %478, %442 : i128, !llvm.ptr
      llvm.store %477, %455 : i128, !llvm.ptr
      cf.br ^bb75
    ^bb77:
    %479 = llvm.load %442 : !llvm.ptr -> i128
    func.return %479 : i128
  }
  func.func @i128_to_f64(%arg0: i128) -> f64 {
    %480 = arith.constant 0 : i32
    %482 = arith.trunci %arg0 : i128 to i64
    %483 = arith.extsi %480 : i32 to i64
    %481 = arith.cmpi eq, %482, %483 : i64
    cf.cond_br %481, ^bb78, ^bb79
    ^bb78:
      %484 = arith.constant 0.0 : f32
      %485 = arith.extf %484 : f32 to f64
      func.return %485 : f64
    ^bb79:
      cf.br ^bb80
    ^bb80:
    %486 = arith.constant 0 : i32
    %487 = llvm.mlir.constant(1 : i64) : i64
    %488 = llvm.alloca %487 x i128 : (i64) -> !llvm.ptr
    llvm.store %arg0, %488 : i128, !llvm.ptr
    %489 = llvm.load %488 : !llvm.ptr -> i128
    %490 = arith.constant 0 : i32
    %492 = arith.trunci %489 : i128 to i64
    %493 = arith.extsi %490 : i32 to i64
    %491 = arith.cmpi slt, %492, %493 : i64
    %494 = scf.if %491 -> (i32) {
      %495 = arith.constant 1 : i32
      %496 = arith.constant 0 : i32
      %497 = llvm.load %488 : !llvm.ptr -> i128
      %499 = arith.extsi %496 : i32 to i64
      %500 = arith.trunci %497 : i128 to i64
      %498 = arith.subi %499, %500 : i64
      %501 = arith.extsi %498 : i64 to i128
      llvm.store %501, %488 : i128, !llvm.ptr
      scf.yield %495 : i32
    } else {
      scf.yield %486 : i32
    }
    %502 = llvm.load %488 : !llvm.ptr -> i128
    %503 = arith.trunci %502 : i128 to i64
    %504 = llvm.load %488 : !llvm.ptr -> i128
    %505 = arith.constant 64 : i32
    %507 = arith.trunci %504 : i128 to i64
    %508 = arith.extsi %505 : i32 to i64
    %506 = arith.shrsi %507, %508 : i64
    %509 = arith.constant 0.0 : f32
    %510 = arith.extf %509 : f32 to f64
    %511 = llvm.mlir.constant(1 : i64) : i64
    %512 = llvm.alloca %511 x f64 : (i64) -> !llvm.ptr
    llvm.store %510, %512 : f64, !llvm.ptr
    %513 = arith.constant 0 : i32
    %515 = arith.extsi %513 : i32 to i64
    %514 = arith.cmpi ne, %506, %515 : i64
    cf.cond_br %514, ^bb81, ^bb82
    ^bb81:
      %516 = arith.sitofp %506 : i64 to f64
      %517 = arith.constant 18446744073709551616.0 : f32
      %519 = arith.extf %517 : f32 to f64
      %518 = arith.mulf %516, %519 : f64
      %520 = arith.sitofp %503 : i64 to f64
      %521 = arith.addf %518, %520 : f64
      llvm.store %521, %512 : f64, !llvm.ptr
      cf.br ^bb83
    ^bb82:
      %522 = arith.sitofp %503 : i64 to f64
      llvm.store %522, %512 : f64, !llvm.ptr
      cf.br ^bb83
    ^bb83:
    %523 = arith.constant 1 : i32
    %524 = arith.cmpi eq, %494, %523 : i32
    cf.cond_br %524, ^bb84, ^bb85
    ^bb84:
      %525 = arith.constant 0 : i32
      %526 = llvm.load %512 : !llvm.ptr -> f64
      %528 = arith.sitofp %525 : i32 to f64
      %527 = arith.subf %528, %526 : f64
      llvm.store %527, %512 : f64, !llvm.ptr
      cf.br ^bb86
    ^bb85:
      cf.br ^bb86
    ^bb86:
    %529 = llvm.load %512 : !llvm.ptr -> f64
    func.return %529 : f64
  }
  func.func @main() -> i32 {
    func.call @init_globals() : () -> ()
    %531 = arith.constant 0 : i32
    %532 = arith.extsi %531 : i32 to i128
    %533 = llvm.mlir.constant(1 : i64) : i64
    %534 = llvm.alloca %533 x i128 : (i64) -> !llvm.ptr
    llvm.store %532, %534 : i128, !llvm.ptr
    %535 = arith.constant 1 : i32
    %536 = arith.extsi %535 : i32 to i128
    %537 = llvm.mlir.constant(1 : i64) : i64
    %538 = llvm.alloca %537 x i128 : (i64) -> !llvm.ptr
    llvm.store %536, %538 : i128, !llvm.ptr
    %539 = arith.constant 0 : i32
    %540 = llvm.mlir.constant(1 : i64) : i64
    %541 = llvm.alloca %540 x i32 : (i64) -> !llvm.ptr
    llvm.store %539, %541 : i32, !llvm.ptr
    cf.br ^bb87
    ^bb87:
    %542 = llvm.load %541 : !llvm.ptr -> i32
    %543 = llvm.mlir.addressof @N : !llvm.ptr
    %544 = llvm.load %543 : !llvm.ptr -> i32
    %545 = arith.cmpi slt, %542, %544 : i32
    cf.cond_br %545, ^bb88, ^bb89
    ^bb88:
      %547 = arith.constant 32 : i32
      %548 = arith.constant 4 : i32
      %549 = arith.extsi %547 : i32 to i64
      %550 = arith.extsi %548 : i32 to i64
      %546 = func.call @calloc(%549, %550) : (i64, i64) -> !llvm.ptr
      %551 = arith.constant 0 : i32
      %552 = llvm.load %541 : !llvm.ptr -> i32
      %553 = arith.constant 0 : i32
      %554 = arith.cmpi eq, %552, %553 : i32
      cf.cond_br %554, ^bb90, ^bb91
      ^bb90:
        %555 = llvm.mlir.addressof @N : !llvm.ptr
        %556 = llvm.load %555 : !llvm.ptr -> i32
        %557 = arith.constant 0 : i32
        %558 = arith.extsi %557 : i32 to i64
        %559 = llvm.getelementptr %546[%558] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %556, %559 : i32, !llvm.ptr
        %560 = arith.constant 1 : i32
        cf.br ^bb92(%560 : i32)
      ^bb91:
        %561 = llvm.mlir.addressof @N : !llvm.ptr
        %562 = llvm.load %561 : !llvm.ptr -> i32
        %563 = llvm.load %541 : !llvm.ptr -> i32
        %564 = arith.subi %562, %563 : i32
        %565 = arith.constant 0 : i32
        %566 = arith.extsi %565 : i32 to i64
        %567 = llvm.getelementptr %546[%566] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %564, %567 : i32, !llvm.ptr
        %568 = arith.constant 1 : i32
        %569 = llvm.mlir.constant(1 : i64) : i64
        %570 = llvm.alloca %569 x i32 : (i64) -> !llvm.ptr
        llvm.store %568, %570 : i32, !llvm.ptr
        cf.br ^bb93
        ^bb93:
        %571 = llvm.load %570 : !llvm.ptr -> i32
        %572 = llvm.load %541 : !llvm.ptr -> i32
        %573 = arith.cmpi sle, %571, %572 : i32
        cf.cond_br %573, ^bb94, ^bb95
        ^bb94:
          %574 = arith.constant 1 : i32
          %575 = llvm.load %570 : !llvm.ptr -> i32
          %576 = arith.extsi %575 : i32 to i64
          %577 = llvm.getelementptr %546[%576] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %574, %577 : i32, !llvm.ptr
          %578 = llvm.load %570 : !llvm.ptr -> i32
          %579 = arith.constant 1 : i32
          %580 = arith.addi %578, %579 : i32
          llvm.store %580, %570 : i32, !llvm.ptr
          cf.br ^bb93
        ^bb95:
        %581 = llvm.load %541 : !llvm.ptr -> i32
        %582 = arith.constant 1 : i32
        %583 = arith.addi %581, %582 : i32
        cf.br ^bb92(%583 : i32)
      ^bb92(%584: i32):
      %585 = arith.constant 1 : i32
      %586 = arith.extsi %585 : i32 to i128
      %587 = llvm.mlir.constant(1 : i64) : i64
      %588 = llvm.alloca %587 x i128 : (i64) -> !llvm.ptr
      llvm.store %586, %588 : i128, !llvm.ptr
      %589 = arith.constant 0 : i32
      %590 = llvm.mlir.constant(1 : i64) : i64
      %591 = llvm.alloca %590 x i32 : (i64) -> !llvm.ptr
      llvm.store %589, %591 : i32, !llvm.ptr
      %592 = arith.constant 1 : i32
      %593 = llvm.mlir.constant(1 : i64) : i64
      %594 = llvm.alloca %593 x i32 : (i64) -> !llvm.ptr
      llvm.store %592, %594 : i32, !llvm.ptr
      cf.br ^bb96
      ^bb96:
      %595 = llvm.load %594 : !llvm.ptr -> i32
      %596 = llvm.mlir.addressof @K : !llvm.ptr
      %597 = llvm.load %596 : !llvm.ptr -> i32
      %598 = arith.cmpi sle, %595, %597 : i32
      cf.cond_br %598, ^bb97, ^bb98
      ^bb97:
        %600 = llvm.load %594 : !llvm.ptr -> i32
        %599 = func.call @count_paths(%546, %584, %600) : (!llvm.ptr, i32, i32) -> i128
        %601 = arith.constant 0 : i32
        %603 = arith.trunci %599 : i128 to i64
        %604 = arith.extsi %601 : i32 to i64
        %602 = arith.cmpi eq, %603, %604 : i64
        cf.cond_br %602, ^bb99, ^bb100
        ^bb99:
          %605 = arith.constant 1 : i32
          llvm.store %605, %591 : i32, !llvm.ptr
          cf.br ^bb98
        ^bb100:
          cf.br ^bb101
        ^bb101:
        %606 = llvm.load %588 : !llvm.ptr -> i128
        %608 = arith.trunci %606 : i128 to i64
        %609 = arith.trunci %599 : i128 to i64
        %607 = arith.muli %608, %609 : i64
        %610 = arith.extsi %607 : i64 to i128
        llvm.store %610, %588 : i128, !llvm.ptr
        %611 = llvm.load %594 : !llvm.ptr -> i32
        %612 = arith.constant 1 : i32
        %613 = arith.addi %611, %612 : i32
        llvm.store %613, %594 : i32, !llvm.ptr
        cf.br ^bb96
      ^bb98:
      func.call @free(%546) : (!llvm.ptr) -> ()
      %615 = llvm.load %591 : !llvm.ptr -> i32
      %616 = arith.constant 1 : i32
      %617 = arith.cmpi eq, %615, %616 : i32
      cf.cond_br %617, ^bb102, ^bb103
      ^bb102:
        %618 = llvm.load %541 : !llvm.ptr -> i32
        %619 = arith.constant 1 : i32
        %620 = arith.addi %618, %619 : i32
        llvm.store %620, %541 : i32, !llvm.ptr
        cf.br ^bb87
      ^bb103:
        cf.br ^bb104
      ^bb104:
      %622 = llvm.mlir.addressof @N : !llvm.ptr
      %623 = llvm.load %622 : !llvm.ptr -> i32
      %624 = arith.constant 1 : i32
      %625 = arith.subi %623, %624 : i32
      %626 = llvm.load %541 : !llvm.ptr -> i32
      %621 = func.call @binom(%625, %626) : (i32, i32) -> i128
      %627 = arith.constant 1 : i32
      %628 = arith.extsi %627 : i32 to i128
      %629 = llvm.mlir.constant(1 : i64) : i64
      %630 = llvm.alloca %629 x i128 : (i64) -> !llvm.ptr
      llvm.store %628, %630 : i128, !llvm.ptr
      %631 = arith.constant 0 : i32
      %632 = llvm.mlir.constant(1 : i64) : i64
      %633 = llvm.alloca %632 x i32 : (i64) -> !llvm.ptr
      llvm.store %631, %633 : i32, !llvm.ptr
      cf.br ^bb105
      ^bb105:
      %634 = llvm.load %633 : !llvm.ptr -> i32
      %635 = llvm.mlir.addressof @K : !llvm.ptr
      %636 = llvm.load %635 : !llvm.ptr -> i32
      %637 = arith.constant 1 : i32
      %638 = arith.subi %636, %637 : i32
      %639 = arith.cmpi slt, %634, %638 : i32
      cf.cond_br %639, ^bb106, ^bb107
      ^bb106:
        %640 = llvm.load %630 : !llvm.ptr -> i128
        %642 = arith.trunci %640 : i128 to i64
        %643 = arith.trunci %621 : i128 to i64
        %641 = arith.muli %642, %643 : i64
        %644 = arith.extsi %641 : i64 to i128
        llvm.store %644, %630 : i128, !llvm.ptr
        %645 = llvm.load %633 : !llvm.ptr -> i32
        %646 = arith.constant 1 : i32
        %647 = arith.addi %645, %646 : i32
        llvm.store %647, %633 : i32, !llvm.ptr
        cf.br ^bb105
      ^bb107:
      %648 = llvm.load %588 : !llvm.ptr -> i128
      %649 = llvm.mlir.constant(1 : i64) : i64
      %650 = llvm.alloca %649 x i128 : (i64) -> !llvm.ptr
      llvm.store %648, %650 : i128, !llvm.ptr
      %651 = llvm.load %541 : !llvm.ptr -> i32
      %652 = arith.constant 2 : i32
      %653 = arith.remsi %651, %652 : i32
      %654 = arith.constant 1 : i32
      %655 = arith.cmpi eq, %653, %654 : i32
      cf.cond_br %655, ^bb108, ^bb109
      ^bb108:
        %656 = arith.constant 0 : i32
        %657 = llvm.load %650 : !llvm.ptr -> i128
        %659 = arith.extsi %656 : i32 to i64
        %660 = arith.trunci %657 : i128 to i64
        %658 = arith.subi %659, %660 : i64
        %661 = arith.extsi %658 : i64 to i128
        llvm.store %661, %650 : i128, !llvm.ptr
        cf.br ^bb110
      ^bb109:
        cf.br ^bb110
      ^bb110:
      %662 = llvm.load %630 : !llvm.ptr -> i128
      %664 = llvm.load %650 : !llvm.ptr -> i128
      %663 = func.call @gcd128(%664, %662) : (i128, i128) -> i128
      %665 = llvm.mlir.constant(1 : i64) : i64
      %666 = llvm.alloca %665 x i128 : (i64) -> !llvm.ptr
      llvm.store %663, %666 : i128, !llvm.ptr
      %667 = llvm.load %666 : !llvm.ptr -> i128
      %668 = arith.constant 1 : i32
      %670 = arith.trunci %667 : i128 to i64
      %671 = arith.extsi %668 : i32 to i64
      %669 = arith.cmpi sgt, %670, %671 : i64
      %672 = scf.if %669 -> (i128) {
        %673 = llvm.load %650 : !llvm.ptr -> i128
        %674 = llvm.load %666 : !llvm.ptr -> i128
        %676 = arith.trunci %673 : i128 to i64
        %677 = arith.trunci %674 : i128 to i64
        %675 = arith.divsi %676, %677 : i64
        %678 = arith.extsi %675 : i64 to i128
        llvm.store %678, %650 : i128, !llvm.ptr
        %679 = llvm.load %666 : !llvm.ptr -> i128
        %681 = arith.trunci %662 : i128 to i64
        %682 = arith.trunci %679 : i128 to i64
        %680 = arith.divsi %681, %682 : i64
        %683 = arith.extsi %680 : i64 to i128
        scf.yield %683 : i128
      } else {
        scf.yield %662 : i128
      }
      %684 = llvm.load %534 : !llvm.ptr -> i128
      %686 = arith.trunci %684 : i128 to i64
      %687 = arith.trunci %672 : i128 to i64
      %685 = arith.muli %686, %687 : i64
      %688 = llvm.load %650 : !llvm.ptr -> i128
      %689 = llvm.load %538 : !llvm.ptr -> i128
      %691 = arith.trunci %688 : i128 to i64
      %692 = arith.trunci %689 : i128 to i64
      %690 = arith.muli %691, %692 : i64
      %693 = arith.addi %685, %690 : i64
      %694 = arith.extsi %693 : i64 to i128
      %695 = llvm.load %538 : !llvm.ptr -> i128
      %697 = arith.trunci %695 : i128 to i64
      %698 = arith.trunci %672 : i128 to i64
      %696 = arith.muli %697, %698 : i64
      %699 = arith.extsi %696 : i64 to i128
      llvm.store %694, %534 : i128, !llvm.ptr
      llvm.store %699, %538 : i128, !llvm.ptr
      %701 = llvm.load %534 : !llvm.ptr -> i128
      %702 = llvm.load %538 : !llvm.ptr -> i128
      %700 = func.call @gcd128(%701, %702) : (i128, i128) -> i128
      llvm.store %700, %666 : i128, !llvm.ptr
      %703 = llvm.load %666 : !llvm.ptr -> i128
      %704 = arith.constant 1 : i32
      %706 = arith.trunci %703 : i128 to i64
      %707 = arith.extsi %704 : i32 to i64
      %705 = arith.cmpi sgt, %706, %707 : i64
      cf.cond_br %705, ^bb111, ^bb112
      ^bb111:
        %708 = llvm.load %534 : !llvm.ptr -> i128
        %709 = llvm.load %666 : !llvm.ptr -> i128
        %711 = arith.trunci %708 : i128 to i64
        %712 = arith.trunci %709 : i128 to i64
        %710 = arith.divsi %711, %712 : i64
        %713 = arith.extsi %710 : i64 to i128
        llvm.store %713, %534 : i128, !llvm.ptr
        %714 = llvm.load %538 : !llvm.ptr -> i128
        %715 = llvm.load %666 : !llvm.ptr -> i128
        %717 = arith.trunci %714 : i128 to i64
        %718 = arith.trunci %715 : i128 to i64
        %716 = arith.divsi %717, %718 : i64
        %719 = arith.extsi %716 : i64 to i128
        llvm.store %719, %538 : i128, !llvm.ptr
        cf.br ^bb113
      ^bb112:
        cf.br ^bb113
      ^bb113:
      %720 = llvm.load %541 : !llvm.ptr -> i32
      %721 = arith.constant 1 : i32
      %722 = arith.addi %720, %721 : i32
      llvm.store %722, %541 : i32, !llvm.ptr
      cf.br ^bb87
    ^bb89:
    %723 = arith.constant 1 : i32
    %724 = arith.extsi %723 : i32 to i128
    %725 = llvm.mlir.constant(1 : i64) : i64
    %726 = llvm.alloca %725 x i128 : (i64) -> !llvm.ptr
    llvm.store %724, %726 : i128, !llvm.ptr
    %727 = arith.constant 2 : i32
    %728 = llvm.mlir.constant(1 : i64) : i64
    %729 = llvm.alloca %728 x i32 : (i64) -> !llvm.ptr
    llvm.store %727, %729 : i32, !llvm.ptr
    cf.br ^bb114
    ^bb114:
    %730 = llvm.load %729 : !llvm.ptr -> i32
    %731 = llvm.mlir.addressof @N : !llvm.ptr
    %732 = llvm.load %731 : !llvm.ptr -> i32
    %733 = arith.cmpi sle, %730, %732 : i32
    cf.cond_br %733, ^bb115, ^bb116
    ^bb115:
      %734 = llvm.load %726 : !llvm.ptr -> i128
      %735 = llvm.load %729 : !llvm.ptr -> i32
      %736 = arith.extsi %735 : i32 to i128
      %738 = arith.trunci %734 : i128 to i64
      %739 = arith.trunci %736 : i128 to i64
      %737 = arith.muli %738, %739 : i64
      %740 = arith.extsi %737 : i64 to i128
      llvm.store %740, %726 : i128, !llvm.ptr
      %741 = llvm.load %729 : !llvm.ptr -> i32
      %742 = arith.constant 1 : i32
      %743 = arith.addi %741, %742 : i32
      llvm.store %743, %729 : i32, !llvm.ptr
      cf.br ^bb114
    ^bb116:
    %744 = llvm.load %538 : !llvm.ptr -> i128
    %745 = llvm.load %726 : !llvm.ptr -> i128
    %747 = arith.trunci %744 : i128 to i64
    %748 = arith.trunci %745 : i128 to i64
    %746 = arith.muli %747, %748 : i64
    %749 = arith.extsi %746 : i64 to i128
    %751 = llvm.load %534 : !llvm.ptr -> i128
    %750 = func.call @gcd128(%751, %749) : (i128, i128) -> i128
    %752 = llvm.mlir.constant(1 : i64) : i64
    %753 = llvm.alloca %752 x i128 : (i64) -> !llvm.ptr
    llvm.store %750, %753 : i128, !llvm.ptr
    %754 = llvm.load %753 : !llvm.ptr -> i128
    %755 = arith.constant 1 : i32
    %757 = arith.trunci %754 : i128 to i64
    %758 = arith.extsi %755 : i32 to i64
    %756 = arith.cmpi sgt, %757, %758 : i64
    cf.cond_br %756, ^bb117, ^bb118
    ^bb117:
      %759 = llvm.load %534 : !llvm.ptr -> i128
      %760 = llvm.load %753 : !llvm.ptr -> i128
      %762 = arith.trunci %759 : i128 to i64
      %763 = arith.trunci %760 : i128 to i64
      %761 = arith.divsi %762, %763 : i64
      %764 = arith.extsi %761 : i64 to i128
      llvm.store %764, %534 : i128, !llvm.ptr
      cf.br ^bb119
    ^bb118:
      cf.br ^bb119
    ^bb119:
    %765 = llvm.mlir.constant(1 : i64) : i64
    %766 = llvm.alloca %765 x i128 : (i64) -> !llvm.ptr
    llvm.store %749, %766 : i128, !llvm.ptr
    %767 = llvm.load %753 : !llvm.ptr -> i128
    %768 = arith.constant 1 : i32
    %770 = arith.trunci %767 : i128 to i64
    %771 = arith.extsi %768 : i32 to i64
    %769 = arith.cmpi sgt, %770, %771 : i64
    cf.cond_br %769, ^bb120, ^bb121
    ^bb120:
      %772 = llvm.load %753 : !llvm.ptr -> i128
      %774 = arith.trunci %749 : i128 to i64
      %775 = arith.trunci %772 : i128 to i64
      %773 = arith.divsi %774, %775 : i64
      %776 = arith.extsi %773 : i64 to i128
      llvm.store %776, %766 : i128, !llvm.ptr
      cf.br ^bb122
    ^bb121:
      cf.br ^bb122
    ^bb122:
    %778 = llvm.load %534 : !llvm.ptr -> i128
    %777 = func.call @i128_to_f64(%778) : (i128) -> f64
    %780 = llvm.load %766 : !llvm.ptr -> i128
    %779 = func.call @i128_to_f64(%780) : (i128) -> f64
    %781 = arith.divf %777, %779 : f64
    %782 = llvm.mlir.addressof @str_0 : !llvm.ptr
    %783 = llvm.call @printf(%782, %781) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, f64) -> i32
    %784 = arith.constant 0 : i32
    func.return %784 : i32
  }
}