Problem 388

Distinct lines D(10^10); print first 9 and last 9 digits concatenated.

Answer831907372805129931
Output831907372805129931
StatusPASS
Native helperno
Runtime160 ms
Peak memory57936 KB
Time complexityO(n) (estimated)
Space complexityO(n^2) (estimated)

Performance comparison

MetricOur solutionBest known
Time complexityO(n)O(n)
Space complexityO(n^2)O(n)
ApproachFlow solutionBig-integer arithmetic
VerdictOptimal

Flow source

# Project Euler 388
# Distinct lines D(10^10); print first 9 and last 9 digits concatenated.

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

function icbrt128(n: i128) -> i64 {
    if n < (2 as i128) { return n as i64 }
    # binary search for floor(cbrt(n))
    let mut lo: i64 = 1
    let mut hi: i64 = 1 << 22
    while lo < hi {
        let mid: i64 = (lo + hi + 1) / 2
        let m: i128 = mid as i128
        if m * m * m <= n {
            lo = mid
        } else {
            hi = mid - 1
        }
    }
    return lo
}

function memo_get(keys: ptr<i64>, vals: ptr<i64>, used: ptr<i8>, cap: i64, key: i64, out: ptr<i64>) -> i32 {
    let mut slot: i64 = key
    if slot < 0 { slot = 0 - slot }
    slot = slot & (cap - 1)
    while used[slot] != 0 {
        if keys[slot] == key {
            out[0] = vals[slot]
            return 1
        }
        slot = (slot + 1) & (cap - 1)
    }
    return 0
}

function memo_put(keys: ptr<i64>, vals: ptr<i64>, used: ptr<i8>, cap: i64, key: i64, val: i64) -> void {
    let mut slot: i64 = key
    if slot < 0 { slot = 0 - slot }
    slot = slot & (cap - 1)
    while used[slot] != 0 && keys[slot] != key {
        slot = (slot + 1) & (cap - 1)
    }
    used[slot] = 1
    keys[slot] = key
    vals[slot] = val
}

function mertens(n: i64, B: i64, M_small: ptr<i64>,
                 keys: ptr<i64>, vals: ptr<i64>, used: ptr<i8>, cap: i64) -> i64 {
    if n <= B { return M_small[n] }
    let box: array<i64, 1> = [0]
    if memo_get(keys, vals, used, cap, n, box) == 1 {
        return box[0]
    }
    let mut res: i64 = 1
    let mut l: i64 = 2
    while l <= n {
        let q: i64 = n / l
        let r: i64 = n / q
        res = res - (r - l + 1) * mertens(q, B, M_small, keys, vals, used, cap)
        l = r + 1
    }
    memo_put(keys, vals, used, cap, n, res)
    return res
}

function G(q: i128) -> i128 {
    return q * (q * (q + (3 as i128)) + (3 as i128))
}

function main() -> i32 {
    let N: i64 = 10000000000
    let NN: i128 = (N as i128) * (N as i128)
    let B: i64 = icbrt128(NN)

    let mu: ptr<i8> = calloc(B + 1, 1)
    let lp: ptr<i32> = calloc(B + 1, 4)
    let primes: ptr<i32> = calloc(B / 5 + 10, 4)
    let M_small: ptr<i64> = calloc(B + 1, 8)
    if mu == null || lp == null || primes == null || M_small == null { return 1 }

    mu[1] = 1
    let mut pc: i64 = 0
    let mut i: i64 = 2
    while i <= B {
        if lp[i] == 0 {
            lp[i] = i as i32
            primes[pc] = i as i32
            pc = pc + 1
            mu[i] = (0 - 1) as i8
        }
        let mut j: i64 = 0
        while j < pc {
            let p: i64 = primes[j] as i64
            let ip: i64 = i * p
            if ip > B { break }
            lp[ip] = p as i32
            if i % p == 0 {
                mu[ip] = 0
                break
            }
            mu[ip] = (0 - (mu[i] as i64)) as i8
            j = j + 1
        }
        i = i + 1
    }

    let mut s: i64 = 0
    i = 1
    while i <= B {
        s = s + (mu[i] as i64)
        M_small[i] = s
        i = i + 1
    }

    let cap: i64 = 8192
    let keys: ptr<i64> = calloc(cap, 8)
    let vals: ptr<i64> = calloc(cap, 8)
    let used: ptr<i8> = calloc(cap, 1)
    if keys == null || vals == null || used == null { return 1 }

    # warm
    let _w: i64 = mertens(N, B, M_small, keys, vals, used, cap)

    let mut total: i128 = 0
    # Part 1: d <= B
    let mut l: i64 = 1
    while l <= B {
        let q: i64 = N / l
        let mut r: i64 = N / q
        if r > B { r = B }
        let dm: i64 = M_small[r] - M_small[l - 1]
        total = total + (dm as i128) * G(q as i128)
        l = r + 1
    }

    # Part 2: d > B
    let max_q: i64 = N / (B + 1)
    let mut q: i64 = 1
    while q <= max_q {
        let mut left: i64 = N / (q + 1) + 1
        let right: i64 = N / q
        if left <= B { left = B + 1 }
        if left <= right {
            let mr: i64 = mertens(right, B, M_small, keys, vals, used, cap)
            let ml: i64 = mertens(left - 1, B, M_small, keys, vals, used, cap)
            total = total + ((mr - ml) as i128) * G(q as i128)
        }
        q = q + 1
    }

    let MOD9: i128 = 1000000000
    let last9: i64 = (total % MOD9) as i64
    if last9 < 0 { last9 = 0 - last9 }  # shouldn't be negative

    # first 9 digits
    let mut tmp: i128 = total
    if tmp < (0 as i128) { tmp = 0 as i128 - tmp }
    let mut digs: i64 = 0
    let mut t2: i128 = tmp
    while t2 > (0 as i128) {
        digs = digs + 1
        t2 = t2 / (10 as i128)
    }
    let mut div: i128 = 1
    let mut k: i64 = 0
    while k < digs - 9 {
        div = div * (10 as i128)
        k = k + 1
    }
    let first9: i64 = (tmp / div) as i64
    printf("%lld%09lld\n", first9, last9)

    free(used)
    free(vals)
    free(keys)
    free(M_small)
    free(primes)
    free(lp)
    free(mu)
    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 icbrt128_i128(__int128 n);
int32_t memo_get_ptr_i64_ptr_i64_ptr_i8_i64_i64_ptr_i64(int64_t* keys, int64_t* vals, int8_t* used, int64_t cap, int64_t key, int64_t* out);
void memo_put_ptr_i64_ptr_i64_ptr_i8_i64_i64_i64(int64_t* keys, int64_t* vals, int8_t* used, int64_t cap, int64_t key, int64_t val);
int64_t mertens_i64_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i8_i64(int64_t n, int64_t B, int64_t* M_small, int64_t* keys, int64_t* vals, int8_t* used, int64_t cap);
__int128 G_i128(__int128 q);
int32_t main(void);



int64_t icbrt128_i128(__int128 n) {
    if (n < ((__int128)(2))) {
        return ((int64_t)(n));
    }
    int64_t lo = 1;
    int64_t hi = FLOW_CHECKED_SHL((1), (22));
    while (lo < hi) {
        int64_t mid = FLOW_CHECKED_DIV((((lo + hi) + 1)), (2));
        __int128 m = ((__int128)(mid));
        if (((m * m) * m) <= n) {
            lo = mid;
        } else {
            hi = (mid - 1);
        }
    }
    return lo;
}

int32_t memo_get_ptr_i64_ptr_i64_ptr_i8_i64_i64_ptr_i64(int64_t* keys, int64_t* vals, int8_t* used, int64_t cap, int64_t key, int64_t* out) {
    int64_t slot = key;
    if (slot < 0) {
        slot = (0 - slot);
    }
    slot = (slot & (cap - 1));
    while (used[slot] != 0) {
        if (keys[slot] == key) {
            out[0] = vals[slot];
            return 1;
        }
        slot = ((slot + 1) & (cap - 1));
    }
    return 0;
}

void memo_put_ptr_i64_ptr_i64_ptr_i8_i64_i64_i64(int64_t* keys, int64_t* vals, int8_t* used, int64_t cap, int64_t key, int64_t val) {
    int64_t slot = key;
    if (slot < 0) {
        slot = (0 - slot);
    }
    slot = (slot & (cap - 1));
    while ((used[slot] != 0 && keys[slot] != key)) {
        slot = ((slot + 1) & (cap - 1));
    }
    used[slot] = 1;
    keys[slot] = key;
    vals[slot] = val;
}

int64_t mertens_i64_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i8_i64(int64_t n, int64_t B, int64_t* M_small, int64_t* keys, int64_t* vals, int8_t* used, int64_t cap) {
    if (n <= B) {
        return M_small[n];
    }
    int64_t box[1] = { 0 };
    if (memo_get_ptr_i64_ptr_i64_ptr_i8_i64_i64_ptr_i64(keys, vals, used, cap, n, box) == 1) {
        return (((unsigned)(0) < 1) ? box[0] : (fprintf(stderr, "array index %d out of bounds (size %d)\n", (int)(0), 1), flow_fault_handler("array index out of bounds"), box[0]));
    }
    int64_t res = 1;
    int64_t l = 2;
    while (l <= n) {
        int64_t q = FLOW_CHECKED_DIV((n), (l));
        int64_t r = FLOW_CHECKED_DIV((n), (q));
        res = (res - (((r - l) + 1) * mertens_i64_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i8_i64(q, B, M_small, keys, vals, used, cap)));
        l = (r + 1);
    }
    memo_put_ptr_i64_ptr_i64_ptr_i8_i64_i64_i64(keys, vals, used, cap, n, res);
    return res;
}

__int128 G_i128(__int128 q) {
    return (q * ((q * (q + ((__int128)(3)))) + ((__int128)(3))));
}

int32_t main(void) {
    int64_t N = 10000000000;
    __int128 NN = (((__int128)(N)) * ((__int128)(N)));
    int64_t B = icbrt128_i128(NN);
    int8_t* mu = (int8_t*)(calloc((B + 1), 1));
    int32_t* lp = (int32_t*)(calloc((B + 1), 4));
    int32_t* primes = (int32_t*)(calloc((FLOW_CHECKED_DIV((B), (5)) + 10), 4));
    int64_t* M_small = (int64_t*)(calloc((B + 1), 8));
    if ((((mu == NULL || lp == NULL) || primes == NULL) || M_small == NULL)) {
        return 1;
    }
    mu[1] = 1;
    int64_t pc = 0;
    int64_t i = 2;
    while (i <= B) {
        if (lp[i] == 0) {
            lp[i] = ((int32_t)(i));
            primes[pc] = ((int32_t)(i));
            pc = (pc + 1);
            mu[i] = ((int8_t)((0 - 1)));
        }
        int64_t j = 0;
        while (j < pc) {
            int64_t p = ((int64_t)(primes[j]));
            int64_t ip = (i * p);
            if (ip > B) {
                break;
            }
            lp[ip] = ((int32_t)(p));
            if (FLOW_CHECKED_MOD((i), (p)) == 0) {
                mu[ip] = 0;
                break;
            }
            mu[ip] = ((int8_t)((0 - ((int64_t)(mu[i])))));
            j = (j + 1);
        }
        i = (i + 1);
    }
    int64_t s = 0;
    i = 1;
    while (i <= B) {
        s = (s + ((int64_t)(mu[i])));
        M_small[i] = s;
        i = (i + 1);
    }
    int64_t cap = 8192;
    int64_t* keys = (int64_t*)(calloc(cap, 8));
    int64_t* vals = (int64_t*)(calloc(cap, 8));
    int8_t* used = (int8_t*)(calloc(cap, 1));
    if (((keys == NULL || vals == NULL) || used == NULL)) {
        return 1;
    }
    int64_t _w = mertens_i64_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i8_i64(N, B, M_small, keys, vals, used, cap);
    __int128 total = 0;
    int64_t l = 1;
    while (l <= B) {
        int64_t q = FLOW_CHECKED_DIV((N), (l));
        int64_t r = FLOW_CHECKED_DIV((N), (q));
        if (r > B) {
            r = B;
        }
        int64_t dm = (M_small[r] - M_small[(l - 1)]);
        total = (total + (((__int128)(dm)) * G_i128(((__int128)(q)))));
        l = (r + 1);
    }
    int64_t max_q = FLOW_CHECKED_DIV((N), ((B + 1)));
    int64_t q = 1;
    while (q <= max_q) {
        int64_t left = (FLOW_CHECKED_DIV((N), ((q + 1))) + 1);
        int64_t right = FLOW_CHECKED_DIV((N), (q));
        if (left <= B) {
            left = (B + 1);
        }
        if (left <= right) {
            int64_t mr = mertens_i64_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i8_i64(right, B, M_small, keys, vals, used, cap);
            int64_t ml = mertens_i64_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i8_i64((left - 1), B, M_small, keys, vals, used, cap);
            total = (total + (((__int128)((mr - ml))) * G_i128(((__int128)(q)))));
        }
        q = (q + 1);
    }
    __int128 MOD9 = 1000000000;
    int64_t last9 = ((int64_t)(FLOW_CHECKED_MOD((total), (MOD9))));
    if (last9 < 0) {
        last9 = (0 - last9);
    }
    __int128 tmp = total;
    if (tmp < ((__int128)(0))) {
        tmp = (((__int128)(0)) - tmp);
    }
    int64_t digs = 0;
    __int128 t2 = tmp;
    while (t2 > ((__int128)(0))) {
        digs = (digs + 1);
        t2 = FLOW_CHECKED_DIV((t2), (((__int128)(10))));
    }
    __int128 div = 1;
    int64_t k = 0;
    while (k < (digs - 9)) {
        div = (div * ((__int128)(10)));
        k = (k + 1);
    }
    int64_t first9 = ((int64_t)(FLOW_CHECKED_DIV((tmp), (div))));
    printf("%lld%09lld\n", first9, last9);
    free(used);
    free(vals);
    free(keys);
    free(M_small);
    free(primes);
    free(lp);
    free(mu);
    return 0;
}

Generated MLIR

module {
  llvm.func @printf(!llvm.ptr, ...) -> i32
  llvm.mlir.global internal constant @str_0("%lld%09lld\n\00") {addr_space = 0 : i32} : !llvm.array<12 x i8>
  func.func private @calloc(i64, i64) -> !llvm.ptr
  func.func private @free(!llvm.ptr) -> ()
  func.func @icbrt128(%arg0: i128) -> i64 {
    %0 = arith.constant 2 : i32
    %1 = arith.extsi %0 : i32 to i128
    %3 = arith.trunci %arg0 : i128 to i64
    %4 = arith.trunci %1 : i128 to i64
    %2 = arith.cmpi slt, %3, %4 : i64
    cf.cond_br %2, ^bb0, ^bb1
    ^bb0:
      %5 = arith.trunci %arg0 : i128 to i64
      func.return %5 : i64
    ^bb1:
      cf.br ^bb2
    ^bb2:
    %6 = arith.constant 1 : i32
    %7 = arith.extsi %6 : i32 to i64
    %8 = llvm.mlir.constant(1 : i64) : i64
    %9 = llvm.alloca %8 x i64 : (i64) -> !llvm.ptr
    llvm.store %7, %9 : i64, !llvm.ptr
    %10 = arith.constant 1 : i32
    %11 = arith.constant 22 : i32
    %12 = arith.shli %10, %11 : i32
    %13 = arith.extsi %12 : i32 to i64
    %14 = llvm.mlir.constant(1 : i64) : i64
    %15 = llvm.alloca %14 x i64 : (i64) -> !llvm.ptr
    llvm.store %13, %15 : i64, !llvm.ptr
    cf.br ^bb3
    ^bb3:
    %16 = llvm.load %9 : !llvm.ptr -> i64
    %17 = llvm.load %15 : !llvm.ptr -> i64
    %18 = arith.cmpi slt, %16, %17 : i64
    cf.cond_br %18, ^bb4, ^bb5
    ^bb4:
      %19 = llvm.load %9 : !llvm.ptr -> i64
      %20 = llvm.load %15 : !llvm.ptr -> i64
      %21 = arith.addi %19, %20 : i64
      %22 = arith.constant 1 : i32
      %24 = arith.extsi %22 : i32 to i64
      %23 = arith.addi %21, %24 : i64
      %25 = arith.constant 2 : i32
      %27 = arith.extsi %25 : i32 to i64
      %26 = arith.divsi %23, %27 : i64
      %28 = arith.extsi %26 : i64 to i128
      %30 = arith.trunci %28 : i128 to i64
      %31 = arith.trunci %28 : i128 to i64
      %29 = arith.muli %30, %31 : i64
      %33 = arith.trunci %28 : i128 to i64
      %32 = arith.muli %29, %33 : i64
      %35 = arith.trunci %arg0 : i128 to i64
      %34 = arith.cmpi sle, %32, %35 : i64
      cf.cond_br %34, ^bb6, ^bb7
      ^bb6:
        llvm.store %26, %9 : i64, !llvm.ptr
        cf.br ^bb8
      ^bb7:
        %36 = arith.constant 1 : i32
        %38 = arith.extsi %36 : i32 to i64
        %37 = arith.subi %26, %38 : i64
        llvm.store %37, %15 : i64, !llvm.ptr
        cf.br ^bb8
      ^bb8:
      cf.br ^bb3
    ^bb5:
    %39 = llvm.load %9 : !llvm.ptr -> i64
    func.return %39 : i64
  }
  func.func @memo_get(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr, %arg3: i64, %arg4: i64, %arg5: !llvm.ptr) -> i32 {
    %40 = llvm.mlir.constant(1 : i64) : i64
    %41 = llvm.alloca %40 x i64 : (i64) -> !llvm.ptr
    llvm.store %arg4, %41 : i64, !llvm.ptr
    %42 = llvm.load %41 : !llvm.ptr -> i64
    %43 = arith.constant 0 : i32
    %45 = arith.extsi %43 : i32 to i64
    %44 = arith.cmpi slt, %42, %45 : i64
    cf.cond_br %44, ^bb9, ^bb10
    ^bb9:
      %46 = arith.constant 0 : i32
      %47 = llvm.load %41 : !llvm.ptr -> i64
      %49 = arith.extsi %46 : i32 to i64
      %48 = arith.subi %49, %47 : i64
      llvm.store %48, %41 : i64, !llvm.ptr
      cf.br ^bb11
    ^bb10:
      cf.br ^bb11
    ^bb11:
    %50 = llvm.load %41 : !llvm.ptr -> i64
    %51 = arith.constant 1 : i32
    %53 = arith.extsi %51 : i32 to i64
    %52 = arith.subi %arg3, %53 : i64
    %54 = arith.andi %50, %52 : i64
    llvm.store %54, %41 : i64, !llvm.ptr
    cf.br ^bb12
    ^bb12:
    %56 = llvm.load %41 : !llvm.ptr -> i64
    %57 = llvm.getelementptr %arg2[%56] : (!llvm.ptr, i64) -> !llvm.ptr, i8
    %55 = llvm.load %57 : !llvm.ptr -> i8
    %58 = arith.constant 0 : i32
    %60 = arith.extsi %55 : i8 to i32
    %59 = arith.cmpi ne, %60, %58 : i32
    cf.cond_br %59, ^bb13, ^bb14
    ^bb13:
      %62 = llvm.load %41 : !llvm.ptr -> i64
      %63 = llvm.getelementptr %arg0[%62] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %61 = llvm.load %63 : !llvm.ptr -> i64
      %64 = arith.cmpi eq, %61, %arg4 : i64
      cf.cond_br %64, ^bb15, ^bb16
      ^bb15:
        %66 = llvm.load %41 : !llvm.ptr -> i64
        %67 = llvm.getelementptr %arg1[%66] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %65 = llvm.load %67 : !llvm.ptr -> i64
        %68 = arith.constant 0 : i32
        %69 = arith.extsi %68 : i32 to i64
        %70 = llvm.getelementptr %arg5[%69] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %65, %70 : i64, !llvm.ptr
        %71 = arith.constant 1 : i32
        func.return %71 : i32
      ^bb16:
        cf.br ^bb17
      ^bb17:
      %72 = llvm.load %41 : !llvm.ptr -> i64
      %73 = arith.constant 1 : i32
      %75 = arith.extsi %73 : i32 to i64
      %74 = arith.addi %72, %75 : i64
      %76 = arith.constant 1 : i32
      %78 = arith.extsi %76 : i32 to i64
      %77 = arith.subi %arg3, %78 : i64
      %79 = arith.andi %74, %77 : i64
      llvm.store %79, %41 : i64, !llvm.ptr
      cf.br ^bb12
    ^bb14:
    %80 = arith.constant 0 : i32
    func.return %80 : i32
  }
  func.func @memo_put(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr, %arg3: i64, %arg4: i64, %arg5: i64) -> () {
    %81 = llvm.mlir.constant(1 : i64) : i64
    %82 = llvm.alloca %81 x i64 : (i64) -> !llvm.ptr
    llvm.store %arg4, %82 : i64, !llvm.ptr
    %83 = llvm.load %82 : !llvm.ptr -> i64
    %84 = arith.constant 0 : i32
    %86 = arith.extsi %84 : i32 to i64
    %85 = arith.cmpi slt, %83, %86 : i64
    cf.cond_br %85, ^bb18, ^bb19
    ^bb18:
      %87 = arith.constant 0 : i32
      %88 = llvm.load %82 : !llvm.ptr -> i64
      %90 = arith.extsi %87 : i32 to i64
      %89 = arith.subi %90, %88 : i64
      llvm.store %89, %82 : i64, !llvm.ptr
      cf.br ^bb20
    ^bb19:
      cf.br ^bb20
    ^bb20:
    %91 = llvm.load %82 : !llvm.ptr -> i64
    %92 = arith.constant 1 : i32
    %94 = arith.extsi %92 : i32 to i64
    %93 = arith.subi %arg3, %94 : i64
    %95 = arith.andi %91, %93 : i64
    llvm.store %95, %82 : i64, !llvm.ptr
    cf.br ^bb21
    ^bb21:
    %97 = llvm.load %82 : !llvm.ptr -> i64
    %98 = llvm.getelementptr %arg2[%97] : (!llvm.ptr, i64) -> !llvm.ptr, i8
    %96 = llvm.load %98 : !llvm.ptr -> i8
    %99 = arith.constant 0 : i32
    %101 = arith.extsi %96 : i8 to i32
    %100 = arith.cmpi ne, %101, %99 : i32
    %102 = scf.if %100 -> (i1) {
      %104 = llvm.load %82 : !llvm.ptr -> i64
      %105 = llvm.getelementptr %arg0[%104] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %103 = llvm.load %105 : !llvm.ptr -> i64
      %106 = arith.cmpi ne, %103, %arg4 : i64
      scf.yield %106 : i1
    } else {
      %107 = arith.constant false
      scf.yield %107 : i1
    }
    cf.cond_br %102, ^bb22, ^bb23
    ^bb22:
      %108 = llvm.load %82 : !llvm.ptr -> i64
      %109 = arith.constant 1 : i32
      %111 = arith.extsi %109 : i32 to i64
      %110 = arith.addi %108, %111 : i64
      %112 = arith.constant 1 : i32
      %114 = arith.extsi %112 : i32 to i64
      %113 = arith.subi %arg3, %114 : i64
      %115 = arith.andi %110, %113 : i64
      llvm.store %115, %82 : i64, !llvm.ptr
      cf.br ^bb21
    ^bb23:
    %116 = arith.constant 1 : i32
    %117 = llvm.load %82 : !llvm.ptr -> i64
    %118 = arith.trunci %116 : i32 to i8
    %119 = llvm.getelementptr %arg2[%117] : (!llvm.ptr, i64) -> !llvm.ptr, i8
    llvm.store %118, %119 : i8, !llvm.ptr
    %120 = llvm.load %82 : !llvm.ptr -> i64
    %121 = llvm.getelementptr %arg0[%120] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %arg4, %121 : i64, !llvm.ptr
    %122 = llvm.load %82 : !llvm.ptr -> i64
    %123 = llvm.getelementptr %arg1[%122] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %arg5, %123 : i64, !llvm.ptr
    func.return
  }
  func.func @mertens(%arg0: i64, %arg1: i64, %arg2: !llvm.ptr, %arg3: !llvm.ptr, %arg4: !llvm.ptr, %arg5: !llvm.ptr, %arg6: i64) -> i64 {
    %124 = arith.cmpi sle, %arg0, %arg1 : i64
    cf.cond_br %124, ^bb24, ^bb25
    ^bb24:
      %126 = llvm.getelementptr %arg2[%arg0] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %125 = llvm.load %126 : !llvm.ptr -> i64
      func.return %125 : i64
    ^bb25:
      cf.br ^bb26
    ^bb26:
    %128 = arith.constant 0 : i32
    %129 = llvm.mlir.constant(1 : i64) : i64
    %130 = llvm.alloca %129 x !llvm.array<1 x i64> : (i64) -> !llvm.ptr
    %131 = llvm.mlir.zero : !llvm.array<1 x i64>
    llvm.store %131, %130 : !llvm.array<1 x i64>, !llvm.ptr
    %132 = arith.extsi %128 : i32 to i64
    %133 = llvm.mlir.constant(0 : i64) : i64
    %134 = llvm.getelementptr %130[0, %133] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.array<1 x i64>
    llvm.store %132, %134 : i64, !llvm.ptr
    %135 = func.call @memo_get(%arg3, %arg4, %arg5, %arg6, %arg0, %130) : (!llvm.ptr, !llvm.ptr, !llvm.ptr, i64, i64, !llvm.ptr) -> i32
    %136 = arith.constant 1 : i32
    %137 = arith.cmpi eq, %135, %136 : i32
    cf.cond_br %137, ^bb27, ^bb28
    ^bb27:
      %139 = arith.constant 0 : i32
      %140 = arith.extsi %139 : i32 to i64
      %141 = llvm.getelementptr %130[0, %140] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.array<1 x i64>
      %138 = llvm.load %141 : !llvm.ptr -> i64
      func.return %138 : i64
    ^bb28:
      cf.br ^bb29
    ^bb29:
    %142 = arith.constant 1 : i32
    %143 = arith.extsi %142 : i32 to i64
    %144 = llvm.mlir.constant(1 : i64) : i64
    %145 = llvm.alloca %144 x i64 : (i64) -> !llvm.ptr
    llvm.store %143, %145 : i64, !llvm.ptr
    %146 = arith.constant 2 : i32
    %147 = arith.extsi %146 : i32 to i64
    %148 = llvm.mlir.constant(1 : i64) : i64
    %149 = llvm.alloca %148 x i64 : (i64) -> !llvm.ptr
    llvm.store %147, %149 : i64, !llvm.ptr
    cf.br ^bb30
    ^bb30:
    %150 = llvm.load %149 : !llvm.ptr -> i64
    %151 = arith.cmpi sle, %150, %arg0 : i64
    cf.cond_br %151, ^bb31, ^bb32
    ^bb31:
      %152 = llvm.load %149 : !llvm.ptr -> i64
      %153 = arith.divsi %arg0, %152 : i64
      %154 = arith.divsi %arg0, %153 : i64
      %155 = llvm.load %145 : !llvm.ptr -> i64
      %156 = llvm.load %149 : !llvm.ptr -> i64
      %157 = arith.subi %154, %156 : i64
      %158 = arith.constant 1 : i32
      %160 = arith.extsi %158 : i32 to i64
      %159 = arith.addi %157, %160 : i64
      %161 = func.call @mertens(%153, %arg1, %arg2, %arg3, %arg4, %arg5, %arg6) : (i64, i64, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, i64) -> i64
      %162 = arith.muli %159, %161 : i64
      %163 = arith.subi %155, %162 : i64
      llvm.store %163, %145 : i64, !llvm.ptr
      %164 = arith.constant 1 : i32
      %166 = arith.extsi %164 : i32 to i64
      %165 = arith.addi %154, %166 : i64
      llvm.store %165, %149 : i64, !llvm.ptr
      cf.br ^bb30
    ^bb32:
    %168 = llvm.load %145 : !llvm.ptr -> i64
    func.call @memo_put(%arg3, %arg4, %arg5, %arg6, %arg0, %168) : (!llvm.ptr, !llvm.ptr, !llvm.ptr, i64, i64, i64) -> ()
    %169 = llvm.load %145 : !llvm.ptr -> i64
    func.return %169 : i64
  }
  func.func @G(%arg0: i128) -> i128 {
    %170 = arith.constant 3 : i32
    %171 = arith.extsi %170 : i32 to i128
    %173 = arith.trunci %arg0 : i128 to i64
    %174 = arith.trunci %171 : i128 to i64
    %172 = arith.addi %173, %174 : i64
    %176 = arith.trunci %arg0 : i128 to i64
    %175 = arith.muli %176, %172 : i64
    %177 = arith.constant 3 : i32
    %178 = arith.extsi %177 : i32 to i128
    %180 = arith.trunci %178 : i128 to i64
    %179 = arith.addi %175, %180 : i64
    %182 = arith.trunci %arg0 : i128 to i64
    %181 = arith.muli %182, %179 : i64
    %183 = arith.extsi %181 : i64 to i128
    func.return %183 : i128
  }
  func.func @main() -> i32 {
    %184 = arith.constant 5705032704 : i32
    %185 = arith.extsi %184 : i32 to i64
    %186 = arith.extsi %185 : i64 to i128
    %187 = arith.extsi %185 : i64 to i128
    %189 = arith.trunci %186 : i128 to i64
    %190 = arith.trunci %187 : i128 to i64
    %188 = arith.muli %189, %190 : i64
    %191 = arith.extsi %188 : i64 to i128
    %192 = func.call @icbrt128(%191) : (i128) -> i64
    %194 = arith.constant 1 : i32
    %196 = arith.extsi %194 : i32 to i64
    %195 = arith.addi %192, %196 : i64
    %197 = arith.constant 1 : i32
    %198 = arith.extsi %197 : i32 to i64
    %193 = func.call @calloc(%195, %198) : (i64, i64) -> !llvm.ptr
    %200 = arith.constant 1 : i32
    %202 = arith.extsi %200 : i32 to i64
    %201 = arith.addi %192, %202 : i64
    %203 = arith.constant 4 : i32
    %204 = arith.extsi %203 : i32 to i64
    %199 = func.call @calloc(%201, %204) : (i64, i64) -> !llvm.ptr
    %206 = arith.constant 5 : i32
    %208 = arith.extsi %206 : i32 to i64
    %207 = arith.divsi %192, %208 : i64
    %209 = arith.constant 10 : i32
    %211 = arith.extsi %209 : i32 to i64
    %210 = arith.addi %207, %211 : i64
    %212 = arith.constant 4 : i32
    %213 = arith.extsi %212 : i32 to i64
    %205 = func.call @calloc(%210, %213) : (i64, i64) -> !llvm.ptr
    %215 = arith.constant 1 : i32
    %217 = arith.extsi %215 : i32 to i64
    %216 = arith.addi %192, %217 : i64
    %218 = arith.constant 8 : i32
    %219 = arith.extsi %218 : i32 to i64
    %214 = func.call @calloc(%216, %219) : (i64, i64) -> !llvm.ptr
    %220 = llvm.mlir.zero : !llvm.ptr
    %221 = llvm.icmp "eq" %193, %220 : !llvm.ptr
    %222 = scf.if %221 -> (i1) {
      %223 = arith.constant true
      scf.yield %223 : i1
    } else {
      %224 = llvm.mlir.zero : !llvm.ptr
      %225 = llvm.icmp "eq" %199, %224 : !llvm.ptr
      scf.yield %225 : i1
    }
    %226 = scf.if %222 -> (i1) {
      %227 = arith.constant true
      scf.yield %227 : i1
    } else {
      %228 = llvm.mlir.zero : !llvm.ptr
      %229 = llvm.icmp "eq" %205, %228 : !llvm.ptr
      scf.yield %229 : i1
    }
    %230 = scf.if %226 -> (i1) {
      %231 = arith.constant true
      scf.yield %231 : i1
    } else {
      %232 = llvm.mlir.zero : !llvm.ptr
      %233 = llvm.icmp "eq" %214, %232 : !llvm.ptr
      scf.yield %233 : i1
    }
    cf.cond_br %230, ^bb33, ^bb34
    ^bb33:
      %234 = arith.constant 1 : i32
      func.return %234 : i32
    ^bb34:
      cf.br ^bb35
    ^bb35:
    %235 = arith.constant 1 : i32
    %236 = arith.constant 1 : i32
    %237 = arith.trunci %235 : i32 to i8
    %238 = arith.extsi %236 : i32 to i64
    %239 = llvm.getelementptr %193[%238] : (!llvm.ptr, i64) -> !llvm.ptr, i8
    llvm.store %237, %239 : i8, !llvm.ptr
    %240 = arith.constant 0 : i32
    %241 = arith.extsi %240 : i32 to i64
    %242 = llvm.mlir.constant(1 : i64) : i64
    %243 = llvm.alloca %242 x i64 : (i64) -> !llvm.ptr
    llvm.store %241, %243 : i64, !llvm.ptr
    %244 = arith.constant 2 : i32
    %245 = arith.extsi %244 : i32 to i64
    %246 = llvm.mlir.constant(1 : i64) : i64
    %247 = llvm.alloca %246 x i64 : (i64) -> !llvm.ptr
    llvm.store %245, %247 : i64, !llvm.ptr
    cf.br ^bb36
    ^bb36:
    %248 = llvm.load %247 : !llvm.ptr -> i64
    %249 = arith.cmpi sle, %248, %192 : i64
    cf.cond_br %249, ^bb37, ^bb38
    ^bb37:
      %251 = llvm.load %247 : !llvm.ptr -> i64
      %252 = llvm.getelementptr %199[%251] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %250 = llvm.load %252 : !llvm.ptr -> i32
      %253 = arith.constant 0 : i32
      %254 = arith.cmpi eq, %250, %253 : i32
      cf.cond_br %254, ^bb39, ^bb40
      ^bb39:
        %255 = llvm.load %247 : !llvm.ptr -> i64
        %256 = arith.trunci %255 : i64 to i32
        %257 = llvm.load %247 : !llvm.ptr -> i64
        %258 = llvm.getelementptr %199[%257] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %256, %258 : i32, !llvm.ptr
        %259 = llvm.load %247 : !llvm.ptr -> i64
        %260 = arith.trunci %259 : i64 to i32
        %261 = llvm.load %243 : !llvm.ptr -> i64
        %262 = llvm.getelementptr %205[%261] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %260, %262 : i32, !llvm.ptr
        %263 = llvm.load %243 : !llvm.ptr -> i64
        %264 = arith.constant 1 : i32
        %266 = arith.extsi %264 : i32 to i64
        %265 = arith.addi %263, %266 : i64
        llvm.store %265, %243 : i64, !llvm.ptr
        %267 = arith.constant 0 : i32
        %268 = arith.constant 1 : i32
        %269 = arith.subi %267, %268 : i32
        %270 = arith.trunci %269 : i32 to i8
        %271 = llvm.load %247 : !llvm.ptr -> i64
        %272 = llvm.getelementptr %193[%271] : (!llvm.ptr, i64) -> !llvm.ptr, i8
        llvm.store %270, %272 : i8, !llvm.ptr
        cf.br ^bb41
      ^bb40:
        cf.br ^bb41
      ^bb41:
      %273 = arith.constant 0 : i32
      %274 = arith.extsi %273 : i32 to i64
      %275 = llvm.mlir.constant(1 : i64) : i64
      %276 = llvm.alloca %275 x i64 : (i64) -> !llvm.ptr
      llvm.store %274, %276 : i64, !llvm.ptr
      cf.br ^bb42
      ^bb42:
      %277 = llvm.load %276 : !llvm.ptr -> i64
      %278 = llvm.load %243 : !llvm.ptr -> i64
      %279 = arith.cmpi slt, %277, %278 : i64
      cf.cond_br %279, ^bb43, ^bb44
      ^bb43:
        %281 = llvm.load %276 : !llvm.ptr -> i64
        %282 = llvm.getelementptr %205[%281] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %280 = llvm.load %282 : !llvm.ptr -> i32
        %283 = arith.extsi %280 : i32 to i64
        %284 = llvm.load %247 : !llvm.ptr -> i64
        %285 = arith.muli %284, %283 : i64
        %286 = arith.cmpi sgt, %285, %192 : i64
        cf.cond_br %286, ^bb45, ^bb46
        ^bb45:
          cf.br ^bb44
        ^bb46:
          cf.br ^bb47
        ^bb47:
        %287 = arith.trunci %283 : i64 to i32
        %288 = llvm.getelementptr %199[%285] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %287, %288 : i32, !llvm.ptr
        %289 = llvm.load %247 : !llvm.ptr -> i64
        %290 = arith.remsi %289, %283 : i64
        %291 = arith.constant 0 : i32
        %293 = arith.extsi %291 : i32 to i64
        %292 = arith.cmpi eq, %290, %293 : i64
        cf.cond_br %292, ^bb48, ^bb49
        ^bb48:
          %294 = arith.constant 0 : i32
          %295 = arith.trunci %294 : i32 to i8
          %296 = llvm.getelementptr %193[%285] : (!llvm.ptr, i64) -> !llvm.ptr, i8
          llvm.store %295, %296 : i8, !llvm.ptr
          cf.br ^bb44
        ^bb49:
          cf.br ^bb50
        ^bb50:
        %297 = arith.constant 0 : i32
        %299 = llvm.load %247 : !llvm.ptr -> i64
        %300 = llvm.getelementptr %193[%299] : (!llvm.ptr, i64) -> !llvm.ptr, i8
        %298 = llvm.load %300 : !llvm.ptr -> i8
        %301 = arith.extsi %298 : i8 to i64
        %303 = arith.extsi %297 : i32 to i64
        %302 = arith.subi %303, %301 : i64
        %304 = arith.trunci %302 : i64 to i8
        %305 = llvm.getelementptr %193[%285] : (!llvm.ptr, i64) -> !llvm.ptr, i8
        llvm.store %304, %305 : i8, !llvm.ptr
        %306 = llvm.load %276 : !llvm.ptr -> i64
        %307 = arith.constant 1 : i32
        %309 = arith.extsi %307 : i32 to i64
        %308 = arith.addi %306, %309 : i64
        llvm.store %308, %276 : i64, !llvm.ptr
        cf.br ^bb42
      ^bb44:
      %310 = llvm.load %247 : !llvm.ptr -> i64
      %311 = arith.constant 1 : i32
      %313 = arith.extsi %311 : i32 to i64
      %312 = arith.addi %310, %313 : i64
      llvm.store %312, %247 : i64, !llvm.ptr
      cf.br ^bb36
    ^bb38:
    %314 = arith.constant 0 : i32
    %315 = arith.extsi %314 : i32 to i64
    %316 = llvm.mlir.constant(1 : i64) : i64
    %317 = llvm.alloca %316 x i64 : (i64) -> !llvm.ptr
    llvm.store %315, %317 : i64, !llvm.ptr
    %318 = arith.constant 1 : i32
    %319 = arith.extsi %318 : i32 to i64
    llvm.store %319, %247 : i64, !llvm.ptr
    cf.br ^bb51
    ^bb51:
    %320 = llvm.load %247 : !llvm.ptr -> i64
    %321 = arith.cmpi sle, %320, %192 : i64
    cf.cond_br %321, ^bb52, ^bb53
    ^bb52:
      %322 = llvm.load %317 : !llvm.ptr -> i64
      %324 = llvm.load %247 : !llvm.ptr -> i64
      %325 = llvm.getelementptr %193[%324] : (!llvm.ptr, i64) -> !llvm.ptr, i8
      %323 = llvm.load %325 : !llvm.ptr -> i8
      %326 = arith.extsi %323 : i8 to i64
      %327 = arith.addi %322, %326 : i64
      llvm.store %327, %317 : i64, !llvm.ptr
      %328 = llvm.load %317 : !llvm.ptr -> i64
      %329 = llvm.load %247 : !llvm.ptr -> i64
      %330 = llvm.getelementptr %214[%329] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %328, %330 : i64, !llvm.ptr
      %331 = llvm.load %247 : !llvm.ptr -> i64
      %332 = arith.constant 1 : i32
      %334 = arith.extsi %332 : i32 to i64
      %333 = arith.addi %331, %334 : i64
      llvm.store %333, %247 : i64, !llvm.ptr
      cf.br ^bb51
    ^bb53:
    %335 = arith.constant 8192 : i32
    %336 = arith.extsi %335 : i32 to i64
    %338 = arith.constant 8 : i32
    %339 = arith.extsi %338 : i32 to i64
    %337 = func.call @calloc(%336, %339) : (i64, i64) -> !llvm.ptr
    %341 = arith.constant 8 : i32
    %342 = arith.extsi %341 : i32 to i64
    %340 = func.call @calloc(%336, %342) : (i64, i64) -> !llvm.ptr
    %344 = arith.constant 1 : i32
    %345 = arith.extsi %344 : i32 to i64
    %343 = func.call @calloc(%336, %345) : (i64, i64) -> !llvm.ptr
    %346 = llvm.mlir.zero : !llvm.ptr
    %347 = llvm.icmp "eq" %337, %346 : !llvm.ptr
    %348 = scf.if %347 -> (i1) {
      %349 = arith.constant true
      scf.yield %349 : i1
    } else {
      %350 = llvm.mlir.zero : !llvm.ptr
      %351 = llvm.icmp "eq" %340, %350 : !llvm.ptr
      scf.yield %351 : i1
    }
    %352 = scf.if %348 -> (i1) {
      %353 = arith.constant true
      scf.yield %353 : i1
    } else {
      %354 = llvm.mlir.zero : !llvm.ptr
      %355 = llvm.icmp "eq" %343, %354 : !llvm.ptr
      scf.yield %355 : i1
    }
    cf.cond_br %352, ^bb54, ^bb55
    ^bb54:
      %356 = arith.constant 1 : i32
      func.return %356 : i32
    ^bb55:
      cf.br ^bb56
    ^bb56:
    %357 = func.call @mertens(%185, %192, %214, %337, %340, %343, %336) : (i64, i64, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, i64) -> i64
    %358 = arith.constant 0 : i32
    %359 = arith.extsi %358 : i32 to i128
    %360 = llvm.mlir.constant(1 : i64) : i64
    %361 = llvm.alloca %360 x i128 : (i64) -> !llvm.ptr
    llvm.store %359, %361 : i128, !llvm.ptr
    %362 = arith.constant 1 : 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
    cf.br ^bb57
    ^bb57:
    %366 = llvm.load %365 : !llvm.ptr -> i64
    %367 = arith.cmpi sle, %366, %192 : i64
    cf.cond_br %367, ^bb58, ^bb59
    ^bb58:
      %368 = llvm.load %365 : !llvm.ptr -> i64
      %369 = arith.divsi %185, %368 : i64
      %370 = arith.divsi %185, %369 : i64
      %371 = llvm.mlir.constant(1 : i64) : i64
      %372 = llvm.alloca %371 x i64 : (i64) -> !llvm.ptr
      llvm.store %370, %372 : i64, !llvm.ptr
      %373 = llvm.load %372 : !llvm.ptr -> i64
      %374 = arith.cmpi sgt, %373, %192 : i64
      cf.cond_br %374, ^bb60, ^bb61
      ^bb60:
        llvm.store %192, %372 : i64, !llvm.ptr
        cf.br ^bb62
      ^bb61:
        cf.br ^bb62
      ^bb62:
      %376 = llvm.load %372 : !llvm.ptr -> i64
      %377 = llvm.getelementptr %214[%376] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %375 = llvm.load %377 : !llvm.ptr -> i64
      %379 = llvm.load %365 : !llvm.ptr -> i64
      %380 = arith.constant 1 : i32
      %382 = arith.extsi %380 : i32 to i64
      %381 = arith.subi %379, %382 : i64
      %383 = llvm.getelementptr %214[%381] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %378 = llvm.load %383 : !llvm.ptr -> i64
      %384 = arith.subi %375, %378 : i64
      %385 = llvm.load %361 : !llvm.ptr -> i128
      %386 = arith.extsi %384 : i64 to i128
      %388 = arith.extsi %369 : i64 to i128
      %387 = func.call @G(%388) : (i128) -> i128
      %390 = arith.trunci %386 : i128 to i64
      %391 = arith.trunci %387 : i128 to i64
      %389 = arith.muli %390, %391 : i64
      %393 = arith.trunci %385 : i128 to i64
      %392 = arith.addi %393, %389 : i64
      %394 = arith.extsi %392 : i64 to i128
      llvm.store %394, %361 : i128, !llvm.ptr
      %395 = llvm.load %372 : !llvm.ptr -> i64
      %396 = arith.constant 1 : i32
      %398 = arith.extsi %396 : i32 to i64
      %397 = arith.addi %395, %398 : i64
      llvm.store %397, %365 : i64, !llvm.ptr
      cf.br ^bb57
    ^bb59:
    %399 = arith.constant 1 : i32
    %401 = arith.extsi %399 : i32 to i64
    %400 = arith.addi %192, %401 : i64
    %402 = arith.divsi %185, %400 : i64
    %403 = arith.constant 1 : i32
    %404 = arith.extsi %403 : i32 to i64
    %405 = llvm.mlir.constant(1 : i64) : i64
    %406 = llvm.alloca %405 x i64 : (i64) -> !llvm.ptr
    llvm.store %404, %406 : i64, !llvm.ptr
    cf.br ^bb63
    ^bb63:
    %407 = llvm.load %406 : !llvm.ptr -> i64
    %408 = arith.cmpi sle, %407, %402 : i64
    cf.cond_br %408, ^bb64, ^bb65
    ^bb64:
      %409 = llvm.load %406 : !llvm.ptr -> i64
      %410 = arith.constant 1 : i32
      %412 = arith.extsi %410 : i32 to i64
      %411 = arith.addi %409, %412 : i64
      %413 = arith.divsi %185, %411 : i64
      %414 = arith.constant 1 : i32
      %416 = arith.extsi %414 : i32 to i64
      %415 = arith.addi %413, %416 : i64
      %417 = llvm.mlir.constant(1 : i64) : i64
      %418 = llvm.alloca %417 x i64 : (i64) -> !llvm.ptr
      llvm.store %415, %418 : i64, !llvm.ptr
      %419 = llvm.load %406 : !llvm.ptr -> i64
      %420 = arith.divsi %185, %419 : i64
      %421 = llvm.load %418 : !llvm.ptr -> i64
      %422 = arith.cmpi sle, %421, %192 : i64
      cf.cond_br %422, ^bb66, ^bb67
      ^bb66:
        %423 = arith.constant 1 : i32
        %425 = arith.extsi %423 : i32 to i64
        %424 = arith.addi %192, %425 : i64
        llvm.store %424, %418 : i64, !llvm.ptr
        cf.br ^bb68
      ^bb67:
        cf.br ^bb68
      ^bb68:
      %426 = llvm.load %418 : !llvm.ptr -> i64
      %427 = arith.cmpi sle, %426, %420 : i64
      cf.cond_br %427, ^bb69, ^bb70
      ^bb69:
        %428 = func.call @mertens(%420, %192, %214, %337, %340, %343, %336) : (i64, i64, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, i64) -> i64
        %430 = llvm.load %418 : !llvm.ptr -> i64
        %431 = arith.constant 1 : i32
        %433 = arith.extsi %431 : i32 to i64
        %432 = arith.subi %430, %433 : i64
        %429 = func.call @mertens(%432, %192, %214, %337, %340, %343, %336) : (i64, i64, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, i64) -> i64
        %434 = llvm.load %361 : !llvm.ptr -> i128
        %435 = arith.subi %428, %429 : i64
        %436 = arith.extsi %435 : i64 to i128
        %438 = llvm.load %406 : !llvm.ptr -> i64
        %439 = arith.extsi %438 : i64 to i128
        %437 = func.call @G(%439) : (i128) -> i128
        %441 = arith.trunci %436 : i128 to i64
        %442 = arith.trunci %437 : i128 to i64
        %440 = arith.muli %441, %442 : i64
        %444 = arith.trunci %434 : i128 to i64
        %443 = arith.addi %444, %440 : i64
        %445 = arith.extsi %443 : i64 to i128
        llvm.store %445, %361 : i128, !llvm.ptr
        cf.br ^bb71
      ^bb70:
        cf.br ^bb71
      ^bb71:
      %446 = llvm.load %406 : !llvm.ptr -> i64
      %447 = arith.constant 1 : i32
      %449 = arith.extsi %447 : i32 to i64
      %448 = arith.addi %446, %449 : i64
      llvm.store %448, %406 : i64, !llvm.ptr
      cf.br ^bb63
    ^bb65:
    %450 = arith.constant 1000000000 : i32
    %451 = arith.extsi %450 : i32 to i128
    %452 = llvm.load %361 : !llvm.ptr -> i128
    %454 = arith.trunci %452 : i128 to i64
    %455 = arith.trunci %451 : i128 to i64
    %453 = arith.remsi %454, %455 : i64
    %456 = arith.constant 0 : i32
    %458 = arith.extsi %456 : i32 to i64
    %457 = arith.cmpi slt, %453, %458 : i64
    %459 = scf.if %457 -> (i64) {
      %460 = arith.constant 0 : i32
      %462 = arith.extsi %460 : i32 to i64
      %461 = arith.subi %462, %453 : i64
      scf.yield %461 : i64
    } else {
      scf.yield %453 : i64
    }
    %463 = llvm.load %361 : !llvm.ptr -> i128
    %464 = llvm.mlir.constant(1 : i64) : i64
    %465 = llvm.alloca %464 x i128 : (i64) -> !llvm.ptr
    llvm.store %463, %465 : i128, !llvm.ptr
    %466 = llvm.load %465 : !llvm.ptr -> i128
    %467 = arith.constant 0 : i32
    %468 = arith.extsi %467 : i32 to i128
    %470 = arith.trunci %466 : i128 to i64
    %471 = arith.trunci %468 : i128 to i64
    %469 = arith.cmpi slt, %470, %471 : i64
    cf.cond_br %469, ^bb72, ^bb73
    ^bb72:
      %472 = arith.constant 0 : i32
      %473 = arith.extsi %472 : i32 to i128
      %474 = llvm.load %465 : !llvm.ptr -> i128
      %476 = arith.trunci %473 : i128 to i64
      %477 = arith.trunci %474 : i128 to i64
      %475 = arith.subi %476, %477 : i64
      %478 = arith.extsi %475 : i64 to i128
      llvm.store %478, %465 : i128, !llvm.ptr
      cf.br ^bb74
    ^bb73:
      cf.br ^bb74
    ^bb74:
    %479 = arith.constant 0 : i32
    %480 = arith.extsi %479 : i32 to i64
    %481 = llvm.mlir.constant(1 : i64) : i64
    %482 = llvm.alloca %481 x i64 : (i64) -> !llvm.ptr
    llvm.store %480, %482 : i64, !llvm.ptr
    %483 = llvm.load %465 : !llvm.ptr -> i128
    %484 = llvm.mlir.constant(1 : i64) : i64
    %485 = llvm.alloca %484 x i128 : (i64) -> !llvm.ptr
    llvm.store %483, %485 : i128, !llvm.ptr
    cf.br ^bb75
    ^bb75:
    %486 = llvm.load %485 : !llvm.ptr -> i128
    %487 = arith.constant 0 : i32
    %488 = arith.extsi %487 : i32 to i128
    %490 = arith.trunci %486 : i128 to i64
    %491 = arith.trunci %488 : i128 to i64
    %489 = arith.cmpi sgt, %490, %491 : i64
    cf.cond_br %489, ^bb76, ^bb77
    ^bb76:
      %492 = llvm.load %482 : !llvm.ptr -> i64
      %493 = arith.constant 1 : i32
      %495 = arith.extsi %493 : i32 to i64
      %494 = arith.addi %492, %495 : i64
      llvm.store %494, %482 : i64, !llvm.ptr
      %496 = llvm.load %485 : !llvm.ptr -> i128
      %497 = arith.constant 10 : i32
      %498 = arith.extsi %497 : i32 to i128
      %500 = arith.trunci %496 : i128 to i64
      %501 = arith.trunci %498 : i128 to i64
      %499 = arith.divsi %500, %501 : i64
      %502 = arith.extsi %499 : i64 to i128
      llvm.store %502, %485 : i128, !llvm.ptr
      cf.br ^bb75
    ^bb77:
    %503 = arith.constant 1 : i32
    %504 = arith.extsi %503 : i32 to i128
    %505 = llvm.mlir.constant(1 : i64) : i64
    %506 = llvm.alloca %505 x i128 : (i64) -> !llvm.ptr
    llvm.store %504, %506 : i128, !llvm.ptr
    %507 = arith.constant 0 : i32
    %508 = arith.extsi %507 : i32 to i64
    %509 = llvm.mlir.constant(1 : i64) : i64
    %510 = llvm.alloca %509 x i64 : (i64) -> !llvm.ptr
    llvm.store %508, %510 : i64, !llvm.ptr
    cf.br ^bb78
    ^bb78:
    %511 = llvm.load %510 : !llvm.ptr -> i64
    %512 = llvm.load %482 : !llvm.ptr -> i64
    %513 = arith.constant 9 : i32
    %515 = arith.extsi %513 : i32 to i64
    %514 = arith.subi %512, %515 : i64
    %516 = arith.cmpi slt, %511, %514 : i64
    cf.cond_br %516, ^bb79, ^bb80
    ^bb79:
      %517 = llvm.load %506 : !llvm.ptr -> i128
      %518 = arith.constant 10 : i32
      %519 = arith.extsi %518 : i32 to i128
      %521 = arith.trunci %517 : i128 to i64
      %522 = arith.trunci %519 : i128 to i64
      %520 = arith.muli %521, %522 : i64
      %523 = arith.extsi %520 : i64 to i128
      llvm.store %523, %506 : i128, !llvm.ptr
      %524 = llvm.load %510 : !llvm.ptr -> i64
      %525 = arith.constant 1 : i32
      %527 = arith.extsi %525 : i32 to i64
      %526 = arith.addi %524, %527 : i64
      llvm.store %526, %510 : i64, !llvm.ptr
      cf.br ^bb78
    ^bb80:
    %528 = llvm.load %465 : !llvm.ptr -> i128
    %529 = llvm.load %506 : !llvm.ptr -> i128
    %531 = arith.trunci %528 : i128 to i64
    %532 = arith.trunci %529 : i128 to i64
    %530 = arith.divsi %531, %532 : i64
    %533 = llvm.mlir.addressof @str_0 : !llvm.ptr
    %534 = llvm.call @printf(%533, %530, %459) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i64, i64) -> i32
    func.call @free(%343) : (!llvm.ptr) -> ()
    func.call @free(%340) : (!llvm.ptr) -> ()
    func.call @free(%337) : (!llvm.ptr) -> ()
    func.call @free(%214) : (!llvm.ptr) -> ()
    func.call @free(%205) : (!llvm.ptr) -> ()
    func.call @free(%199) : (!llvm.ptr) -> ()
    func.call @free(%193) : (!llvm.ptr) -> ()
    %542 = arith.constant 0 : i32
    func.return %542 : i32
  }
}