Problem 508

Integers in Base i-1 — B(10^15) mod 1e9+7 via recursive region sums.

Answer891874596
Output891874596
StatusPASS
Native helperno
Runtime0 ms
Peak memory17168 KB
Time complexityO(n^2) (estimated)
Space complexityO(n^2) (estimated)

Performance comparison

MetricOur solutionBest known
Time complexityO(n^2)?
Space complexityO(n^2)?
ApproachFlow solutionNot curated
VerdictUnknown

Flow source

# Project Euler 508
# Integers in Base i-1 — B(10^15) mod 1e9+7 via recursive region sums.

const MOD: i64 = 1000000007
const LIM: i64 = 1000000000000000
const BRUTE: i64 = 4000
const CAP: i64 = 1048576

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

function floordiv(a: i64, b: i64) -> i64 {
    if b == 0 { return 0 }
    let q: i64 = a / b
    let r: i64 = a - q * b
    if r != 0 && ((r > 0) != (b > 0)) { q = q - 1 }
    return q
}

function f_gauss(a0: i64, b0: i64) -> i64 {
    let mut a: i64 = a0
    let mut b: i64 = b0
    let mut cnt: i64 = 0
    while a != 0 || b != 0 {
        if ((a ^ b) & 1) != 0 {
            a = a - 1
            cnt = cnt + 1
        }
        let na: i64 = floordiv(b - a, 2)
        let nb: i64 = floordiv(-(a + b), 2)
        a = na
        b = nb
    }
    return cnt
}

function count_rect(x0: i64, x1: i64, y0: i64, y1: i64) -> i128 {
    if x0 > x1 || y0 > y1 { return 0 as i128 }
    let w: i128 = ((x1 - x0 + 1) as i128)
    let h: i128 = ((y1 - y0 + 1) as i128)
    return w * h
}

function count_parity(lo: i64, hi: i64, parity: i64) -> i64 {
    if lo > hi { return 0 }
    let mut first: i64 = lo
    if (lo & 1) != parity { first = lo + 1 }
    if first > hi { return 0 }
    return floordiv(hi - first, 2) + 1
}

function count_diamond(u0: i64, u1: i64, v0: i64, v1: i64) -> i128 {
    if u0 > u1 || v0 > v1 { return 0 as i128 }
    let eu: i128 = (count_parity(u0, u1, 0) as i128)
    let ou: i128 = ((u1 - u0 + 1) as i128) - eu
    let ev: i128 = (count_parity(v0, v1, 0) as i128)
    let ov: i128 = ((v1 - v0 + 1) as i128) - ev
    return eu * ev + ou * ov
}

function ceil_div(n: i64, d: i64) -> i64 {
    return -floordiv(-n, d)
}

function hkey(a0: i64, a1: i64, b0: i64, b1: i64, tag: i64) -> i64 {
    let P: i128 = 1000000000000000003 as i128
    let mut k: i128 = (tag as i128)
    k = (k * (1000003 as i128) + (a0 as i128)) % P
    k = (k * (1000003 as i128) + (a1 as i128)) % P
    k = (k * (1000003 as i128) + (b0 as i128)) % P
    k = (k * (1000003 as i128) + (b1 as i128)) % P
    if k < 0 { k = k + P }
    return k as i64
}

function hslot(key: i64, keys: ptr<i64>, used: ptr<i8>) -> i64 {
    let mut h: i64 = key % CAP
    if h < 0 { h = h + CAP }
    while used[h] == 1 && keys[h] != key {
        h = h + 1
        if h == CAP { h = 0 }
    }
    return h
}

function brute_rect(x0: i64, x1: i64, y0: i64, y1: i64) -> i64 {
    let mut s: i64 = 0
    let mut a: i64 = x0
    while a <= x1 {
        let mut b: i64 = y0
        while b <= y1 {
            s = s + f_gauss(a, b)
            b = b + 1
        }
        a = a + 1
    }
    return s % MOD
}

function brute_diamond(u0: i64, u1: i64, v0: i64, v1: i64) -> i64 {
    let mut s: i64 = 0
    let mut u: i64 = u0
    while u <= u1 {
        let parity: i64 = u & 1
        let mut v: i64 = v0
        if (v & 1) != parity { v = v + 1 }
        while v <= v1 {
            s = s + f_gauss(floordiv(u + v, 2), floordiv(u - v, 2))
            v = v + 2
        }
        u = u + 1
    }
    return s % MOD
}

function rect_to_diamond(x0: i64, x1: i64, y0: i64, y1: i64, r: i64,
                         u0: ptr<i64>, u1: ptr<i64>, v0: ptr<i64>, v1: ptr<i64>) -> void {
    u0[0] = -x1 + r
    u1[0] = -x0 + r
    v0[0] = y0
    v1[0] = y1
}

function diamond_to_rect(u0: i64, u1: i64, v0: i64, v1: i64, r: i64,
                         x0: ptr<i64>, x1: ptr<i64>, y0: ptr<i64>, y1: ptr<i64>) -> void {
    x0[0] = ceil_div(r - v1, 2)
    x1[0] = floordiv(r - v0, 2)
    y0[0] = ceil_div(r - u1, 2)
    y1[0] = floordiv(r - u0, 2)
}

function sum_region(tag: i32, a0: i64, a1: i64, b0: i64, b1: i64,
                  keys: ptr<i64>, vals: ptr<i64>, used: ptr<i8>, buf: ptr<i64>) -> i64 {
    if a0 > a1 || b0 > b1 { return 0 }
    if tag == 0 {
        let n0: i128 = count_rect(a0, a1, b0, b1)
        if n0 <= (BRUTE as i128) { return brute_rect(a0, a1, b0, b1) }
    } else {
        let n1: i128 = count_diamond(a0, a1, b0, b1)
        if n1 <= (BRUTE as i128) { return brute_diamond(a0, a1, b0, b1) }
    }

    let key: i64 = hkey(a0, a1, b0, b1, tag as i64)
    let slot: i64 = hslot(key, keys, used)
    if used[slot] == 1 && keys[slot] == key { return vals[slot] }

    let mut res: i64 = 0
    if tag == 0 {
        rect_to_diamond(a0, a1, b0, b1, 0, buf, buf + 1, buf + 2, buf + 3)
        res = sum_region(1, buf[0], buf[1], buf[2], buf[3], keys, vals, used, buf)
        rect_to_diamond(a0, a1, b0, b1, 1, buf, buf + 1, buf + 2, buf + 3)
        let du0: i64 = buf[0]
        let du1: i64 = buf[1]
        let dv0: i64 = buf[2]
        let dv1: i64 = buf[3]
        res = (res + sum_region(1, du0, du1, dv0, dv1, keys, vals, used, buf)) % MOD
        res = (res + ((count_diamond(du0, du1, dv0, dv1) % (MOD as i128)) as i64)) % MOD
    } else {
        diamond_to_rect(a0, a1, b0, b1, 0, buf, buf + 1, buf + 2, buf + 3)
        res = sum_region(0, buf[0], buf[1], buf[2], buf[3], keys, vals, used, buf)
        diamond_to_rect(a0, a1, b0, b1, 1, buf, buf + 1, buf + 2, buf + 3)
        let rx0: i64 = buf[0]
        let rx1: i64 = buf[1]
        let ry0: i64 = buf[2]
        let ry1: i64 = buf[3]
        res = (res + sum_region(0, rx0, rx1, ry0, ry1, keys, vals, used, buf)) % MOD
        res = (res + ((count_rect(rx0, rx1, ry0, ry1) % (MOD as i128)) as i64)) % MOD
    }

    let store: i64 = hslot(key, keys, used)
    used[store] = 1
    keys[store] = key
    vals[store] = res
    return res
}

function main() -> i32 {
    let keys: ptr<i64> = calloc(CAP, 8)
    let vals: ptr<i64> = calloc(CAP, 8)
    let used: ptr<i8> = calloc(CAP, 1)
    let buf: ptr<i64> = calloc(4, 8)
    if keys == null || vals == null || used == null || buf == null { return 1 }

    let ans: i64 = sum_region(0, -LIM, LIM, -LIM, LIM, keys, vals, used, buf)
    printf("%lld\n", ans)
    free(keys); free(vals); free(used); free(buf)
    return 0
}

Generated C

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

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

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

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

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

#include <math.h>

void* _ui_state = NULL;

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

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

int64_t floordiv_i64_i64(int64_t a, int64_t b);
int64_t f_gauss_i64_i64(int64_t a0, int64_t b0);
__int128 count_rect_i64_i64_i64_i64(int64_t x0, int64_t x1, int64_t y0, int64_t y1);
int64_t count_parity_i64_i64_i64(int64_t lo, int64_t hi, int64_t parity);
__int128 count_diamond_i64_i64_i64_i64(int64_t u0, int64_t u1, int64_t v0, int64_t v1);
int64_t ceil_div_i64_i64(int64_t n, int64_t d);
int64_t hkey_i64_i64_i64_i64_i64(int64_t a0, int64_t a1, int64_t b0, int64_t b1, int64_t tag);
int64_t hslot_i64_ptr_i64_ptr_i8(int64_t key, int64_t* keys, int8_t* used);
int64_t brute_rect_i64_i64_i64_i64(int64_t x0, int64_t x1, int64_t y0, int64_t y1);
int64_t brute_diamond_i64_i64_i64_i64(int64_t u0, int64_t u1, int64_t v0, int64_t v1);
void rect_to_diamond_i64_i64_i64_i64_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64(int64_t x0, int64_t x1, int64_t y0, int64_t y1, int64_t r, int64_t* u0, int64_t* u1, int64_t* v0, int64_t* v1);
void diamond_to_rect_i64_i64_i64_i64_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64(int64_t u0, int64_t u1, int64_t v0, int64_t v1, int64_t r, int64_t* x0, int64_t* x1, int64_t* y0, int64_t* y1);
int64_t sum_region_i32_i64_i64_i64_i64_ptr_i64_ptr_i64_ptr_i8_ptr_i64(int32_t tag, int64_t a0, int64_t a1, int64_t b0, int64_t b1, int64_t* keys, int64_t* vals, int8_t* used, int64_t* buf);
int32_t main(void);

static const int64_t MOD = 1000000007;
static const int64_t LIM = 1000000000000000;
static const int64_t BRUTE = 4000;
static const int64_t CAP = 1048576;



int64_t floordiv_i64_i64(int64_t a, int64_t b) {
    if (b == 0) {
        return 0;
    }
    int64_t q = FLOW_CHECKED_DIV((a), (b));
    int64_t r = (a - (q * b));
    if ((r != 0 && r > 0 != b > 0)) {
        q = (q - 1);
    }
    return q;
}

int64_t f_gauss_i64_i64(int64_t a0, int64_t b0) {
    int64_t a = a0;
    int64_t b = b0;
    int64_t cnt = 0;
    while ((a != 0 || b != 0)) {
        if (((a ^ b) & 1) != 0) {
            a = (a - 1);
            cnt = (cnt + 1);
        }
        int64_t na = floordiv_i64_i64((b - a), 2);
        int64_t nb = floordiv_i64_i64((-(a + b)), 2);
        a = na;
        b = nb;
    }
    return cnt;
}

__int128 count_rect_i64_i64_i64_i64(int64_t x0, int64_t x1, int64_t y0, int64_t y1) {
    if ((x0 > x1 || y0 > y1)) {
        return ((__int128)(0));
    }
    __int128 w = ((__int128)(((x1 - x0) + 1)));
    __int128 h = ((__int128)(((y1 - y0) + 1)));
    return (w * h);
}

int64_t count_parity_i64_i64_i64(int64_t lo, int64_t hi, int64_t parity) {
    if (lo > hi) {
        return 0;
    }
    int64_t first = lo;
    if ((lo & 1) != parity) {
        first = (lo + 1);
    }
    if (first > hi) {
        return 0;
    }
    return (floordiv_i64_i64((hi - first), 2) + 1);
}

__int128 count_diamond_i64_i64_i64_i64(int64_t u0, int64_t u1, int64_t v0, int64_t v1) {
    if ((u0 > u1 || v0 > v1)) {
        return ((__int128)(0));
    }
    __int128 eu = ((__int128)(count_parity_i64_i64_i64(u0, u1, 0)));
    __int128 ou = (((__int128)(((u1 - u0) + 1))) - eu);
    __int128 ev = ((__int128)(count_parity_i64_i64_i64(v0, v1, 0)));
    __int128 ov = (((__int128)(((v1 - v0) + 1))) - ev);
    return ((eu * ev) + (ou * ov));
}

int64_t ceil_div_i64_i64(int64_t n, int64_t d) {
    return (-floordiv_i64_i64((-n), d));
}

int64_t hkey_i64_i64_i64_i64_i64(int64_t a0, int64_t a1, int64_t b0, int64_t b1, int64_t tag) {
    __int128 P = ((__int128)(1000000000000000003));
    __int128 k = ((__int128)(tag));
    k = FLOW_CHECKED_MOD((((k * ((__int128)(1000003))) + ((__int128)(a0)))), (P));
    k = FLOW_CHECKED_MOD((((k * ((__int128)(1000003))) + ((__int128)(a1)))), (P));
    k = FLOW_CHECKED_MOD((((k * ((__int128)(1000003))) + ((__int128)(b0)))), (P));
    k = FLOW_CHECKED_MOD((((k * ((__int128)(1000003))) + ((__int128)(b1)))), (P));
    if (k < 0) {
        k = (k + P);
    }
    return ((int64_t)(k));
}

int64_t hslot_i64_ptr_i64_ptr_i8(int64_t key, int64_t* keys, int8_t* used) {
    int64_t h = FLOW_CHECKED_MOD((key), (CAP));
    if (h < 0) {
        h = (h + CAP);
    }
    while ((used[h] == 1 && keys[h] != key)) {
        h = (h + 1);
        if (h == CAP) {
            h = 0;
        }
    }
    return h;
}

int64_t brute_rect_i64_i64_i64_i64(int64_t x0, int64_t x1, int64_t y0, int64_t y1) {
    int64_t s = 0;
    int64_t a = x0;
    while (a <= x1) {
        int64_t b = y0;
        while (b <= y1) {
            s = (s + f_gauss_i64_i64(a, b));
            b = (b + 1);
        }
        a = (a + 1);
    }
    return FLOW_CHECKED_MOD((s), (MOD));
}

int64_t brute_diamond_i64_i64_i64_i64(int64_t u0, int64_t u1, int64_t v0, int64_t v1) {
    int64_t s = 0;
    int64_t u = u0;
    while (u <= u1) {
        int64_t parity = (u & 1);
        int64_t v = v0;
        if ((v & 1) != parity) {
            v = (v + 1);
        }
        while (v <= v1) {
            s = (s + f_gauss_i64_i64(floordiv_i64_i64((u + v), 2), floordiv_i64_i64((u - v), 2)));
            v = (v + 2);
        }
        u = (u + 1);
    }
    return FLOW_CHECKED_MOD((s), (MOD));
}

void rect_to_diamond_i64_i64_i64_i64_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64(int64_t x0, int64_t x1, int64_t y0, int64_t y1, int64_t r, int64_t* u0, int64_t* u1, int64_t* v0, int64_t* v1) {
    u0[0] = ((-x1) + r);
    u1[0] = ((-x0) + r);
    v0[0] = y0;
    v1[0] = y1;
}

void diamond_to_rect_i64_i64_i64_i64_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64(int64_t u0, int64_t u1, int64_t v0, int64_t v1, int64_t r, int64_t* x0, int64_t* x1, int64_t* y0, int64_t* y1) {
    x0[0] = ceil_div_i64_i64((r - v1), 2);
    x1[0] = floordiv_i64_i64((r - v0), 2);
    y0[0] = ceil_div_i64_i64((r - u1), 2);
    y1[0] = floordiv_i64_i64((r - u0), 2);
}

int64_t sum_region_i32_i64_i64_i64_i64_ptr_i64_ptr_i64_ptr_i8_ptr_i64(int32_t tag, int64_t a0, int64_t a1, int64_t b0, int64_t b1, int64_t* keys, int64_t* vals, int8_t* used, int64_t* buf) {
    if ((a0 > a1 || b0 > b1)) {
        return 0;
    }
    if (tag == 0) {
        __int128 n0 = count_rect_i64_i64_i64_i64(a0, a1, b0, b1);
        if (n0 <= ((__int128)(BRUTE))) {
            return brute_rect_i64_i64_i64_i64(a0, a1, b0, b1);
        }
    } else {
        __int128 n1 = count_diamond_i64_i64_i64_i64(a0, a1, b0, b1);
        if (n1 <= ((__int128)(BRUTE))) {
            return brute_diamond_i64_i64_i64_i64(a0, a1, b0, b1);
        }
    }
    int64_t key = hkey_i64_i64_i64_i64_i64(a0, a1, b0, b1, ((int64_t)(tag)));
    int64_t slot = hslot_i64_ptr_i64_ptr_i8(key, keys, used);
    if ((used[slot] == 1 && keys[slot] == key)) {
        return vals[slot];
    }
    int64_t res = 0;
    if (tag == 0) {
        rect_to_diamond_i64_i64_i64_i64_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64(a0, a1, b0, b1, 0, buf, (buf + 1), (buf + 2), (buf + 3));
        res = sum_region_i32_i64_i64_i64_i64_ptr_i64_ptr_i64_ptr_i8_ptr_i64(1, buf[0], buf[1], buf[2], buf[3], keys, vals, used, buf);
        rect_to_diamond_i64_i64_i64_i64_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64(a0, a1, b0, b1, 1, buf, (buf + 1), (buf + 2), (buf + 3));
        int64_t du0 = buf[0];
        int64_t du1 = buf[1];
        int64_t dv0 = buf[2];
        int64_t dv1 = buf[3];
        res = FLOW_CHECKED_MOD(((res + sum_region_i32_i64_i64_i64_i64_ptr_i64_ptr_i64_ptr_i8_ptr_i64(1, du0, du1, dv0, dv1, keys, vals, used, buf))), (MOD));
        res = FLOW_CHECKED_MOD(((res + ((int64_t)(FLOW_CHECKED_MOD((count_diamond_i64_i64_i64_i64(du0, du1, dv0, dv1)), (((__int128)(MOD)))))))), (MOD));
    } else {
        diamond_to_rect_i64_i64_i64_i64_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64(a0, a1, b0, b1, 0, buf, (buf + 1), (buf + 2), (buf + 3));
        res = sum_region_i32_i64_i64_i64_i64_ptr_i64_ptr_i64_ptr_i8_ptr_i64(0, buf[0], buf[1], buf[2], buf[3], keys, vals, used, buf);
        diamond_to_rect_i64_i64_i64_i64_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64(a0, a1, b0, b1, 1, buf, (buf + 1), (buf + 2), (buf + 3));
        int64_t rx0 = buf[0];
        int64_t rx1 = buf[1];
        int64_t ry0 = buf[2];
        int64_t ry1 = buf[3];
        res = FLOW_CHECKED_MOD(((res + sum_region_i32_i64_i64_i64_i64_ptr_i64_ptr_i64_ptr_i8_ptr_i64(0, rx0, rx1, ry0, ry1, keys, vals, used, buf))), (MOD));
        res = FLOW_CHECKED_MOD(((res + ((int64_t)(FLOW_CHECKED_MOD((count_rect_i64_i64_i64_i64(rx0, rx1, ry0, ry1)), (((__int128)(MOD)))))))), (MOD));
    }
    int64_t store = hslot_i64_ptr_i64_ptr_i8(key, keys, used);
    used[store] = 1;
    keys[store] = key;
    vals[store] = res;
    return res;
}

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