Problem 950

Pirate Treasure. Exact integer arithmetic with i128. Compute sum_{k=1..6} T(10^16, 10^k+1, 1/sqrt(10^k+1)) mod 10^9.

Answer429162542
Output429162542
StatusPASS
Native helperno
Runtime20 ms
Peak memory1072 KB
Time complexityO(n^2) (estimated)
Space complexityO(1) (estimated)

Performance comparison

MetricOur solutionBest known
Time complexityO(n^2)O(n log n)
Space complexityO(1)O(n)
ApproachFlow solutionModular DP or matrix exponentiation
VerdictSuboptimal

Flow source

# Project Euler 950
# Pirate Treasure. Exact integer arithmetic with i128.
# Compute sum_{k=1..6} T(10^16, 10^k+1, 1/sqrt(10^k+1)) mod 10^9.

const MOD9: i128 = 1000000000

function isqrt128(x: i128) -> i128 {
    if x <= 0 { return 0 }
    # Check if fits in i64 path
    if x < (1 as i128) << 63 {
        let mut r: i128 = x
        let mut s: i128 = 0
        let mut b: i128 = (1 as i128) << 62
        while b > r { b = b >> 2 }
        while b > 0 {
            if r >= s + b {
                r = r - (s + b)
                s = (s >> 1) + b
            } else {
                s = s >> 1
            }
            b = b >> 2
        }
        return s
    }
    # Newton's method for large values
    let mut bits: i64 = 0
    let mut tmp: i128 = x
    while tmp > 0 {
        bits = bits + 1
        tmp = tmp >> 1
    }
    let mut r: i128 = (1 as i128) << (bits / 2 + 1)
    while true {
        let next: i128 = (r + x / r) / 2
        if next >= r { break }
        r = next
    }
    while r * r > x { r = r - 1 }
    while (r + 1) * (r + 1) <= x { r = r + 1 }
    return r
}

function floor_div_sqrt(d: i128, D: i128) -> i128 {
    if d <= 0 { return 0 }
    let dd: i128 = d * d
    let mut t: i128 = isqrt128(dd / D)
    while (t + 1) * (t + 1) * D <= dd { t = t + 1 }
    while t * t * D > dd { t = t - 1 }
    return t
}

function ceil_div_sqrt(d: i128, D: i128) -> i128 {
    if d <= 0 { return 0 }
    return floor_div_sqrt(d, D) + 1
}

function initial_prefix_sum(N: i128, C: i128) -> i128 {
    if N <= 0 { return 0 }
    let limit: i128 = 2 * C + 2
    let mut M: i128 = N
    if M > limit { M = limit }
    if M > 2 * C { M = 2 * C }
    if M <= 0 { return 0 }

    let m: i128 = M / 2
    let mut s: i128 = 2 * (m * C - (m * (m - 1)) / 2)
    if M % 2 == 1 {
        s = s + (C - m)
    }
    return s
}

function next_reset(L: i128, C: i128, D: i128) -> i128 {
    if C == 0 {
        return 2 * L
    }

    let mut t: i128 = 1
    while t <= C {
        let y: i128 = C / t
        let x: i128 = 2 * L - 2 * y
        let d: i128 = x - L
        if d > 0 {
            let s: i128 = ceil_div_sqrt(d, D)
            if C / s == y {
                return x
            }
        }
        t = C / y + 1
    }

    return 2 * L
}

function T_func(N: i128, C: i128, D: i128) -> i128 {
    if N <= 0 { return 0 }

    let start_reset: i128 = 2 * C + 2
    if N <= start_reset {
        return initial_prefix_sum(N, C)
    }

    let mut total: i128 = initial_prefix_sum(start_reset, C)
    let mut L: i128 = start_reset
    let mut cL: i128 = 0

    while L < N {
        let x: i128 = next_reset(L, C, D)
        if x > N {
            let d: i128 = N - L + 1
            total = total + (d - 1) * cL + (d - 1) * d / 2
            break
        }

        let d: i128 = x - L
        if d > 1 {
            total = total + (d - 1) * cL + (d - 1) * d / 2
        }

        let required_votes: i128 = (x + 1) / 2
        let free_votes: i128 = d
        let mut need_bribes: i128 = required_votes - free_votes
        if need_bribes < 0 { need_bribes = 0 }

        let s: i128 = ceil_div_sqrt(d, D)
        let cost: i128 = need_bribes * s
        cL = C - cost

        total = total + cL
        L = x
    }

    return total
}

function main() -> i32 {
    let mut Nval: i128 = 1
    for i in 0..16 {
        Nval = Nval * 10
    }

    let mut acc: i128 = 0
    for k in 1..7 {
        let mut C: i128 = 1
        for j in 0..k {
            C = C * 10
        }
        C = C + 1
        acc = acc + T_func(Nval, C, C)
    }

    let mut result: i128 = acc % MOD9
    if result < 0 { result = result + MOD9 }
    printf("%lld\n", result as i64)
    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; }

__int128 isqrt128_i128(__int128 x);
__int128 floor_div_sqrt_i128_i128(__int128 d, __int128 D);
__int128 ceil_div_sqrt_i128_i128(__int128 d, __int128 D);
__int128 initial_prefix_sum_i128_i128(__int128 N, __int128 C);
__int128 next_reset_i128_i128_i128(__int128 L, __int128 C, __int128 D);
__int128 T_func_i128_i128_i128(__int128 N, __int128 C, __int128 D);
int32_t main(void);

static const __int128 MOD9 = 1000000000;

__int128 isqrt128_i128(__int128 x) {
    if (x <= 0) {
        return 0;
    }
    if (x < FLOW_CHECKED_SHL((((__int128)(1))), (63))) {
        __int128 r = x;
        __int128 s = 0;
        __int128 b = FLOW_CHECKED_SHL((((__int128)(1))), (62));
        while (b > r) {
            b = FLOW_CHECKED_SHR((b), (2));
        }
        while (b > 0) {
            if (r >= (s + b)) {
                r = (r - (s + b));
                s = (FLOW_CHECKED_SHR((s), (1)) + b);
            } else {
                s = FLOW_CHECKED_SHR((s), (1));
            }
            b = FLOW_CHECKED_SHR((b), (2));
        }
        return s;
    }
    int64_t bits = 0;
    __int128 tmp = x;
    while (tmp > 0) {
        bits = (bits + 1);
        tmp = FLOW_CHECKED_SHR((tmp), (1));
    }
    __int128 r = FLOW_CHECKED_SHL((((__int128)(1))), ((FLOW_CHECKED_DIV((bits), (2)) + 1)));
    while (1) {
        __int128 next = FLOW_CHECKED_DIV(((r + FLOW_CHECKED_DIV((x), (r)))), (2));
        if (next >= r) {
            break;
        }
        r = next;
    }
    while ((r * r) > x) {
        r = (r - 1);
    }
    while (((r + 1) * (r + 1)) <= x) {
        r = (r + 1);
    }
    return r;
}

__int128 floor_div_sqrt_i128_i128(__int128 d, __int128 D) {
    if (d <= 0) {
        return 0;
    }
    __int128 dd = (d * d);
    __int128 t = isqrt128_i128(FLOW_CHECKED_DIV((dd), (D)));
    while ((((t + 1) * (t + 1)) * D) <= dd) {
        t = (t + 1);
    }
    while (((t * t) * D) > dd) {
        t = (t - 1);
    }
    return t;
}

__int128 ceil_div_sqrt_i128_i128(__int128 d, __int128 D) {
    if (d <= 0) {
        return 0;
    }
    return (floor_div_sqrt_i128_i128(d, D) + 1);
}

__int128 initial_prefix_sum_i128_i128(__int128 N, __int128 C) {
    if (N <= 0) {
        return 0;
    }
    __int128 limit = ((2 * C) + 2);
    __int128 M = N;
    if (M > limit) {
        M = limit;
    }
    if (M > (2 * C)) {
        M = (2 * C);
    }
    if (M <= 0) {
        return 0;
    }
    __int128 m = FLOW_CHECKED_DIV((M), (2));
    __int128 s = (2 * ((m * C) - FLOW_CHECKED_DIV(((m * (m - 1))), (2))));
    if (FLOW_CHECKED_MOD((M), (2)) == 1) {
        s = (s + (C - m));
    }
    return s;
}

__int128 next_reset_i128_i128_i128(__int128 L, __int128 C, __int128 D) {
    if (C == 0) {
        return (2 * L);
    }
    __int128 t = 1;
    while (t <= C) {
        __int128 y = FLOW_CHECKED_DIV((C), (t));
        __int128 x = ((2 * L) - (2 * y));
        __int128 d = (x - L);
        if (d > 0) {
            __int128 s = ceil_div_sqrt_i128_i128(d, D);
            if (FLOW_CHECKED_DIV((C), (s)) == y) {
                return x;
            }
        }
        t = (FLOW_CHECKED_DIV((C), (y)) + 1);
    }
    return (2 * L);
}

__int128 T_func_i128_i128_i128(__int128 N, __int128 C, __int128 D) {
    if (N <= 0) {
        return 0;
    }
    __int128 start_reset = ((2 * C) + 2);
    if (N <= start_reset) {
        return initial_prefix_sum_i128_i128(N, C);
    }
    __int128 total = initial_prefix_sum_i128_i128(start_reset, C);
    __int128 L = start_reset;
    __int128 cL = 0;
    while (L < N) {
        __int128 x = next_reset_i128_i128_i128(L, C, D);
        if (x > N) {
            __int128 d = ((N - L) + 1);
            total = ((total + ((d - 1) * cL)) + FLOW_CHECKED_DIV((((d - 1) * d)), (2)));
            break;
        }
        __int128 d = (x - L);
        if (d > 1) {
            total = ((total + ((d - 1) * cL)) + FLOW_CHECKED_DIV((((d - 1) * d)), (2)));
        }
        __int128 required_votes = FLOW_CHECKED_DIV(((x + 1)), (2));
        __int128 free_votes = d;
        __int128 need_bribes = (required_votes - free_votes);
        if (need_bribes < 0) {
            need_bribes = 0;
        }
        __int128 s = ceil_div_sqrt_i128_i128(d, D);
        __int128 cost = (need_bribes * s);
        cL = (C - cost);
        total = (total + cL);
        L = x;
    }
    return total;
}

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