Problem 912

Where are the Odds — digit DP F(10^16) mod 10^9+7.

Answer674045136
Output674045136
StatusPASS
Native helperno
Runtime0 ms
Peak memory1104 KB
Time complexityO(n) (estimated)
Space complexityO(n^2) (estimated)

Performance comparison

MetricOur solutionBest known
Time complexityO(n)O(n * d * s)
Space complexityO(n^2)O(d * s)
ApproachFlow solutionDigit DP
VerdictUnknown

Flow source

# Project Euler 912
# Where are the Odds — digit DP F(10^16) mod 10^9+7.

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

const MOD: i64 = 1000000007

# Row layout (5 i128 = 80 bytes): count[3], then pack oc/os/os2 as i64 in trailing space.
# Simpler: parallel arrays.

let mut count0: ptr<i128> = null
let mut count1: ptr<i128> = null
let mut count2: ptr<i128> = null
let mut oc0: ptr<i64> = null
let mut oc1: ptr<i64> = null
let mut oc2: ptr<i64> = null
let mut os0: ptr<i64> = null
let mut os1: ptr<i64> = null
let mut os2a: ptr<i64> = null
let mut os20: ptr<i64> = null
let mut os21: ptr<i64> = null
let mut os22: ptr<i64> = null
let mut nrows: i64 = 0

function ensure(cap_needed: i64) -> void {
    # grow handled in build
}

function get_count(rem: i64, cons: i64) -> i128 {
    match cons {
        0 => { return count0[rem] }
        1 => { return count1[rem] }
        _ => { return count2[rem] }
    }
}

function get_oc(rem: i64, cons: i64) -> i64 {
    match cons {
        0 => { return oc0[rem] }
        1 => { return oc1[rem] }
        _ => { return oc2[rem] }
    }
}

function get_os(rem: i64, cons: i64) -> i64 {
    match cons {
        0 => { return os0[rem] }
        1 => { return os1[rem] }
        _ => { return os2a[rem] }
    }
}

function get_os2(rem: i64, cons: i64) -> i64 {
    match cons {
        0 => { return os20[rem] }
        1 => { return os21[rem] }
        _ => { return os22[rem] }
    }
}

function set_row(rem: i64, cons: i64, cnt: i128, oc: i64, os: i64, os2v: i64) -> void {
    match cons {
        0 => {
            count0[rem] = cnt
            oc0[rem] = oc
            os0[rem] = os
            os20[rem] = os2v
        }
        1 => {
            count1[rem] = cnt
            oc1[rem] = oc
            os1[rem] = os
            os21[rem] = os2v
        }
        _ => {
            count2[rem] = cnt
            oc2[rem] = oc
            os2a[rem] = os
            os22[rem] = os2v
        }
    }
}

function prefix(rem: i64, cons: i64, t: i128, oc_out: ptr<i64>, os_out: ptr<i64>, os2_out: ptr<i64>) -> void {
    if t <= (0 as i128) {
        oc_out[0] = 0
        os_out[0] = 0
        os2_out[0] = 0
        return
    }
    let total: i128 = get_count(rem, cons)
    if t >= total {
        oc_out[0] = get_oc(rem, cons)
        os_out[0] = get_os(rem, cons)
        os2_out[0] = get_os2(rem, cons)
        return
    }
    if rem == 0 {
        if cons > 0 {
            oc_out[0] = 1
            os_out[0] = 1
            os2_out[0] = 1
        } else {
            oc_out[0] = 0
            os_out[0] = 0
            os2_out[0] = 0
        }
        return
    }
    let c0: i128 = get_count(rem - 1, 0)
    if t <= c0 {
        prefix(rem - 1, 0, t, oc_out, os_out, os2_out)
        return
    }
    let oc0v: i64 = get_oc(rem - 1, 0)
    let os0v: i64 = get_os(rem - 1, 0)
    let os20v: i64 = get_os2(rem - 1, 0)
    let mut oc1v: i64 = 0
    let mut os1v: i64 = 0
    let mut os21v: i64 = 0
    prefix(rem - 1, cons + 1, t - c0, &oc1v, &os1v, &os21v)
    let c0m: i64 = (c0 % (MOD as i128)) as i64
    oc_out[0] = (oc0v + oc1v) % MOD
    os_out[0] = (os0v + os1v + oc1v * c0m) % MOD
    os2_out[0] = (os20v + os21v + (2 * c0m % MOD) * os1v + oc1v * ((c0m * c0m) % MOD)) % MOD
}

function build_until(need: i128) -> void {
    let mut cap: i64 = 128
    count0 = calloc(cap, 16)
    count1 = calloc(cap, 16)
    count2 = calloc(cap, 16)
    oc0 = calloc(cap, 8)
    oc1 = calloc(cap, 8)
    oc2 = calloc(cap, 8)
    os0 = calloc(cap, 8)
    os1 = calloc(cap, 8)
    os2a = calloc(cap, 8)
    os20 = calloc(cap, 8)
    os21 = calloc(cap, 8)
    os22 = calloc(cap, 8)
    set_row(0, 0, 1 as i128, 0, 0, 0)
    set_row(0, 1, 1 as i128, 1, 1, 1)
    set_row(0, 2, 1 as i128, 1, 1, 1)
    nrows = 1
    let mut cum: i128 = 1
    while cum < need {
        if nrows + 1 >= cap {
            cap = cap * 2
            count0 = realloc(count0, cap * 16)
            count1 = realloc(count1, cap * 16)
            count2 = realloc(count2, cap * 16)
            oc0 = realloc(oc0, cap * 8)
            oc1 = realloc(oc1, cap * 8)
            oc2 = realloc(oc2, cap * 8)
            os0 = realloc(os0, cap * 8)
            os1 = realloc(os1, cap * 8)
            os2a = realloc(os2a, cap * 8)
            os20 = realloc(os20, cap * 8)
            os21 = realloc(os21, cap * 8)
            os22 = realloc(os22, cap * 8)
        }
        let prev: i64 = nrows - 1
        let c0: i128 = get_count(prev, 0)
        let c0m: i64 = (c0 % (MOD as i128)) as i64
        let mut cons: i64 = 0
        while cons < 3 {
            let oc0v: i64 = get_oc(prev, 0)
            let os0v: i64 = get_os(prev, 0)
            let os20v: i64 = get_os2(prev, 0)
            let mut count1v: i128 = 0
            let mut oc1v: i64 = 0
            let mut os1v: i64 = 0
            let mut os21v: i64 = 0
            if cons < 2 {
                count1v = get_count(prev, cons + 1)
                oc1v = get_oc(prev, cons + 1)
                os1v = get_os(prev, cons + 1)
                os21v = get_os2(prev, cons + 1)
            }
            let cnt: i128 = c0 + count1v
            let oc: i64 = (oc0v + oc1v) % MOD
            let os: i64 = (os0v + os1v + oc1v * c0m) % MOD
            let os2v: i64 = (os20v + os21v + (2 * c0m % MOD) * os1v + oc1v * ((c0m * c0m) % MOD)) % MOD
            set_row(nrows, cons, cnt, oc, os, os2v)
            cons = cons + 1
        }
        cum = cum + get_count(nrows, 1)
        nrows = nrows + 1
    }
}

function compute_F(N: i128) -> i64 {
    let mut ans: i64 = 0
    let mut prev: i128 = 0
    let mut remaining: i128 = N
    let mut rem: i64 = 0
    while rem < nrows && remaining > (0 as i128) {
        let block: i128 = get_count(rem, 1)
        let mut take: i128 = block
        if block > remaining { take = remaining }
        let mut oc: i64 = 0
        let mut os: i64 = 0
        let mut os2v: i64 = 0
        if take == block {
            oc = get_oc(rem, 1)
            os = get_os(rem, 1)
            os2v = get_os2(rem, 1)
        } else {
            prefix(rem, 1, take, &oc, &os, &os2v)
        }
        let prev_mod: i64 = (prev % (MOD as i128)) as i64
        ans = (ans + oc * ((prev_mod * prev_mod) % MOD) + (2 * prev_mod % MOD) * os + os2v) % MOD
        prev = prev + take
        remaining = remaining - take
        rem = rem + 1
    }
    return ans
}

function main() -> i32 {
    let N: i128 = 10000000000000000 as i128
    build_until(N)
    printf("%lld\n", compute_F(N))
    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 ensure_i64(int64_t cap_needed);
__int128 get_count_i64_i64(int64_t rem, int64_t cons);
int64_t get_oc_i64_i64(int64_t rem, int64_t cons);
int64_t get_os_i64_i64(int64_t rem, int64_t cons);
int64_t get_os2_i64_i64(int64_t rem, int64_t cons);
void set_row_i64_i64_i128_i64_i64_i64(int64_t rem, int64_t cons, __int128 cnt, int64_t oc, int64_t os, int64_t os2v);
void prefix_i64_i64_i128_ptr_i64_ptr_i64_ptr_i64(int64_t rem, int64_t cons, __int128 t, int64_t* oc_out, int64_t* os_out, int64_t* os2_out);
void build_until_i128(__int128 need);
int64_t compute_F_i128(__int128 N);
int32_t main(void);

static const int64_t MOD = 1000000007;

/* Module statics */
static __int128* count0 = NULL;
static __int128* count1 = NULL;
static __int128* count2 = NULL;
static int64_t* oc0 = NULL;
static int64_t* oc1 = NULL;
static int64_t* oc2 = NULL;
static int64_t* os0 = NULL;
static int64_t* os1 = NULL;
static int64_t* os2a = NULL;
static int64_t* os20 = NULL;
static int64_t* os21 = NULL;
static int64_t* os22 = NULL;
static int64_t nrows = 0;




void ensure_i64(int64_t cap_needed) {
}

__int128 get_count_i64_i64(int64_t rem, int64_t cons) {
    { // match block
        if ((cons) == 0) {
            return count0[rem];
        } else if ((cons) == 1) {
            return count1[rem];
        } else { // exhaustive
            return count2[rem];
        }
    } // end match
}

int64_t get_oc_i64_i64(int64_t rem, int64_t cons) {
    { // match block
        if ((cons) == 0) {
            return oc0[rem];
        } else if ((cons) == 1) {
            return oc1[rem];
        } else { // exhaustive
            return oc2[rem];
        }
    } // end match
}

int64_t get_os_i64_i64(int64_t rem, int64_t cons) {
    { // match block
        if ((cons) == 0) {
            return os0[rem];
        } else if ((cons) == 1) {
            return os1[rem];
        } else { // exhaustive
            return os2a[rem];
        }
    } // end match
}

int64_t get_os2_i64_i64(int64_t rem, int64_t cons) {
    { // match block
        if ((cons) == 0) {
            return os20[rem];
        } else if ((cons) == 1) {
            return os21[rem];
        } else { // exhaustive
            return os22[rem];
        }
    } // end match
}

void set_row_i64_i64_i128_i64_i64_i64(int64_t rem, int64_t cons, __int128 cnt, int64_t oc, int64_t os, int64_t os2v) {
    { // match block
        if ((cons) == 0) {
            count0[rem] = cnt;
            oc0[rem] = oc;
            os0[rem] = os;
            os20[rem] = os2v;
        } else if ((cons) == 1) {
            count1[rem] = cnt;
            oc1[rem] = oc;
            os1[rem] = os;
            os21[rem] = os2v;
        } else { // exhaustive
            count2[rem] = cnt;
            oc2[rem] = oc;
            os2a[rem] = os;
            os22[rem] = os2v;
        }
    } // end match
}

void prefix_i64_i64_i128_ptr_i64_ptr_i64_ptr_i64(int64_t rem, int64_t cons, __int128 t, int64_t* oc_out, int64_t* os_out, int64_t* os2_out) {
    if (t <= ((__int128)(0))) {
        oc_out[0] = 0;
        os_out[0] = 0;
        os2_out[0] = 0;
        return;
    }
    __int128 total = get_count_i64_i64(rem, cons);
    if (t >= total) {
        oc_out[0] = get_oc_i64_i64(rem, cons);
        os_out[0] = get_os_i64_i64(rem, cons);
        os2_out[0] = get_os2_i64_i64(rem, cons);
        return;
    }
    if (rem == 0) {
        if (cons > 0) {
            oc_out[0] = 1;
            os_out[0] = 1;
            os2_out[0] = 1;
        } else {
            oc_out[0] = 0;
            os_out[0] = 0;
            os2_out[0] = 0;
        }
        return;
    }
    __int128 c0 = get_count_i64_i64((rem - 1), 0);
    if (t <= c0) {
        prefix_i64_i64_i128_ptr_i64_ptr_i64_ptr_i64((rem - 1), 0, t, oc_out, os_out, os2_out);
        return;
    }
    int64_t oc0v = get_oc_i64_i64((rem - 1), 0);
    int64_t os0v = get_os_i64_i64((rem - 1), 0);
    int64_t os20v = get_os2_i64_i64((rem - 1), 0);
    int64_t oc1v = 0;
    int64_t os1v = 0;
    int64_t os21v = 0;
    prefix_i64_i64_i128_ptr_i64_ptr_i64_ptr_i64((rem - 1), (cons + 1), (t - c0), (&(oc1v)), (&(os1v)), (&(os21v)));
    int64_t c0m = ((int64_t)(FLOW_CHECKED_MOD((c0), (((__int128)(MOD))))));
    oc_out[0] = FLOW_CHECKED_MOD(((oc0v + oc1v)), (MOD));
    os_out[0] = FLOW_CHECKED_MOD((((os0v + os1v) + (oc1v * c0m))), (MOD));
    os2_out[0] = FLOW_CHECKED_MOD(((((os20v + os21v) + (FLOW_CHECKED_MOD(((2 * c0m)), (MOD)) * os1v)) + (oc1v * FLOW_CHECKED_MOD(((c0m * c0m)), (MOD))))), (MOD));
}

void build_until_i128(__int128 need) {
    int64_t cap = 128;
    count0 = calloc(cap, 16);
    count1 = calloc(cap, 16);
    count2 = calloc(cap, 16);
    oc0 = calloc(cap, 8);
    oc1 = calloc(cap, 8);
    oc2 = calloc(cap, 8);
    os0 = calloc(cap, 8);
    os1 = calloc(cap, 8);
    os2a = calloc(cap, 8);
    os20 = calloc(cap, 8);
    os21 = calloc(cap, 8);
    os22 = calloc(cap, 8);
    set_row_i64_i64_i128_i64_i64_i64(0, 0, ((__int128)(1)), 0, 0, 0);
    set_row_i64_i64_i128_i64_i64_i64(0, 1, ((__int128)(1)), 1, 1, 1);
    set_row_i64_i64_i128_i64_i64_i64(0, 2, ((__int128)(1)), 1, 1, 1);
    nrows = 1;
    __int128 cum = 1;
    while (cum < need) {
        if ((nrows + 1) >= cap) {
            cap = (cap * 2);
            count0 = realloc(count0, (cap * 16));
            count1 = realloc(count1, (cap * 16));
            count2 = realloc(count2, (cap * 16));
            oc0 = realloc(oc0, (cap * 8));
            oc1 = realloc(oc1, (cap * 8));
            oc2 = realloc(oc2, (cap * 8));
            os0 = realloc(os0, (cap * 8));
            os1 = realloc(os1, (cap * 8));
            os2a = realloc(os2a, (cap * 8));
            os20 = realloc(os20, (cap * 8));
            os21 = realloc(os21, (cap * 8));
            os22 = realloc(os22, (cap * 8));
        }
        int64_t prev = (nrows - 1);
        __int128 c0 = get_count_i64_i64(prev, 0);
        int64_t c0m = ((int64_t)(FLOW_CHECKED_MOD((c0), (((__int128)(MOD))))));
        int64_t cons = 0;
        while (cons < 3) {
            int64_t oc0v = get_oc_i64_i64(prev, 0);
            int64_t os0v = get_os_i64_i64(prev, 0);
            int64_t os20v = get_os2_i64_i64(prev, 0);
            __int128 count1v = 0;
            int64_t oc1v = 0;
            int64_t os1v = 0;
            int64_t os21v = 0;
            if (cons < 2) {
                count1v = get_count_i64_i64(prev, (cons + 1));
                oc1v = get_oc_i64_i64(prev, (cons + 1));
                os1v = get_os_i64_i64(prev, (cons + 1));
                os21v = get_os2_i64_i64(prev, (cons + 1));
            }
            __int128 cnt = (c0 + count1v);
            int64_t oc = FLOW_CHECKED_MOD(((oc0v + oc1v)), (MOD));
            int64_t os = FLOW_CHECKED_MOD((((os0v + os1v) + (oc1v * c0m))), (MOD));
            int64_t os2v = FLOW_CHECKED_MOD(((((os20v + os21v) + (FLOW_CHECKED_MOD(((2 * c0m)), (MOD)) * os1v)) + (oc1v * FLOW_CHECKED_MOD(((c0m * c0m)), (MOD))))), (MOD));
            set_row_i64_i64_i128_i64_i64_i64(nrows, cons, cnt, oc, os, os2v);
            cons = (cons + 1);
        }
        cum = (cum + get_count_i64_i64(nrows, 1));
        nrows = (nrows + 1);
    }
}

int64_t compute_F_i128(__int128 N) {
    int64_t ans = 0;
    __int128 prev = 0;
    __int128 remaining = N;
    int64_t rem = 0;
    while ((rem < nrows && remaining > ((__int128)(0)))) {
        __int128 block = get_count_i64_i64(rem, 1);
        __int128 take = block;
        if (block > remaining) {
            take = remaining;
        }
        int64_t oc = 0;
        int64_t os = 0;
        int64_t os2v = 0;
        if (take == block) {
            oc = get_oc_i64_i64(rem, 1);
            os = get_os_i64_i64(rem, 1);
            os2v = get_os2_i64_i64(rem, 1);
        } else {
            prefix_i64_i64_i128_ptr_i64_ptr_i64_ptr_i64(rem, 1, take, (&(oc)), (&(os)), (&(os2v)));
        }
        int64_t prev_mod = ((int64_t)(FLOW_CHECKED_MOD((prev), (((__int128)(MOD))))));
        ans = FLOW_CHECKED_MOD(((((ans + (oc * FLOW_CHECKED_MOD(((prev_mod * prev_mod)), (MOD)))) + (FLOW_CHECKED_MOD(((2 * prev_mod)), (MOD)) * os)) + os2v)), (MOD));
        prev = (prev + take);
        remaining = (remaining - take);
        rem = (rem + 1);
    }
    return ans;
}

int32_t main(void) {
    __int128 N = ((__int128)(10000000000000000));
    build_until_i128(N);
    printf("%lld\n", compute_F_i128(N));
    return 0;
}

Generated MLIR

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