Problem 715

f(k)/(k^2 phi(k)) is multiplicative with value p^(3(e-1)) * (p^3 - chi4(p)) at p^e, where chi4 is the nonprincipal character mod 4 (count solutions of a rank-6 quadratic form mod p). Its Dirichlet series is zeta(s-3)/L(s,chi4), so g = Id^3 * (mu.chi4) and G(n) = sum_d mu(d)chi4(d) * S3(floor(n/d)) with S3(m) = (m(m+1)/2)^2. Compute M(x) = sum_{d<=x} mu(d)chi4(d) by a linear sieve up to K = 4*10^7 plus the Mertens-style recursion from (mu.chi4)*chi4 = epsilon, then sum over quotient blocks. O(n^(2/3)) total.

Answer883188017
Output883188017
StatusPASS
Native helperno
Runtime5470 ms
Peak memory245216 KB
Time complexityO(n) (estimated)
Space complexityO(n^2) (estimated)

Performance comparison

MetricOur solutionBest known
Time complexityO(n)O(n log log n)
Space complexityO(n^2)O(n)
ApproachFlow solutionSieve-based totient computation
VerdictOptimal

Flow source

# Project Euler 715: Sextuplet Norms
#
# f(k)/(k^2 phi(k)) is multiplicative with value p^(3(e-1)) * (p^3 - chi4(p))
# at p^e, where chi4 is the nonprincipal character mod 4 (count solutions of
# a rank-6 quadratic form mod p). Its Dirichlet series is zeta(s-3)/L(s,chi4),
# so g = Id^3 * (mu.chi4) and G(n) = sum_d mu(d)chi4(d) * S3(floor(n/d)) with
# S3(m) = (m(m+1)/2)^2. Compute M(x) = sum_{d<=x} mu(d)chi4(d) by a linear
# sieve up to K = 4*10^7 plus the Mertens-style recursion from
# (mu.chi4)*chi4 = epsilon, then sum over quotient blocks. O(n^(2/3)) total.

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

# C(t) = sum_{d<=t} chi4(d), period 4 pattern 1,1,0,0
function cfun(t: i64) -> i64 {
    let r: i64 = t % 4
    if r == 1 || r == 2 {
        return 1
    }
    return 0
}

function main() -> i32 {
    let n: i64 = 1000000000000
    let kk: i64 = 40000000
    let md: i64 = 1000000007
    let inv2: i64 = 500000004

    # linear sieve for mu up to kk
    let comp: ptr<i8> = calloc(kk + 1, 1)
    let mu: ptr<i8> = calloc(kk + 1, 1)
    let primes: ptr<i32> = calloc(2500000, 4)
    mu[1] = 1
    let mut np: i64 = 0
    let mut i: i64 = 2
    while i <= kk {
        if comp[i] == 0 {
            primes[np] = i as i32
            np = np + 1
            mu[i] = 0 - 1
        }
        let mut j: i64 = 0
        while j < np {
            let p: i64 = primes[j] as i64
            let ip: i64 = i * p
            if ip > kk {
                break
            }
            comp[ip] = 1
            if i % p == 0 {
                mu[ip] = 0
                break
            }
            mu[ip] = 0 - mu[i]
            j = j + 1
        }
        i = i + 1
    }
    free(comp)
    free(primes)

    # prefix sums of h(d) = mu(d) * chi4(d)
    let msmall: ptr<i32> = calloc(kk + 1, 4)
    let mut acc: i64 = 0
    i = 1
    while i <= kk {
        if i % 2 == 1 {
            let m: i64 = mu[i] as i64
            if i % 4 == 1 {
                acc = acc + m
            } else {
                acc = acc - m
            }
        }
        msmall[i] = acc as i32
        i = i + 1
    }
    free(mu)

    # M(n/ii) for ii = 1..imax via M(x) = 1 - sum_{d>=2} chi4(d) M(x/d)
    let imax: i64 = n / kk
    let mbig: ptr<i64> = calloc(imax + 2, 8)
    let mut ii: i64 = imax
    while ii >= 1 {
        let x: i64 = n / ii
        if x <= kk {
            mbig[ii] = msmall[x] as i64
        } else {
            let mut s: i64 = 1
            let mut d: i64 = 2
            while d <= x {
                let q: i64 = x / d
                let d2: i64 = x / q
                let w: i64 = cfun(d2) - cfun(d - 1)
                if w != 0 {
                    if q <= kk {
                        s = s - w * (msmall[q] as i64)
                    } else {
                        s = s - w * mbig[ii * d]
                    }
                }
                d = d2 + 1
            }
            mbig[ii] = s
        }
        ii = ii - 1
    }

    # G(n) = sum over quotient blocks of (M(hi) - M(lo-1)) * S3(q) mod md
    let mut total: i64 = 0
    let mut prev: i64 = 0
    let mut lo: i64 = 1
    while lo <= n {
        let q: i64 = n / lo
        let hi: i64 = n / q
        let mut m2: i64 = 0
        if hi <= kk {
            m2 = msmall[hi] as i64
        } else {
            m2 = mbig[n / hi]
        }
        let mut w: i64 = (m2 - prev) % md
        if w < 0 {
            w = w + md
        }
        let a: i64 = q % md
        let b: i64 = (q + 1) % md
        let s1: i64 = a * b % md * inv2 % md
        let s3: i64 = s1 * s1 % md
        total = (total + w * s3) % md
        prev = m2
        lo = hi + 1
    }
    free(msmall)
    free(mbig)
    printf("%lld\n", total)
    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 cfun_i64(int64_t t);
int32_t main(void);



int64_t cfun_i64(int64_t t) {
    int64_t r = FLOW_CHECKED_MOD((t), (4));
    if ((r == 1 || r == 2)) {
        return 1;
    }
    return 0;
}

int32_t main(void) {
    int64_t n = 1000000000000;
    int64_t kk = 40000000;
    int64_t md = 1000000007;
    int64_t inv2 = 500000004;
    int8_t* comp = (int8_t*)(calloc((kk + 1), 1));
    int8_t* mu = (int8_t*)(calloc((kk + 1), 1));
    int32_t* primes = (int32_t*)(calloc(2500000, 4));
    mu[1] = 1;
    int64_t np = 0;
    int64_t i = 2;
    while (i <= kk) {
        if (comp[i] == 0) {
            primes[np] = ((int32_t)(i));
            np = (np + 1);
            mu[i] = (0 - 1);
        }
        int64_t j = 0;
        while (j < np) {
            int64_t p = ((int64_t)(primes[j]));
            int64_t ip = (i * p);
            if (ip > kk) {
                break;
            }
            comp[ip] = 1;
            if (FLOW_CHECKED_MOD((i), (p)) == 0) {
                mu[ip] = 0;
                break;
            }
            mu[ip] = (0 - mu[i]);
            j = (j + 1);
        }
        i = (i + 1);
    }
    free(comp);
    free(primes);
    int32_t* msmall = (int32_t*)(calloc((kk + 1), 4));
    int64_t acc = 0;
    i = 1;
    while (i <= kk) {
        if (FLOW_CHECKED_MOD((i), (2)) == 1) {
            int64_t m = ((int64_t)(mu[i]));
            if (FLOW_CHECKED_MOD((i), (4)) == 1) {
                acc = (acc + m);
            } else {
                acc = (acc - m);
            }
        }
        msmall[i] = ((int32_t)(acc));
        i = (i + 1);
    }
    free(mu);
    int64_t imax = FLOW_CHECKED_DIV((n), (kk));
    int64_t* mbig = (int64_t*)(calloc((imax + 2), 8));
    int64_t ii = imax;
    while (ii >= 1) {
        int64_t x = FLOW_CHECKED_DIV((n), (ii));
        if (x <= kk) {
            mbig[ii] = ((int64_t)(msmall[x]));
        } else {
            int64_t s = 1;
            int64_t d = 2;
            while (d <= x) {
                int64_t q = FLOW_CHECKED_DIV((x), (d));
                int64_t d2 = FLOW_CHECKED_DIV((x), (q));
                int64_t w = (cfun_i64(d2) - cfun_i64((d - 1)));
                if (w != 0) {
                    if (q <= kk) {
                        s = (s - (w * ((int64_t)(msmall[q]))));
                    } else {
                        s = (s - (w * mbig[(ii * d)]));
                    }
                }
                d = (d2 + 1);
            }
            mbig[ii] = s;
        }
        ii = (ii - 1);
    }
    int64_t total = 0;
    int64_t prev = 0;
    int64_t lo = 1;
    while (lo <= n) {
        int64_t q = FLOW_CHECKED_DIV((n), (lo));
        int64_t hi = FLOW_CHECKED_DIV((n), (q));
        int64_t m2 = 0;
        if (hi <= kk) {
            m2 = ((int64_t)(msmall[hi]));
        } else {
            m2 = mbig[FLOW_CHECKED_DIV((n), (hi))];
        }
        int64_t w = FLOW_CHECKED_MOD(((m2 - prev)), (md));
        if (w < 0) {
            w = (w + md);
        }
        int64_t a = FLOW_CHECKED_MOD((q), (md));
        int64_t b = FLOW_CHECKED_MOD(((q + 1)), (md));
        int64_t s1 = FLOW_CHECKED_MOD(((FLOW_CHECKED_MOD(((a * b)), (md)) * inv2)), (md));
        int64_t s3 = FLOW_CHECKED_MOD(((s1 * s1)), (md));
        total = FLOW_CHECKED_MOD(((total + (w * s3))), (md));
        prev = m2;
        lo = (hi + 1);
    }
    free(msmall);
    free(mbig);
    printf("%lld\n", total);
    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 @cfun(%arg0: i64) -> i64 {
    %0 = arith.constant 4 : i32
    %2 = arith.extsi %0 : i32 to i64
    %1 = arith.remsi %arg0, %2 : i64
    %3 = arith.constant 1 : i32
    %5 = arith.extsi %3 : i32 to i64
    %4 = arith.cmpi eq, %1, %5 : i64
    %6 = scf.if %4 -> (i1) {
      %7 = arith.constant true
      scf.yield %7 : i1
    } else {
      %8 = arith.constant 2 : i32
      %10 = arith.extsi %8 : i32 to i64
      %9 = arith.cmpi eq, %1, %10 : i64
      scf.yield %9 : i1
    }
    cf.cond_br %6, ^bb0, ^bb1
    ^bb0:
      %11 = arith.constant 1 : i32
      %12 = arith.extsi %11 : i32 to i64
      func.return %12 : i64
    ^bb1:
      cf.br ^bb2
    ^bb2:
    %13 = arith.constant 0 : i32
    %14 = arith.extsi %13 : i32 to i64
    func.return %14 : i64
  }
  func.func @main() -> i32 {
    %15 = arith.constant 995705032704 : i32
    %16 = arith.extsi %15 : i32 to i64
    %17 = arith.constant 40000000 : i32
    %18 = arith.extsi %17 : i32 to i64
    %19 = arith.constant 1000000007 : i32
    %20 = arith.extsi %19 : i32 to i64
    %21 = arith.constant 500000004 : i32
    %22 = arith.extsi %21 : i32 to i64
    %24 = arith.constant 1 : i32
    %26 = arith.extsi %24 : i32 to i64
    %25 = arith.addi %18, %26 : i64
    %27 = arith.constant 1 : i32
    %28 = arith.extsi %27 : i32 to i64
    %23 = func.call @calloc(%25, %28) : (i64, i64) -> !llvm.ptr
    %30 = arith.constant 1 : i32
    %32 = arith.extsi %30 : i32 to i64
    %31 = arith.addi %18, %32 : i64
    %33 = arith.constant 1 : i32
    %34 = arith.extsi %33 : i32 to i64
    %29 = func.call @calloc(%31, %34) : (i64, i64) -> !llvm.ptr
    %36 = arith.constant 2500000 : i32
    %37 = arith.constant 4 : i32
    %38 = arith.extsi %36 : i32 to i64
    %39 = arith.extsi %37 : i32 to i64
    %35 = func.call @calloc(%38, %39) : (i64, i64) -> !llvm.ptr
    %40 = arith.constant 1 : i32
    %41 = arith.constant 1 : i32
    %42 = arith.trunci %40 : i32 to i8
    %43 = arith.extsi %41 : i32 to i64
    %44 = llvm.getelementptr %29[%43] : (!llvm.ptr, i64) -> !llvm.ptr, i8
    llvm.store %42, %44 : i8, !llvm.ptr
    %45 = arith.constant 0 : i32
    %46 = arith.extsi %45 : i32 to i64
    %47 = llvm.mlir.constant(1 : i64) : i64
    %48 = llvm.alloca %47 x i64 : (i64) -> !llvm.ptr
    llvm.store %46, %48 : i64, !llvm.ptr
    %49 = arith.constant 2 : i32
    %50 = arith.extsi %49 : i32 to i64
    %51 = llvm.mlir.constant(1 : i64) : i64
    %52 = llvm.alloca %51 x i64 : (i64) -> !llvm.ptr
    llvm.store %50, %52 : i64, !llvm.ptr
    cf.br ^bb3
    ^bb3:
    %53 = llvm.load %52 : !llvm.ptr -> i64
    %54 = arith.cmpi sle, %53, %18 : i64
    cf.cond_br %54, ^bb4, ^bb5
    ^bb4:
      %56 = llvm.load %52 : !llvm.ptr -> i64
      %57 = llvm.getelementptr %23[%56] : (!llvm.ptr, i64) -> !llvm.ptr, i8
      %55 = llvm.load %57 : !llvm.ptr -> i8
      %58 = arith.constant 0 : i32
      %60 = arith.extsi %55 : i8 to i32
      %59 = arith.cmpi eq, %60, %58 : i32
      cf.cond_br %59, ^bb6, ^bb7
      ^bb6:
        %61 = llvm.load %52 : !llvm.ptr -> i64
        %62 = arith.trunci %61 : i64 to i32
        %63 = llvm.load %48 : !llvm.ptr -> i64
        %64 = llvm.getelementptr %35[%63] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %62, %64 : i32, !llvm.ptr
        %65 = llvm.load %48 : !llvm.ptr -> i64
        %66 = arith.constant 1 : i32
        %68 = arith.extsi %66 : i32 to i64
        %67 = arith.addi %65, %68 : i64
        llvm.store %67, %48 : i64, !llvm.ptr
        %69 = arith.constant 0 : i32
        %70 = arith.constant 1 : i32
        %71 = arith.subi %69, %70 : i32
        %72 = llvm.load %52 : !llvm.ptr -> i64
        %73 = arith.trunci %71 : i32 to i8
        %74 = llvm.getelementptr %29[%72] : (!llvm.ptr, i64) -> !llvm.ptr, i8
        llvm.store %73, %74 : i8, !llvm.ptr
        cf.br ^bb8
      ^bb7:
        cf.br ^bb8
      ^bb8:
      %75 = arith.constant 0 : i32
      %76 = arith.extsi %75 : i32 to i64
      %77 = llvm.mlir.constant(1 : i64) : i64
      %78 = llvm.alloca %77 x i64 : (i64) -> !llvm.ptr
      llvm.store %76, %78 : i64, !llvm.ptr
      cf.br ^bb9
      ^bb9:
      %79 = llvm.load %78 : !llvm.ptr -> i64
      %80 = llvm.load %48 : !llvm.ptr -> i64
      %81 = arith.cmpi slt, %79, %80 : i64
      cf.cond_br %81, ^bb10, ^bb11
      ^bb10:
        %83 = llvm.load %78 : !llvm.ptr -> i64
        %84 = llvm.getelementptr %35[%83] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %82 = llvm.load %84 : !llvm.ptr -> i32
        %85 = arith.extsi %82 : i32 to i64
        %86 = llvm.load %52 : !llvm.ptr -> i64
        %87 = arith.muli %86, %85 : i64
        %88 = arith.cmpi sgt, %87, %18 : i64
        cf.cond_br %88, ^bb12, ^bb13
        ^bb12:
          cf.br ^bb11
        ^bb13:
          cf.br ^bb14
        ^bb14:
        %89 = arith.constant 1 : i32
        %90 = arith.trunci %89 : i32 to i8
        %91 = llvm.getelementptr %23[%87] : (!llvm.ptr, i64) -> !llvm.ptr, i8
        llvm.store %90, %91 : i8, !llvm.ptr
        %92 = llvm.load %52 : !llvm.ptr -> i64
        %93 = arith.remsi %92, %85 : i64
        %94 = arith.constant 0 : i32
        %96 = arith.extsi %94 : i32 to i64
        %95 = arith.cmpi eq, %93, %96 : i64
        cf.cond_br %95, ^bb15, ^bb16
        ^bb15:
          %97 = arith.constant 0 : i32
          %98 = arith.trunci %97 : i32 to i8
          %99 = llvm.getelementptr %29[%87] : (!llvm.ptr, i64) -> !llvm.ptr, i8
          llvm.store %98, %99 : i8, !llvm.ptr
          cf.br ^bb11
        ^bb16:
          cf.br ^bb17
        ^bb17:
        %100 = arith.constant 0 : i32
        %102 = llvm.load %52 : !llvm.ptr -> i64
        %103 = llvm.getelementptr %29[%102] : (!llvm.ptr, i64) -> !llvm.ptr, i8
        %101 = llvm.load %103 : !llvm.ptr -> i8
        %105 = arith.extsi %101 : i8 to i32
        %104 = arith.subi %100, %105 : i32
        %106 = arith.trunci %104 : i32 to i8
        %107 = llvm.getelementptr %29[%87] : (!llvm.ptr, i64) -> !llvm.ptr, i8
        llvm.store %106, %107 : i8, !llvm.ptr
        %108 = llvm.load %78 : !llvm.ptr -> i64
        %109 = arith.constant 1 : i32
        %111 = arith.extsi %109 : i32 to i64
        %110 = arith.addi %108, %111 : i64
        llvm.store %110, %78 : i64, !llvm.ptr
        cf.br ^bb9
      ^bb11:
      %112 = llvm.load %52 : !llvm.ptr -> i64
      %113 = arith.constant 1 : i32
      %115 = arith.extsi %113 : i32 to i64
      %114 = arith.addi %112, %115 : i64
      llvm.store %114, %52 : i64, !llvm.ptr
      cf.br ^bb3
    ^bb5:
    func.call @free(%23) : (!llvm.ptr) -> ()
    func.call @free(%35) : (!llvm.ptr) -> ()
    %119 = arith.constant 1 : i32
    %121 = arith.extsi %119 : i32 to i64
    %120 = arith.addi %18, %121 : i64
    %122 = arith.constant 4 : i32
    %123 = arith.extsi %122 : i32 to i64
    %118 = func.call @calloc(%120, %123) : (i64, i64) -> !llvm.ptr
    %124 = arith.constant 0 : i32
    %125 = arith.extsi %124 : i32 to i64
    %126 = llvm.mlir.constant(1 : i64) : i64
    %127 = llvm.alloca %126 x i64 : (i64) -> !llvm.ptr
    llvm.store %125, %127 : i64, !llvm.ptr
    %128 = arith.constant 1 : i32
    %129 = arith.extsi %128 : i32 to i64
    llvm.store %129, %52 : i64, !llvm.ptr
    cf.br ^bb18
    ^bb18:
    %130 = llvm.load %52 : !llvm.ptr -> i64
    %131 = arith.cmpi sle, %130, %18 : i64
    cf.cond_br %131, ^bb19, ^bb20
    ^bb19:
      %132 = llvm.load %52 : !llvm.ptr -> i64
      %133 = arith.constant 2 : i32
      %135 = arith.extsi %133 : i32 to i64
      %134 = arith.remsi %132, %135 : i64
      %136 = arith.constant 1 : i32
      %138 = arith.extsi %136 : i32 to i64
      %137 = arith.cmpi eq, %134, %138 : i64
      cf.cond_br %137, ^bb21, ^bb22
      ^bb21:
        %140 = llvm.load %52 : !llvm.ptr -> i64
        %141 = llvm.getelementptr %29[%140] : (!llvm.ptr, i64) -> !llvm.ptr, i8
        %139 = llvm.load %141 : !llvm.ptr -> i8
        %142 = arith.extsi %139 : i8 to i64
        %143 = llvm.load %52 : !llvm.ptr -> i64
        %144 = arith.constant 4 : i32
        %146 = arith.extsi %144 : i32 to i64
        %145 = arith.remsi %143, %146 : i64
        %147 = arith.constant 1 : i32
        %149 = arith.extsi %147 : i32 to i64
        %148 = arith.cmpi eq, %145, %149 : i64
        cf.cond_br %148, ^bb24, ^bb25
        ^bb24:
          %150 = llvm.load %127 : !llvm.ptr -> i64
          %151 = arith.addi %150, %142 : i64
          llvm.store %151, %127 : i64, !llvm.ptr
          cf.br ^bb26
        ^bb25:
          %152 = llvm.load %127 : !llvm.ptr -> i64
          %153 = arith.subi %152, %142 : i64
          llvm.store %153, %127 : i64, !llvm.ptr
          cf.br ^bb26
        ^bb26:
        cf.br ^bb23
      ^bb22:
        cf.br ^bb23
      ^bb23:
      %154 = llvm.load %127 : !llvm.ptr -> i64
      %155 = arith.trunci %154 : i64 to i32
      %156 = llvm.load %52 : !llvm.ptr -> i64
      %157 = llvm.getelementptr %118[%156] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %155, %157 : i32, !llvm.ptr
      %158 = llvm.load %52 : !llvm.ptr -> i64
      %159 = arith.constant 1 : i32
      %161 = arith.extsi %159 : i32 to i64
      %160 = arith.addi %158, %161 : i64
      llvm.store %160, %52 : i64, !llvm.ptr
      cf.br ^bb18
    ^bb20:
    func.call @free(%29) : (!llvm.ptr) -> ()
    %163 = arith.divsi %16, %18 : i64
    %165 = arith.constant 2 : i32
    %167 = arith.extsi %165 : i32 to i64
    %166 = arith.addi %163, %167 : i64
    %168 = arith.constant 8 : i32
    %169 = arith.extsi %168 : i32 to i64
    %164 = func.call @calloc(%166, %169) : (i64, i64) -> !llvm.ptr
    %170 = llvm.mlir.constant(1 : i64) : i64
    %171 = llvm.alloca %170 x i64 : (i64) -> !llvm.ptr
    llvm.store %163, %171 : i64, !llvm.ptr
    cf.br ^bb27
    ^bb27:
    %172 = llvm.load %171 : !llvm.ptr -> i64
    %173 = arith.constant 1 : i32
    %175 = arith.extsi %173 : i32 to i64
    %174 = arith.cmpi sge, %172, %175 : i64
    cf.cond_br %174, ^bb28, ^bb29
    ^bb28:
      %176 = llvm.load %171 : !llvm.ptr -> i64
      %177 = arith.divsi %16, %176 : i64
      %178 = arith.cmpi sle, %177, %18 : i64
      cf.cond_br %178, ^bb30, ^bb31
      ^bb30:
        %180 = llvm.getelementptr %118[%177] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %179 = llvm.load %180 : !llvm.ptr -> i32
        %181 = arith.extsi %179 : i32 to i64
        %182 = llvm.load %171 : !llvm.ptr -> i64
        %183 = llvm.getelementptr %164[%182] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %181, %183 : i64, !llvm.ptr
        cf.br ^bb32
      ^bb31:
        %184 = arith.constant 1 : i32
        %185 = arith.extsi %184 : i32 to i64
        %186 = llvm.mlir.constant(1 : i64) : i64
        %187 = llvm.alloca %186 x i64 : (i64) -> !llvm.ptr
        llvm.store %185, %187 : i64, !llvm.ptr
        %188 = arith.constant 2 : i32
        %189 = arith.extsi %188 : i32 to i64
        %190 = llvm.mlir.constant(1 : i64) : i64
        %191 = llvm.alloca %190 x i64 : (i64) -> !llvm.ptr
        llvm.store %189, %191 : i64, !llvm.ptr
        cf.br ^bb33
        ^bb33:
        %192 = llvm.load %191 : !llvm.ptr -> i64
        %193 = arith.cmpi sle, %192, %177 : i64
        cf.cond_br %193, ^bb34, ^bb35
        ^bb34:
          %194 = llvm.load %191 : !llvm.ptr -> i64
          %195 = arith.divsi %177, %194 : i64
          %196 = arith.divsi %177, %195 : i64
          %197 = func.call @cfun(%196) : (i64) -> i64
          %199 = llvm.load %191 : !llvm.ptr -> i64
          %200 = arith.constant 1 : i32
          %202 = arith.extsi %200 : i32 to i64
          %201 = arith.subi %199, %202 : i64
          %198 = func.call @cfun(%201) : (i64) -> i64
          %203 = arith.subi %197, %198 : i64
          %204 = arith.constant 0 : i32
          %206 = arith.extsi %204 : i32 to i64
          %205 = arith.cmpi ne, %203, %206 : i64
          cf.cond_br %205, ^bb36, ^bb37
          ^bb36:
            %207 = arith.cmpi sle, %195, %18 : i64
            cf.cond_br %207, ^bb39, ^bb40
            ^bb39:
              %208 = llvm.load %187 : !llvm.ptr -> i64
              %210 = llvm.getelementptr %118[%195] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              %209 = llvm.load %210 : !llvm.ptr -> i32
              %211 = arith.extsi %209 : i32 to i64
              %212 = arith.muli %203, %211 : i64
              %213 = arith.subi %208, %212 : i64
              llvm.store %213, %187 : i64, !llvm.ptr
              cf.br ^bb41
            ^bb40:
              %214 = llvm.load %187 : !llvm.ptr -> i64
              %216 = llvm.load %171 : !llvm.ptr -> i64
              %217 = llvm.load %191 : !llvm.ptr -> i64
              %218 = arith.muli %216, %217 : i64
              %219 = llvm.getelementptr %164[%218] : (!llvm.ptr, i64) -> !llvm.ptr, i64
              %215 = llvm.load %219 : !llvm.ptr -> i64
              %220 = arith.muli %203, %215 : i64
              %221 = arith.subi %214, %220 : i64
              llvm.store %221, %187 : i64, !llvm.ptr
              cf.br ^bb41
            ^bb41:
            cf.br ^bb38
          ^bb37:
            cf.br ^bb38
          ^bb38:
          %222 = arith.constant 1 : i32
          %224 = arith.extsi %222 : i32 to i64
          %223 = arith.addi %196, %224 : i64
          llvm.store %223, %191 : i64, !llvm.ptr
          cf.br ^bb33
        ^bb35:
        %225 = llvm.load %187 : !llvm.ptr -> i64
        %226 = llvm.load %171 : !llvm.ptr -> i64
        %227 = llvm.getelementptr %164[%226] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %225, %227 : i64, !llvm.ptr
        cf.br ^bb32
      ^bb32:
      %228 = llvm.load %171 : !llvm.ptr -> i64
      %229 = arith.constant 1 : i32
      %231 = arith.extsi %229 : i32 to i64
      %230 = arith.subi %228, %231 : i64
      llvm.store %230, %171 : i64, !llvm.ptr
      cf.br ^bb27
    ^bb29:
    %232 = arith.constant 0 : i32
    %233 = arith.extsi %232 : i32 to i64
    %234 = llvm.mlir.constant(1 : i64) : i64
    %235 = llvm.alloca %234 x i64 : (i64) -> !llvm.ptr
    llvm.store %233, %235 : i64, !llvm.ptr
    %236 = arith.constant 0 : i32
    %237 = arith.extsi %236 : i32 to i64
    %238 = llvm.mlir.constant(1 : i64) : i64
    %239 = llvm.alloca %238 x i64 : (i64) -> !llvm.ptr
    llvm.store %237, %239 : i64, !llvm.ptr
    %240 = arith.constant 1 : i32
    %241 = arith.extsi %240 : i32 to i64
    %242 = llvm.mlir.constant(1 : i64) : i64
    %243 = llvm.alloca %242 x i64 : (i64) -> !llvm.ptr
    llvm.store %241, %243 : i64, !llvm.ptr
    cf.br ^bb42
    ^bb42:
    %244 = llvm.load %243 : !llvm.ptr -> i64
    %245 = arith.cmpi sle, %244, %16 : i64
    cf.cond_br %245, ^bb43, ^bb44
    ^bb43:
      %246 = llvm.load %243 : !llvm.ptr -> i64
      %247 = arith.divsi %16, %246 : i64
      %248 = arith.divsi %16, %247 : i64
      %249 = arith.constant 0 : i32
      %250 = arith.extsi %249 : i32 to i64
      %251 = llvm.mlir.constant(1 : i64) : i64
      %252 = llvm.alloca %251 x i64 : (i64) -> !llvm.ptr
      llvm.store %250, %252 : i64, !llvm.ptr
      %253 = arith.cmpi sle, %248, %18 : i64
      cf.cond_br %253, ^bb45, ^bb46
      ^bb45:
        %255 = llvm.getelementptr %118[%248] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %254 = llvm.load %255 : !llvm.ptr -> i32
        %256 = arith.extsi %254 : i32 to i64
        llvm.store %256, %252 : i64, !llvm.ptr
        cf.br ^bb47
      ^bb46:
        %258 = arith.divsi %16, %248 : i64
        %259 = llvm.getelementptr %164[%258] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %257 = llvm.load %259 : !llvm.ptr -> i64
        llvm.store %257, %252 : i64, !llvm.ptr
        cf.br ^bb47
      ^bb47:
      %260 = llvm.load %252 : !llvm.ptr -> i64
      %261 = llvm.load %239 : !llvm.ptr -> i64
      %262 = arith.subi %260, %261 : i64
      %263 = arith.remsi %262, %20 : i64
      %264 = llvm.mlir.constant(1 : i64) : i64
      %265 = llvm.alloca %264 x i64 : (i64) -> !llvm.ptr
      llvm.store %263, %265 : i64, !llvm.ptr
      %266 = llvm.load %265 : !llvm.ptr -> i64
      %267 = arith.constant 0 : i32
      %269 = arith.extsi %267 : i32 to i64
      %268 = arith.cmpi slt, %266, %269 : i64
      cf.cond_br %268, ^bb48, ^bb49
      ^bb48:
        %270 = llvm.load %265 : !llvm.ptr -> i64
        %271 = arith.addi %270, %20 : i64
        llvm.store %271, %265 : i64, !llvm.ptr
        cf.br ^bb50
      ^bb49:
        cf.br ^bb50
      ^bb50:
      %272 = arith.remsi %247, %20 : i64
      %273 = arith.constant 1 : i32
      %275 = arith.extsi %273 : i32 to i64
      %274 = arith.addi %247, %275 : i64
      %276 = arith.remsi %274, %20 : i64
      %277 = arith.muli %272, %276 : i64
      %278 = arith.remsi %277, %20 : i64
      %279 = arith.muli %278, %22 : i64
      %280 = arith.remsi %279, %20 : i64
      %281 = arith.muli %280, %280 : i64
      %282 = arith.remsi %281, %20 : i64
      %283 = llvm.load %235 : !llvm.ptr -> i64
      %284 = llvm.load %265 : !llvm.ptr -> i64
      %285 = arith.muli %284, %282 : i64
      %286 = arith.addi %283, %285 : i64
      %287 = arith.remsi %286, %20 : i64
      llvm.store %287, %235 : i64, !llvm.ptr
      %288 = llvm.load %252 : !llvm.ptr -> i64
      llvm.store %288, %239 : i64, !llvm.ptr
      %289 = arith.constant 1 : i32
      %291 = arith.extsi %289 : i32 to i64
      %290 = arith.addi %248, %291 : i64
      llvm.store %290, %243 : i64, !llvm.ptr
      cf.br ^bb42
    ^bb44:
    func.call @free(%118) : (!llvm.ptr) -> ()
    func.call @free(%164) : (!llvm.ptr) -> ()
    %294 = llvm.mlir.addressof @str_0 : !llvm.ptr
    %295 = llvm.load %235 : !llvm.ptr -> i64
    %296 = llvm.call @printf(%294, %295) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i64) -> i32
    %297 = arith.constant 0 : i32
    func.return %297 : i32
  }
}