Problem 915

s(1)=1, s(n+1) = (s(n)-1)^3 + 2 T(N) = sum_{a=1..N} sum_{b=1..N} gcd(s(s(a)), s(s(b))) Compute T(10^8) mod 123456789. Uses cycle detection for s(n) mod M, summatory totient via sieve + memoized recursion.

Answer55601924
Output55601924
StatusPASS
Native helperno
Runtime20 ms
Peak memory49056 KB
Time complexityO(n^2) (estimated)
Space complexityO(n^2) (estimated)

Performance comparison

MetricOur solutionBest known
Time complexityO(n^2)O(n log log n)
Space complexityO(n^2)O(n)
ApproachFlow solutionSieve-based totient computation
VerdictSuboptimal

Flow source

# Project Euler 915: Giant GCDs
# s(1)=1, s(n+1) = (s(n)-1)^3 + 2
# T(N) = sum_{a=1..N} sum_{b=1..N} gcd(s(s(a)), s(s(b)))
# Compute T(10^8) mod 123456789.
# Uses cycle detection for s(n) mod M, summatory totient via sieve + memoized recursion.

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

const MOD: i64 = 123456789
const BASE: i64 = 2000000
const MEMO_CAP: i64 = 1 << 20

let mut s_mod_MOD_arr: ptr<i64> = null
let mut muM: i64 = 0
let mut lamM: i64 = 0

let mut s_mod_lam_arr: ptr<i64> = null
let mut muP: i64 = 0
let mut lamP: i64 = 0

let mut small_exact_arr: ptr<i64> = null
let mut n_small_max: i64 = 0
let mut muM_mod: i64 = 0

let mut phi_prefix_arr: ptr<i64> = null
let mut memo_keys: ptr<i64> = null
let mut memo_vals: ptr<i64> = null

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

function f_mod(x: i64, m: i64) -> i64 {
    let y: i64 = (x + m - 1) % m
    let y2: i64 = mulmod(y, y, m)
    let y3: i64 = mulmod(y2, y, m)
    return (y3 + 2) % m
}

function cycle_info(m: i64) -> ptr<i64> {
    let result: ptr<i64> = calloc(2, 8)
    let mut tortoise: i64 = f_mod(0, m)
    let mut hare: i64 = f_mod(f_mod(0, m), m)
    while tortoise != hare {
        tortoise = f_mod(tortoise, m)
        hare = f_mod(f_mod(hare, m), m)
    }
    let mut mu: i64 = 0
    tortoise = 0
    while tortoise != hare {
        tortoise = f_mod(tortoise, m)
        hare = f_mod(hare, m)
        mu = mu + 1
    }
    let mut lam: i64 = 1
    hare = f_mod(tortoise, m)
    while tortoise != hare {
        hare = f_mod(hare, m)
        lam = lam + 1
    }
    result[0] = mu
    result[1] = lam
    return result
}

function build_s_mod(m: i64, length: i64) -> ptr<i64> {
    let arr: ptr<i64> = calloc(length + 1, 8)
    let mut x: i64 = 0
    let mut n: i64 = 1
    while n <= length {
        x = f_mod(x, m)
        arr[n] = x
        n = n + 1
    }
    return arr
}

function sieve_phi_prefix(n: i64) -> ptr<i64> {
    let phi: ptr<i64> = calloc(n + 1, 8)
    let mut i: i64 = 0
    while i <= n {
        phi[i] = i
        i = i + 1
    }
    i = 2
    while i <= n {
        if phi[i] == i {
            let mut j: i64 = i
            while j <= n {
                phi[j] = phi[j] - phi[j] / i
                j = j + i
            }
        }
        i = i + 1
    }
    let pref: ptr<i64> = calloc(n + 1, 8)
    let mut s: i64 = 0
    i = 1
    while i <= n {
        s = s + phi[i]
        pref[i] = s
        i = i + 1
    }
    free(phi as ptr<void>)
    return pref
}

function mix64(x: i64) -> i64 {
    let mut v: i64 = x
    v = v ^ (v >> 30)
    v = v * 0xbf58476d1ce4e5b9
    v = v ^ (v >> 27)
    v = v * 0x94d049bb133111eb
    v = v ^ (v >> 31)
    return v
}

function s_index_modMOD(k: i64) -> i64 {
    if k <= muM + lamM {
        return s_mod_MOD_arr[k]
    }
    let k2: i64 = muM + ((k - muM) % lamM)
    return s_mod_MOD_arr[k2]
}

function s_n_mod_lamM(n: i64) -> i64 {
    if n <= muP + lamP {
        return s_mod_lam_arr[n]
    }
    let n2: i64 = muP + ((n - muP) % lamP)
    return s_mod_lam_arr[n2]
}

function s2_mod(n: i64) -> i64 {
    if n <= n_small_max {
        return s_index_modMOD(small_exact_arr[n])
    }
    let k_mod: i64 = s_n_mod_lamM(n)
    let diff: i64
    if k_mod >= muM_mod {
        diff = (k_mod - muM_mod) % lamM
    } else {
        diff = lamM - ((muM_mod - k_mod) % lamM)
    }
    if diff == lamM {
        return s_mod_MOD_arr[muM]
    }
    return s_mod_MOD_arr[muM + diff]
}

function phi_sum_memo(n: i64) -> i64 {
    if n <= BASE {
        return phi_prefix_arr[n]
    }
    let mut h: i64 = mix64(n) & (MEMO_CAP - 1)
    while memo_keys[h] != 0 {
        if memo_keys[h] == n { return memo_vals[h] }
        h = (h + 1) & (MEMO_CAP - 1)
    }
    let mut res: i64 = (n * (n + 1)) / 2
    let mut l: i64 = 2
    while l <= n {
        let q: i64 = n / l
        let r: i64 = n / q
        let sub: i64 = phi_sum_memo(q)
        let cnt: i64 = r - l + 1
        let val: i128 = (cnt as i128) * (sub as i128)
        res = ((res as i128) - val) as i64
        l = r + 1
    }
    memo_keys[h] = n
    memo_vals[h] = res
    return res
}

function coprime_pairs(m: i64) -> i64 {
    let ps: i64 = phi_sum_memo(m) % MOD
    return (2 * ps - 1 + MOD) % MOD
}

function prefix_s2(n: i64, start: i64, period: i64, small_prefix: ptr<i64>, period_prefix: ptr<i64>, period_sum: i64) -> i64 {
    if n == 0 { return 0 }
    if n < start { return small_prefix[n] }
    let base: i64 = 0
    if start > 0 { base = small_prefix[start - 1] }
    let t: i64 = n - (start - 1)
    let full: i64 = t / period
    let rem: i64 = t % period
    return (base + mulmod(full % MOD, period_sum, MOD) + period_prefix[rem]) % MOD
}

function main() -> i32 {
    let N: i64 = 100000000

    # Periodicity of s(n) mod MOD
    let ci: ptr<i64> = cycle_info(MOD)
    muM = ci[0]
    lamM = ci[1]
    free(ci as ptr<void>)
    s_mod_MOD_arr = build_s_mod(MOD, muM + lamM)

    # Periodicity of s(n) mod lamM
    let ci2: ptr<i64> = cycle_info(lamM)
    muP = ci2[0]
    lamP = ci2[1]
    free(ci2 as ptr<void>)
    s_mod_lam_arr = build_s_mod(lamM, muP + lamP)

    # Compute exact s(n) for small n until s(n) > muM
    small_exact_arr = calloc(20, 8)
    small_exact_arr[0] = 0
    let mut x: i64 = 0
    let mut n: i64 = 0
    while true {
        n = n + 1
        let xm1: i128 = (x as i128) - 1
        let xc: i128 = xm1 * xm1 * xm1 + 2
        x = xc as i64
        small_exact_arr[n] = x
        if x > muM { break }
    }
    n_small_max = n - 1
    muM_mod = muM % lamM

    # s2_mod becomes periodic once s(n) mod lamM is in its cycle
    let mut start: i64 = muP
    if n_small_max + 1 > start { start = n_small_max + 1 }
    if 1 > start { start = 1 }
    let period: i64 = lamP

    let period_vals: ptr<i64> = calloc(period, 8)
    let mut i: i64 = 0
    while i < period {
        period_vals[i] = s2_mod(start + i) % MOD
        i = i + 1
    }

    let small_prefix: ptr<i64> = calloc(start, 8)
    let mut acc: i64 = 0
    i = 1
    while i < start {
        acc = (acc + s2_mod(i)) % MOD
        small_prefix[i] = acc
        i = i + 1
    }

    let period_prefix: ptr<i64> = calloc(period + 1, 8)
    let mut accp: i64 = 0
    i = 0
    while i < period {
        accp = (accp + period_vals[i]) % MOD
        period_prefix[i + 1] = accp
        i = i + 1
    }
    let period_sum: i64 = period_prefix[period]

    # Summatory totient
    phi_prefix_arr = sieve_phi_prefix(BASE)
    memo_keys = calloc(MEMO_CAP, 8)
    memo_vals = calloc(MEMO_CAP, 8)

    # Block over d where floor(N/d) is constant
    let mut ans: i64 = 0
    let mut l: i64 = 1
    while l <= N {
        let q: i64 = N / l
        let r: i64 = N / q

        let pr: i64 = prefix_s2(r, start, period, small_prefix, period_prefix, period_sum)
        let pl: i64 = prefix_s2(l - 1, start, period, small_prefix, period_prefix, period_sum)
        let sum_s2: i64 = (pr + MOD - pl) % MOD
        ans = (ans + mulmod(sum_s2, coprime_pairs(q), MOD)) % MOD
        l = r + 1
    }

    printf("%lld\n", ans % MOD)
    return 0
}

Generated C

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

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

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

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

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

#include <math.h>

void* _ui_state = NULL;

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

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

int64_t mulmod_i64_i64_i64(int64_t a, int64_t b, int64_t m);
int64_t f_mod_i64_i64(int64_t x, int64_t m);
int64_t* cycle_info_i64(int64_t m);
int64_t* build_s_mod_i64_i64(int64_t m, int64_t length);
int64_t* sieve_phi_prefix_i64(int64_t n);
int64_t mix64_i64(int64_t x);
int64_t s_index_modMOD_i64(int64_t k);
int64_t s_n_mod_lamM_i64(int64_t n);
int64_t s2_mod_i64(int64_t n);
int64_t phi_sum_memo_i64(int64_t n);
int64_t coprime_pairs_i64(int64_t m);
int64_t prefix_s2_i64_i64_i64_ptr_i64_ptr_i64_i64(int64_t n, int64_t start, int64_t period, int64_t* small_prefix, int64_t* period_prefix, int64_t period_sum);
int32_t main(void);

static const int64_t MOD = 123456789;
static const int64_t BASE = 2000000;
static const int64_t MEMO_CAP = FLOW_CHECKED_SHL((1), (20));

/* Module statics */
static int64_t* s_mod_MOD_arr = NULL;
static int64_t muM = 0;
static int64_t lamM = 0;
static int64_t* s_mod_lam_arr = NULL;
static int64_t muP = 0;
static int64_t lamP = 0;
static int64_t* small_exact_arr = NULL;
static int64_t n_small_max = 0;
static int64_t muM_mod = 0;
static int64_t* phi_prefix_arr = NULL;
static int64_t* memo_keys = NULL;
static int64_t* memo_vals = NULL;




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

int64_t f_mod_i64_i64(int64_t x, int64_t m) {
    int64_t y = FLOW_CHECKED_MOD((((x + m) - 1)), (m));
    int64_t y2 = mulmod_i64_i64_i64(y, y, m);
    int64_t y3 = mulmod_i64_i64_i64(y2, y, m);
    return FLOW_CHECKED_MOD(((y3 + 2)), (m));
}

int64_t* cycle_info_i64(int64_t m) {
    int64_t* result = (int64_t*)(calloc(2, 8));
    int64_t tortoise = f_mod_i64_i64(0, m);
    int64_t hare = f_mod_i64_i64(f_mod_i64_i64(0, m), m);
    while (tortoise != hare) {
        tortoise = f_mod_i64_i64(tortoise, m);
        hare = f_mod_i64_i64(f_mod_i64_i64(hare, m), m);
    }
    int64_t mu = 0;
    tortoise = 0;
    while (tortoise != hare) {
        tortoise = f_mod_i64_i64(tortoise, m);
        hare = f_mod_i64_i64(hare, m);
        mu = (mu + 1);
    }
    int64_t lam = 1;
    hare = f_mod_i64_i64(tortoise, m);
    while (tortoise != hare) {
        hare = f_mod_i64_i64(hare, m);
        lam = (lam + 1);
    }
    result[0] = mu;
    result[1] = lam;
    return result;
}

int64_t* build_s_mod_i64_i64(int64_t m, int64_t length) {
    int64_t* arr = (int64_t*)(calloc((length + 1), 8));
    int64_t x = 0;
    int64_t n = 1;
    while (n <= length) {
        x = f_mod_i64_i64(x, m);
        arr[n] = x;
        n = (n + 1);
    }
    return arr;
}

int64_t* sieve_phi_prefix_i64(int64_t n) {
    int64_t* phi = (int64_t*)(calloc((n + 1), 8));
    int64_t i = 0;
    while (i <= n) {
        phi[i] = i;
        i = (i + 1);
    }
    i = 2;
    while (i <= n) {
        if (phi[i] == i) {
            int64_t j = i;
            while (j <= n) {
                phi[j] = (phi[j] - FLOW_CHECKED_DIV((phi[j]), (i)));
                j = (j + i);
            }
        }
        i = (i + 1);
    }
    int64_t* pref = (int64_t*)(calloc((n + 1), 8));
    int64_t s = 0;
    i = 1;
    while (i <= n) {
        s = (s + phi[i]);
        pref[i] = s;
        i = (i + 1);
    }
    free(((void*)(phi)));
    return pref;
}

int64_t mix64_i64(int64_t x) {
    int64_t v = x;
    v = (v ^ FLOW_CHECKED_SHR((v), (30)));
    v = (v * ((__int128)0xBF58476D1CE4E5B9ULL));
    v = (v ^ FLOW_CHECKED_SHR((v), (27)));
    v = (v * ((__int128)0x94D049BB133111EBULL));
    v = (v ^ FLOW_CHECKED_SHR((v), (31)));
    return v;
}

int64_t s_index_modMOD_i64(int64_t k) {
    if (k <= (muM + lamM)) {
        return s_mod_MOD_arr[k];
    }
    int64_t k2 = (muM + FLOW_CHECKED_MOD(((k - muM)), (lamM)));
    return s_mod_MOD_arr[k2];
}

int64_t s_n_mod_lamM_i64(int64_t n) {
    if (n <= (muP + lamP)) {
        return s_mod_lam_arr[n];
    }
    int64_t n2 = (muP + FLOW_CHECKED_MOD(((n - muP)), (lamP)));
    return s_mod_lam_arr[n2];
}

int64_t s2_mod_i64(int64_t n) {
    if (n <= n_small_max) {
        return s_index_modMOD_i64(small_exact_arr[n]);
    }
    int64_t k_mod = s_n_mod_lamM_i64(n);
    int64_t diff;
    if (k_mod >= muM_mod) {
        diff = FLOW_CHECKED_MOD(((k_mod - muM_mod)), (lamM));
    } else {
        diff = (lamM - FLOW_CHECKED_MOD(((muM_mod - k_mod)), (lamM)));
    }
    if (diff == lamM) {
        return s_mod_MOD_arr[muM];
    }
    return s_mod_MOD_arr[(muM + diff)];
}

int64_t phi_sum_memo_i64(int64_t n) {
    if (n <= BASE) {
        return phi_prefix_arr[n];
    }
    int64_t h = (mix64_i64(n) & (MEMO_CAP - 1));
    while (memo_keys[h] != 0) {
        if (memo_keys[h] == n) {
            return memo_vals[h];
        }
        h = ((h + 1) & (MEMO_CAP - 1));
    }
    int64_t res = FLOW_CHECKED_DIV(((n * (n + 1))), (2));
    int64_t l = 2;
    while (l <= n) {
        int64_t q = FLOW_CHECKED_DIV((n), (l));
        int64_t r = FLOW_CHECKED_DIV((n), (q));
        int64_t sub = phi_sum_memo_i64(q);
        int64_t cnt = ((r - l) + 1);
        __int128 val = (((__int128)(cnt)) * ((__int128)(sub)));
        res = ((int64_t)((((__int128)(res)) - val)));
        l = (r + 1);
    }
    memo_keys[h] = n;
    memo_vals[h] = res;
    return res;
}

int64_t coprime_pairs_i64(int64_t m) {
    int64_t ps = FLOW_CHECKED_MOD((phi_sum_memo_i64(m)), (MOD));
    return FLOW_CHECKED_MOD(((((2 * ps) - 1) + MOD)), (MOD));
}

int64_t prefix_s2_i64_i64_i64_ptr_i64_ptr_i64_i64(int64_t n, int64_t start, int64_t period, int64_t* small_prefix, int64_t* period_prefix, int64_t period_sum) {
    if (n == 0) {
        return 0;
    }
    if (n < start) {
        return small_prefix[n];
    }
    int64_t base = 0;
    if (start > 0) {
        base = small_prefix[(start - 1)];
    }
    int64_t t = (n - (start - 1));
    int64_t full = FLOW_CHECKED_DIV((t), (period));
    int64_t rem = FLOW_CHECKED_MOD((t), (period));
    return FLOW_CHECKED_MOD((((base + mulmod_i64_i64_i64(FLOW_CHECKED_MOD((full), (MOD)), period_sum, MOD)) + period_prefix[rem])), (MOD));
}

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