Problem 908

Compute C(10^4) mod 1111211113. Port of the C reference solver: moduli generation, binomial coefficients, Mobius inversion.

Answer451822602
Output451822602
StatusPASS
Native helperno
Runtime5640 ms
Peak memory5728 KB
Time complexityO(n log n) (estimated)
Space complexityO(n^2) (estimated)

Performance comparison

MetricOur solutionBest known
Time complexityO(n log n)O(n log log n)
Space complexityO(n^2)O(n)
ApproachFlow solutionMobius sieve
VerdictSuboptimal

Flow source

# Project Euler 908: Clock Sequence II
# Compute C(10^4) mod 1111211113.
# Port of the C reference solver: moduli generation, binomial coefficients, Mobius inversion.

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

const MOD: i64 = 1111211113
const N: i64 = 10000

# Global pairs buffer for moduli generation
let mut pairs_buf: ptr<i64> = null
let mut pairs_count: i64 = 0
let mut pairs_cap: i64 = 0

# Options per prime: stored as flat arrays (all opts for all primes in one buffer)
# opt_all_m[prime_idx * 64 + oi], opt_all_k[prime_idx * 64 + oi]
let mut opt_all_m: ptr<i64> = null
let mut opt_all_k: ptr<i64> = null
let mut opt_counts: ptr<i32> = null

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

function add_pair(m: i64, k: i64) -> void {
    if pairs_count >= pairs_cap {
        let new_cap: i64 = 1024
        if pairs_cap > 0 {
            new_cap = pairs_cap * 2
        }
        let new_buf: ptr<i64> = calloc(new_cap * 2, 8)
        let mut i: i64 = 0
        while i < pairs_count {
            new_buf[i * 2] = pairs_buf[i * 2]
            new_buf[i * 2 + 1] = pairs_buf[i * 2 + 1]
            i = i + 1
        }
        if pairs_buf != null {
            free(pairs_buf)
        }
        pairs_buf = new_buf
        pairs_cap = new_cap
    }
    pairs_buf[pairs_count * 2] = m
    pairs_buf[pairs_count * 2 + 1] = k
    pairs_count = pairs_count + 1
}

# k(p^e)
function k_prime_power(p: i64, e: i64) -> i64 {
    if e <= 0 {
        return 1
    }
    if p == 2 {
        let mut result: i64 = 1
        let mut i: i64 = 0
        while i < e {
            result = result * 2
            i = i + 1
        }
        return result
    }
    let mut k: i64 = (p + 1) / 2
    let mut exp: i64 = 2
    while exp <= e {
        if (exp % 2) == 0 {
            k = p * k - (p - 1)
        } else {
            k = p * k - (p - 1) / 2
        }
        exp = exp + 1
    }
    return k
}

# DFS to generate all (m, k) pairs with k <= max_k
function dfs_moduli(start_idx: i64, num_primes: i64, primes: ptr<i64>,
                    m_cur: i64, k_cur: i64, max_k: i64) -> void {
    add_pair(m_cur, k_cur)
    let mut j: i64 = start_idx
    while j < num_primes {
        let p: i64 = primes[j]
        let oc: i32 = opt_counts[j]
        if oc == 0 {
            j = j + 1
            continue
        }
        # smallest k-factor for this prime
        if k_cur * opt_all_k[j * 64 + 0] > max_k {
            break
        }
        let mut oi: i64 = 0
        while oi < (oc as i64) {
            let mp: i64 = opt_all_m[j * 64 + oi]
            let kp: i64 = opt_all_k[j * 64 + oi]
            let k_new: i64 = k_cur * kp
            if k_new > max_k {
                break
            }
            let m_new: i128 = (m_cur as i128) * (mp as i128)
            dfs_moduli(j + 1, num_primes, primes, m_new as i64, k_new, max_k)
            oi = oi + 1
        }
        j = j + 1
    }
}

# Generate moduli (m, k(m)) with k(m) <= max_k
# Returns pairs in pairs_buf, count in pairs_count
function generate_moduli(max_k: i64) -> void {
    # Sieve primes up to 2*max_k
    let limit: i64 = 2 * max_k
    let is_comp: ptr<i8> = calloc(limit + 1, 1)
    let primes: ptr<i64> = calloc(limit + 1, 8)
    let mut pc: i64 = 0
    let mut p: i64 = 2
    while p <= limit {
        if is_comp[p] == 0 {
            primes[pc] = p
            pc = pc + 1
            let mut m: i64 = p * p
            while m <= limit {
                is_comp[m] = 1
                m = m + p
            }
        }
        p = p + 1
    }

    # Build options for each prime
    opt_all_m = calloc(pc * 64, 8)
    opt_all_k = calloc(pc * 64, 8)
    opt_counts = calloc(pc, 4)

    let mut j: i64 = 0
    while j < pc {
        let pr: i64 = primes[j]
        let mut oc: i64 = 0
        if pr == 2 {
            let mut m: i64 = 2
            let mut k: i64 = 2
            while k <= max_k {
                opt_all_m[j * 64 + oc] = m
                opt_all_k[j * 64 + oc] = k
                oc = oc + 1
                m = m * 2
                k = k * 2
            }
        } else {
            let mut m: i64 = pr
            let mut k: i64 = (pr + 1) / 2
            let mut e: i64 = 1
            while k <= max_k {
                opt_all_m[j * 64 + oc] = m
                opt_all_k[j * 64 + oc] = k
                oc = oc + 1
                e = e + 1
                m = m * pr
                if (e % 2) == 0 {
                    k = pr * k - (pr - 1)
                } else {
                    k = pr * k - (pr - 1) / 2
                }
            }
        }
        opt_counts[j] = oc as i32
        j = j + 1
    }

    pairs_buf = null
    pairs_count = 0
    pairs_cap = 0

    dfs_moduli(0, pc, primes, 1, 1, max_k)

    # Cleanup options
    free(opt_all_m)
    free(opt_all_k)
    free(opt_counts)
    free(primes)
    free(is_comp)
}

# Prepare modular inverses 1..n mod mod
function prepare_inverses(n: i64, mod: i64) -> ptr<i64> {
    let inv: ptr<i64> = calloc(n + 1, 8)
    inv[1] = 1
    let mut i: i64 = 2
    while i <= n {
        inv[i] = (mod - (mod / i) * inv[mod % i] % mod) % mod
        i = i + 1
    }
    return inv
}

# Compute B array
function compute_B(max_period: i64, mod: i64, B: ptr<i64>) -> void {
    generate_moduli(max_period)
    let inv: ptr<i64> = prepare_inverses(max_period, mod)

    let mut i: i64 = 0
    while i <= max_period {
        B[i] = 0
        i = i + 1
    }

    let mut idx: i64 = 0
    while idx < pairs_count {
        let m: i64 = pairs_buf[idx * 2]
        let k: i64 = pairs_buf[idx * 2 + 1]
        if k > max_period {
            idx = idx + 1
            continue
        }
        let n: i64 = m - k
        if n < 0 {
            idx = idx + 1
            continue
        }
        let mut rmax: i64 = max_period - k
        if rmax < 0 {
            idx = idx + 1
            continue
        }
        if n < rmax {
            rmax = n
        }

        # r = 0
        let idx0: i64 = k
        B[idx0] = B[idx0] + 1
        if B[idx0] >= mod {
            B[idx0] = B[idx0] - mod
        }

        let mut c: i64 = 1
        let mut r: i64 = 1
        while r <= rmax {
            c = ((c as i128) * (n - r + 1) % mod) as i64
            c = ((c as i128) * inv[r] % mod) as i64
            let bidx: i64 = idx0 + r
            B[bidx] = B[bidx] + c
            if B[bidx] >= mod {
                B[bidx] = B[bidx] - mod
            }
            r = r + 1
        }
        idx = idx + 1
    }

    free(inv)
    free(pairs_buf)
}

# Mobius via linear sieve
function mobius_upto(n: i64, mu: ptr<i8>) -> void {
    let mut i: i64 = 0
    while i <= n {
        mu[i] = 0
        i = i + 1
    }
    let primes: ptr<i64> = calloc(n + 1, 8)
    let is_comp: ptr<i8> = calloc(n + 1, 1)
    let mut pc: i64 = 0
    mu[1] = 1
    i = 2
    while i <= n {
        if is_comp[i] == 0 {
            primes[pc] = i
            pc = pc + 1
            mu[i] = (0 - 1) as i8
        }
        let mut j: i64 = 0
        while j < pc {
            let p: i64 = primes[j]
            let v: i64 = i * p
            if v > n {
                break
            }
            is_comp[v] = 1
            if (i % p) == 0 {
                mu[v] = 0
                break
            }
            mu[v] = (0 - (mu[i] as i32)) as i8
            j = j + 1
        }
        i = i + 1
    }
    free(primes)
    free(is_comp)
}

# Compute A from B via Mobius
function compute_A_from_B(B: ptr<i64>, mu: ptr<i8>, mod: i64, A: ptr<i64>, n: i64) -> void {
    let mut i: i64 = 0
    while i <= n {
        A[i] = 0
        i = i + 1
    }
    let mut d: i64 = 1
    while d <= n {
        let md: i8 = mu[d]
        if md == 0 {
            d = d + 1
            continue
        }
        if md == 1 {
            let mut q: i64 = 1
            while q <= n / d {
                let p: i64 = d * q
                A[p] = A[p] + B[q]
                if A[p] >= mod {
                    A[p] = A[p] - mod
                }
                q = q + 1
            }
        } else {
            let mut q: i64 = 1
            while q <= n / d {
                let p: i64 = d * q
                A[p] = A[p] - B[q]
                if A[p] < 0 {
                    A[p] = A[p] + mod
                }
                q = q + 1
            }
        }
        d = d + 1
    }
}

function main() -> i32 {
    let B: ptr<i64> = calloc(N + 1, 8)
    compute_B(N, MOD, B)

    let mu: ptr<i8> = calloc(N + 1, 1)
    mobius_upto(N, mu)

    let A: ptr<i64> = calloc(N + 1, 8)
    compute_A_from_B(B, mu, MOD, A, N)

    # Prefix sum
    let mut s: i64 = 0
    let mut i: i64 = 1
    while i <= N {
        s = s + A[i]
        s = s % MOD
        i = i + 1
    }

    printf("%lld\n", s % MOD)
    free(B)
    free(mu)
    free(A)
    return 0
}

Generated C

#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* Flow runtime helpers */
typedef struct flow_temp_node { struct flow_temp_node* next; } flow_temp_node;
static flow_temp_node* flow_temp_head = NULL;
static int flow_temp_atexit_set = 0;
__attribute__((unused)) static void flow_temp_free_all(void) {
    while (flow_temp_head) {
        flow_temp_node* n = flow_temp_head;
        flow_temp_head = n->next;
        free(n);
    }
}
__attribute__((unused)) static void* flow_temp_alloc(size_t nbytes) {
    flow_temp_node* node = (flow_temp_node*)malloc(sizeof(flow_temp_node) + nbytes);
    if (!node) return NULL;
    node->next = flow_temp_head;
    flow_temp_head = node;
    if (!flow_temp_atexit_set) {
        flow_temp_atexit_set = 1;
        atexit(flow_temp_free_all);
    }
    return (void*)(node + 1);
}
#ifndef FLOW_DIAG
#define FLOW_DIAG(msg) fprintf(stderr, "%s", (msg))
#endif
#ifndef FLOW_LOG
#define FLOW_LOG(fmt, ...) printf(fmt, __VA_ARGS__)
#endif
#ifndef FLOW_LOG_EMPTY
#define FLOW_LOG_EMPTY(fmt) printf(fmt)
#endif
static char* flow_strcat(const char* a, const char* b) {
    size_t la = strlen(a ? a : ""), lb = strlen(b ? b : "");
    char* r = (char*)flow_temp_alloc(la + lb + 1);
    if (!r) return NULL;
    if (la) memcpy(r, a, la);
    if (lb) memcpy(r + la, b, lb);
    r[la + lb] = '\0';
    return r;
}

#define __flow_in_arr(arr, val) __extension__ ({ \
    int _found = 0; \
    size_t _n = sizeof(arr)/sizeof((arr)[0]); \
    for (size_t _i = 0; _i < _n; _i++) { \
        if ((arr)[_i] == (val)) { _found = 1; break; } \
    } _found; })

/* Unified fault handler (MISRA #279) — override with -DFLOW_FAULT_HANDLER=fn */
#ifndef FLOW_FAULT_HANDLER
__attribute__((unused)) static inline void flow_fault_handler(const char* msg) {
    fprintf(stderr, "flow: %s\n", msg ? msg : "fault");
    abort();
#if defined(__GNUC__) || defined(__clang__)
    __builtin_unreachable();
#endif
}
#else
#define flow_fault_handler FLOW_FAULT_HANDLER
#endif
#define flow_div_by_zero_handler() flow_fault_handler("division by zero")
#define flow_shift_ub_handler() flow_fault_handler("invalid shift (amount out of range or left-shift of negative)")

#ifndef FLOW_CHECKED_DIV
#define FLOW_CHECKED_DIV(L, R) (((R) != 0) ? ((L) / (R)) : (flow_div_by_zero_handler(), (L) * 0))
#endif
#ifndef FLOW_CHECKED_MOD
#define FLOW_CHECKED_MOD(L, R) (((R) != 0) ? ((L) % (R)) : (flow_div_by_zero_handler(), (L) * 0))
#endif
#ifndef FLOW_CHECKED_SHL
#define FLOW_CHECKED_SHL(L, R) ((((R) >= 0) && ((unsigned long long)(R) < (sizeof(L) * 8ull)) && ((L) >= 0)) ? ((L) << (R)) : (flow_shift_ub_handler(), (L) * 0))
#endif
#ifndef FLOW_CHECKED_SHR
#define FLOW_CHECKED_SHR(L, R) ((((R) >= 0) && ((unsigned long long)(R) < (sizeof(L) * 8ull))) ? ((L) >> (R)) : (flow_shift_ub_handler(), (L) * 0))
#endif

#include <math.h>

void* _ui_state = NULL;

static inline float i32_to_f32(int32_t v) { return (float)v; }

/* Host stub for @gpu kernels (device codegen replaces this). */
static inline int32_t gpu_thread_id(void) { return 0; }

int64_t gcd64_i64_i64(int64_t a, int64_t b);
void add_pair_i64_i64(int64_t m, int64_t k);
int64_t k_prime_power_i64_i64(int64_t p, int64_t e);
void dfs_moduli_i64_i64_ptr_i64_i64_i64_i64(int64_t start_idx, int64_t num_primes, int64_t* primes, int64_t m_cur, int64_t k_cur, int64_t max_k);
void generate_moduli_i64(int64_t max_k);
int64_t* prepare_inverses_i64_i64(int64_t n, int64_t mod);
void compute_B_i64_i64_ptr_i64(int64_t max_period, int64_t mod, int64_t* B);
void mobius_upto_i64_ptr_i8(int64_t n, int8_t* mu);
void compute_A_from_B_ptr_i64_ptr_i8_i64_ptr_i64_i64(int64_t* B, int8_t* mu, int64_t mod, int64_t* A, int64_t n);
int32_t main(void);

static const int64_t MOD = 1111211113;
static const int64_t N = 10000;

/* Module statics */
static int64_t* pairs_buf = NULL;
static int64_t pairs_count = 0;
static int64_t pairs_cap = 0;
static int64_t* opt_all_m = NULL;
static int64_t* opt_all_k = NULL;
static int32_t* opt_counts = NULL;




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

void add_pair_i64_i64(int64_t m, int64_t k) {
    if (pairs_count >= pairs_cap) {
        int64_t new_cap = 1024;
        if (pairs_cap > 0) {
            new_cap = (pairs_cap * 2);
        }
        int64_t* new_buf = (int64_t*)(calloc((new_cap * 2), 8));
        int64_t i = 0;
        while (i < pairs_count) {
            new_buf[(i * 2)] = pairs_buf[(i * 2)];
            new_buf[((i * 2) + 1)] = pairs_buf[((i * 2) + 1)];
            i = (i + 1);
        }
        if (pairs_buf != NULL) {
            free(pairs_buf);
        }
        pairs_buf = new_buf;
        pairs_cap = new_cap;
    }
    pairs_buf[(pairs_count * 2)] = m;
    pairs_buf[((pairs_count * 2) + 1)] = k;
    pairs_count = (pairs_count + 1);
}

int64_t k_prime_power_i64_i64(int64_t p, int64_t e) {
    if (e <= 0) {
        return 1;
    }
    if (p == 2) {
        int64_t result = 1;
        int64_t i = 0;
        while (i < e) {
            result = (result * 2);
            i = (i + 1);
        }
        return result;
    }
    int64_t k = FLOW_CHECKED_DIV(((p + 1)), (2));
    int64_t exp = 2;
    while (exp <= e) {
        if (FLOW_CHECKED_MOD((exp), (2)) == 0) {
            k = ((p * k) - (p - 1));
        } else {
            k = ((p * k) - FLOW_CHECKED_DIV(((p - 1)), (2)));
        }
        exp = (exp + 1);
    }
    return k;
}

void dfs_moduli_i64_i64_ptr_i64_i64_i64_i64(int64_t start_idx, int64_t num_primes, int64_t* primes, int64_t m_cur, int64_t k_cur, int64_t max_k) {
    add_pair_i64_i64(m_cur, k_cur);
    int64_t j = start_idx;
    while (j < num_primes) {
        int64_t p = primes[j];
        int32_t oc = opt_counts[j];
        if (oc == 0) {
            j = (j + 1);
            continue;
        }
        if ((k_cur * opt_all_k[((j * 64) + 0)]) > max_k) {
            break;
        }
        int64_t oi = 0;
        while (oi < ((int64_t)(oc))) {
            int64_t mp = opt_all_m[((j * 64) + oi)];
            int64_t kp = opt_all_k[((j * 64) + oi)];
            int64_t k_new = (k_cur * kp);
            if (k_new > max_k) {
                break;
            }
            __int128 m_new = (((__int128)(m_cur)) * ((__int128)(mp)));
            dfs_moduli_i64_i64_ptr_i64_i64_i64_i64((j + 1), num_primes, primes, ((int64_t)(m_new)), k_new, max_k);
            oi = (oi + 1);
        }
        j = (j + 1);
    }
}

void generate_moduli_i64(int64_t max_k) {
    int64_t limit = (2 * max_k);
    int8_t* is_comp = (int8_t*)(calloc((limit + 1), 1));
    int64_t* primes = (int64_t*)(calloc((limit + 1), 8));
    int64_t pc = 0;
    int64_t p = 2;
    while (p <= limit) {
        if (is_comp[p] == 0) {
            primes[pc] = p;
            pc = (pc + 1);
            int64_t m = (p * p);
            while (m <= limit) {
                is_comp[m] = 1;
                m = (m + p);
            }
        }
        p = (p + 1);
    }
    opt_all_m = calloc((pc * 64), 8);
    opt_all_k = calloc((pc * 64), 8);
    opt_counts = calloc(pc, 4);
    int64_t j = 0;
    while (j < pc) {
        int64_t pr = primes[j];
        int64_t oc = 0;
        if (pr == 2) {
            int64_t m = 2;
            int64_t k = 2;
            while (k <= max_k) {
                opt_all_m[((j * 64) + oc)] = m;
                opt_all_k[((j * 64) + oc)] = k;
                oc = (oc + 1);
                m = (m * 2);
                k = (k * 2);
            }
        } else {
            int64_t m = pr;
            int64_t k = FLOW_CHECKED_DIV(((pr + 1)), (2));
            int64_t e = 1;
            while (k <= max_k) {
                opt_all_m[((j * 64) + oc)] = m;
                opt_all_k[((j * 64) + oc)] = k;
                oc = (oc + 1);
                e = (e + 1);
                m = (m * pr);
                if (FLOW_CHECKED_MOD((e), (2)) == 0) {
                    k = ((pr * k) - (pr - 1));
                } else {
                    k = ((pr * k) - FLOW_CHECKED_DIV(((pr - 1)), (2)));
                }
            }
        }
        opt_counts[j] = ((int32_t)(oc));
        j = (j + 1);
    }
    pairs_buf = NULL;
    pairs_count = 0;
    pairs_cap = 0;
    dfs_moduli_i64_i64_ptr_i64_i64_i64_i64(0, pc, primes, 1, 1, max_k);
    free(opt_all_m);
    free(opt_all_k);
    free(opt_counts);
    free(primes);
    free(is_comp);
}

int64_t* prepare_inverses_i64_i64(int64_t n, int64_t mod) {
    int64_t* inv = (int64_t*)(calloc((n + 1), 8));
    inv[1] = 1;
    int64_t i = 2;
    while (i <= n) {
        inv[i] = FLOW_CHECKED_MOD(((mod - FLOW_CHECKED_MOD(((FLOW_CHECKED_DIV((mod), (i)) * inv[FLOW_CHECKED_MOD((mod), (i))])), (mod)))), (mod));
        i = (i + 1);
    }
    return inv;
}

void compute_B_i64_i64_ptr_i64(int64_t max_period, int64_t mod, int64_t* B) {
    generate_moduli_i64(max_period);
    int64_t* inv = (int64_t*)(prepare_inverses_i64_i64(max_period, mod));
    int64_t i = 0;
    while (i <= max_period) {
        B[i] = 0;
        i = (i + 1);
    }
    int64_t idx = 0;
    while (idx < pairs_count) {
        int64_t m = pairs_buf[(idx * 2)];
        int64_t k = pairs_buf[((idx * 2) + 1)];
        if (k > max_period) {
            idx = (idx + 1);
            continue;
        }
        int64_t n = (m - k);
        if (n < 0) {
            idx = (idx + 1);
            continue;
        }
        int64_t rmax = (max_period - k);
        if (rmax < 0) {
            idx = (idx + 1);
            continue;
        }
        if (n < rmax) {
            rmax = n;
        }
        int64_t idx0 = k;
        B[idx0] = (B[idx0] + 1);
        if (B[idx0] >= mod) {
            B[idx0] = (B[idx0] - mod);
        }
        int64_t c = 1;
        int64_t r = 1;
        while (r <= rmax) {
            c = ((int64_t)(FLOW_CHECKED_MOD(((((__int128)(c)) * ((n - r) + 1))), (mod))));
            c = ((int64_t)(FLOW_CHECKED_MOD(((((__int128)(c)) * inv[r])), (mod))));
            int64_t bidx = (idx0 + r);
            B[bidx] = (B[bidx] + c);
            if (B[bidx] >= mod) {
                B[bidx] = (B[bidx] - mod);
            }
            r = (r + 1);
        }
        idx = (idx + 1);
    }
    free(inv);
    free(pairs_buf);
}

void mobius_upto_i64_ptr_i8(int64_t n, int8_t* mu) {
    int64_t i = 0;
    while (i <= n) {
        mu[i] = 0;
        i = (i + 1);
    }
    int64_t* primes = (int64_t*)(calloc((n + 1), 8));
    int8_t* is_comp = (int8_t*)(calloc((n + 1), 1));
    int64_t pc = 0;
    mu[1] = 1;
    i = 2;
    while (i <= n) {
        if (is_comp[i] == 0) {
            primes[pc] = i;
            pc = (pc + 1);
            mu[i] = ((int8_t)((0 - 1)));
        }
        int64_t j = 0;
        while (j < pc) {
            int64_t p = primes[j];
            int64_t v = (i * p);
            if (v > n) {
                break;
            }
            is_comp[v] = 1;
            if (FLOW_CHECKED_MOD((i), (p)) == 0) {
                mu[v] = 0;
                break;
            }
            mu[v] = ((int8_t)((0 - ((int32_t)(mu[i])))));
            j = (j + 1);
        }
        i = (i + 1);
    }
    free(primes);
    free(is_comp);
}

void compute_A_from_B_ptr_i64_ptr_i8_i64_ptr_i64_i64(int64_t* B, int8_t* mu, int64_t mod, int64_t* A, int64_t n) {
    int64_t i = 0;
    while (i <= n) {
        A[i] = 0;
        i = (i + 1);
    }
    int64_t d = 1;
    while (d <= n) {
        int8_t md = mu[d];
        if (md == 0) {
            d = (d + 1);
            continue;
        }
        if (md == 1) {
            int64_t q = 1;
            while (q <= FLOW_CHECKED_DIV((n), (d))) {
                int64_t p = (d * q);
                A[p] = (A[p] + B[q]);
                if (A[p] >= mod) {
                    A[p] = (A[p] - mod);
                }
                q = (q + 1);
            }
        } else {
            int64_t q = 1;
            while (q <= FLOW_CHECKED_DIV((n), (d))) {
                int64_t p = (d * q);
                A[p] = (A[p] - B[q]);
                if (A[p] < 0) {
                    A[p] = (A[p] + mod);
                }
                q = (q + 1);
            }
        }
        d = (d + 1);
    }
}

int32_t main(void) {
    int64_t* B = (int64_t*)(calloc((N + 1), 8));
    compute_B_i64_i64_ptr_i64(N, MOD, B);
    int8_t* mu = (int8_t*)(calloc((N + 1), 1));
    mobius_upto_i64_ptr_i8(N, mu);
    int64_t* A = (int64_t*)(calloc((N + 1), 8));
    compute_A_from_B_ptr_i64_ptr_i8_i64_ptr_i64_i64(B, mu, MOD, A, N);
    int64_t s = 0;
    int64_t i = 1;
    while (i <= N) {
        s = (s + A[i]);
        s = FLOW_CHECKED_MOD((s), (MOD));
        i = (i + 1);
    }
    printf("%lld\n", FLOW_CHECKED_MOD((s), (MOD)));
    free(B);
    free(mu);
    free(A);
    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 @memset(!llvm.ptr, i32, i64) -> !llvm.ptr
  // Constant: MOD
  llvm.mlir.global internal constant @MOD(1111211113 : i64) : i64
  // Constant: N
  llvm.mlir.global internal constant @N(10000 : i64) : i64
  // Module static: pairs_buf
  llvm.mlir.global internal @pairs_buf() {addr_space = 0 : i32} : !llvm.ptr {
    %0 = llvm.mlir.zero : !llvm.ptr
    llvm.return %0 : !llvm.ptr
  }
  // Module static: pairs_count
  llvm.mlir.global internal @pairs_count(0 : i64) : i64
  // Module static: pairs_cap
  llvm.mlir.global internal @pairs_cap(0 : i64) : i64
  // Module static: opt_all_m
  llvm.mlir.global internal @opt_all_m() {addr_space = 0 : i32} : !llvm.ptr {
    %1 = llvm.mlir.zero : !llvm.ptr
    llvm.return %1 : !llvm.ptr
  }
  // Module static: opt_all_k
  llvm.mlir.global internal @opt_all_k() {addr_space = 0 : i32} : !llvm.ptr {
    %2 = llvm.mlir.zero : !llvm.ptr
    llvm.return %2 : !llvm.ptr
  }
  // Module static: opt_counts
  llvm.mlir.global internal @opt_counts() {addr_space = 0 : i32} : !llvm.ptr {
    %3 = llvm.mlir.zero : !llvm.ptr
    llvm.return %3 : !llvm.ptr
  }
  func.func @gcd64(%arg0: i64, %arg1: i64) -> i64 {
    %4 = llvm.mlir.constant(1 : i64) : i64
    %5 = llvm.alloca %4 x i64 : (i64) -> !llvm.ptr
    llvm.store %arg0, %5 : i64, !llvm.ptr
    %6 = llvm.mlir.constant(1 : i64) : i64
    %7 = llvm.alloca %6 x i64 : (i64) -> !llvm.ptr
    llvm.store %arg1, %7 : i64, !llvm.ptr
    cf.br ^bb0
    ^bb0:
    %8 = llvm.load %7 : !llvm.ptr -> i64
    %9 = arith.constant 0 : i32
    %11 = arith.extsi %9 : i32 to i64
    %10 = arith.cmpi ne, %8, %11 : i64
    cf.cond_br %10, ^bb1, ^bb2
    ^bb1:
      %12 = llvm.load %5 : !llvm.ptr -> i64
      %13 = llvm.load %7 : !llvm.ptr -> i64
      %14 = arith.remsi %12, %13 : i64
      %15 = llvm.load %7 : !llvm.ptr -> i64
      llvm.store %15, %5 : i64, !llvm.ptr
      llvm.store %14, %7 : i64, !llvm.ptr
      cf.br ^bb0
    ^bb2:
    %16 = llvm.load %5 : !llvm.ptr -> i64
    func.return %16 : i64
  }
  func.func @add_pair(%arg0: i64, %arg1: i64) -> () {
    %17 = llvm.mlir.addressof @pairs_count : !llvm.ptr
    %18 = llvm.load %17 : !llvm.ptr -> i64
    %19 = llvm.mlir.addressof @pairs_cap : !llvm.ptr
    %20 = llvm.load %19 : !llvm.ptr -> i64
    %21 = arith.cmpi sge, %18, %20 : i64
    cf.cond_br %21, ^bb3, ^bb4
    ^bb3:
      %22 = arith.constant 1024 : i32
      %23 = arith.extsi %22 : i32 to i64
      %24 = llvm.mlir.addressof @pairs_cap : !llvm.ptr
      %25 = llvm.load %24 : !llvm.ptr -> i64
      %26 = arith.constant 0 : i32
      %28 = arith.extsi %26 : i32 to i64
      %27 = arith.cmpi sgt, %25, %28 : i64
      %29 = scf.if %27 -> (i64) {
        %30 = llvm.mlir.addressof @pairs_cap : !llvm.ptr
        %31 = llvm.load %30 : !llvm.ptr -> i64
        %32 = arith.constant 2 : i32
        %34 = arith.extsi %32 : i32 to i64
        %33 = arith.muli %31, %34 : i64
        scf.yield %33 : i64
      } else {
        scf.yield %23 : i64
      }
      %36 = arith.constant 2 : i32
      %38 = arith.extsi %36 : i32 to i64
      %37 = arith.muli %29, %38 : i64
      %39 = arith.constant 8 : i32
      %40 = arith.extsi %39 : i32 to i64
      %35 = func.call @calloc(%37, %40) : (i64, i64) -> !llvm.ptr
      %41 = arith.constant 0 : i32
      %42 = arith.extsi %41 : i32 to i64
      %43 = llvm.mlir.constant(1 : i64) : i64
      %44 = llvm.alloca %43 x i64 : (i64) -> !llvm.ptr
      llvm.store %42, %44 : i64, !llvm.ptr
      cf.br ^bb6
      ^bb6:
      %45 = llvm.load %44 : !llvm.ptr -> i64
      %46 = llvm.mlir.addressof @pairs_count : !llvm.ptr
      %47 = llvm.load %46 : !llvm.ptr -> i64
      %48 = arith.cmpi slt, %45, %47 : i64
      cf.cond_br %48, ^bb7, ^bb8
      ^bb7:
        %50 = llvm.mlir.addressof @pairs_buf : !llvm.ptr
        %51 = llvm.load %50 : !llvm.ptr -> !llvm.ptr
        %52 = llvm.load %44 : !llvm.ptr -> i64
        %53 = arith.constant 2 : i32
        %55 = arith.extsi %53 : i32 to i64
        %54 = arith.muli %52, %55 : i64
        %56 = llvm.getelementptr %51[%54] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %49 = llvm.load %56 : !llvm.ptr -> i64
        %57 = llvm.load %44 : !llvm.ptr -> i64
        %58 = arith.constant 2 : i32
        %60 = arith.extsi %58 : i32 to i64
        %59 = arith.muli %57, %60 : i64
        %61 = llvm.getelementptr %35[%59] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %49, %61 : i64, !llvm.ptr
        %63 = llvm.mlir.addressof @pairs_buf : !llvm.ptr
        %64 = llvm.load %63 : !llvm.ptr -> !llvm.ptr
        %65 = llvm.load %44 : !llvm.ptr -> i64
        %66 = arith.constant 2 : i32
        %68 = arith.extsi %66 : i32 to i64
        %67 = arith.muli %65, %68 : i64
        %69 = arith.constant 1 : i32
        %71 = arith.extsi %69 : i32 to i64
        %70 = arith.addi %67, %71 : i64
        %72 = llvm.getelementptr %64[%70] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %62 = llvm.load %72 : !llvm.ptr -> i64
        %73 = llvm.load %44 : !llvm.ptr -> i64
        %74 = arith.constant 2 : i32
        %76 = arith.extsi %74 : i32 to i64
        %75 = arith.muli %73, %76 : i64
        %77 = arith.constant 1 : i32
        %79 = arith.extsi %77 : i32 to i64
        %78 = arith.addi %75, %79 : i64
        %80 = llvm.getelementptr %35[%78] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %62, %80 : i64, !llvm.ptr
        %81 = llvm.load %44 : !llvm.ptr -> i64
        %82 = arith.constant 1 : i32
        %84 = arith.extsi %82 : i32 to i64
        %83 = arith.addi %81, %84 : i64
        llvm.store %83, %44 : i64, !llvm.ptr
        cf.br ^bb6
      ^bb8:
      %85 = llvm.mlir.addressof @pairs_buf : !llvm.ptr
      %86 = llvm.load %85 : !llvm.ptr -> !llvm.ptr
      %87 = llvm.mlir.zero : !llvm.ptr
      %88 = llvm.icmp "ne" %86, %87 : !llvm.ptr
      cf.cond_br %88, ^bb9, ^bb10
      ^bb9:
        %90 = llvm.mlir.addressof @pairs_buf : !llvm.ptr
        %91 = llvm.load %90 : !llvm.ptr -> !llvm.ptr
        func.call @free(%91) : (!llvm.ptr) -> ()
        cf.br ^bb11
      ^bb10:
        cf.br ^bb11
      ^bb11:
      %92 = llvm.mlir.addressof @pairs_buf : !llvm.ptr
      llvm.store %35, %92 : !llvm.ptr, !llvm.ptr
      %93 = llvm.mlir.addressof @pairs_cap : !llvm.ptr
      llvm.store %29, %93 : i64, !llvm.ptr
      cf.br ^bb5
    ^bb4:
      cf.br ^bb5
    ^bb5:
    %94 = llvm.mlir.addressof @pairs_buf : !llvm.ptr
    %95 = llvm.load %94 : !llvm.ptr -> !llvm.ptr
    %96 = llvm.mlir.addressof @pairs_count : !llvm.ptr
    %97 = llvm.load %96 : !llvm.ptr -> i64
    %98 = arith.constant 2 : i32
    %100 = arith.extsi %98 : i32 to i64
    %99 = arith.muli %97, %100 : i64
    %101 = llvm.getelementptr %95[%99] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %arg0, %101 : i64, !llvm.ptr
    %102 = llvm.mlir.addressof @pairs_buf : !llvm.ptr
    %103 = llvm.load %102 : !llvm.ptr -> !llvm.ptr
    %104 = llvm.mlir.addressof @pairs_count : !llvm.ptr
    %105 = llvm.load %104 : !llvm.ptr -> i64
    %106 = arith.constant 2 : i32
    %108 = arith.extsi %106 : i32 to i64
    %107 = arith.muli %105, %108 : i64
    %109 = arith.constant 1 : i32
    %111 = arith.extsi %109 : i32 to i64
    %110 = arith.addi %107, %111 : i64
    %112 = llvm.getelementptr %103[%110] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %arg1, %112 : i64, !llvm.ptr
    %113 = llvm.mlir.addressof @pairs_count : !llvm.ptr
    %114 = llvm.load %113 : !llvm.ptr -> i64
    %115 = arith.constant 1 : i32
    %117 = arith.extsi %115 : i32 to i64
    %116 = arith.addi %114, %117 : i64
    %118 = llvm.mlir.addressof @pairs_count : !llvm.ptr
    llvm.store %116, %118 : i64, !llvm.ptr
    func.return
  }
  func.func @k_prime_power(%arg0: i64, %arg1: i64) -> i64 {
    %119 = arith.constant 0 : i32
    %121 = arith.extsi %119 : i32 to i64
    %120 = arith.cmpi sle, %arg1, %121 : i64
    cf.cond_br %120, ^bb12, ^bb13
    ^bb12:
      %122 = arith.constant 1 : i32
      %123 = arith.extsi %122 : i32 to i64
      func.return %123 : i64
    ^bb13:
      cf.br ^bb14
    ^bb14:
    %124 = arith.constant 2 : i32
    %126 = arith.extsi %124 : i32 to i64
    %125 = arith.cmpi eq, %arg0, %126 : i64
    cf.cond_br %125, ^bb15, ^bb16
    ^bb15:
      %127 = arith.constant 1 : i32
      %128 = arith.extsi %127 : i32 to i64
      %129 = llvm.mlir.constant(1 : i64) : i64
      %130 = llvm.alloca %129 x i64 : (i64) -> !llvm.ptr
      llvm.store %128, %130 : i64, !llvm.ptr
      %131 = arith.constant 0 : i32
      %132 = arith.extsi %131 : i32 to i64
      %133 = llvm.mlir.constant(1 : i64) : i64
      %134 = llvm.alloca %133 x i64 : (i64) -> !llvm.ptr
      llvm.store %132, %134 : i64, !llvm.ptr
      cf.br ^bb18
      ^bb18:
      %135 = llvm.load %134 : !llvm.ptr -> i64
      %136 = arith.cmpi slt, %135, %arg1 : i64
      cf.cond_br %136, ^bb19, ^bb20
      ^bb19:
        %137 = llvm.load %130 : !llvm.ptr -> i64
        %138 = arith.constant 2 : i32
        %140 = arith.extsi %138 : i32 to i64
        %139 = arith.muli %137, %140 : i64
        llvm.store %139, %130 : i64, !llvm.ptr
        %141 = llvm.load %134 : !llvm.ptr -> i64
        %142 = arith.constant 1 : i32
        %144 = arith.extsi %142 : i32 to i64
        %143 = arith.addi %141, %144 : i64
        llvm.store %143, %134 : i64, !llvm.ptr
        cf.br ^bb18
      ^bb20:
      %145 = llvm.load %130 : !llvm.ptr -> i64
      func.return %145 : i64
    ^bb16:
      cf.br ^bb17
    ^bb17:
    %146 = arith.constant 1 : i32
    %148 = arith.extsi %146 : i32 to i64
    %147 = arith.addi %arg0, %148 : i64
    %149 = arith.constant 2 : i32
    %151 = arith.extsi %149 : i32 to i64
    %150 = arith.divsi %147, %151 : i64
    %152 = llvm.mlir.constant(1 : i64) : i64
    %153 = llvm.alloca %152 x i64 : (i64) -> !llvm.ptr
    llvm.store %150, %153 : i64, !llvm.ptr
    %154 = arith.constant 2 : i32
    %155 = arith.extsi %154 : i32 to i64
    %156 = llvm.mlir.constant(1 : i64) : i64
    %157 = llvm.alloca %156 x i64 : (i64) -> !llvm.ptr
    llvm.store %155, %157 : i64, !llvm.ptr
    cf.br ^bb21
    ^bb21:
    %158 = llvm.load %157 : !llvm.ptr -> i64
    %159 = arith.cmpi sle, %158, %arg1 : i64
    cf.cond_br %159, ^bb22, ^bb23
    ^bb22:
      %160 = llvm.load %157 : !llvm.ptr -> i64
      %161 = arith.constant 2 : i32
      %163 = arith.extsi %161 : i32 to i64
      %162 = arith.remsi %160, %163 : i64
      %164 = arith.constant 0 : i32
      %166 = arith.extsi %164 : i32 to i64
      %165 = arith.cmpi eq, %162, %166 : i64
      cf.cond_br %165, ^bb24, ^bb25
      ^bb24:
        %167 = llvm.load %153 : !llvm.ptr -> i64
        %168 = arith.muli %arg0, %167 : i64
        %169 = arith.constant 1 : i32
        %171 = arith.extsi %169 : i32 to i64
        %170 = arith.subi %arg0, %171 : i64
        %172 = arith.subi %168, %170 : i64
        llvm.store %172, %153 : i64, !llvm.ptr
        cf.br ^bb26
      ^bb25:
        %173 = llvm.load %153 : !llvm.ptr -> i64
        %174 = arith.muli %arg0, %173 : i64
        %175 = arith.constant 1 : i32
        %177 = arith.extsi %175 : i32 to i64
        %176 = arith.subi %arg0, %177 : i64
        %178 = arith.constant 2 : i32
        %180 = arith.extsi %178 : i32 to i64
        %179 = arith.divsi %176, %180 : i64
        %181 = arith.subi %174, %179 : i64
        llvm.store %181, %153 : i64, !llvm.ptr
        cf.br ^bb26
      ^bb26:
      %182 = llvm.load %157 : !llvm.ptr -> i64
      %183 = arith.constant 1 : i32
      %185 = arith.extsi %183 : i32 to i64
      %184 = arith.addi %182, %185 : i64
      llvm.store %184, %157 : i64, !llvm.ptr
      cf.br ^bb21
    ^bb23:
    %186 = llvm.load %153 : !llvm.ptr -> i64
    func.return %186 : i64
  }
  func.func @dfs_moduli(%arg0: i64, %arg1: i64, %arg2: !llvm.ptr, %arg3: i64, %arg4: i64, %arg5: i64) -> () {
    func.call @add_pair(%arg3, %arg4) : (i64, i64) -> ()
    %188 = llvm.mlir.constant(1 : i64) : i64
    %189 = llvm.alloca %188 x i64 : (i64) -> !llvm.ptr
    llvm.store %arg0, %189 : i64, !llvm.ptr
    cf.br ^bb27
    ^bb27:
    %190 = llvm.load %189 : !llvm.ptr -> i64
    %191 = arith.cmpi slt, %190, %arg1 : i64
    cf.cond_br %191, ^bb28, ^bb29
    ^bb28:
      %193 = llvm.load %189 : !llvm.ptr -> i64
      %194 = llvm.getelementptr %arg2[%193] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %192 = llvm.load %194 : !llvm.ptr -> i64
      %196 = llvm.mlir.addressof @opt_counts : !llvm.ptr
      %197 = llvm.load %196 : !llvm.ptr -> !llvm.ptr
      %198 = llvm.load %189 : !llvm.ptr -> i64
      %199 = llvm.getelementptr %197[%198] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %195 = llvm.load %199 : !llvm.ptr -> i32
      %200 = arith.constant 0 : i32
      %201 = arith.cmpi eq, %195, %200 : i32
      cf.cond_br %201, ^bb30, ^bb31
      ^bb30:
        %202 = llvm.load %189 : !llvm.ptr -> i64
        %203 = arith.constant 1 : i32
        %205 = arith.extsi %203 : i32 to i64
        %204 = arith.addi %202, %205 : i64
        llvm.store %204, %189 : i64, !llvm.ptr
        cf.br ^bb27
      ^bb31:
        cf.br ^bb32
      ^bb32:
      %207 = llvm.mlir.addressof @opt_all_k : !llvm.ptr
      %208 = llvm.load %207 : !llvm.ptr -> !llvm.ptr
      %209 = llvm.load %189 : !llvm.ptr -> i64
      %210 = arith.constant 64 : i32
      %212 = arith.extsi %210 : i32 to i64
      %211 = arith.muli %209, %212 : i64
      %213 = arith.constant 0 : i32
      %215 = arith.extsi %213 : i32 to i64
      %214 = arith.addi %211, %215 : i64
      %216 = llvm.getelementptr %208[%214] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %206 = llvm.load %216 : !llvm.ptr -> i64
      %217 = arith.muli %arg4, %206 : i64
      %218 = arith.cmpi sgt, %217, %arg5 : i64
      cf.cond_br %218, ^bb33, ^bb34
      ^bb33:
        cf.br ^bb29
      ^bb34:
        cf.br ^bb35
      ^bb35:
      %219 = arith.constant 0 : i32
      %220 = arith.extsi %219 : i32 to i64
      %221 = llvm.mlir.constant(1 : i64) : i64
      %222 = llvm.alloca %221 x i64 : (i64) -> !llvm.ptr
      llvm.store %220, %222 : i64, !llvm.ptr
      cf.br ^bb36
      ^bb36:
      %223 = llvm.load %222 : !llvm.ptr -> i64
      %224 = arith.extsi %195 : i32 to i64
      %225 = arith.cmpi slt, %223, %224 : i64
      cf.cond_br %225, ^bb37, ^bb38
      ^bb37:
        %227 = llvm.mlir.addressof @opt_all_m : !llvm.ptr
        %228 = llvm.load %227 : !llvm.ptr -> !llvm.ptr
        %229 = llvm.load %189 : !llvm.ptr -> i64
        %230 = arith.constant 64 : i32
        %232 = arith.extsi %230 : i32 to i64
        %231 = arith.muli %229, %232 : i64
        %233 = llvm.load %222 : !llvm.ptr -> i64
        %234 = arith.addi %231, %233 : i64
        %235 = llvm.getelementptr %228[%234] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %226 = llvm.load %235 : !llvm.ptr -> i64
        %237 = llvm.mlir.addressof @opt_all_k : !llvm.ptr
        %238 = llvm.load %237 : !llvm.ptr -> !llvm.ptr
        %239 = llvm.load %189 : !llvm.ptr -> i64
        %240 = arith.constant 64 : i32
        %242 = arith.extsi %240 : i32 to i64
        %241 = arith.muli %239, %242 : i64
        %243 = llvm.load %222 : !llvm.ptr -> i64
        %244 = arith.addi %241, %243 : i64
        %245 = llvm.getelementptr %238[%244] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %236 = llvm.load %245 : !llvm.ptr -> i64
        %246 = arith.muli %arg4, %236 : i64
        %247 = arith.cmpi sgt, %246, %arg5 : i64
        cf.cond_br %247, ^bb39, ^bb40
        ^bb39:
          cf.br ^bb38
        ^bb40:
          cf.br ^bb41
        ^bb41:
        %248 = arith.extsi %arg3 : i64 to i128
        %249 = arith.extsi %226 : i64 to i128
        %251 = arith.trunci %248 : i128 to i64
        %252 = arith.trunci %249 : i128 to i64
        %250 = arith.muli %251, %252 : i64
        %253 = arith.extsi %250 : i64 to i128
        %255 = llvm.load %189 : !llvm.ptr -> i64
        %256 = arith.constant 1 : i32
        %258 = arith.extsi %256 : i32 to i64
        %257 = arith.addi %255, %258 : i64
        %259 = arith.trunci %253 : i128 to i64
        func.call @dfs_moduli(%257, %arg1, %arg2, %259, %246, %arg5) : (i64, i64, !llvm.ptr, i64, i64, i64) -> ()
        %260 = llvm.load %222 : !llvm.ptr -> i64
        %261 = arith.constant 1 : i32
        %263 = arith.extsi %261 : i32 to i64
        %262 = arith.addi %260, %263 : i64
        llvm.store %262, %222 : i64, !llvm.ptr
        cf.br ^bb36
      ^bb38:
      %264 = llvm.load %189 : !llvm.ptr -> i64
      %265 = arith.constant 1 : i32
      %267 = arith.extsi %265 : i32 to i64
      %266 = arith.addi %264, %267 : i64
      llvm.store %266, %189 : i64, !llvm.ptr
      cf.br ^bb27
    ^bb29:
    func.return
  }
  func.func @generate_moduli(%arg0: i64) -> () {
    %268 = arith.constant 2 : i32
    %270 = arith.extsi %268 : i32 to i64
    %269 = arith.muli %270, %arg0 : i64
    %272 = arith.constant 1 : i32
    %274 = arith.extsi %272 : i32 to i64
    %273 = arith.addi %269, %274 : i64
    %275 = arith.constant 1 : i32
    %276 = arith.extsi %275 : i32 to i64
    %271 = func.call @calloc(%273, %276) : (i64, i64) -> !llvm.ptr
    %278 = arith.constant 1 : i32
    %280 = arith.extsi %278 : i32 to i64
    %279 = arith.addi %269, %280 : i64
    %281 = arith.constant 8 : i32
    %282 = arith.extsi %281 : i32 to i64
    %277 = func.call @calloc(%279, %282) : (i64, i64) -> !llvm.ptr
    %283 = arith.constant 0 : i32
    %284 = arith.extsi %283 : i32 to i64
    %285 = llvm.mlir.constant(1 : i64) : i64
    %286 = llvm.alloca %285 x i64 : (i64) -> !llvm.ptr
    llvm.store %284, %286 : i64, !llvm.ptr
    %287 = arith.constant 2 : i32
    %288 = arith.extsi %287 : i32 to i64
    %289 = llvm.mlir.constant(1 : i64) : i64
    %290 = llvm.alloca %289 x i64 : (i64) -> !llvm.ptr
    llvm.store %288, %290 : i64, !llvm.ptr
    cf.br ^bb42
    ^bb42:
    %291 = llvm.load %290 : !llvm.ptr -> i64
    %292 = arith.cmpi sle, %291, %269 : i64
    cf.cond_br %292, ^bb43, ^bb44
    ^bb43:
      %294 = llvm.load %290 : !llvm.ptr -> i64
      %295 = llvm.getelementptr %271[%294] : (!llvm.ptr, i64) -> !llvm.ptr, i8
      %293 = llvm.load %295 : !llvm.ptr -> i8
      %296 = arith.constant 0 : i32
      %298 = arith.extsi %293 : i8 to i32
      %297 = arith.cmpi eq, %298, %296 : i32
      cf.cond_br %297, ^bb45, ^bb46
      ^bb45:
        %299 = llvm.load %290 : !llvm.ptr -> i64
        %300 = llvm.load %286 : !llvm.ptr -> i64
        %301 = llvm.getelementptr %277[%300] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %299, %301 : i64, !llvm.ptr
        %302 = llvm.load %286 : !llvm.ptr -> i64
        %303 = arith.constant 1 : i32
        %305 = arith.extsi %303 : i32 to i64
        %304 = arith.addi %302, %305 : i64
        llvm.store %304, %286 : i64, !llvm.ptr
        %306 = llvm.load %290 : !llvm.ptr -> i64
        %307 = llvm.load %290 : !llvm.ptr -> i64
        %308 = arith.muli %306, %307 : i64
        %309 = llvm.mlir.constant(1 : i64) : i64
        %310 = llvm.alloca %309 x i64 : (i64) -> !llvm.ptr
        llvm.store %308, %310 : i64, !llvm.ptr
        cf.br ^bb48
        ^bb48:
        %311 = llvm.load %310 : !llvm.ptr -> i64
        %312 = arith.cmpi sle, %311, %269 : i64
        cf.cond_br %312, ^bb49, ^bb50
        ^bb49:
          %313 = arith.constant 1 : i32
          %314 = llvm.load %310 : !llvm.ptr -> i64
          %315 = arith.trunci %313 : i32 to i8
          %316 = llvm.getelementptr %271[%314] : (!llvm.ptr, i64) -> !llvm.ptr, i8
          llvm.store %315, %316 : i8, !llvm.ptr
          %317 = llvm.load %310 : !llvm.ptr -> i64
          %318 = llvm.load %290 : !llvm.ptr -> i64
          %319 = arith.addi %317, %318 : i64
          llvm.store %319, %310 : i64, !llvm.ptr
          cf.br ^bb48
        ^bb50:
        cf.br ^bb47
      ^bb46:
        cf.br ^bb47
      ^bb47:
      %320 = llvm.load %290 : !llvm.ptr -> i64
      %321 = arith.constant 1 : i32
      %323 = arith.extsi %321 : i32 to i64
      %322 = arith.addi %320, %323 : i64
      llvm.store %322, %290 : i64, !llvm.ptr
      cf.br ^bb42
    ^bb44:
    %325 = llvm.load %286 : !llvm.ptr -> i64
    %326 = arith.constant 64 : i32
    %328 = arith.extsi %326 : i32 to i64
    %327 = arith.muli %325, %328 : i64
    %329 = arith.constant 8 : i32
    %330 = arith.extsi %329 : i32 to i64
    %324 = func.call @calloc(%327, %330) : (i64, i64) -> !llvm.ptr
    %331 = llvm.mlir.addressof @opt_all_m : !llvm.ptr
    llvm.store %324, %331 : !llvm.ptr, !llvm.ptr
    %333 = llvm.load %286 : !llvm.ptr -> i64
    %334 = arith.constant 64 : i32
    %336 = arith.extsi %334 : i32 to i64
    %335 = arith.muli %333, %336 : i64
    %337 = arith.constant 8 : i32
    %338 = arith.extsi %337 : i32 to i64
    %332 = func.call @calloc(%335, %338) : (i64, i64) -> !llvm.ptr
    %339 = llvm.mlir.addressof @opt_all_k : !llvm.ptr
    llvm.store %332, %339 : !llvm.ptr, !llvm.ptr
    %341 = llvm.load %286 : !llvm.ptr -> i64
    %342 = arith.constant 4 : i32
    %343 = arith.extsi %342 : i32 to i64
    %340 = func.call @calloc(%341, %343) : (i64, i64) -> !llvm.ptr
    %344 = llvm.mlir.addressof @opt_counts : !llvm.ptr
    llvm.store %340, %344 : !llvm.ptr, !llvm.ptr
    %345 = arith.constant 0 : i32
    %346 = arith.extsi %345 : i32 to i64
    %347 = llvm.mlir.constant(1 : i64) : i64
    %348 = llvm.alloca %347 x i64 : (i64) -> !llvm.ptr
    llvm.store %346, %348 : i64, !llvm.ptr
    cf.br ^bb51
    ^bb51:
    %349 = llvm.load %348 : !llvm.ptr -> i64
    %350 = llvm.load %286 : !llvm.ptr -> i64
    %351 = arith.cmpi slt, %349, %350 : i64
    cf.cond_br %351, ^bb52, ^bb53
    ^bb52:
      %353 = llvm.load %348 : !llvm.ptr -> i64
      %354 = llvm.getelementptr %277[%353] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %352 = llvm.load %354 : !llvm.ptr -> i64
      %355 = arith.constant 0 : i32
      %356 = arith.extsi %355 : i32 to i64
      %357 = llvm.mlir.constant(1 : i64) : i64
      %358 = llvm.alloca %357 x i64 : (i64) -> !llvm.ptr
      llvm.store %356, %358 : i64, !llvm.ptr
      %359 = arith.constant 2 : i32
      %361 = arith.extsi %359 : i32 to i64
      %360 = arith.cmpi eq, %352, %361 : i64
      cf.cond_br %360, ^bb54, ^bb55
      ^bb54:
        %362 = arith.constant 2 : i32
        %363 = arith.extsi %362 : i32 to i64
        %364 = llvm.mlir.constant(1 : i64) : i64
        %365 = llvm.alloca %364 x i64 : (i64) -> !llvm.ptr
        llvm.store %363, %365 : i64, !llvm.ptr
        %366 = arith.constant 2 : i32
        %367 = arith.extsi %366 : i32 to i64
        %368 = llvm.mlir.constant(1 : i64) : i64
        %369 = llvm.alloca %368 x i64 : (i64) -> !llvm.ptr
        llvm.store %367, %369 : i64, !llvm.ptr
        cf.br ^bb57
        ^bb57:
        %370 = llvm.load %369 : !llvm.ptr -> i64
        %371 = arith.cmpi sle, %370, %arg0 : i64
        cf.cond_br %371, ^bb58, ^bb59
        ^bb58:
          %372 = llvm.load %365 : !llvm.ptr -> i64
          %373 = llvm.mlir.addressof @opt_all_m : !llvm.ptr
          %374 = llvm.load %373 : !llvm.ptr -> !llvm.ptr
          %375 = llvm.load %348 : !llvm.ptr -> i64
          %376 = arith.constant 64 : i32
          %378 = arith.extsi %376 : i32 to i64
          %377 = arith.muli %375, %378 : i64
          %379 = llvm.load %358 : !llvm.ptr -> i64
          %380 = arith.addi %377, %379 : i64
          %381 = llvm.getelementptr %374[%380] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %372, %381 : i64, !llvm.ptr
          %382 = llvm.load %369 : !llvm.ptr -> i64
          %383 = llvm.mlir.addressof @opt_all_k : !llvm.ptr
          %384 = llvm.load %383 : !llvm.ptr -> !llvm.ptr
          %385 = llvm.load %348 : !llvm.ptr -> i64
          %386 = arith.constant 64 : i32
          %388 = arith.extsi %386 : i32 to i64
          %387 = arith.muli %385, %388 : i64
          %389 = llvm.load %358 : !llvm.ptr -> i64
          %390 = arith.addi %387, %389 : i64
          %391 = llvm.getelementptr %384[%390] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %382, %391 : i64, !llvm.ptr
          %392 = llvm.load %358 : !llvm.ptr -> i64
          %393 = arith.constant 1 : i32
          %395 = arith.extsi %393 : i32 to i64
          %394 = arith.addi %392, %395 : i64
          llvm.store %394, %358 : i64, !llvm.ptr
          %396 = llvm.load %365 : !llvm.ptr -> i64
          %397 = arith.constant 2 : i32
          %399 = arith.extsi %397 : i32 to i64
          %398 = arith.muli %396, %399 : i64
          llvm.store %398, %365 : i64, !llvm.ptr
          %400 = llvm.load %369 : !llvm.ptr -> i64
          %401 = arith.constant 2 : i32
          %403 = arith.extsi %401 : i32 to i64
          %402 = arith.muli %400, %403 : i64
          llvm.store %402, %369 : i64, !llvm.ptr
          cf.br ^bb57
        ^bb59:
        cf.br ^bb56
      ^bb55:
        %404 = llvm.mlir.constant(1 : i64) : i64
        %405 = llvm.alloca %404 x i64 : (i64) -> !llvm.ptr
        llvm.store %352, %405 : i64, !llvm.ptr
        %406 = arith.constant 1 : i32
        %408 = arith.extsi %406 : i32 to i64
        %407 = arith.addi %352, %408 : i64
        %409 = arith.constant 2 : i32
        %411 = arith.extsi %409 : i32 to i64
        %410 = arith.divsi %407, %411 : i64
        %412 = llvm.mlir.constant(1 : i64) : i64
        %413 = llvm.alloca %412 x i64 : (i64) -> !llvm.ptr
        llvm.store %410, %413 : i64, !llvm.ptr
        %414 = arith.constant 1 : i32
        %415 = arith.extsi %414 : i32 to i64
        %416 = llvm.mlir.constant(1 : i64) : i64
        %417 = llvm.alloca %416 x i64 : (i64) -> !llvm.ptr
        llvm.store %415, %417 : i64, !llvm.ptr
        cf.br ^bb60
        ^bb60:
        %418 = llvm.load %413 : !llvm.ptr -> i64
        %419 = arith.cmpi sle, %418, %arg0 : i64
        cf.cond_br %419, ^bb61, ^bb62
        ^bb61:
          %420 = llvm.load %405 : !llvm.ptr -> i64
          %421 = llvm.mlir.addressof @opt_all_m : !llvm.ptr
          %422 = llvm.load %421 : !llvm.ptr -> !llvm.ptr
          %423 = llvm.load %348 : !llvm.ptr -> i64
          %424 = arith.constant 64 : i32
          %426 = arith.extsi %424 : i32 to i64
          %425 = arith.muli %423, %426 : i64
          %427 = llvm.load %358 : !llvm.ptr -> i64
          %428 = arith.addi %425, %427 : i64
          %429 = llvm.getelementptr %422[%428] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %420, %429 : i64, !llvm.ptr
          %430 = llvm.load %413 : !llvm.ptr -> i64
          %431 = llvm.mlir.addressof @opt_all_k : !llvm.ptr
          %432 = llvm.load %431 : !llvm.ptr -> !llvm.ptr
          %433 = llvm.load %348 : !llvm.ptr -> i64
          %434 = arith.constant 64 : i32
          %436 = arith.extsi %434 : i32 to i64
          %435 = arith.muli %433, %436 : i64
          %437 = llvm.load %358 : !llvm.ptr -> i64
          %438 = arith.addi %435, %437 : i64
          %439 = llvm.getelementptr %432[%438] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %430, %439 : i64, !llvm.ptr
          %440 = llvm.load %358 : !llvm.ptr -> i64
          %441 = arith.constant 1 : i32
          %443 = arith.extsi %441 : i32 to i64
          %442 = arith.addi %440, %443 : i64
          llvm.store %442, %358 : i64, !llvm.ptr
          %444 = llvm.load %417 : !llvm.ptr -> i64
          %445 = arith.constant 1 : i32
          %447 = arith.extsi %445 : i32 to i64
          %446 = arith.addi %444, %447 : i64
          llvm.store %446, %417 : i64, !llvm.ptr
          %448 = llvm.load %405 : !llvm.ptr -> i64
          %449 = arith.muli %448, %352 : i64
          llvm.store %449, %405 : i64, !llvm.ptr
          %450 = llvm.load %417 : !llvm.ptr -> i64
          %451 = arith.constant 2 : i32
          %453 = arith.extsi %451 : i32 to i64
          %452 = arith.remsi %450, %453 : i64
          %454 = arith.constant 0 : i32
          %456 = arith.extsi %454 : i32 to i64
          %455 = arith.cmpi eq, %452, %456 : i64
          cf.cond_br %455, ^bb63, ^bb64
          ^bb63:
            %457 = llvm.load %413 : !llvm.ptr -> i64
            %458 = arith.muli %352, %457 : i64
            %459 = arith.constant 1 : i32
            %461 = arith.extsi %459 : i32 to i64
            %460 = arith.subi %352, %461 : i64
            %462 = arith.subi %458, %460 : i64
            llvm.store %462, %413 : i64, !llvm.ptr
            cf.br ^bb65
          ^bb64:
            %463 = llvm.load %413 : !llvm.ptr -> i64
            %464 = arith.muli %352, %463 : i64
            %465 = arith.constant 1 : i32
            %467 = arith.extsi %465 : i32 to i64
            %466 = arith.subi %352, %467 : i64
            %468 = arith.constant 2 : i32
            %470 = arith.extsi %468 : i32 to i64
            %469 = arith.divsi %466, %470 : i64
            %471 = arith.subi %464, %469 : i64
            llvm.store %471, %413 : i64, !llvm.ptr
            cf.br ^bb65
          ^bb65:
          cf.br ^bb60
        ^bb62:
        cf.br ^bb56
      ^bb56:
      %472 = llvm.load %358 : !llvm.ptr -> i64
      %473 = arith.trunci %472 : i64 to i32
      %474 = llvm.mlir.addressof @opt_counts : !llvm.ptr
      %475 = llvm.load %474 : !llvm.ptr -> !llvm.ptr
      %476 = llvm.load %348 : !llvm.ptr -> i64
      %477 = llvm.getelementptr %475[%476] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %473, %477 : i32, !llvm.ptr
      %478 = llvm.load %348 : !llvm.ptr -> i64
      %479 = arith.constant 1 : i32
      %481 = arith.extsi %479 : i32 to i64
      %480 = arith.addi %478, %481 : i64
      llvm.store %480, %348 : i64, !llvm.ptr
      cf.br ^bb51
    ^bb53:
    %482 = llvm.mlir.zero : !llvm.ptr
    %483 = llvm.mlir.addressof @pairs_buf : !llvm.ptr
    llvm.store %482, %483 : !llvm.ptr, !llvm.ptr
    %484 = arith.constant 0 : i32
    %485 = arith.extsi %484 : i32 to i64
    %486 = llvm.mlir.addressof @pairs_count : !llvm.ptr
    llvm.store %485, %486 : i64, !llvm.ptr
    %487 = arith.constant 0 : i32
    %488 = arith.extsi %487 : i32 to i64
    %489 = llvm.mlir.addressof @pairs_cap : !llvm.ptr
    llvm.store %488, %489 : i64, !llvm.ptr
    %491 = arith.constant 0 : i32
    %492 = llvm.load %286 : !llvm.ptr -> i64
    %493 = arith.constant 1 : i32
    %494 = arith.constant 1 : i32
    %495 = arith.extsi %491 : i32 to i64
    %496 = arith.extsi %493 : i32 to i64
    %497 = arith.extsi %494 : i32 to i64
    func.call @dfs_moduli(%495, %492, %277, %496, %497, %arg0) : (i64, i64, !llvm.ptr, i64, i64, i64) -> ()
    %499 = llvm.mlir.addressof @opt_all_m : !llvm.ptr
    %500 = llvm.load %499 : !llvm.ptr -> !llvm.ptr
    func.call @free(%500) : (!llvm.ptr) -> ()
    %502 = llvm.mlir.addressof @opt_all_k : !llvm.ptr
    %503 = llvm.load %502 : !llvm.ptr -> !llvm.ptr
    func.call @free(%503) : (!llvm.ptr) -> ()
    %505 = llvm.mlir.addressof @opt_counts : !llvm.ptr
    %506 = llvm.load %505 : !llvm.ptr -> !llvm.ptr
    func.call @free(%506) : (!llvm.ptr) -> ()
    func.call @free(%277) : (!llvm.ptr) -> ()
    func.call @free(%271) : (!llvm.ptr) -> ()
    func.return
  }
  func.func @prepare_inverses(%arg0: i64, %arg1: i64) -> !llvm.ptr {
    %510 = arith.constant 1 : i32
    %512 = arith.extsi %510 : i32 to i64
    %511 = arith.addi %arg0, %512 : i64
    %513 = arith.constant 8 : i32
    %514 = arith.extsi %513 : i32 to i64
    %509 = func.call @calloc(%511, %514) : (i64, i64) -> !llvm.ptr
    %515 = arith.constant 1 : i32
    %516 = arith.constant 1 : i32
    %517 = arith.extsi %515 : i32 to i64
    %518 = arith.extsi %516 : i32 to i64
    %519 = llvm.getelementptr %509[%518] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %517, %519 : i64, !llvm.ptr
    %520 = arith.constant 2 : i32
    %521 = arith.extsi %520 : i32 to i64
    %522 = llvm.mlir.constant(1 : i64) : i64
    %523 = llvm.alloca %522 x i64 : (i64) -> !llvm.ptr
    llvm.store %521, %523 : i64, !llvm.ptr
    cf.br ^bb66
    ^bb66:
    %524 = llvm.load %523 : !llvm.ptr -> i64
    %525 = arith.cmpi sle, %524, %arg0 : i64
    cf.cond_br %525, ^bb67, ^bb68
    ^bb67:
      %526 = llvm.load %523 : !llvm.ptr -> i64
      %527 = arith.divsi %arg1, %526 : i64
      %529 = llvm.load %523 : !llvm.ptr -> i64
      %530 = arith.remsi %arg1, %529 : i64
      %531 = llvm.getelementptr %509[%530] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %528 = llvm.load %531 : !llvm.ptr -> i64
      %532 = arith.muli %527, %528 : i64
      %533 = arith.remsi %532, %arg1 : i64
      %534 = arith.subi %arg1, %533 : i64
      %535 = arith.remsi %534, %arg1 : i64
      %536 = llvm.load %523 : !llvm.ptr -> i64
      %537 = llvm.getelementptr %509[%536] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %535, %537 : i64, !llvm.ptr
      %538 = llvm.load %523 : !llvm.ptr -> i64
      %539 = arith.constant 1 : i32
      %541 = arith.extsi %539 : i32 to i64
      %540 = arith.addi %538, %541 : i64
      llvm.store %540, %523 : i64, !llvm.ptr
      cf.br ^bb66
    ^bb68:
    func.return %509 : !llvm.ptr
  }
  func.func @compute_B(%arg0: i64, %arg1: i64, %arg2: !llvm.ptr) -> () {
    func.call @generate_moduli(%arg0) : (i64) -> ()
    %543 = func.call @prepare_inverses(%arg0, %arg1) : (i64, i64) -> !llvm.ptr
    %544 = arith.constant 0 : i32
    %545 = arith.extsi %544 : i32 to i64
    %546 = llvm.mlir.constant(1 : i64) : i64
    %547 = llvm.alloca %546 x i64 : (i64) -> !llvm.ptr
    llvm.store %545, %547 : i64, !llvm.ptr
    cf.br ^bb69
    ^bb69:
    %548 = llvm.load %547 : !llvm.ptr -> i64
    %549 = arith.cmpi sle, %548, %arg0 : i64
    cf.cond_br %549, ^bb70, ^bb71
    ^bb70:
      %550 = arith.constant 0 : i32
      %551 = llvm.load %547 : !llvm.ptr -> i64
      %552 = arith.extsi %550 : i32 to i64
      %553 = llvm.getelementptr %arg2[%551] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %552, %553 : i64, !llvm.ptr
      %554 = llvm.load %547 : !llvm.ptr -> i64
      %555 = arith.constant 1 : i32
      %557 = arith.extsi %555 : i32 to i64
      %556 = arith.addi %554, %557 : i64
      llvm.store %556, %547 : i64, !llvm.ptr
      cf.br ^bb69
    ^bb71:
    %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
    cf.br ^bb72
    ^bb72:
    %562 = llvm.load %561 : !llvm.ptr -> i64
    %563 = llvm.mlir.addressof @pairs_count : !llvm.ptr
    %564 = llvm.load %563 : !llvm.ptr -> i64
    %565 = arith.cmpi slt, %562, %564 : i64
    cf.cond_br %565, ^bb73, ^bb74
    ^bb73:
      %567 = llvm.mlir.addressof @pairs_buf : !llvm.ptr
      %568 = llvm.load %567 : !llvm.ptr -> !llvm.ptr
      %569 = llvm.load %561 : !llvm.ptr -> i64
      %570 = arith.constant 2 : i32
      %572 = arith.extsi %570 : i32 to i64
      %571 = arith.muli %569, %572 : i64
      %573 = llvm.getelementptr %568[%571] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %566 = llvm.load %573 : !llvm.ptr -> i64
      %575 = llvm.mlir.addressof @pairs_buf : !llvm.ptr
      %576 = llvm.load %575 : !llvm.ptr -> !llvm.ptr
      %577 = llvm.load %561 : !llvm.ptr -> i64
      %578 = arith.constant 2 : i32
      %580 = arith.extsi %578 : i32 to i64
      %579 = arith.muli %577, %580 : i64
      %581 = arith.constant 1 : i32
      %583 = arith.extsi %581 : i32 to i64
      %582 = arith.addi %579, %583 : i64
      %584 = llvm.getelementptr %576[%582] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %574 = llvm.load %584 : !llvm.ptr -> i64
      %585 = arith.cmpi sgt, %574, %arg0 : i64
      cf.cond_br %585, ^bb75, ^bb76
      ^bb75:
        %586 = llvm.load %561 : !llvm.ptr -> i64
        %587 = arith.constant 1 : i32
        %589 = arith.extsi %587 : i32 to i64
        %588 = arith.addi %586, %589 : i64
        llvm.store %588, %561 : i64, !llvm.ptr
        cf.br ^bb72
      ^bb76:
        cf.br ^bb77
      ^bb77:
      %590 = arith.subi %566, %574 : i64
      %591 = arith.constant 0 : i32
      %593 = arith.extsi %591 : i32 to i64
      %592 = arith.cmpi slt, %590, %593 : i64
      cf.cond_br %592, ^bb78, ^bb79
      ^bb78:
        %594 = llvm.load %561 : !llvm.ptr -> i64
        %595 = arith.constant 1 : i32
        %597 = arith.extsi %595 : i32 to i64
        %596 = arith.addi %594, %597 : i64
        llvm.store %596, %561 : i64, !llvm.ptr
        cf.br ^bb72
      ^bb79:
        cf.br ^bb80
      ^bb80:
      %598 = arith.subi %arg0, %574 : i64
      %599 = llvm.mlir.constant(1 : i64) : i64
      %600 = llvm.alloca %599 x i64 : (i64) -> !llvm.ptr
      llvm.store %598, %600 : i64, !llvm.ptr
      %601 = llvm.load %600 : !llvm.ptr -> i64
      %602 = arith.constant 0 : i32
      %604 = arith.extsi %602 : i32 to i64
      %603 = arith.cmpi slt, %601, %604 : i64
      cf.cond_br %603, ^bb81, ^bb82
      ^bb81:
        %605 = llvm.load %561 : !llvm.ptr -> i64
        %606 = arith.constant 1 : i32
        %608 = arith.extsi %606 : i32 to i64
        %607 = arith.addi %605, %608 : i64
        llvm.store %607, %561 : i64, !llvm.ptr
        cf.br ^bb72
      ^bb82:
        cf.br ^bb83
      ^bb83:
      %609 = llvm.load %600 : !llvm.ptr -> i64
      %610 = arith.cmpi slt, %590, %609 : i64
      cf.cond_br %610, ^bb84, ^bb85
      ^bb84:
        llvm.store %590, %600 : i64, !llvm.ptr
        cf.br ^bb86
      ^bb85:
        cf.br ^bb86
      ^bb86:
      %612 = llvm.getelementptr %arg2[%574] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %611 = llvm.load %612 : !llvm.ptr -> i64
      %613 = arith.constant 1 : i32
      %615 = arith.extsi %613 : i32 to i64
      %614 = arith.addi %611, %615 : i64
      %616 = llvm.getelementptr %arg2[%574] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %614, %616 : i64, !llvm.ptr
      %618 = llvm.getelementptr %arg2[%574] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %617 = llvm.load %618 : !llvm.ptr -> i64
      %619 = arith.cmpi sge, %617, %arg1 : i64
      cf.cond_br %619, ^bb87, ^bb88
      ^bb87:
        %621 = llvm.getelementptr %arg2[%574] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %620 = llvm.load %621 : !llvm.ptr -> i64
        %622 = arith.subi %620, %arg1 : i64
        %623 = llvm.getelementptr %arg2[%574] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %622, %623 : i64, !llvm.ptr
        cf.br ^bb89
      ^bb88:
        cf.br ^bb89
      ^bb89:
      %624 = arith.constant 1 : i32
      %625 = arith.extsi %624 : i32 to i64
      %626 = llvm.mlir.constant(1 : i64) : i64
      %627 = llvm.alloca %626 x i64 : (i64) -> !llvm.ptr
      llvm.store %625, %627 : i64, !llvm.ptr
      %628 = arith.constant 1 : i32
      %629 = arith.extsi %628 : i32 to i64
      %630 = llvm.mlir.constant(1 : i64) : i64
      %631 = llvm.alloca %630 x i64 : (i64) -> !llvm.ptr
      llvm.store %629, %631 : i64, !llvm.ptr
      cf.br ^bb90
      ^bb90:
      %632 = llvm.load %631 : !llvm.ptr -> i64
      %633 = llvm.load %600 : !llvm.ptr -> i64
      %634 = arith.cmpi sle, %632, %633 : i64
      cf.cond_br %634, ^bb91, ^bb92
      ^bb91:
        %635 = llvm.load %627 : !llvm.ptr -> i64
        %636 = arith.extsi %635 : i64 to i128
        %637 = llvm.load %631 : !llvm.ptr -> i64
        %638 = arith.subi %590, %637 : i64
        %639 = arith.constant 1 : i32
        %641 = arith.extsi %639 : i32 to i64
        %640 = arith.addi %638, %641 : i64
        %643 = arith.trunci %636 : i128 to i64
        %642 = arith.muli %643, %640 : i64
        %644 = arith.remsi %642, %arg1 : i64
        llvm.store %644, %627 : i64, !llvm.ptr
        %645 = llvm.load %627 : !llvm.ptr -> i64
        %646 = arith.extsi %645 : i64 to i128
        %648 = llvm.load %631 : !llvm.ptr -> i64
        %649 = llvm.getelementptr %543[%648] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %647 = llvm.load %649 : !llvm.ptr -> i64
        %651 = arith.trunci %646 : i128 to i64
        %650 = arith.muli %651, %647 : i64
        %652 = arith.remsi %650, %arg1 : i64
        llvm.store %652, %627 : i64, !llvm.ptr
        %653 = llvm.load %631 : !llvm.ptr -> i64
        %654 = arith.addi %574, %653 : i64
        %656 = llvm.getelementptr %arg2[%654] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %655 = llvm.load %656 : !llvm.ptr -> i64
        %657 = llvm.load %627 : !llvm.ptr -> i64
        %658 = arith.addi %655, %657 : i64
        %659 = llvm.getelementptr %arg2[%654] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %658, %659 : i64, !llvm.ptr
        %661 = llvm.getelementptr %arg2[%654] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %660 = llvm.load %661 : !llvm.ptr -> i64
        %662 = arith.cmpi sge, %660, %arg1 : i64
        cf.cond_br %662, ^bb93, ^bb94
        ^bb93:
          %664 = llvm.getelementptr %arg2[%654] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %663 = llvm.load %664 : !llvm.ptr -> i64
          %665 = arith.subi %663, %arg1 : i64
          %666 = llvm.getelementptr %arg2[%654] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %665, %666 : i64, !llvm.ptr
          cf.br ^bb95
        ^bb94:
          cf.br ^bb95
        ^bb95:
        %667 = llvm.load %631 : !llvm.ptr -> i64
        %668 = arith.constant 1 : i32
        %670 = arith.extsi %668 : i32 to i64
        %669 = arith.addi %667, %670 : i64
        llvm.store %669, %631 : i64, !llvm.ptr
        cf.br ^bb90
      ^bb92:
      %671 = llvm.load %561 : !llvm.ptr -> i64
      %672 = arith.constant 1 : i32
      %674 = arith.extsi %672 : i32 to i64
      %673 = arith.addi %671, %674 : i64
      llvm.store %673, %561 : i64, !llvm.ptr
      cf.br ^bb72
    ^bb74:
    func.call @free(%543) : (!llvm.ptr) -> ()
    %677 = llvm.mlir.addressof @pairs_buf : !llvm.ptr
    %678 = llvm.load %677 : !llvm.ptr -> !llvm.ptr
    func.call @free(%678) : (!llvm.ptr) -> ()
    func.return
  }
  func.func @mobius_upto(%arg0: i64, %arg1: !llvm.ptr) -> () {
    %679 = arith.constant 0 : i32
    %680 = arith.extsi %679 : i32 to i64
    %681 = llvm.mlir.constant(1 : i64) : i64
    %682 = llvm.alloca %681 x i64 : (i64) -> !llvm.ptr
    llvm.store %680, %682 : i64, !llvm.ptr
    cf.br ^bb96
    ^bb96:
    %683 = llvm.load %682 : !llvm.ptr -> i64
    %684 = arith.cmpi sle, %683, %arg0 : i64
    cf.cond_br %684, ^bb97, ^bb98
    ^bb97:
      %685 = arith.constant 0 : i32
      %686 = llvm.load %682 : !llvm.ptr -> i64
      %687 = arith.trunci %685 : i32 to i8
      %688 = llvm.getelementptr %arg1[%686] : (!llvm.ptr, i64) -> !llvm.ptr, i8
      llvm.store %687, %688 : i8, !llvm.ptr
      %689 = llvm.load %682 : !llvm.ptr -> i64
      %690 = arith.constant 1 : i32
      %692 = arith.extsi %690 : i32 to i64
      %691 = arith.addi %689, %692 : i64
      llvm.store %691, %682 : i64, !llvm.ptr
      cf.br ^bb96
    ^bb98:
    %694 = arith.constant 1 : i32
    %696 = arith.extsi %694 : i32 to i64
    %695 = arith.addi %arg0, %696 : i64
    %697 = arith.constant 8 : i32
    %698 = arith.extsi %697 : i32 to i64
    %693 = func.call @calloc(%695, %698) : (i64, i64) -> !llvm.ptr
    %700 = arith.constant 1 : i32
    %702 = arith.extsi %700 : i32 to i64
    %701 = arith.addi %arg0, %702 : i64
    %703 = arith.constant 1 : i32
    %704 = arith.extsi %703 : i32 to i64
    %699 = func.call @calloc(%701, %704) : (i64, i64) -> !llvm.ptr
    %705 = arith.constant 0 : i32
    %706 = arith.extsi %705 : i32 to i64
    %707 = llvm.mlir.constant(1 : i64) : i64
    %708 = llvm.alloca %707 x i64 : (i64) -> !llvm.ptr
    llvm.store %706, %708 : i64, !llvm.ptr
    %709 = arith.constant 1 : i32
    %710 = arith.constant 1 : i32
    %711 = arith.trunci %709 : i32 to i8
    %712 = arith.extsi %710 : i32 to i64
    %713 = llvm.getelementptr %arg1[%712] : (!llvm.ptr, i64) -> !llvm.ptr, i8
    llvm.store %711, %713 : i8, !llvm.ptr
    %714 = arith.constant 2 : i32
    %715 = arith.extsi %714 : i32 to i64
    llvm.store %715, %682 : i64, !llvm.ptr
    cf.br ^bb99
    ^bb99:
    %716 = llvm.load %682 : !llvm.ptr -> i64
    %717 = arith.cmpi sle, %716, %arg0 : i64
    cf.cond_br %717, ^bb100, ^bb101
    ^bb100:
      %719 = llvm.load %682 : !llvm.ptr -> i64
      %720 = llvm.getelementptr %699[%719] : (!llvm.ptr, i64) -> !llvm.ptr, i8
      %718 = llvm.load %720 : !llvm.ptr -> i8
      %721 = arith.constant 0 : i32
      %723 = arith.extsi %718 : i8 to i32
      %722 = arith.cmpi eq, %723, %721 : i32
      cf.cond_br %722, ^bb102, ^bb103
      ^bb102:
        %724 = llvm.load %682 : !llvm.ptr -> i64
        %725 = llvm.load %708 : !llvm.ptr -> i64
        %726 = llvm.getelementptr %693[%725] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %724, %726 : i64, !llvm.ptr
        %727 = llvm.load %708 : !llvm.ptr -> i64
        %728 = arith.constant 1 : i32
        %730 = arith.extsi %728 : i32 to i64
        %729 = arith.addi %727, %730 : i64
        llvm.store %729, %708 : i64, !llvm.ptr
        %731 = arith.constant 0 : i32
        %732 = arith.constant 1 : i32
        %733 = arith.subi %731, %732 : i32
        %734 = arith.trunci %733 : i32 to i8
        %735 = llvm.load %682 : !llvm.ptr -> i64
        %736 = llvm.getelementptr %arg1[%735] : (!llvm.ptr, i64) -> !llvm.ptr, i8
        llvm.store %734, %736 : i8, !llvm.ptr
        cf.br ^bb104
      ^bb103:
        cf.br ^bb104
      ^bb104:
      %737 = arith.constant 0 : i32
      %738 = arith.extsi %737 : i32 to i64
      %739 = llvm.mlir.constant(1 : i64) : i64
      %740 = llvm.alloca %739 x i64 : (i64) -> !llvm.ptr
      llvm.store %738, %740 : i64, !llvm.ptr
      cf.br ^bb105
      ^bb105:
      %741 = llvm.load %740 : !llvm.ptr -> i64
      %742 = llvm.load %708 : !llvm.ptr -> i64
      %743 = arith.cmpi slt, %741, %742 : i64
      cf.cond_br %743, ^bb106, ^bb107
      ^bb106:
        %745 = llvm.load %740 : !llvm.ptr -> i64
        %746 = llvm.getelementptr %693[%745] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %744 = llvm.load %746 : !llvm.ptr -> i64
        %747 = llvm.load %682 : !llvm.ptr -> i64
        %748 = arith.muli %747, %744 : i64
        %749 = arith.cmpi sgt, %748, %arg0 : i64
        cf.cond_br %749, ^bb108, ^bb109
        ^bb108:
          cf.br ^bb107
        ^bb109:
          cf.br ^bb110
        ^bb110:
        %750 = arith.constant 1 : i32
        %751 = arith.trunci %750 : i32 to i8
        %752 = llvm.getelementptr %699[%748] : (!llvm.ptr, i64) -> !llvm.ptr, i8
        llvm.store %751, %752 : i8, !llvm.ptr
        %753 = llvm.load %682 : !llvm.ptr -> i64
        %754 = arith.remsi %753, %744 : i64
        %755 = arith.constant 0 : i32
        %757 = arith.extsi %755 : i32 to i64
        %756 = arith.cmpi eq, %754, %757 : i64
        cf.cond_br %756, ^bb111, ^bb112
        ^bb111:
          %758 = arith.constant 0 : i32
          %759 = arith.trunci %758 : i32 to i8
          %760 = llvm.getelementptr %arg1[%748] : (!llvm.ptr, i64) -> !llvm.ptr, i8
          llvm.store %759, %760 : i8, !llvm.ptr
          cf.br ^bb107
        ^bb112:
          cf.br ^bb113
        ^bb113:
        %761 = arith.constant 0 : i32
        %763 = llvm.load %682 : !llvm.ptr -> i64
        %764 = llvm.getelementptr %arg1[%763] : (!llvm.ptr, i64) -> !llvm.ptr, i8
        %762 = llvm.load %764 : !llvm.ptr -> i8
        %765 = arith.extsi %762 : i8 to i32
        %766 = arith.subi %761, %765 : i32
        %767 = arith.trunci %766 : i32 to i8
        %768 = llvm.getelementptr %arg1[%748] : (!llvm.ptr, i64) -> !llvm.ptr, i8
        llvm.store %767, %768 : i8, !llvm.ptr
        %769 = llvm.load %740 : !llvm.ptr -> i64
        %770 = arith.constant 1 : i32
        %772 = arith.extsi %770 : i32 to i64
        %771 = arith.addi %769, %772 : i64
        llvm.store %771, %740 : i64, !llvm.ptr
        cf.br ^bb105
      ^bb107:
      %773 = llvm.load %682 : !llvm.ptr -> i64
      %774 = arith.constant 1 : i32
      %776 = arith.extsi %774 : i32 to i64
      %775 = arith.addi %773, %776 : i64
      llvm.store %775, %682 : i64, !llvm.ptr
      cf.br ^bb99
    ^bb101:
    func.call @free(%693) : (!llvm.ptr) -> ()
    func.call @free(%699) : (!llvm.ptr) -> ()
    func.return
  }
  func.func @compute_A_from_B(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: i64, %arg3: !llvm.ptr, %arg4: i64) -> () {
    %779 = arith.constant 0 : i32
    %780 = arith.extsi %779 : i32 to i64
    %781 = llvm.mlir.constant(1 : i64) : i64
    %782 = llvm.alloca %781 x i64 : (i64) -> !llvm.ptr
    llvm.store %780, %782 : i64, !llvm.ptr
    cf.br ^bb114
    ^bb114:
    %783 = llvm.load %782 : !llvm.ptr -> i64
    %784 = arith.cmpi sle, %783, %arg4 : i64
    cf.cond_br %784, ^bb115, ^bb116
    ^bb115:
      %785 = arith.constant 0 : i32
      %786 = llvm.load %782 : !llvm.ptr -> i64
      %787 = arith.extsi %785 : i32 to i64
      %788 = llvm.getelementptr %arg3[%786] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %787, %788 : i64, !llvm.ptr
      %789 = llvm.load %782 : !llvm.ptr -> i64
      %790 = arith.constant 1 : i32
      %792 = arith.extsi %790 : i32 to i64
      %791 = arith.addi %789, %792 : i64
      llvm.store %791, %782 : i64, !llvm.ptr
      cf.br ^bb114
    ^bb116:
    %793 = arith.constant 1 : i32
    %794 = arith.extsi %793 : i32 to i64
    %795 = llvm.mlir.constant(1 : i64) : i64
    %796 = llvm.alloca %795 x i64 : (i64) -> !llvm.ptr
    llvm.store %794, %796 : i64, !llvm.ptr
    cf.br ^bb117
    ^bb117:
    %797 = llvm.load %796 : !llvm.ptr -> i64
    %798 = arith.cmpi sle, %797, %arg4 : i64
    cf.cond_br %798, ^bb118, ^bb119
    ^bb118:
      %800 = llvm.load %796 : !llvm.ptr -> i64
      %801 = llvm.getelementptr %arg1[%800] : (!llvm.ptr, i64) -> !llvm.ptr, i8
      %799 = llvm.load %801 : !llvm.ptr -> i8
      %802 = arith.constant 0 : i32
      %804 = arith.extsi %799 : i8 to i32
      %803 = arith.cmpi eq, %804, %802 : i32
      cf.cond_br %803, ^bb120, ^bb121
      ^bb120:
        %805 = llvm.load %796 : !llvm.ptr -> i64
        %806 = arith.constant 1 : i32
        %808 = arith.extsi %806 : i32 to i64
        %807 = arith.addi %805, %808 : i64
        llvm.store %807, %796 : i64, !llvm.ptr
        cf.br ^bb117
      ^bb121:
        cf.br ^bb122
      ^bb122:
      %809 = arith.constant 1 : i32
      %811 = arith.extsi %799 : i8 to i32
      %810 = arith.cmpi eq, %811, %809 : i32
      cf.cond_br %810, ^bb123, ^bb124
      ^bb123:
        %812 = arith.constant 1 : i32
        %813 = arith.extsi %812 : i32 to i64
        %814 = llvm.mlir.constant(1 : i64) : i64
        %815 = llvm.alloca %814 x i64 : (i64) -> !llvm.ptr
        llvm.store %813, %815 : i64, !llvm.ptr
        cf.br ^bb126
        ^bb126:
        %816 = llvm.load %815 : !llvm.ptr -> i64
        %817 = llvm.load %796 : !llvm.ptr -> i64
        %818 = arith.divsi %arg4, %817 : i64
        %819 = arith.cmpi sle, %816, %818 : i64
        cf.cond_br %819, ^bb127, ^bb128
        ^bb127:
          %820 = llvm.load %796 : !llvm.ptr -> i64
          %821 = llvm.load %815 : !llvm.ptr -> i64
          %822 = arith.muli %820, %821 : i64
          %824 = llvm.getelementptr %arg3[%822] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %823 = llvm.load %824 : !llvm.ptr -> i64
          %826 = llvm.load %815 : !llvm.ptr -> i64
          %827 = llvm.getelementptr %arg0[%826] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %825 = llvm.load %827 : !llvm.ptr -> i64
          %828 = arith.addi %823, %825 : i64
          %829 = llvm.getelementptr %arg3[%822] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %828, %829 : i64, !llvm.ptr
          %831 = llvm.getelementptr %arg3[%822] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %830 = llvm.load %831 : !llvm.ptr -> i64
          %832 = arith.cmpi sge, %830, %arg2 : i64
          cf.cond_br %832, ^bb129, ^bb130
          ^bb129:
            %834 = llvm.getelementptr %arg3[%822] : (!llvm.ptr, i64) -> !llvm.ptr, i64
            %833 = llvm.load %834 : !llvm.ptr -> i64
            %835 = arith.subi %833, %arg2 : i64
            %836 = llvm.getelementptr %arg3[%822] : (!llvm.ptr, i64) -> !llvm.ptr, i64
            llvm.store %835, %836 : i64, !llvm.ptr
            cf.br ^bb131
          ^bb130:
            cf.br ^bb131
          ^bb131:
          %837 = llvm.load %815 : !llvm.ptr -> i64
          %838 = arith.constant 1 : i32
          %840 = arith.extsi %838 : i32 to i64
          %839 = arith.addi %837, %840 : i64
          llvm.store %839, %815 : i64, !llvm.ptr
          cf.br ^bb126
        ^bb128:
        cf.br ^bb125
      ^bb124:
        %841 = arith.constant 1 : i32
        %842 = arith.extsi %841 : i32 to i64
        %843 = llvm.mlir.constant(1 : i64) : i64
        %844 = llvm.alloca %843 x i64 : (i64) -> !llvm.ptr
        llvm.store %842, %844 : i64, !llvm.ptr
        cf.br ^bb132
        ^bb132:
        %845 = llvm.load %844 : !llvm.ptr -> i64
        %846 = llvm.load %796 : !llvm.ptr -> i64
        %847 = arith.divsi %arg4, %846 : i64
        %848 = arith.cmpi sle, %845, %847 : i64
        cf.cond_br %848, ^bb133, ^bb134
        ^bb133:
          %849 = llvm.load %796 : !llvm.ptr -> i64
          %850 = llvm.load %844 : !llvm.ptr -> i64
          %851 = arith.muli %849, %850 : i64
          %853 = llvm.getelementptr %arg3[%851] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %852 = llvm.load %853 : !llvm.ptr -> i64
          %855 = llvm.load %844 : !llvm.ptr -> i64
          %856 = llvm.getelementptr %arg0[%855] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %854 = llvm.load %856 : !llvm.ptr -> i64
          %857 = arith.subi %852, %854 : i64
          %858 = llvm.getelementptr %arg3[%851] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %857, %858 : i64, !llvm.ptr
          %860 = llvm.getelementptr %arg3[%851] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %859 = llvm.load %860 : !llvm.ptr -> i64
          %861 = arith.constant 0 : i32
          %863 = arith.extsi %861 : i32 to i64
          %862 = arith.cmpi slt, %859, %863 : i64
          cf.cond_br %862, ^bb135, ^bb136
          ^bb135:
            %865 = llvm.getelementptr %arg3[%851] : (!llvm.ptr, i64) -> !llvm.ptr, i64
            %864 = llvm.load %865 : !llvm.ptr -> i64
            %866 = arith.addi %864, %arg2 : i64
            %867 = llvm.getelementptr %arg3[%851] : (!llvm.ptr, i64) -> !llvm.ptr, i64
            llvm.store %866, %867 : i64, !llvm.ptr
            cf.br ^bb137
          ^bb136:
            cf.br ^bb137
          ^bb137:
          %868 = llvm.load %844 : !llvm.ptr -> i64
          %869 = arith.constant 1 : i32
          %871 = arith.extsi %869 : i32 to i64
          %870 = arith.addi %868, %871 : i64
          llvm.store %870, %844 : i64, !llvm.ptr
          cf.br ^bb132
        ^bb134:
        cf.br ^bb125
      ^bb125:
      %872 = llvm.load %796 : !llvm.ptr -> i64
      %873 = arith.constant 1 : i32
      %875 = arith.extsi %873 : i32 to i64
      %874 = arith.addi %872, %875 : i64
      llvm.store %874, %796 : i64, !llvm.ptr
      cf.br ^bb117
    ^bb119:
    func.return
  }
  func.func @main() -> i32 {
    %877 = llvm.mlir.addressof @N : !llvm.ptr
    %878 = llvm.load %877 : !llvm.ptr -> i64
    %879 = arith.constant 1 : i32
    %881 = arith.extsi %879 : i32 to i64
    %880 = arith.addi %878, %881 : i64
    %882 = arith.constant 8 : i32
    %883 = arith.extsi %882 : i32 to i64
    %876 = func.call @calloc(%880, %883) : (i64, i64) -> !llvm.ptr
    %885 = llvm.mlir.addressof @N : !llvm.ptr
    %886 = llvm.load %885 : !llvm.ptr -> i64
    %887 = llvm.mlir.addressof @MOD : !llvm.ptr
    %888 = llvm.load %887 : !llvm.ptr -> i64
    func.call @compute_B(%886, %888, %876) : (i64, i64, !llvm.ptr) -> ()
    %890 = llvm.mlir.addressof @N : !llvm.ptr
    %891 = llvm.load %890 : !llvm.ptr -> i64
    %892 = arith.constant 1 : i32
    %894 = arith.extsi %892 : i32 to i64
    %893 = arith.addi %891, %894 : i64
    %895 = arith.constant 1 : i32
    %896 = arith.extsi %895 : i32 to i64
    %889 = func.call @calloc(%893, %896) : (i64, i64) -> !llvm.ptr
    %898 = llvm.mlir.addressof @N : !llvm.ptr
    %899 = llvm.load %898 : !llvm.ptr -> i64
    func.call @mobius_upto(%899, %889) : (i64, !llvm.ptr) -> ()
    %901 = llvm.mlir.addressof @N : !llvm.ptr
    %902 = llvm.load %901 : !llvm.ptr -> i64
    %903 = arith.constant 1 : i32
    %905 = arith.extsi %903 : i32 to i64
    %904 = arith.addi %902, %905 : i64
    %906 = arith.constant 8 : i32
    %907 = arith.extsi %906 : i32 to i64
    %900 = func.call @calloc(%904, %907) : (i64, i64) -> !llvm.ptr
    %909 = llvm.mlir.addressof @MOD : !llvm.ptr
    %910 = llvm.load %909 : !llvm.ptr -> i64
    %911 = llvm.mlir.addressof @N : !llvm.ptr
    %912 = llvm.load %911 : !llvm.ptr -> i64
    func.call @compute_A_from_B(%876, %889, %910, %900, %912) : (!llvm.ptr, !llvm.ptr, i64, !llvm.ptr, i64) -> ()
    %913 = arith.constant 0 : i32
    %914 = arith.extsi %913 : i32 to i64
    %915 = llvm.mlir.constant(1 : i64) : i64
    %916 = llvm.alloca %915 x i64 : (i64) -> !llvm.ptr
    llvm.store %914, %916 : i64, !llvm.ptr
    %917 = arith.constant 1 : i32
    %918 = arith.extsi %917 : i32 to i64
    %919 = llvm.mlir.constant(1 : i64) : i64
    %920 = llvm.alloca %919 x i64 : (i64) -> !llvm.ptr
    llvm.store %918, %920 : i64, !llvm.ptr
    cf.br ^bb138
    ^bb138:
    %921 = llvm.load %920 : !llvm.ptr -> i64
    %922 = llvm.mlir.addressof @N : !llvm.ptr
    %923 = llvm.load %922 : !llvm.ptr -> i64
    %924 = arith.cmpi sle, %921, %923 : i64
    cf.cond_br %924, ^bb139, ^bb140
    ^bb139:
      %925 = llvm.load %916 : !llvm.ptr -> i64
      %927 = llvm.load %920 : !llvm.ptr -> i64
      %928 = llvm.getelementptr %900[%927] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %926 = llvm.load %928 : !llvm.ptr -> i64
      %929 = arith.addi %925, %926 : i64
      llvm.store %929, %916 : i64, !llvm.ptr
      %930 = llvm.load %916 : !llvm.ptr -> i64
      %931 = llvm.mlir.addressof @MOD : !llvm.ptr
      %932 = llvm.load %931 : !llvm.ptr -> i64
      %933 = arith.remsi %930, %932 : i64
      llvm.store %933, %916 : i64, !llvm.ptr
      %934 = llvm.load %920 : !llvm.ptr -> i64
      %935 = arith.constant 1 : i32
      %937 = arith.extsi %935 : i32 to i64
      %936 = arith.addi %934, %937 : i64
      llvm.store %936, %920 : i64, !llvm.ptr
      cf.br ^bb138
    ^bb140:
    %938 = llvm.mlir.addressof @str_0 : !llvm.ptr
    %939 = llvm.load %916 : !llvm.ptr -> i64
    %940 = llvm.mlir.addressof @MOD : !llvm.ptr
    %941 = llvm.load %940 : !llvm.ptr -> i64
    %942 = arith.remsi %939, %941 : i64
    %943 = llvm.call @printf(%938, %942) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i64) -> i32
    func.call @free(%876) : (!llvm.ptr) -> ()
    func.call @free(%889) : (!llvm.ptr) -> ()
    func.call @free(%900) : (!llvm.ptr) -> ()
    %947 = arith.constant 0 : i32
    func.return %947 : i32
  }
}