Problem 538

Maximum Quadrilaterals — sum f(U_n) for n=4..3_000_000.

Answer22472871503401097
Output22472871503401097
StatusPASS
Native helperno
Runtime1250 ms
Peak memory83200 KB
Time complexityO(n^2) (estimated)
Space complexityO(n^2) (estimated)

Performance comparison

MetricOur solutionBest known
Time complexityO(n^2)O(n log n)
Space complexityO(n^2)O(n)
ApproachFlow solutionSearch with pruning or sieve
VerdictSuboptimal

Flow source

# Project Euler 538
# Maximum Quadrilaterals — sum f(U_n) for n=4..3_000_000.

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

const N: i64 = 3000000

function popcount(x0: i64) -> i32 {
    let mut x: i64 = x0
    let mut c: i32 = 0
    while x > 0 {
        if (x & 1) != 0 { c = c + 1 }
        x = x >> 1
    }
    return c
}

function merge(a: ptr<i64>, tmp: ptr<i64>, lo: i64, mid: i64, hi: i64) -> void {
    let mut i: i64 = lo
    let mut j: i64 = mid
    let mut k: i64 = lo
    while i < mid && j < hi {
        if a[i] <= a[j] { tmp[k] = a[i]; i = i + 1 }
        else { tmp[k] = a[j]; j = j + 1 }
        k = k + 1
    }
    while i < mid { tmp[k] = a[i]; i = i + 1; k = k + 1 }
    while j < hi { tmp[k] = a[j]; j = j + 1; k = k + 1 }
    i = lo
    while i < hi { a[i] = tmp[i]; i = i + 1 }
}

function merge_sort_iter(a: ptr<i64>, tmp: ptr<i64>, n: i64) -> void {
    let mut width: i64 = 1
    while width < n {
        let mut i: i64 = 0
        while i < n {
            let mid: i64 = i + width
            if mid >= n { break }
            let mut hi: i64 = i + 2 * width
            if hi > n { hi = n }
            merge(a, tmp, i, mid, hi)
            i = i + 2 * width
        }
        width = width * 2
    }
}

function better_log(log_new: f64, per_new: i64, log_best: f64, per_best: i64) -> i32 {
    if log_new > log_best + 1e-12 { return 1 }
    if log_new > log_best - 1e-12 && per_new > per_best { return 1 }
    return 0
}

function main() -> i32 {
    let pow3: ptr<i64> = calloc(25, 8)
    let u: ptr<i64> = calloc(N + 1, 8)
    let sorted: ptr<i64> = calloc(N, 8)
    let tmp: ptr<i64> = calloc(N, 8)
    if pow3 == null || u == null || sorted == null { return 1 }
    pow3[0] = 1
    let mut k: i64 = 1
    while k < 25 { pow3[k] = pow3[k - 1] * 3; k = k + 1 }
    let mut n: i64 = 1
    while n <= N {
        u[n] = (1 << popcount(3 * n)) + pow3[popcount(n) as i64] + (popcount(n + 1) as i64)
        sorted[n - 1] = u[n]
        n = n + 1
    }
    merge_sort_iter(sorted, tmp, N)
    let uniq: ptr<i64> = calloc(N + 1, 8)
    let idx_of: ptr<i32> = calloc(N + 1, 4)
    let mut nu: i64 = 0
    let mut prev: i64 = -1
    let mut i: i64 = 0
    while i < N {
        if sorted[i] != prev { uniq[nu] = sorted[i]; nu = nu + 1; prev = sorted[i] }
        i = i + 1
    }
    n = 1
    while n <= N {
        let v: i64 = u[n]
        let mut lo: i64 = 0
        let mut hi: i64 = nu
        while lo < hi {
            let mid: i64 = (lo + hi) / 2
            if uniq[mid] < v { lo = mid + 1 } else { hi = mid }
        }
        idx_of[n] = lo as i32
        n = n + 1
    }
    free(sorted); free(tmp)
    let counts: ptr<i32> = calloc(nu, 4)
    let active: ptr<i32> = calloc(nu, 4)
    let left: ptr<i64> = calloc(3, 8)
    let right: ptr<i64> = calloc(3, 8)
    let around: ptr<i64> = calloc(7, 8)
    if counts == null || active == null { return 1 }
    let mut an: i64 = 0
    let mut best_log: f64 = -1.0
    let mut best_per: i64 = 0
    let mut total: i64 = 0
    n = 1
    while n <= N {
        let idx: i64 = idx_of[n] as i64
        let c_before: i32 = counts[idx]
        if c_before == 0 {
            let mut pos: i64 = 0
            while pos < an && active[pos] < (idx as i32) { pos = pos + 1 }
            let mut sh: i64 = an
            while sh > pos { active[sh] = active[sh - 1]; sh = sh - 1 }
            active[pos] = idx as i32
            an = an + 1
        }
        counts[idx] = c_before + 1
        let mut pos: i64 = 0
        while pos < an {
            if active[pos] == (idx as i32) { break }
            pos = pos + 1
        }
        let v: i64 = u[n]
        let mut ln: i64 = 0
        let mut t: i64 = c_before as i64
        if t > 3 { t = 3 }
        while ln < t { left[ln] = v; ln = ln + 1 }
        let mut q: i64 = pos - 1
        while ln < 3 && q >= 0 {
            let idx2: i64 = active[q] as i64
            let v2: i64 = uniq[idx2]
            let mut take: i64 = counts[idx2] as i64
            if take > 3 - ln { take = 3 - ln }
            let mut ti: i64 = 0
            while ti < take { left[ln] = v2; ln = ln + 1; ti = ti + 1 }
            q = q - 1
        }
        let mut rn: i64 = 0
        q = pos + 1
        while rn < 3 && q < an {
            let idx3: i64 = active[q] as i64
            let v3: i64 = uniq[idx3]
            let mut take2: i64 = counts[idx3] as i64
            if take2 > 3 - rn { take2 = 3 - rn }
            let mut ti2: i64 = 0
            while ti2 < take2 { right[rn] = v3; rn = rn + 1; ti2 = ti2 + 1 }
            q = q + 1
        }
        let mut alen: i64 = 0
        let mut li: i64 = ln - 1
        while li >= 0 { around[alen] = left[li]; alen = alen + 1; li = li - 1 }
        around[alen] = v
        alen = alen + 1
        let mut ri: i64 = 0
        while ri < rn { around[alen] = right[ri]; alen = alen + 1; ri = ri + 1 }
        let pidx: i64 = alen - rn - 1
        let mut start: i64 = pidx - 3
        while start <= pidx {
            if start >= 0 && start + 4 <= alen {
                let a: i64 = around[start]
                let b: i64 = around[start + 1]
                let c: i64 = around[start + 2]
                let d: i64 = around[start + 3]
                if d < a + b + c {
                    let P: i64 = a + b + c + d
                    let prod_log: f64 = log((P - 2 * a) as f64) + log((P - 2 * b) as f64)
                        + log((P - 2 * c) as f64) + log((P - 2 * d) as f64)
                    if better_log(prod_log, P, best_log, best_per) == 1 {
                        best_log = prod_log
                        best_per = P
                    }
                }
            }
            start = start + 1
        }
        if n >= 4 { total = total + best_per }
        n = n + 1
    }
    printf("%lld\n", total)
    free(pow3); free(u); free(uniq); free(idx_of); free(counts); free(active)
    free(left); free(right); free(around)
    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; }

int32_t popcount_i64(int64_t x0);
void merge_ptr_i64_ptr_i64_i64_i64_i64(int64_t* a, int64_t* tmp, int64_t lo, int64_t mid, int64_t hi);
void merge_sort_iter_ptr_i64_ptr_i64_i64(int64_t* a, int64_t* tmp, int64_t n);
int32_t better_log_f64_i64_f64_i64(double log_new, int64_t per_new, double log_best, int64_t per_best);
int32_t main(void);

static const int64_t N = 3000000;




int32_t popcount_i64(int64_t x0) {
    int64_t x = x0;
    int32_t c = 0;
    while (x > 0) {
        if ((x & 1) != 0) {
            c = (c + 1);
        }
        x = FLOW_CHECKED_SHR((x), (1));
    }
    return c;
}

void merge_ptr_i64_ptr_i64_i64_i64_i64(int64_t* a, int64_t* tmp, int64_t lo, int64_t mid, int64_t hi) {
    int64_t i = lo;
    int64_t j = mid;
    int64_t k = lo;
    while ((i < mid && j < hi)) {
        if (a[i] <= a[j]) {
            tmp[k] = a[i];
            i = (i + 1);
        } else {
            tmp[k] = a[j];
            j = (j + 1);
        }
        k = (k + 1);
    }
    while (i < mid) {
        tmp[k] = a[i];
        i = (i + 1);
        k = (k + 1);
    }
    while (j < hi) {
        tmp[k] = a[j];
        j = (j + 1);
        k = (k + 1);
    }
    i = lo;
    while (i < hi) {
        a[i] = tmp[i];
        i = (i + 1);
    }
}

void merge_sort_iter_ptr_i64_ptr_i64_i64(int64_t* a, int64_t* tmp, int64_t n) {
    int64_t width = 1;
    while (width < n) {
        int64_t i = 0;
        while (i < n) {
            int64_t mid = (i + width);
            if (mid >= n) {
                break;
            }
            int64_t hi = (i + (2 * width));
            if (hi > n) {
                hi = n;
            }
            merge_ptr_i64_ptr_i64_i64_i64_i64(a, tmp, i, mid, hi);
            i = (i + (2 * width));
        }
        width = (width * 2);
    }
}

int32_t better_log_f64_i64_f64_i64(double log_new, int64_t per_new, double log_best, int64_t per_best) {
    if (log_new > (log_best + 1e-12)) {
        return 1;
    }
    if ((log_new > (log_best - 1e-12) && per_new > per_best)) {
        return 1;
    }
    return 0;
}

int32_t main(void) {
    int64_t* pow3 = (int64_t*)(calloc(25, 8));
    int64_t* u = (int64_t*)(calloc((N + 1), 8));
    int64_t* sorted = (int64_t*)(calloc(N, 8));
    int64_t* tmp = (int64_t*)(calloc(N, 8));
    if (((pow3 == NULL || u == NULL) || sorted == NULL)) {
        return 1;
    }
    pow3[0] = 1;
    int64_t k = 1;
    while (k < 25) {
        pow3[k] = (pow3[(k - 1)] * 3);
        k = (k + 1);
    }
    int64_t n = 1;
    while (n <= N) {
        u[n] = ((FLOW_CHECKED_SHL((1), (popcount_i64((3 * n)))) + pow3[((int64_t)(popcount_i64(n)))]) + ((int64_t)(popcount_i64((n + 1)))));
        sorted[(n - 1)] = u[n];
        n = (n + 1);
    }
    merge_sort_iter_ptr_i64_ptr_i64_i64(sorted, tmp, N);
    int64_t* uniq = (int64_t*)(calloc((N + 1), 8));
    int32_t* idx_of = (int32_t*)(calloc((N + 1), 4));
    int64_t nu = 0;
    int64_t prev = (-1);
    int64_t i = 0;
    while (i < N) {
        if (sorted[i] != prev) {
            uniq[nu] = sorted[i];
            nu = (nu + 1);
            prev = sorted[i];
        }
        i = (i + 1);
    }
    n = 1;
    while (n <= N) {
        int64_t v = u[n];
        int64_t lo = 0;
        int64_t hi = nu;
        while (lo < hi) {
            int64_t mid = FLOW_CHECKED_DIV(((lo + hi)), (2));
            if (uniq[mid] < v) {
                lo = (mid + 1);
            } else {
                hi = mid;
            }
        }
        idx_of[n] = ((int32_t)(lo));
        n = (n + 1);
    }
    free(sorted);
    free(tmp);
    int32_t* counts = (int32_t*)(calloc(nu, 4));
    int32_t* active = (int32_t*)(calloc(nu, 4));
    int64_t* left = (int64_t*)(calloc(3, 8));
    int64_t* right = (int64_t*)(calloc(3, 8));
    int64_t* around = (int64_t*)(calloc(7, 8));
    if ((counts == NULL || active == NULL)) {
        return 1;
    }
    int64_t an = 0;
    double best_log = (-1.0);
    int64_t best_per = 0;
    int64_t total = 0;
    n = 1;
    while (n <= N) {
        int64_t idx = ((int64_t)(idx_of[n]));
        int32_t c_before = counts[idx];
        if (c_before == 0) {
            int64_t pos = 0;
            while ((pos < an && active[pos] < ((int32_t)(idx)))) {
                pos = (pos + 1);
            }
            int64_t sh = an;
            while (sh > pos) {
                active[sh] = active[(sh - 1)];
                sh = (sh - 1);
            }
            active[pos] = ((int32_t)(idx));
            an = (an + 1);
        }
        counts[idx] = (c_before + 1);
        int64_t pos = 0;
        while (pos < an) {
            if (active[pos] == ((int32_t)(idx))) {
                break;
            }
            pos = (pos + 1);
        }
        int64_t v = u[n];
        int64_t ln = 0;
        int64_t t = ((int64_t)(c_before));
        if (t > 3) {
            t = 3;
        }
        while (ln < t) {
            left[ln] = v;
            ln = (ln + 1);
        }
        int64_t q = (pos - 1);
        while ((ln < 3 && q >= 0)) {
            int64_t idx2 = ((int64_t)(active[q]));
            int64_t v2 = uniq[idx2];
            int64_t take = ((int64_t)(counts[idx2]));
            if (take > (3 - ln)) {
                take = (3 - ln);
            }
            int64_t ti = 0;
            while (ti < take) {
                left[ln] = v2;
                ln = (ln + 1);
                ti = (ti + 1);
            }
            q = (q - 1);
        }
        int64_t rn = 0;
        q = (pos + 1);
        while ((rn < 3 && q < an)) {
            int64_t idx3 = ((int64_t)(active[q]));
            int64_t v3 = uniq[idx3];
            int64_t take2 = ((int64_t)(counts[idx3]));
            if (take2 > (3 - rn)) {
                take2 = (3 - rn);
            }
            int64_t ti2 = 0;
            while (ti2 < take2) {
                right[rn] = v3;
                rn = (rn + 1);
                ti2 = (ti2 + 1);
            }
            q = (q + 1);
        }
        int64_t alen = 0;
        int64_t li = (ln - 1);
        while (li >= 0) {
            around[alen] = left[li];
            alen = (alen + 1);
            li = (li - 1);
        }
        around[alen] = v;
        alen = (alen + 1);
        int64_t ri = 0;
        while (ri < rn) {
            around[alen] = right[ri];
            alen = (alen + 1);
            ri = (ri + 1);
        }
        int64_t pidx = ((alen - rn) - 1);
        int64_t start = (pidx - 3);
        while (start <= pidx) {
            if ((start >= 0 && (start + 4) <= alen)) {
                int64_t a = around[start];
                int64_t b = around[(start + 1)];
                int64_t c = around[(start + 2)];
                int64_t d = around[(start + 3)];
                if (d < ((a + b) + c)) {
                    int64_t P = (((a + b) + c) + d);
                    double prod_log = (((log(((double)((P - (2 * a))))) + log(((double)((P - (2 * b)))))) + log(((double)((P - (2 * c)))))) + log(((double)((P - (2 * d))))));
                    if (better_log_f64_i64_f64_i64(prod_log, P, best_log, best_per) == 1) {
                        best_log = prod_log;
                        best_per = P;
                    }
                }
            }
            start = (start + 1);
        }
        if (n >= 4) {
            total = (total + best_per);
        }
        n = (n + 1);
    }
    printf("%lld\n", total);
    free(pow3);
    free(u);
    free(uniq);
    free(idx_of);
    free(counts);
    free(active);
    free(left);
    free(right);
    free(around);
    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 @log(f64) -> f64
  // Constant: N
  llvm.mlir.global internal constant @N(3000000 : i64) : i64
  func.func @popcount(%arg0: i64) -> i32 {
    %0 = llvm.mlir.constant(1 : i64) : i64
    %1 = llvm.alloca %0 x i64 : (i64) -> !llvm.ptr
    llvm.store %arg0, %1 : i64, !llvm.ptr
    %2 = arith.constant 0 : i32
    %3 = llvm.mlir.constant(1 : i64) : i64
    %4 = llvm.alloca %3 x i32 : (i64) -> !llvm.ptr
    llvm.store %2, %4 : i32, !llvm.ptr
    cf.br ^bb0
    ^bb0:
    %5 = llvm.load %1 : !llvm.ptr -> i64
    %6 = arith.constant 0 : i32
    %8 = arith.extsi %6 : i32 to i64
    %7 = arith.cmpi sgt, %5, %8 : i64
    cf.cond_br %7, ^bb1, ^bb2
    ^bb1:
      %9 = llvm.load %1 : !llvm.ptr -> i64
      %10 = arith.constant 1 : i32
      %12 = arith.extsi %10 : i32 to i64
      %11 = arith.andi %9, %12 : i64
      %13 = arith.constant 0 : i32
      %15 = arith.extsi %13 : i32 to i64
      %14 = arith.cmpi ne, %11, %15 : i64
      cf.cond_br %14, ^bb3, ^bb4
      ^bb3:
        %16 = llvm.load %4 : !llvm.ptr -> i32
        %17 = arith.constant 1 : i32
        %18 = arith.addi %16, %17 : i32
        llvm.store %18, %4 : i32, !llvm.ptr
        cf.br ^bb5
      ^bb4:
        cf.br ^bb5
      ^bb5:
      %19 = llvm.load %1 : !llvm.ptr -> i64
      %20 = arith.constant 1 : i32
      %22 = arith.extsi %20 : i32 to i64
      %21 = arith.shrsi %19, %22 : i64
      llvm.store %21, %1 : i64, !llvm.ptr
      cf.br ^bb0
    ^bb2:
    %23 = llvm.load %4 : !llvm.ptr -> i32
    func.return %23 : i32
  }
  func.func @merge(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: i64, %arg3: i64, %arg4: i64) -> () {
    %24 = llvm.mlir.constant(1 : i64) : i64
    %25 = llvm.alloca %24 x i64 : (i64) -> !llvm.ptr
    llvm.store %arg2, %25 : i64, !llvm.ptr
    %26 = llvm.mlir.constant(1 : i64) : i64
    %27 = llvm.alloca %26 x i64 : (i64) -> !llvm.ptr
    llvm.store %arg3, %27 : i64, !llvm.ptr
    %28 = llvm.mlir.constant(1 : i64) : i64
    %29 = llvm.alloca %28 x i64 : (i64) -> !llvm.ptr
    llvm.store %arg2, %29 : i64, !llvm.ptr
    cf.br ^bb6
    ^bb6:
    %30 = llvm.load %25 : !llvm.ptr -> i64
    %31 = arith.cmpi slt, %30, %arg3 : i64
    %32 = scf.if %31 -> (i1) {
      %33 = llvm.load %27 : !llvm.ptr -> i64
      %34 = arith.cmpi slt, %33, %arg4 : i64
      scf.yield %34 : i1
    } else {
      %35 = arith.constant false
      scf.yield %35 : i1
    }
    cf.cond_br %32, ^bb7, ^bb8
    ^bb7:
      %37 = llvm.load %25 : !llvm.ptr -> i64
      %38 = llvm.getelementptr %arg0[%37] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %36 = llvm.load %38 : !llvm.ptr -> i64
      %40 = llvm.load %27 : !llvm.ptr -> i64
      %41 = llvm.getelementptr %arg0[%40] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %39 = llvm.load %41 : !llvm.ptr -> i64
      %42 = arith.cmpi sle, %36, %39 : i64
      cf.cond_br %42, ^bb9, ^bb10
      ^bb9:
        %44 = llvm.load %25 : !llvm.ptr -> i64
        %45 = llvm.getelementptr %arg0[%44] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %43 = llvm.load %45 : !llvm.ptr -> i64
        %46 = llvm.load %29 : !llvm.ptr -> i64
        %47 = llvm.getelementptr %arg1[%46] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %43, %47 : i64, !llvm.ptr
        %48 = llvm.load %25 : !llvm.ptr -> i64
        %49 = arith.constant 1 : i32
        %51 = arith.extsi %49 : i32 to i64
        %50 = arith.addi %48, %51 : i64
        llvm.store %50, %25 : i64, !llvm.ptr
        cf.br ^bb11
      ^bb10:
        %53 = llvm.load %27 : !llvm.ptr -> i64
        %54 = llvm.getelementptr %arg0[%53] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %52 = llvm.load %54 : !llvm.ptr -> i64
        %55 = llvm.load %29 : !llvm.ptr -> i64
        %56 = llvm.getelementptr %arg1[%55] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %52, %56 : i64, !llvm.ptr
        %57 = llvm.load %27 : !llvm.ptr -> i64
        %58 = arith.constant 1 : i32
        %60 = arith.extsi %58 : i32 to i64
        %59 = arith.addi %57, %60 : i64
        llvm.store %59, %27 : i64, !llvm.ptr
        cf.br ^bb11
      ^bb11:
      %61 = llvm.load %29 : !llvm.ptr -> i64
      %62 = arith.constant 1 : i32
      %64 = arith.extsi %62 : i32 to i64
      %63 = arith.addi %61, %64 : i64
      llvm.store %63, %29 : i64, !llvm.ptr
      cf.br ^bb6
    ^bb8:
    cf.br ^bb12
    ^bb12:
    %65 = llvm.load %25 : !llvm.ptr -> i64
    %66 = arith.cmpi slt, %65, %arg3 : i64
    cf.cond_br %66, ^bb13, ^bb14
    ^bb13:
      %68 = llvm.load %25 : !llvm.ptr -> i64
      %69 = llvm.getelementptr %arg0[%68] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %67 = llvm.load %69 : !llvm.ptr -> i64
      %70 = llvm.load %29 : !llvm.ptr -> i64
      %71 = llvm.getelementptr %arg1[%70] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %67, %71 : i64, !llvm.ptr
      %72 = llvm.load %25 : !llvm.ptr -> i64
      %73 = arith.constant 1 : i32
      %75 = arith.extsi %73 : i32 to i64
      %74 = arith.addi %72, %75 : i64
      llvm.store %74, %25 : i64, !llvm.ptr
      %76 = llvm.load %29 : !llvm.ptr -> i64
      %77 = arith.constant 1 : i32
      %79 = arith.extsi %77 : i32 to i64
      %78 = arith.addi %76, %79 : i64
      llvm.store %78, %29 : i64, !llvm.ptr
      cf.br ^bb12
    ^bb14:
    cf.br ^bb15
    ^bb15:
    %80 = llvm.load %27 : !llvm.ptr -> i64
    %81 = arith.cmpi slt, %80, %arg4 : i64
    cf.cond_br %81, ^bb16, ^bb17
    ^bb16:
      %83 = llvm.load %27 : !llvm.ptr -> i64
      %84 = llvm.getelementptr %arg0[%83] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %82 = llvm.load %84 : !llvm.ptr -> i64
      %85 = llvm.load %29 : !llvm.ptr -> i64
      %86 = llvm.getelementptr %arg1[%85] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %82, %86 : i64, !llvm.ptr
      %87 = llvm.load %27 : !llvm.ptr -> i64
      %88 = arith.constant 1 : i32
      %90 = arith.extsi %88 : i32 to i64
      %89 = arith.addi %87, %90 : i64
      llvm.store %89, %27 : i64, !llvm.ptr
      %91 = llvm.load %29 : !llvm.ptr -> i64
      %92 = arith.constant 1 : i32
      %94 = arith.extsi %92 : i32 to i64
      %93 = arith.addi %91, %94 : i64
      llvm.store %93, %29 : i64, !llvm.ptr
      cf.br ^bb15
    ^bb17:
    llvm.store %arg2, %25 : i64, !llvm.ptr
    cf.br ^bb18
    ^bb18:
    %95 = llvm.load %25 : !llvm.ptr -> i64
    %96 = arith.cmpi slt, %95, %arg4 : i64
    cf.cond_br %96, ^bb19, ^bb20
    ^bb19:
      %98 = llvm.load %25 : !llvm.ptr -> i64
      %99 = llvm.getelementptr %arg1[%98] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %97 = llvm.load %99 : !llvm.ptr -> i64
      %100 = llvm.load %25 : !llvm.ptr -> i64
      %101 = llvm.getelementptr %arg0[%100] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %97, %101 : i64, !llvm.ptr
      %102 = llvm.load %25 : !llvm.ptr -> i64
      %103 = arith.constant 1 : i32
      %105 = arith.extsi %103 : i32 to i64
      %104 = arith.addi %102, %105 : i64
      llvm.store %104, %25 : i64, !llvm.ptr
      cf.br ^bb18
    ^bb20:
    func.return
  }
  func.func @merge_sort_iter(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: i64) -> () {
    %106 = arith.constant 1 : i32
    %107 = arith.extsi %106 : i32 to i64
    %108 = llvm.mlir.constant(1 : i64) : i64
    %109 = llvm.alloca %108 x i64 : (i64) -> !llvm.ptr
    llvm.store %107, %109 : i64, !llvm.ptr
    cf.br ^bb21
    ^bb21:
    %110 = llvm.load %109 : !llvm.ptr -> i64
    %111 = arith.cmpi slt, %110, %arg2 : i64
    cf.cond_br %111, ^bb22, ^bb23
    ^bb22:
      %112 = arith.constant 0 : i32
      %113 = arith.extsi %112 : i32 to i64
      %114 = llvm.mlir.constant(1 : i64) : i64
      %115 = llvm.alloca %114 x i64 : (i64) -> !llvm.ptr
      llvm.store %113, %115 : i64, !llvm.ptr
      cf.br ^bb24
      ^bb24:
      %116 = llvm.load %115 : !llvm.ptr -> i64
      %117 = arith.cmpi slt, %116, %arg2 : i64
      cf.cond_br %117, ^bb25, ^bb26
      ^bb25:
        %118 = llvm.load %115 : !llvm.ptr -> i64
        %119 = llvm.load %109 : !llvm.ptr -> i64
        %120 = arith.addi %118, %119 : i64
        %121 = arith.cmpi sge, %120, %arg2 : i64
        cf.cond_br %121, ^bb27, ^bb28
        ^bb27:
          cf.br ^bb26
        ^bb28:
          cf.br ^bb29
        ^bb29:
        %122 = llvm.load %115 : !llvm.ptr -> i64
        %123 = arith.constant 2 : i32
        %124 = llvm.load %109 : !llvm.ptr -> i64
        %126 = arith.extsi %123 : i32 to i64
        %125 = arith.muli %126, %124 : i64
        %127 = arith.addi %122, %125 : i64
        %128 = llvm.mlir.constant(1 : i64) : i64
        %129 = llvm.alloca %128 x i64 : (i64) -> !llvm.ptr
        llvm.store %127, %129 : i64, !llvm.ptr
        %130 = llvm.load %129 : !llvm.ptr -> i64
        %131 = arith.cmpi sgt, %130, %arg2 : i64
        cf.cond_br %131, ^bb30, ^bb31
        ^bb30:
          llvm.store %arg2, %129 : i64, !llvm.ptr
          cf.br ^bb32
        ^bb31:
          cf.br ^bb32
        ^bb32:
        %133 = llvm.load %115 : !llvm.ptr -> i64
        %134 = llvm.load %129 : !llvm.ptr -> i64
        func.call @merge(%arg0, %arg1, %133, %120, %134) : (!llvm.ptr, !llvm.ptr, i64, i64, i64) -> ()
        %135 = llvm.load %115 : !llvm.ptr -> i64
        %136 = arith.constant 2 : i32
        %137 = llvm.load %109 : !llvm.ptr -> i64
        %139 = arith.extsi %136 : i32 to i64
        %138 = arith.muli %139, %137 : i64
        %140 = arith.addi %135, %138 : i64
        llvm.store %140, %115 : i64, !llvm.ptr
        cf.br ^bb24
      ^bb26:
      %141 = llvm.load %109 : !llvm.ptr -> i64
      %142 = arith.constant 2 : i32
      %144 = arith.extsi %142 : i32 to i64
      %143 = arith.muli %141, %144 : i64
      llvm.store %143, %109 : i64, !llvm.ptr
      cf.br ^bb21
    ^bb23:
    func.return
  }
  func.func @better_log(%arg0: f64, %arg1: i64, %arg2: f64, %arg3: i64) -> i32 {
    %145 = arith.constant 0 : f32
    %147 = arith.extf %145 : f32 to f64
    %146 = arith.addf %arg2, %147 : f64
    %148 = arith.cmpf ogt, %arg0, %146 : f64
    cf.cond_br %148, ^bb33, ^bb34
    ^bb33:
      %149 = arith.constant 1 : i32
      func.return %149 : i32
    ^bb34:
      cf.br ^bb35
    ^bb35:
    %150 = arith.constant 0 : f32
    %152 = arith.extf %150 : f32 to f64
    %151 = arith.subf %arg2, %152 : f64
    %153 = arith.cmpf ogt, %arg0, %151 : f64
    %154 = scf.if %153 -> (i1) {
      %155 = arith.cmpi sgt, %arg1, %arg3 : i64
      scf.yield %155 : i1
    } else {
      %156 = arith.constant false
      scf.yield %156 : i1
    }
    cf.cond_br %154, ^bb36, ^bb37
    ^bb36:
      %157 = arith.constant 1 : i32
      func.return %157 : i32
    ^bb37:
      cf.br ^bb38
    ^bb38:
    %158 = arith.constant 0 : i32
    func.return %158 : i32
  }
  func.func @main() -> i32 {
    %160 = arith.constant 25 : i32
    %161 = arith.constant 8 : i32
    %162 = arith.extsi %160 : i32 to i64
    %163 = arith.extsi %161 : i32 to i64
    %159 = func.call @calloc(%162, %163) : (i64, i64) -> !llvm.ptr
    %165 = llvm.mlir.addressof @N : !llvm.ptr
    %166 = llvm.load %165 : !llvm.ptr -> i64
    %167 = arith.constant 1 : i32
    %169 = arith.extsi %167 : i32 to i64
    %168 = arith.addi %166, %169 : i64
    %170 = arith.constant 8 : i32
    %171 = arith.extsi %170 : i32 to i64
    %164 = func.call @calloc(%168, %171) : (i64, i64) -> !llvm.ptr
    %173 = llvm.mlir.addressof @N : !llvm.ptr
    %174 = llvm.load %173 : !llvm.ptr -> i64
    %175 = arith.constant 8 : i32
    %176 = arith.extsi %175 : i32 to i64
    %172 = func.call @calloc(%174, %176) : (i64, i64) -> !llvm.ptr
    %178 = llvm.mlir.addressof @N : !llvm.ptr
    %179 = llvm.load %178 : !llvm.ptr -> i64
    %180 = arith.constant 8 : i32
    %181 = arith.extsi %180 : i32 to i64
    %177 = func.call @calloc(%179, %181) : (i64, i64) -> !llvm.ptr
    %182 = llvm.mlir.zero : !llvm.ptr
    %183 = llvm.icmp "eq" %159, %182 : !llvm.ptr
    %184 = scf.if %183 -> (i1) {
      %185 = arith.constant true
      scf.yield %185 : i1
    } else {
      %186 = llvm.mlir.zero : !llvm.ptr
      %187 = llvm.icmp "eq" %164, %186 : !llvm.ptr
      scf.yield %187 : i1
    }
    %188 = scf.if %184 -> (i1) {
      %189 = arith.constant true
      scf.yield %189 : i1
    } else {
      %190 = llvm.mlir.zero : !llvm.ptr
      %191 = llvm.icmp "eq" %172, %190 : !llvm.ptr
      scf.yield %191 : i1
    }
    cf.cond_br %188, ^bb39, ^bb40
    ^bb39:
      %192 = arith.constant 1 : i32
      func.return %192 : i32
    ^bb40:
      cf.br ^bb41
    ^bb41:
    %193 = arith.constant 1 : i32
    %194 = arith.constant 0 : i32
    %195 = arith.extsi %193 : i32 to i64
    %196 = arith.extsi %194 : i32 to i64
    %197 = llvm.getelementptr %159[%196] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %195, %197 : i64, !llvm.ptr
    %198 = arith.constant 1 : i32
    %199 = arith.extsi %198 : i32 to i64
    %200 = llvm.mlir.constant(1 : i64) : i64
    %201 = llvm.alloca %200 x i64 : (i64) -> !llvm.ptr
    llvm.store %199, %201 : i64, !llvm.ptr
    cf.br ^bb42
    ^bb42:
    %202 = llvm.load %201 : !llvm.ptr -> i64
    %203 = arith.constant 25 : i32
    %205 = arith.extsi %203 : i32 to i64
    %204 = arith.cmpi slt, %202, %205 : i64
    cf.cond_br %204, ^bb43, ^bb44
    ^bb43:
      %207 = llvm.load %201 : !llvm.ptr -> i64
      %208 = arith.constant 1 : i32
      %210 = arith.extsi %208 : i32 to i64
      %209 = arith.subi %207, %210 : i64
      %211 = llvm.getelementptr %159[%209] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %206 = llvm.load %211 : !llvm.ptr -> i64
      %212 = arith.constant 3 : i32
      %214 = arith.extsi %212 : i32 to i64
      %213 = arith.muli %206, %214 : i64
      %215 = llvm.load %201 : !llvm.ptr -> i64
      %216 = llvm.getelementptr %159[%215] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %213, %216 : i64, !llvm.ptr
      %217 = llvm.load %201 : !llvm.ptr -> i64
      %218 = arith.constant 1 : i32
      %220 = arith.extsi %218 : i32 to i64
      %219 = arith.addi %217, %220 : i64
      llvm.store %219, %201 : i64, !llvm.ptr
      cf.br ^bb42
    ^bb44:
    %221 = arith.constant 1 : i32
    %222 = arith.extsi %221 : i32 to i64
    %223 = llvm.mlir.constant(1 : i64) : i64
    %224 = llvm.alloca %223 x i64 : (i64) -> !llvm.ptr
    llvm.store %222, %224 : i64, !llvm.ptr
    cf.br ^bb45
    ^bb45:
    %225 = llvm.load %224 : !llvm.ptr -> i64
    %226 = llvm.mlir.addressof @N : !llvm.ptr
    %227 = llvm.load %226 : !llvm.ptr -> i64
    %228 = arith.cmpi sle, %225, %227 : i64
    cf.cond_br %228, ^bb46, ^bb47
    ^bb46:
      %229 = arith.constant 1 : i32
      %231 = arith.constant 3 : i32
      %232 = llvm.load %224 : !llvm.ptr -> i64
      %234 = arith.extsi %231 : i32 to i64
      %233 = arith.muli %234, %232 : i64
      %230 = func.call @popcount(%233) : (i64) -> i32
      %235 = arith.shli %229, %230 : i32
      %238 = llvm.load %224 : !llvm.ptr -> i64
      %237 = func.call @popcount(%238) : (i64) -> i32
      %239 = arith.extsi %237 : i32 to i64
      %240 = llvm.getelementptr %159[%239] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %236 = llvm.load %240 : !llvm.ptr -> i64
      %242 = arith.extsi %235 : i32 to i64
      %241 = arith.addi %242, %236 : i64
      %244 = llvm.load %224 : !llvm.ptr -> i64
      %245 = arith.constant 1 : i32
      %247 = arith.extsi %245 : i32 to i64
      %246 = arith.addi %244, %247 : i64
      %243 = func.call @popcount(%246) : (i64) -> i32
      %248 = arith.extsi %243 : i32 to i64
      %249 = arith.addi %241, %248 : i64
      %250 = llvm.load %224 : !llvm.ptr -> i64
      %251 = llvm.getelementptr %164[%250] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %249, %251 : i64, !llvm.ptr
      %253 = llvm.load %224 : !llvm.ptr -> i64
      %254 = llvm.getelementptr %164[%253] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %252 = llvm.load %254 : !llvm.ptr -> i64
      %255 = llvm.load %224 : !llvm.ptr -> i64
      %256 = arith.constant 1 : i32
      %258 = arith.extsi %256 : i32 to i64
      %257 = arith.subi %255, %258 : i64
      %259 = llvm.getelementptr %172[%257] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %252, %259 : i64, !llvm.ptr
      %260 = llvm.load %224 : !llvm.ptr -> i64
      %261 = arith.constant 1 : i32
      %263 = arith.extsi %261 : i32 to i64
      %262 = arith.addi %260, %263 : i64
      llvm.store %262, %224 : i64, !llvm.ptr
      cf.br ^bb45
    ^bb47:
    %265 = llvm.mlir.addressof @N : !llvm.ptr
    %266 = llvm.load %265 : !llvm.ptr -> i64
    func.call @merge_sort_iter(%172, %177, %266) : (!llvm.ptr, !llvm.ptr, i64) -> ()
    %268 = llvm.mlir.addressof @N : !llvm.ptr
    %269 = llvm.load %268 : !llvm.ptr -> i64
    %270 = arith.constant 1 : i32
    %272 = arith.extsi %270 : i32 to i64
    %271 = arith.addi %269, %272 : i64
    %273 = arith.constant 8 : i32
    %274 = arith.extsi %273 : i32 to i64
    %267 = func.call @calloc(%271, %274) : (i64, i64) -> !llvm.ptr
    %276 = llvm.mlir.addressof @N : !llvm.ptr
    %277 = llvm.load %276 : !llvm.ptr -> i64
    %278 = arith.constant 1 : i32
    %280 = arith.extsi %278 : i32 to i64
    %279 = arith.addi %277, %280 : i64
    %281 = arith.constant 4 : i32
    %282 = arith.extsi %281 : i32 to i64
    %275 = func.call @calloc(%279, %282) : (i64, i64) -> !llvm.ptr
    %283 = arith.constant 0 : i32
    %284 = arith.extsi %283 : i32 to i64
    %285 = llvm.mlir.constant(1 : i64) : i64
    %286 = llvm.alloca %285 x i64 : (i64) -> !llvm.ptr
    llvm.store %284, %286 : i64, !llvm.ptr
    %287 = arith.constant 1 : i32
    %289 = arith.constant 0 : i32
    %288 = arith.subi %289, %287 : i32
    %290 = arith.extsi %288 : i32 to i64
    %291 = llvm.mlir.constant(1 : i64) : i64
    %292 = llvm.alloca %291 x i64 : (i64) -> !llvm.ptr
    llvm.store %290, %292 : i64, !llvm.ptr
    %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
    cf.br ^bb48
    ^bb48:
    %297 = llvm.load %296 : !llvm.ptr -> i64
    %298 = llvm.mlir.addressof @N : !llvm.ptr
    %299 = llvm.load %298 : !llvm.ptr -> i64
    %300 = arith.cmpi slt, %297, %299 : i64
    cf.cond_br %300, ^bb49, ^bb50
    ^bb49:
      %302 = llvm.load %296 : !llvm.ptr -> i64
      %303 = llvm.getelementptr %172[%302] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %301 = llvm.load %303 : !llvm.ptr -> i64
      %304 = llvm.load %292 : !llvm.ptr -> i64
      %305 = arith.cmpi ne, %301, %304 : i64
      cf.cond_br %305, ^bb51, ^bb52
      ^bb51:
        %307 = llvm.load %296 : !llvm.ptr -> i64
        %308 = llvm.getelementptr %172[%307] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %306 = llvm.load %308 : !llvm.ptr -> i64
        %309 = llvm.load %286 : !llvm.ptr -> i64
        %310 = llvm.getelementptr %267[%309] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %306, %310 : i64, !llvm.ptr
        %311 = llvm.load %286 : !llvm.ptr -> i64
        %312 = arith.constant 1 : i32
        %314 = arith.extsi %312 : i32 to i64
        %313 = arith.addi %311, %314 : i64
        llvm.store %313, %286 : i64, !llvm.ptr
        %316 = llvm.load %296 : !llvm.ptr -> i64
        %317 = llvm.getelementptr %172[%316] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %315 = llvm.load %317 : !llvm.ptr -> i64
        llvm.store %315, %292 : i64, !llvm.ptr
        cf.br ^bb53
      ^bb52:
        cf.br ^bb53
      ^bb53:
      %318 = llvm.load %296 : !llvm.ptr -> i64
      %319 = arith.constant 1 : i32
      %321 = arith.extsi %319 : i32 to i64
      %320 = arith.addi %318, %321 : i64
      llvm.store %320, %296 : i64, !llvm.ptr
      cf.br ^bb48
    ^bb50:
    %322 = arith.constant 1 : i32
    %323 = arith.extsi %322 : i32 to i64
    llvm.store %323, %224 : i64, !llvm.ptr
    cf.br ^bb54
    ^bb54:
    %324 = llvm.load %224 : !llvm.ptr -> i64
    %325 = llvm.mlir.addressof @N : !llvm.ptr
    %326 = llvm.load %325 : !llvm.ptr -> i64
    %327 = arith.cmpi sle, %324, %326 : i64
    cf.cond_br %327, ^bb55, ^bb56
    ^bb55:
      %329 = llvm.load %224 : !llvm.ptr -> i64
      %330 = llvm.getelementptr %164[%329] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %328 = llvm.load %330 : !llvm.ptr -> i64
      %331 = arith.constant 0 : i32
      %332 = arith.extsi %331 : i32 to i64
      %333 = llvm.mlir.constant(1 : i64) : i64
      %334 = llvm.alloca %333 x i64 : (i64) -> !llvm.ptr
      llvm.store %332, %334 : i64, !llvm.ptr
      %335 = llvm.load %286 : !llvm.ptr -> i64
      %336 = llvm.mlir.constant(1 : i64) : i64
      %337 = llvm.alloca %336 x i64 : (i64) -> !llvm.ptr
      llvm.store %335, %337 : i64, !llvm.ptr
      cf.br ^bb57
      ^bb57:
      %338 = llvm.load %334 : !llvm.ptr -> i64
      %339 = llvm.load %337 : !llvm.ptr -> i64
      %340 = arith.cmpi slt, %338, %339 : i64
      cf.cond_br %340, ^bb58, ^bb59
      ^bb58:
        %341 = llvm.load %334 : !llvm.ptr -> i64
        %342 = llvm.load %337 : !llvm.ptr -> i64
        %343 = arith.addi %341, %342 : i64
        %344 = arith.constant 2 : i32
        %346 = arith.extsi %344 : i32 to i64
        %345 = arith.divsi %343, %346 : i64
        %348 = llvm.getelementptr %267[%345] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %347 = llvm.load %348 : !llvm.ptr -> i64
        %349 = arith.cmpi slt, %347, %328 : i64
        cf.cond_br %349, ^bb60, ^bb61
        ^bb60:
          %350 = arith.constant 1 : i32
          %352 = arith.extsi %350 : i32 to i64
          %351 = arith.addi %345, %352 : i64
          llvm.store %351, %334 : i64, !llvm.ptr
          cf.br ^bb62
        ^bb61:
          llvm.store %345, %337 : i64, !llvm.ptr
          cf.br ^bb62
        ^bb62:
        cf.br ^bb57
      ^bb59:
      %353 = llvm.load %334 : !llvm.ptr -> i64
      %354 = arith.trunci %353 : i64 to i32
      %355 = llvm.load %224 : !llvm.ptr -> i64
      %356 = llvm.getelementptr %275[%355] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %354, %356 : i32, !llvm.ptr
      %357 = llvm.load %224 : !llvm.ptr -> i64
      %358 = arith.constant 1 : i32
      %360 = arith.extsi %358 : i32 to i64
      %359 = arith.addi %357, %360 : i64
      llvm.store %359, %224 : i64, !llvm.ptr
      cf.br ^bb54
    ^bb56:
    func.call @free(%172) : (!llvm.ptr) -> ()
    func.call @free(%177) : (!llvm.ptr) -> ()
    %364 = llvm.load %286 : !llvm.ptr -> i64
    %365 = arith.constant 4 : i32
    %366 = arith.extsi %365 : i32 to i64
    %363 = func.call @calloc(%364, %366) : (i64, i64) -> !llvm.ptr
    %368 = llvm.load %286 : !llvm.ptr -> i64
    %369 = arith.constant 4 : i32
    %370 = arith.extsi %369 : i32 to i64
    %367 = func.call @calloc(%368, %370) : (i64, i64) -> !llvm.ptr
    %372 = arith.constant 3 : i32
    %373 = arith.constant 8 : i32
    %374 = arith.extsi %372 : i32 to i64
    %375 = arith.extsi %373 : i32 to i64
    %371 = func.call @calloc(%374, %375) : (i64, i64) -> !llvm.ptr
    %377 = arith.constant 3 : i32
    %378 = arith.constant 8 : i32
    %379 = arith.extsi %377 : i32 to i64
    %380 = arith.extsi %378 : i32 to i64
    %376 = func.call @calloc(%379, %380) : (i64, i64) -> !llvm.ptr
    %382 = arith.constant 7 : i32
    %383 = arith.constant 8 : i32
    %384 = arith.extsi %382 : i32 to i64
    %385 = arith.extsi %383 : i32 to i64
    %381 = func.call @calloc(%384, %385) : (i64, i64) -> !llvm.ptr
    %386 = llvm.mlir.zero : !llvm.ptr
    %387 = llvm.icmp "eq" %363, %386 : !llvm.ptr
    %388 = scf.if %387 -> (i1) {
      %389 = arith.constant true
      scf.yield %389 : i1
    } else {
      %390 = llvm.mlir.zero : !llvm.ptr
      %391 = llvm.icmp "eq" %367, %390 : !llvm.ptr
      scf.yield %391 : i1
    }
    cf.cond_br %388, ^bb63, ^bb64
    ^bb63:
      %392 = arith.constant 1 : i32
      func.return %392 : i32
    ^bb64:
      cf.br ^bb65
    ^bb65:
    %393 = arith.constant 0 : i32
    %394 = arith.extsi %393 : i32 to i64
    %395 = llvm.mlir.constant(1 : i64) : i64
    %396 = llvm.alloca %395 x i64 : (i64) -> !llvm.ptr
    llvm.store %394, %396 : i64, !llvm.ptr
    %397 = arith.constant 1.0 : f32
    %398 = arith.negf %397 : f32
    %399 = arith.extf %398 : f32 to f64
    %400 = llvm.mlir.constant(1 : i64) : i64
    %401 = llvm.alloca %400 x f64 : (i64) -> !llvm.ptr
    llvm.store %399, %401 : f64, !llvm.ptr
    %402 = arith.constant 0 : i32
    %403 = arith.extsi %402 : i32 to i64
    %404 = llvm.mlir.constant(1 : i64) : i64
    %405 = llvm.alloca %404 x i64 : (i64) -> !llvm.ptr
    llvm.store %403, %405 : i64, !llvm.ptr
    %406 = arith.constant 0 : i32
    %407 = arith.extsi %406 : i32 to i64
    %408 = llvm.mlir.constant(1 : i64) : i64
    %409 = llvm.alloca %408 x i64 : (i64) -> !llvm.ptr
    llvm.store %407, %409 : i64, !llvm.ptr
    %410 = arith.constant 1 : i32
    %411 = arith.extsi %410 : i32 to i64
    llvm.store %411, %224 : i64, !llvm.ptr
    cf.br ^bb66
    ^bb66:
    %412 = llvm.load %224 : !llvm.ptr -> i64
    %413 = llvm.mlir.addressof @N : !llvm.ptr
    %414 = llvm.load %413 : !llvm.ptr -> i64
    %415 = arith.cmpi sle, %412, %414 : i64
    cf.cond_br %415, ^bb67, ^bb68
    ^bb67:
      %417 = llvm.load %224 : !llvm.ptr -> i64
      %418 = llvm.getelementptr %275[%417] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %416 = llvm.load %418 : !llvm.ptr -> i32
      %419 = arith.extsi %416 : i32 to i64
      %421 = llvm.getelementptr %363[%419] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %420 = llvm.load %421 : !llvm.ptr -> i32
      %422 = arith.constant 0 : i32
      %423 = arith.cmpi eq, %420, %422 : i32
      cf.cond_br %423, ^bb69, ^bb70
      ^bb69:
        %424 = arith.constant 0 : i32
        %425 = arith.extsi %424 : i32 to i64
        %426 = llvm.mlir.constant(1 : i64) : i64
        %427 = llvm.alloca %426 x i64 : (i64) -> !llvm.ptr
        llvm.store %425, %427 : i64, !llvm.ptr
        cf.br ^bb72
        ^bb72:
        %428 = llvm.load %427 : !llvm.ptr -> i64
        %429 = llvm.load %396 : !llvm.ptr -> i64
        %430 = arith.cmpi slt, %428, %429 : i64
        %431 = scf.if %430 -> (i1) {
          %433 = llvm.load %427 : !llvm.ptr -> i64
          %434 = llvm.getelementptr %367[%433] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %432 = llvm.load %434 : !llvm.ptr -> i32
          %435 = arith.trunci %419 : i64 to i32
          %436 = arith.cmpi slt, %432, %435 : i32
          scf.yield %436 : i1
        } else {
          %437 = arith.constant false
          scf.yield %437 : i1
        }
        cf.cond_br %431, ^bb73, ^bb74
        ^bb73:
          %438 = llvm.load %427 : !llvm.ptr -> i64
          %439 = arith.constant 1 : i32
          %441 = arith.extsi %439 : i32 to i64
          %440 = arith.addi %438, %441 : i64
          llvm.store %440, %427 : i64, !llvm.ptr
          cf.br ^bb72
        ^bb74:
        %442 = llvm.load %396 : !llvm.ptr -> i64
        %443 = llvm.mlir.constant(1 : i64) : i64
        %444 = llvm.alloca %443 x i64 : (i64) -> !llvm.ptr
        llvm.store %442, %444 : i64, !llvm.ptr
        cf.br ^bb75
        ^bb75:
        %445 = llvm.load %444 : !llvm.ptr -> i64
        %446 = llvm.load %427 : !llvm.ptr -> i64
        %447 = arith.cmpi sgt, %445, %446 : i64
        cf.cond_br %447, ^bb76, ^bb77
        ^bb76:
          %449 = llvm.load %444 : !llvm.ptr -> i64
          %450 = arith.constant 1 : i32
          %452 = arith.extsi %450 : i32 to i64
          %451 = arith.subi %449, %452 : i64
          %453 = llvm.getelementptr %367[%451] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %448 = llvm.load %453 : !llvm.ptr -> i32
          %454 = llvm.load %444 : !llvm.ptr -> i64
          %455 = llvm.getelementptr %367[%454] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %448, %455 : i32, !llvm.ptr
          %456 = llvm.load %444 : !llvm.ptr -> i64
          %457 = arith.constant 1 : i32
          %459 = arith.extsi %457 : i32 to i64
          %458 = arith.subi %456, %459 : i64
          llvm.store %458, %444 : i64, !llvm.ptr
          cf.br ^bb75
        ^bb77:
        %460 = arith.trunci %419 : i64 to i32
        %461 = llvm.load %427 : !llvm.ptr -> i64
        %462 = llvm.getelementptr %367[%461] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %460, %462 : i32, !llvm.ptr
        %463 = llvm.load %396 : !llvm.ptr -> i64
        %464 = arith.constant 1 : i32
        %466 = arith.extsi %464 : i32 to i64
        %465 = arith.addi %463, %466 : i64
        llvm.store %465, %396 : i64, !llvm.ptr
        cf.br ^bb71
      ^bb70:
        cf.br ^bb71
      ^bb71:
      %467 = arith.constant 1 : i32
      %468 = arith.addi %420, %467 : i32
      %469 = llvm.getelementptr %363[%419] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %468, %469 : i32, !llvm.ptr
      %470 = arith.constant 0 : i32
      %471 = arith.extsi %470 : i32 to i64
      %472 = llvm.mlir.constant(1 : i64) : i64
      %473 = llvm.alloca %472 x i64 : (i64) -> !llvm.ptr
      llvm.store %471, %473 : i64, !llvm.ptr
      cf.br ^bb78
      ^bb78:
      %474 = llvm.load %473 : !llvm.ptr -> i64
      %475 = llvm.load %396 : !llvm.ptr -> i64
      %476 = arith.cmpi slt, %474, %475 : i64
      cf.cond_br %476, ^bb79, ^bb80
      ^bb79:
        %478 = llvm.load %473 : !llvm.ptr -> i64
        %479 = llvm.getelementptr %367[%478] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %477 = llvm.load %479 : !llvm.ptr -> i32
        %480 = arith.trunci %419 : i64 to i32
        %481 = arith.cmpi eq, %477, %480 : i32
        cf.cond_br %481, ^bb81, ^bb82
        ^bb81:
          cf.br ^bb80
        ^bb82:
          cf.br ^bb83
        ^bb83:
        %482 = llvm.load %473 : !llvm.ptr -> i64
        %483 = arith.constant 1 : i32
        %485 = arith.extsi %483 : i32 to i64
        %484 = arith.addi %482, %485 : i64
        llvm.store %484, %473 : i64, !llvm.ptr
        cf.br ^bb78
      ^bb80:
      %487 = llvm.load %224 : !llvm.ptr -> i64
      %488 = llvm.getelementptr %164[%487] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %486 = llvm.load %488 : !llvm.ptr -> i64
      %489 = arith.constant 0 : i32
      %490 = arith.extsi %489 : i32 to i64
      %491 = llvm.mlir.constant(1 : i64) : i64
      %492 = llvm.alloca %491 x i64 : (i64) -> !llvm.ptr
      llvm.store %490, %492 : i64, !llvm.ptr
      %493 = arith.extsi %420 : i32 to i64
      %494 = llvm.mlir.constant(1 : i64) : i64
      %495 = llvm.alloca %494 x i64 : (i64) -> !llvm.ptr
      llvm.store %493, %495 : i64, !llvm.ptr
      %496 = llvm.load %495 : !llvm.ptr -> i64
      %497 = arith.constant 3 : i32
      %499 = arith.extsi %497 : i32 to i64
      %498 = arith.cmpi sgt, %496, %499 : i64
      cf.cond_br %498, ^bb84, ^bb85
      ^bb84:
        %500 = arith.constant 3 : i32
        %501 = arith.extsi %500 : i32 to i64
        llvm.store %501, %495 : i64, !llvm.ptr
        cf.br ^bb86
      ^bb85:
        cf.br ^bb86
      ^bb86:
      cf.br ^bb87
      ^bb87:
      %502 = llvm.load %492 : !llvm.ptr -> i64
      %503 = llvm.load %495 : !llvm.ptr -> i64
      %504 = arith.cmpi slt, %502, %503 : i64
      cf.cond_br %504, ^bb88, ^bb89
      ^bb88:
        %505 = llvm.load %492 : !llvm.ptr -> i64
        %506 = llvm.getelementptr %371[%505] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %486, %506 : i64, !llvm.ptr
        %507 = llvm.load %492 : !llvm.ptr -> i64
        %508 = arith.constant 1 : i32
        %510 = arith.extsi %508 : i32 to i64
        %509 = arith.addi %507, %510 : i64
        llvm.store %509, %492 : i64, !llvm.ptr
        cf.br ^bb87
      ^bb89:
      %511 = llvm.load %473 : !llvm.ptr -> i64
      %512 = arith.constant 1 : i32
      %514 = arith.extsi %512 : i32 to i64
      %513 = arith.subi %511, %514 : i64
      %515 = llvm.mlir.constant(1 : i64) : i64
      %516 = llvm.alloca %515 x i64 : (i64) -> !llvm.ptr
      llvm.store %513, %516 : i64, !llvm.ptr
      cf.br ^bb90
      ^bb90:
      %517 = llvm.load %492 : !llvm.ptr -> i64
      %518 = arith.constant 3 : i32
      %520 = arith.extsi %518 : i32 to i64
      %519 = arith.cmpi slt, %517, %520 : i64
      %521 = scf.if %519 -> (i1) {
        %522 = llvm.load %516 : !llvm.ptr -> i64
        %523 = arith.constant 0 : i32
        %525 = arith.extsi %523 : i32 to i64
        %524 = arith.cmpi sge, %522, %525 : i64
        scf.yield %524 : i1
      } else {
        %526 = arith.constant false
        scf.yield %526 : i1
      }
      cf.cond_br %521, ^bb91, ^bb92
      ^bb91:
        %528 = llvm.load %516 : !llvm.ptr -> i64
        %529 = llvm.getelementptr %367[%528] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %527 = llvm.load %529 : !llvm.ptr -> i32
        %530 = arith.extsi %527 : i32 to i64
        %532 = llvm.getelementptr %267[%530] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %531 = llvm.load %532 : !llvm.ptr -> i64
        %534 = llvm.getelementptr %363[%530] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %533 = llvm.load %534 : !llvm.ptr -> i32
        %535 = arith.extsi %533 : i32 to i64
        %536 = llvm.mlir.constant(1 : i64) : i64
        %537 = llvm.alloca %536 x i64 : (i64) -> !llvm.ptr
        llvm.store %535, %537 : i64, !llvm.ptr
        %538 = llvm.load %537 : !llvm.ptr -> i64
        %539 = arith.constant 3 : i32
        %540 = llvm.load %492 : !llvm.ptr -> i64
        %542 = arith.extsi %539 : i32 to i64
        %541 = arith.subi %542, %540 : i64
        %543 = arith.cmpi sgt, %538, %541 : i64
        cf.cond_br %543, ^bb93, ^bb94
        ^bb93:
          %544 = arith.constant 3 : i32
          %545 = llvm.load %492 : !llvm.ptr -> i64
          %547 = arith.extsi %544 : i32 to i64
          %546 = arith.subi %547, %545 : i64
          llvm.store %546, %537 : i64, !llvm.ptr
          cf.br ^bb95
        ^bb94:
          cf.br ^bb95
        ^bb95:
        %548 = arith.constant 0 : i32
        %549 = arith.extsi %548 : i32 to i64
        %550 = llvm.mlir.constant(1 : i64) : i64
        %551 = llvm.alloca %550 x i64 : (i64) -> !llvm.ptr
        llvm.store %549, %551 : i64, !llvm.ptr
        cf.br ^bb96
        ^bb96:
        %552 = llvm.load %551 : !llvm.ptr -> i64
        %553 = llvm.load %537 : !llvm.ptr -> i64
        %554 = arith.cmpi slt, %552, %553 : i64
        cf.cond_br %554, ^bb97, ^bb98
        ^bb97:
          %555 = llvm.load %492 : !llvm.ptr -> i64
          %556 = llvm.getelementptr %371[%555] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %531, %556 : i64, !llvm.ptr
          %557 = llvm.load %492 : !llvm.ptr -> i64
          %558 = arith.constant 1 : i32
          %560 = arith.extsi %558 : i32 to i64
          %559 = arith.addi %557, %560 : i64
          llvm.store %559, %492 : i64, !llvm.ptr
          %561 = llvm.load %551 : !llvm.ptr -> i64
          %562 = arith.constant 1 : i32
          %564 = arith.extsi %562 : i32 to i64
          %563 = arith.addi %561, %564 : i64
          llvm.store %563, %551 : i64, !llvm.ptr
          cf.br ^bb96
        ^bb98:
        %565 = llvm.load %516 : !llvm.ptr -> i64
        %566 = arith.constant 1 : i32
        %568 = arith.extsi %566 : i32 to i64
        %567 = arith.subi %565, %568 : i64
        llvm.store %567, %516 : i64, !llvm.ptr
        cf.br ^bb90
      ^bb92:
      %569 = arith.constant 0 : i32
      %570 = arith.extsi %569 : i32 to i64
      %571 = llvm.mlir.constant(1 : i64) : i64
      %572 = llvm.alloca %571 x i64 : (i64) -> !llvm.ptr
      llvm.store %570, %572 : i64, !llvm.ptr
      %573 = llvm.load %473 : !llvm.ptr -> i64
      %574 = arith.constant 1 : i32
      %576 = arith.extsi %574 : i32 to i64
      %575 = arith.addi %573, %576 : i64
      llvm.store %575, %516 : i64, !llvm.ptr
      cf.br ^bb99
      ^bb99:
      %577 = llvm.load %572 : !llvm.ptr -> i64
      %578 = arith.constant 3 : i32
      %580 = arith.extsi %578 : i32 to i64
      %579 = arith.cmpi slt, %577, %580 : i64
      %581 = scf.if %579 -> (i1) {
        %582 = llvm.load %516 : !llvm.ptr -> i64
        %583 = llvm.load %396 : !llvm.ptr -> i64
        %584 = arith.cmpi slt, %582, %583 : i64
        scf.yield %584 : i1
      } else {
        %585 = arith.constant false
        scf.yield %585 : i1
      }
      cf.cond_br %581, ^bb100, ^bb101
      ^bb100:
        %587 = llvm.load %516 : !llvm.ptr -> i64
        %588 = llvm.getelementptr %367[%587] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %586 = llvm.load %588 : !llvm.ptr -> i32
        %589 = arith.extsi %586 : i32 to i64
        %591 = llvm.getelementptr %267[%589] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %590 = llvm.load %591 : !llvm.ptr -> i64
        %593 = llvm.getelementptr %363[%589] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %592 = llvm.load %593 : !llvm.ptr -> i32
        %594 = arith.extsi %592 : i32 to i64
        %595 = llvm.mlir.constant(1 : i64) : i64
        %596 = llvm.alloca %595 x i64 : (i64) -> !llvm.ptr
        llvm.store %594, %596 : i64, !llvm.ptr
        %597 = llvm.load %596 : !llvm.ptr -> i64
        %598 = arith.constant 3 : i32
        %599 = llvm.load %572 : !llvm.ptr -> i64
        %601 = arith.extsi %598 : i32 to i64
        %600 = arith.subi %601, %599 : i64
        %602 = arith.cmpi sgt, %597, %600 : i64
        cf.cond_br %602, ^bb102, ^bb103
        ^bb102:
          %603 = arith.constant 3 : i32
          %604 = llvm.load %572 : !llvm.ptr -> i64
          %606 = arith.extsi %603 : i32 to i64
          %605 = arith.subi %606, %604 : i64
          llvm.store %605, %596 : i64, !llvm.ptr
          cf.br ^bb104
        ^bb103:
          cf.br ^bb104
        ^bb104:
        %607 = arith.constant 0 : i32
        %608 = arith.extsi %607 : i32 to i64
        %609 = llvm.mlir.constant(1 : i64) : i64
        %610 = llvm.alloca %609 x i64 : (i64) -> !llvm.ptr
        llvm.store %608, %610 : i64, !llvm.ptr
        cf.br ^bb105
        ^bb105:
        %611 = llvm.load %610 : !llvm.ptr -> i64
        %612 = llvm.load %596 : !llvm.ptr -> i64
        %613 = arith.cmpi slt, %611, %612 : i64
        cf.cond_br %613, ^bb106, ^bb107
        ^bb106:
          %614 = llvm.load %572 : !llvm.ptr -> i64
          %615 = llvm.getelementptr %376[%614] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %590, %615 : i64, !llvm.ptr
          %616 = llvm.load %572 : !llvm.ptr -> i64
          %617 = arith.constant 1 : i32
          %619 = arith.extsi %617 : i32 to i64
          %618 = arith.addi %616, %619 : i64
          llvm.store %618, %572 : i64, !llvm.ptr
          %620 = llvm.load %610 : !llvm.ptr -> i64
          %621 = arith.constant 1 : i32
          %623 = arith.extsi %621 : i32 to i64
          %622 = arith.addi %620, %623 : i64
          llvm.store %622, %610 : i64, !llvm.ptr
          cf.br ^bb105
        ^bb107:
        %624 = llvm.load %516 : !llvm.ptr -> i64
        %625 = arith.constant 1 : i32
        %627 = arith.extsi %625 : i32 to i64
        %626 = arith.addi %624, %627 : i64
        llvm.store %626, %516 : i64, !llvm.ptr
        cf.br ^bb99
      ^bb101:
      %628 = arith.constant 0 : i32
      %629 = arith.extsi %628 : i32 to i64
      %630 = llvm.mlir.constant(1 : i64) : i64
      %631 = llvm.alloca %630 x i64 : (i64) -> !llvm.ptr
      llvm.store %629, %631 : i64, !llvm.ptr
      %632 = llvm.load %492 : !llvm.ptr -> i64
      %633 = arith.constant 1 : i32
      %635 = arith.extsi %633 : i32 to i64
      %634 = arith.subi %632, %635 : i64
      %636 = llvm.mlir.constant(1 : i64) : i64
      %637 = llvm.alloca %636 x i64 : (i64) -> !llvm.ptr
      llvm.store %634, %637 : i64, !llvm.ptr
      cf.br ^bb108
      ^bb108:
      %638 = llvm.load %637 : !llvm.ptr -> i64
      %639 = arith.constant 0 : i32
      %641 = arith.extsi %639 : i32 to i64
      %640 = arith.cmpi sge, %638, %641 : i64
      cf.cond_br %640, ^bb109, ^bb110
      ^bb109:
        %643 = llvm.load %637 : !llvm.ptr -> i64
        %644 = llvm.getelementptr %371[%643] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %642 = llvm.load %644 : !llvm.ptr -> i64
        %645 = llvm.load %631 : !llvm.ptr -> i64
        %646 = llvm.getelementptr %381[%645] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %642, %646 : i64, !llvm.ptr
        %647 = llvm.load %631 : !llvm.ptr -> i64
        %648 = arith.constant 1 : i32
        %650 = arith.extsi %648 : i32 to i64
        %649 = arith.addi %647, %650 : i64
        llvm.store %649, %631 : i64, !llvm.ptr
        %651 = llvm.load %637 : !llvm.ptr -> i64
        %652 = arith.constant 1 : i32
        %654 = arith.extsi %652 : i32 to i64
        %653 = arith.subi %651, %654 : i64
        llvm.store %653, %637 : i64, !llvm.ptr
        cf.br ^bb108
      ^bb110:
      %655 = llvm.load %631 : !llvm.ptr -> i64
      %656 = llvm.getelementptr %381[%655] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %486, %656 : i64, !llvm.ptr
      %657 = llvm.load %631 : !llvm.ptr -> i64
      %658 = arith.constant 1 : i32
      %660 = arith.extsi %658 : i32 to i64
      %659 = arith.addi %657, %660 : i64
      llvm.store %659, %631 : i64, !llvm.ptr
      %661 = arith.constant 0 : i32
      %662 = arith.extsi %661 : i32 to i64
      %663 = llvm.mlir.constant(1 : i64) : i64
      %664 = llvm.alloca %663 x i64 : (i64) -> !llvm.ptr
      llvm.store %662, %664 : i64, !llvm.ptr
      cf.br ^bb111
      ^bb111:
      %665 = llvm.load %664 : !llvm.ptr -> i64
      %666 = llvm.load %572 : !llvm.ptr -> i64
      %667 = arith.cmpi slt, %665, %666 : i64
      cf.cond_br %667, ^bb112, ^bb113
      ^bb112:
        %669 = llvm.load %664 : !llvm.ptr -> i64
        %670 = llvm.getelementptr %376[%669] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %668 = llvm.load %670 : !llvm.ptr -> i64
        %671 = llvm.load %631 : !llvm.ptr -> i64
        %672 = llvm.getelementptr %381[%671] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %668, %672 : i64, !llvm.ptr
        %673 = llvm.load %631 : !llvm.ptr -> i64
        %674 = arith.constant 1 : i32
        %676 = arith.extsi %674 : i32 to i64
        %675 = arith.addi %673, %676 : i64
        llvm.store %675, %631 : i64, !llvm.ptr
        %677 = llvm.load %664 : !llvm.ptr -> i64
        %678 = arith.constant 1 : i32
        %680 = arith.extsi %678 : i32 to i64
        %679 = arith.addi %677, %680 : i64
        llvm.store %679, %664 : i64, !llvm.ptr
        cf.br ^bb111
      ^bb113:
      %681 = llvm.load %631 : !llvm.ptr -> i64
      %682 = llvm.load %572 : !llvm.ptr -> i64
      %683 = arith.subi %681, %682 : i64
      %684 = arith.constant 1 : i32
      %686 = arith.extsi %684 : i32 to i64
      %685 = arith.subi %683, %686 : i64
      %687 = arith.constant 3 : i32
      %689 = arith.extsi %687 : i32 to i64
      %688 = arith.subi %685, %689 : i64
      %690 = llvm.mlir.constant(1 : i64) : i64
      %691 = llvm.alloca %690 x i64 : (i64) -> !llvm.ptr
      llvm.store %688, %691 : i64, !llvm.ptr
      cf.br ^bb114
      ^bb114:
      %692 = llvm.load %691 : !llvm.ptr -> i64
      %693 = arith.cmpi sle, %692, %685 : i64
      cf.cond_br %693, ^bb115, ^bb116
      ^bb115:
        %694 = llvm.load %691 : !llvm.ptr -> i64
        %695 = arith.constant 0 : i32
        %697 = arith.extsi %695 : i32 to i64
        %696 = arith.cmpi sge, %694, %697 : i64
        %698 = scf.if %696 -> (i1) {
          %699 = llvm.load %691 : !llvm.ptr -> i64
          %700 = arith.constant 4 : i32
          %702 = arith.extsi %700 : i32 to i64
          %701 = arith.addi %699, %702 : i64
          %703 = llvm.load %631 : !llvm.ptr -> i64
          %704 = arith.cmpi sle, %701, %703 : i64
          scf.yield %704 : i1
        } else {
          %705 = arith.constant false
          scf.yield %705 : i1
        }
        cf.cond_br %698, ^bb117, ^bb118
        ^bb117:
          %707 = llvm.load %691 : !llvm.ptr -> i64
          %708 = llvm.getelementptr %381[%707] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %706 = llvm.load %708 : !llvm.ptr -> i64
          %710 = llvm.load %691 : !llvm.ptr -> i64
          %711 = arith.constant 1 : i32
          %713 = arith.extsi %711 : i32 to i64
          %712 = arith.addi %710, %713 : i64
          %714 = llvm.getelementptr %381[%712] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %709 = llvm.load %714 : !llvm.ptr -> i64
          %716 = llvm.load %691 : !llvm.ptr -> i64
          %717 = arith.constant 2 : i32
          %719 = arith.extsi %717 : i32 to i64
          %718 = arith.addi %716, %719 : i64
          %720 = llvm.getelementptr %381[%718] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %715 = llvm.load %720 : !llvm.ptr -> i64
          %722 = llvm.load %691 : !llvm.ptr -> i64
          %723 = arith.constant 3 : i32
          %725 = arith.extsi %723 : i32 to i64
          %724 = arith.addi %722, %725 : i64
          %726 = llvm.getelementptr %381[%724] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %721 = llvm.load %726 : !llvm.ptr -> i64
          %727 = arith.addi %706, %709 : i64
          %728 = arith.addi %727, %715 : i64
          %729 = arith.cmpi slt, %721, %728 : i64
          cf.cond_br %729, ^bb120, ^bb121
          ^bb120:
            %730 = arith.addi %706, %709 : i64
            %731 = arith.addi %730, %715 : i64
            %732 = arith.addi %731, %721 : i64
            %733 = arith.constant 2 : i32
            %735 = arith.extsi %733 : i32 to i64
            %734 = arith.muli %735, %706 : i64
            %736 = arith.subi %732, %734 : i64
            %737 = arith.sitofp %736 : i64 to f64
            %738 = math.log %737 : f64
            %739 = arith.constant 2 : i32
            %741 = arith.extsi %739 : i32 to i64
            %740 = arith.muli %741, %709 : i64
            %742 = arith.subi %732, %740 : i64
            %743 = arith.sitofp %742 : i64 to f64
            %744 = math.log %743 : f64
            %745 = arith.addf %738, %744 : f64
            %746 = arith.constant 2 : i32
            %748 = arith.extsi %746 : i32 to i64
            %747 = arith.muli %748, %715 : i64
            %749 = arith.subi %732, %747 : i64
            %750 = arith.sitofp %749 : i64 to f64
            %751 = math.log %750 : f64
            %752 = arith.addf %745, %751 : f64
            %753 = arith.constant 2 : i32
            %755 = arith.extsi %753 : i32 to i64
            %754 = arith.muli %755, %721 : i64
            %756 = arith.subi %732, %754 : i64
            %757 = arith.sitofp %756 : i64 to f64
            %758 = math.log %757 : f64
            %759 = arith.addf %752, %758 : f64
            %761 = llvm.load %401 : !llvm.ptr -> f64
            %762 = llvm.load %405 : !llvm.ptr -> i64
            %760 = func.call @better_log(%759, %732, %761, %762) : (f64, i64, f64, i64) -> i32
            %763 = arith.constant 1 : i32
            %764 = arith.cmpi eq, %760, %763 : i32
            cf.cond_br %764, ^bb123, ^bb124
            ^bb123:
              llvm.store %759, %401 : f64, !llvm.ptr
              llvm.store %732, %405 : i64, !llvm.ptr
              cf.br ^bb125
            ^bb124:
              cf.br ^bb125
            ^bb125:
            cf.br ^bb122
          ^bb121:
            cf.br ^bb122
          ^bb122:
          cf.br ^bb119
        ^bb118:
          cf.br ^bb119
        ^bb119:
        %765 = llvm.load %691 : !llvm.ptr -> i64
        %766 = arith.constant 1 : i32
        %768 = arith.extsi %766 : i32 to i64
        %767 = arith.addi %765, %768 : i64
        llvm.store %767, %691 : i64, !llvm.ptr
        cf.br ^bb114
      ^bb116:
      %769 = llvm.load %224 : !llvm.ptr -> i64
      %770 = arith.constant 4 : i32
      %772 = arith.extsi %770 : i32 to i64
      %771 = arith.cmpi sge, %769, %772 : i64
      cf.cond_br %771, ^bb126, ^bb127
      ^bb126:
        %773 = llvm.load %409 : !llvm.ptr -> i64
        %774 = llvm.load %405 : !llvm.ptr -> i64
        %775 = arith.addi %773, %774 : i64
        llvm.store %775, %409 : i64, !llvm.ptr
        cf.br ^bb128
      ^bb127:
        cf.br ^bb128
      ^bb128:
      %776 = llvm.load %224 : !llvm.ptr -> i64
      %777 = arith.constant 1 : i32
      %779 = arith.extsi %777 : i32 to i64
      %778 = arith.addi %776, %779 : i64
      llvm.store %778, %224 : i64, !llvm.ptr
      cf.br ^bb66
    ^bb68:
    %780 = llvm.mlir.addressof @str_0 : !llvm.ptr
    %781 = llvm.load %409 : !llvm.ptr -> i64
    %782 = llvm.call @printf(%780, %781) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i64) -> i32
    func.call @free(%159) : (!llvm.ptr) -> ()
    func.call @free(%164) : (!llvm.ptr) -> ()
    func.call @free(%267) : (!llvm.ptr) -> ()
    func.call @free(%275) : (!llvm.ptr) -> ()
    func.call @free(%363) : (!llvm.ptr) -> ()
    func.call @free(%367) : (!llvm.ptr) -> ()
    func.call @free(%371) : (!llvm.ptr) -> ()
    func.call @free(%376) : (!llvm.ptr) -> ()
    func.call @free(%381) : (!llvm.ptr) -> ()
    %792 = arith.constant 0 : i32
    func.return %792 : i32
  }
}