Problem 738

Counting Ordered Factorisations: D(10^10, 10^10) mod 1e9+7. Pure Flow port of the native C solver.

Answer143091030
Output143091030
StatusPASS
Native helperno
Runtime1630 ms
Peak memory132208 KB
Time complexityO(n) (estimated)
Space complexityO(n^2) (estimated)

Performance comparison

MetricOur solutionBest known
Time complexityO(n)O(sqrt(n))
Space complexityO(n^2)O(1)
ApproachFlow solutionTrial division or Pollard rho
VerdictSuboptimal

Flow source

# Project Euler 738
# Counting Ordered Factorisations: D(10^10, 10^10) mod 1e9+7.
# Pure Flow port of the native C solver.

extern {
    function calloc(n: i64, size: i64) -> ptr<void>
    function free(p: ptr<void>) -> void
    function memset(s: ptr<void>, c: i64, n: i64) -> ptr<void>
    function sqrt(x: f64) -> f64
    function cbrt(x: f64) -> f64
}

const MOD: i64 = 1000000007
const HASH_CAP: i64 = 4194304

# Hash table: parallel arrays for (m, a, c, l)
let mut htab_m: ptr<i64> = null
let mut htab_a: ptr<i64> = null
let mut htab_c: ptr<i64> = null
let mut htab_l: ptr<i64> = null

function icbrt_floor(n: i64) -> i64 {
    if n <= 0 { return 0 }
    let mut r: i64 = cbrt(n as f64) as i64
    while (r + 1) * (r + 1) * (r + 1) <= n {
        r = r + 1
    }
    while r * r * r > n {
        r = r - 1
    }
    return r
}

function sum_floor_range(m: i64, l: i64, r: i64) -> i64 {
    let mut res: i64 = 0
    let mut i: i64 = l
    while i <= r {
        let q: i64 = m / i
        let mut j: i64 = m / q
        if j > r { j = r }
        res = res + q * (j - i + 1)
        i = j + 1
    }
    return res
}

function sum_arith(l: i64, r: i64) -> i64 {
    let n: i64 = r - l + 1
    return (l + r) * n / 2
}

function htab_init() -> void {
    htab_m = calloc(HASH_CAP, 8) as ptr<i64>
    htab_a = calloc(HASH_CAP, 8) as ptr<i64>
    htab_c = calloc(HASH_CAP, 8) as ptr<i64>
    htab_l = calloc(HASH_CAP, 8) as ptr<i64>
}

function htab_get(m: i64, a: i64, cp: ptr<i64>, lp: ptr<i64>) -> i32 {
    let mut h: i64 = m * 1000003 + a
    h = h ^ (h >> 16)
    let mut idx: i64 = h & (HASH_CAP - 1)
    while true {
        if htab_m[idx] == 0 && htab_a[idx] == 0 {
            return 0
        }
        if htab_m[idx] == m && htab_a[idx] == a {
            cp[0] = htab_c[idx]
            lp[0] = htab_l[idx]
            return 1
        }
        idx = (idx + 1) & (HASH_CAP - 1)
    }
    return 0
}

function htab_put(m: i64, a: i64, c: i64, l: i64) -> void {
    let mut h: i64 = m * 1000003 + a
    h = h ^ (h >> 16)
    let mut idx: i64 = h & (HASH_CAP - 1)
    while true {
        if htab_m[idx] == 0 && htab_a[idx] == 0 {
            htab_m[idx] = m
            htab_a[idx] = a
            htab_c[idx] = c
            htab_l[idx] = l
            return
        }
        if htab_m[idx] == m && htab_a[idx] == a {
            htab_c[idx] = c
            htab_l[idx] = l
            return
        }
        idx = (idx + 1) & (HASH_CAP - 1)
    }
}

function count_and_length(m: i64, a: i64, Cp: ptr<i64>, Lp: ptr<i64>) -> void {
    if m < a {
        Cp[0] = 0
        Lp[0] = 0
        return
    }

    let cc_buf: array<i64, 1> = [0]
    let ll_buf: array<i64, 1> = [0]
    if htab_get(m, a, &cc_buf[0], &ll_buf[0]) == 1 {
        Cp[0] = cc_buf[0]
        Lp[0] = ll_buf[0]
        return
    }

    let aa: i64 = a * a
    let mut C: i64 = 0
    let mut L: i64 = 0

    if aa > m {
        let cnt: i64 = (m - a + 1) % MOD
        C = cnt
        L = cnt
    } else {
        C = m - a + 1
        L = C

        let mut s: i64 = sqrt(m as f64) as i64
        while (s + 1) * (s + 1) <= m {
            s = s + 1
        }
        while s * s > m {
            s = s - 1
        }

        if aa * a > m {
            let l: i64 = a
            if l <= s {
                let sf: i64 = sum_floor_range(m, l, s)
                let sa: i64 = sum_arith(l, s)
                let baseC: i64 = sf - sa + (s - l + 1)
                C = C + baseC
                L = L + 2 * baseC
            }
        } else {
            let t: i64 = icbrt_floor(m)
            let mut upto: i64 = t
            if s < t { upto = s }

            if upto >= a {
                let mut f: i64 = a
                while f <= upto {
                    let subC_buf: array<i64, 1> = [0]
                    let subL_buf: array<i64, 1> = [0]
                    count_and_length(m / f, f, &subC_buf[0], &subL_buf[0])
                    let subC: i64 = subC_buf[0]
                    let subL: i64 = subL_buf[0]
                    C = C + subC
                    L = L + subL + subC
                    f = f + 1
                }
            }

            let mut l2: i64 = upto + 1
            if a > upto + 1 { l2 = a }
            if l2 <= s {
                let sf: i64 = sum_floor_range(m, l2, s)
                let sa: i64 = sum_arith(l2, s)
                let baseC: i64 = sf - sa + (s - l2 + 1)
                C = C + baseC
                L = L + 2 * baseC
            }
        }
    }

    C = C % MOD
    L = L % MOD
    htab_put(m, a, C, L)
    Cp[0] = C
    Lp[0] = L
}

function main() -> i32 {
    htab_init()
    let N: i64 = 10000000000
    let K: i64 = 10000000000
    let C_buf: array<i64, 1> = [0]
    let L_buf: array<i64, 1> = [0]
    count_and_length(N, 2, &C_buf[0], &L_buf[0])
    let C: i64 = C_buf[0]
    let L: i64 = L_buf[0]
    let mut ans: i64 = (K % MOD) + (K + 1) % MOD * C % MOD - L
    ans = ans % MOD
    if ans < 0 { ans = ans + MOD }
    printf("%lld\n", ans)
    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; }

double cbrt(double x);
int64_t icbrt_floor_i64(int64_t n);
int64_t sum_floor_range_i64_i64_i64(int64_t m, int64_t l, int64_t r);
int64_t sum_arith_i64_i64(int64_t l, int64_t r);
void htab_init(void);
int32_t htab_get_i64_i64_ptr_i64_ptr_i64(int64_t m, int64_t a, int64_t* cp, int64_t* lp);
void htab_put_i64_i64_i64_i64(int64_t m, int64_t a, int64_t c, int64_t l);
void count_and_length_i64_i64_ptr_i64_ptr_i64(int64_t m, int64_t a, int64_t* Cp, int64_t* Lp);
int32_t main(void);

static const int64_t MOD = 1000000007;
static const int64_t HASH_CAP = 4194304;

/* Module statics */
static int64_t* htab_m = NULL;
static int64_t* htab_a = NULL;
static int64_t* htab_c = NULL;
static int64_t* htab_l = NULL;






int64_t icbrt_floor_i64(int64_t n) {
    if (n <= 0) {
        return 0;
    }
    int64_t r = ((int64_t)(cbrt(((double)(n)))));
    while ((((r + 1) * (r + 1)) * (r + 1)) <= n) {
        r = (r + 1);
    }
    while (((r * r) * r) > n) {
        r = (r - 1);
    }
    return r;
}

int64_t sum_floor_range_i64_i64_i64(int64_t m, int64_t l, int64_t r) {
    int64_t res = 0;
    int64_t i = l;
    while (i <= r) {
        int64_t q = FLOW_CHECKED_DIV((m), (i));
        int64_t j = FLOW_CHECKED_DIV((m), (q));
        if (j > r) {
            j = r;
        }
        res = (res + (q * ((j - i) + 1)));
        i = (j + 1);
    }
    return res;
}

int64_t sum_arith_i64_i64(int64_t l, int64_t r) {
    int64_t n = ((r - l) + 1);
    return FLOW_CHECKED_DIV((((l + r) * n)), (2));
}

void htab_init(void) {
    htab_m = ((int64_t*)(calloc(HASH_CAP, 8)));
    htab_a = ((int64_t*)(calloc(HASH_CAP, 8)));
    htab_c = ((int64_t*)(calloc(HASH_CAP, 8)));
    htab_l = ((int64_t*)(calloc(HASH_CAP, 8)));
}

int32_t htab_get_i64_i64_ptr_i64_ptr_i64(int64_t m, int64_t a, int64_t* cp, int64_t* lp) {
    int64_t h = ((m * 1000003) + a);
    h = (h ^ FLOW_CHECKED_SHR((h), (16)));
    int64_t idx = (h & (HASH_CAP - 1));
    while (1) {
        if ((htab_m[idx] == 0 && htab_a[idx] == 0)) {
            return 0;
        }
        if ((htab_m[idx] == m && htab_a[idx] == a)) {
            cp[0] = htab_c[idx];
            lp[0] = htab_l[idx];
            return 1;
        }
        idx = ((idx + 1) & (HASH_CAP - 1));
    }
    return 0;
}

void htab_put_i64_i64_i64_i64(int64_t m, int64_t a, int64_t c, int64_t l) {
    int64_t h = ((m * 1000003) + a);
    h = (h ^ FLOW_CHECKED_SHR((h), (16)));
    int64_t idx = (h & (HASH_CAP - 1));
    while (1) {
        if ((htab_m[idx] == 0 && htab_a[idx] == 0)) {
            htab_m[idx] = m;
            htab_a[idx] = a;
            htab_c[idx] = c;
            htab_l[idx] = l;
            return;
        }
        if ((htab_m[idx] == m && htab_a[idx] == a)) {
            htab_c[idx] = c;
            htab_l[idx] = l;
            return;
        }
        idx = ((idx + 1) & (HASH_CAP - 1));
    }
}

void count_and_length_i64_i64_ptr_i64_ptr_i64(int64_t m, int64_t a, int64_t* Cp, int64_t* Lp) {
    if (m < a) {
        Cp[0] = 0;
        Lp[0] = 0;
        return;
    }
    int64_t cc_buf[1] = { 0 };
    int64_t ll_buf[1] = { 0 };
    if (htab_get_i64_i64_ptr_i64_ptr_i64(m, a, (&(cc_buf[0])), (&(ll_buf[0]))) == 1) {
        Cp[0] = (((unsigned)(0) < 1) ? cc_buf[0] : (fprintf(stderr, "array index %d out of bounds (size %d)\n", (int)(0), 1), flow_fault_handler("array index out of bounds"), cc_buf[0]));
        Lp[0] = (((unsigned)(0) < 1) ? ll_buf[0] : (fprintf(stderr, "array index %d out of bounds (size %d)\n", (int)(0), 1), flow_fault_handler("array index out of bounds"), ll_buf[0]));
        return;
    }
    int64_t aa = (a * a);
    int64_t C = 0;
    int64_t L = 0;
    if (aa > m) {
        int64_t cnt = FLOW_CHECKED_MOD((((m - a) + 1)), (MOD));
        C = cnt;
        L = cnt;
    } else {
        C = ((m - a) + 1);
        L = C;
        int64_t s = ((int64_t)(sqrt(((double)(m)))));
        while (((s + 1) * (s + 1)) <= m) {
            s = (s + 1);
        }
        while ((s * s) > m) {
            s = (s - 1);
        }
        if ((aa * a) > m) {
            int64_t l = a;
            if (l <= s) {
                int64_t sf = sum_floor_range_i64_i64_i64(m, l, s);
                int64_t sa = sum_arith_i64_i64(l, s);
                int64_t baseC = ((sf - sa) + ((s - l) + 1));
                C = (C + baseC);
                L = (L + (2 * baseC));
            }
        } else {
            int64_t t = icbrt_floor_i64(m);
            int64_t upto = t;
            if (s < t) {
                upto = s;
            }
            if (upto >= a) {
                int64_t f = a;
                while (f <= upto) {
                    int64_t subC_buf[1] = { 0 };
                    int64_t subL_buf[1] = { 0 };
                    count_and_length_i64_i64_ptr_i64_ptr_i64(FLOW_CHECKED_DIV((m), (f)), f, (&(subC_buf[0])), (&(subL_buf[0])));
                    int64_t subC = (((unsigned)(0) < 1) ? subC_buf[0] : (fprintf(stderr, "array index %d out of bounds (size %d)\n", (int)(0), 1), flow_fault_handler("array index out of bounds"), subC_buf[0]));
                    int64_t subL = (((unsigned)(0) < 1) ? subL_buf[0] : (fprintf(stderr, "array index %d out of bounds (size %d)\n", (int)(0), 1), flow_fault_handler("array index out of bounds"), subL_buf[0]));
                    C = (C + subC);
                    L = ((L + subL) + subC);
                    f = (f + 1);
                }
            }
            int64_t l2 = (upto + 1);
            if (a > (upto + 1)) {
                l2 = a;
            }
            if (l2 <= s) {
                int64_t sf = sum_floor_range_i64_i64_i64(m, l2, s);
                int64_t sa = sum_arith_i64_i64(l2, s);
                int64_t baseC = ((sf - sa) + ((s - l2) + 1));
                C = (C + baseC);
                L = (L + (2 * baseC));
            }
        }
    }
    C = FLOW_CHECKED_MOD((C), (MOD));
    L = FLOW_CHECKED_MOD((L), (MOD));
    htab_put_i64_i64_i64_i64(m, a, C, L);
    Cp[0] = C;
    Lp[0] = L;
}

int32_t main(void) {
    htab_init();
    int64_t N = 10000000000;
    int64_t K = 10000000000;
    int64_t C_buf[1] = { 0 };
    int64_t L_buf[1] = { 0 };
    count_and_length_i64_i64_ptr_i64_ptr_i64(N, 2, (&(C_buf[0])), (&(L_buf[0])));
    int64_t C = (((unsigned)(0) < 1) ? C_buf[0] : (fprintf(stderr, "array index %d out of bounds (size %d)\n", (int)(0), 1), flow_fault_handler("array index out of bounds"), C_buf[0]));
    int64_t L = (((unsigned)(0) < 1) ? L_buf[0] : (fprintf(stderr, "array index %d out of bounds (size %d)\n", (int)(0), 1), flow_fault_handler("array index out of bounds"), L_buf[0]));
    int64_t ans = ((FLOW_CHECKED_MOD((K), (MOD)) + FLOW_CHECKED_MOD(((FLOW_CHECKED_MOD(((K + 1)), (MOD)) * C)), (MOD))) - L);
    ans = FLOW_CHECKED_MOD((ans), (MOD));
    if (ans < 0) {
        ans = (ans + MOD);
    }
    printf("%lld\n", ans);
    return 0;
}

Generated MLIR

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