Problem 248

150000th number n with phi(n) = 13!.

Answer23507044290
Output23507044290
StatusPASS
Native helperno
Runtime120 ms
Peak memory2768 KB
Time complexityO(n log n) (estimated)
Space complexityO(1) (estimated)

Performance comparison

MetricOur solutionBest known
Time complexityO(n log n)O(n log log n)
Space complexityO(1)O(n)
ApproachFlow solutionSieve-based totient computation
VerdictSuboptimal

Flow source

# Project Euler 248
# 150000th number n with phi(n) = 13!.

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

function addmod(a: i64, b: i64, mod: i64) -> i64 {
    let s: i64 = a + b
    if s >= mod || s < a { return s - mod }
    return s
}

function mulmod(a0: i64, b0: i64, mod: i64) -> i64 {
    let mut a: i64 = a0 % mod
    let mut b: i64 = b0 % mod
    if a < 0 { a = a + mod }
    if b < 0 { b = b + mod }
    let mut result: i64 = 0
    while b > 0 {
        if b % 2 == 1 {
            result = addmod(result, a, mod)
        }
        a = addmod(a, a, mod)
        b = b / 2
    }
    return result
}

function modpow(base: i64, exp: i64, mod: i64) -> i64 {
    let mut r: i64 = 1
    let mut b: i64 = base % mod
    let mut e: i64 = exp
    while e > 0 {
        if e % 2 == 1 { r = mulmod(r, b, mod) }
        b = mulmod(b, b, mod)
        e = e / 2
    }
    return r
}

function is_prime(value: i64) -> bool {
    if value < 2 { return false }
    if value % 2 == 0 { return value == 2 }
    if value % 3 == 0 { return value == 3 }
    if value % 5 == 0 { return value == 5 }
    if value % 7 == 0 { return value == 7 }
    if value % 11 == 0 { return value == 11 }
    if value % 13 == 0 { return value == 13 }
    if value % 17 == 0 { return value == 17 }
    if value % 19 == 0 { return value == 19 }
    if value % 23 == 0 { return value == 23 }
    if value % 29 == 0 { return value == 29 }
    let mut d: i64 = value - 1
    let mut shifts: i32 = 0
    while d % 2 == 0 {
        d = d / 2
        shifts = shifts + 1
    }
    let bases: ptr<i64> = calloc(7, 8)
    bases[0] = 2; bases[1] = 325; bases[2] = 9375; bases[3] = 28178
    bases[4] = 450775; bases[5] = 9780504; bases[6] = 1795265022
    for bi in 0..7 {
        let base: i64 = bases[bi] % value
        if base != 0 {
            let mut x: i64 = modpow(base, d, value)
            if !(x == 1 || x == value - 1) {
                let mut ok: bool = false
                let mut r: i32 = 0
                while r < shifts - 1 {
                    x = mulmod(x, x, value)
                    if x == value - 1 {
                        ok = true
                        break
                    }
                    r = r + 1
                }
                if !ok {
                    free(bases)
                    return false
                }
            }
        }
    }
    free(bases)
    return true
}

let mut CANDS: ptr<i64> = null
let mut NC: i64 = 0
let mut RESULTS: ptr<i64> = null
let mut NR: i64 = 0
let mut FACT: i64 = 1
let mut FPRIMES: ptr<i64> = null
let mut FEXPS: ptr<i32> = null
let mut NF: i32 = 0

function find_cands(number: i64, last_idx: i32) -> void {
    if last_idx >= NF {
        if is_prime(number + 1) {
            CANDS[NC] = number + 1
            NC = NC + 1
        }
        return
    }
    let base: i64 = FPRIMES[last_idx]
    let exp: i32 = FEXPS[last_idx]
    let mut num: i64 = number
    for e in 0..(exp + 1) {
        find_cands(num, last_idx + 1)
        num = num * base
    }
}

function search(number: i64, phi: i64, largest: i64, start: i64) -> void {
    let mut i: i64 = start
    while i < NC {
        let current: i64 = CANDS[i]
        if current < largest { i = i + 1; continue }
        let next_number: i64 = number * current
        let mut next_phi: i64 = phi * (current - 1)
        if current == largest {
            next_phi = next_phi + phi
        }
        if next_phi > FACT { break }
        if next_phi == FACT {
            RESULTS[NR] = next_number
            NR = NR + 1
            break
        }
        if FACT % next_phi == 0 {
            search(next_number, next_phi, current, i)
        }
        i = i + 1
    }
}

function sort_i64(a: ptr<i64>, n: i64) -> void {
    # simple quicksort via stack
    let lo: ptr<i64> = calloc(64, 8)
    let hi: ptr<i64> = calloc(64, 8)
    let mut sp: i32 = 0
    lo[0] = 0; hi[0] = n - 1; sp = 1
    while sp > 0 {
        sp = sp - 1
        let l: i64 = lo[sp]
        let h: i64 = hi[sp]
        if l >= h { continue }
        let pivot: i64 = a[(l + h) / 2]
        let mut i: i64 = l
        let mut j: i64 = h
        while i <= j {
            while a[i] < pivot { i = i + 1 }
            while a[j] > pivot { j = j - 1 }
            if i <= j {
                let t: i64 = a[i]; a[i] = a[j]; a[j] = t
                i = i + 1
                j = j - 1
            }
        }
        if l < j { lo[sp] = l; hi[sp] = j; sp = sp + 1 }
        if i < h { lo[sp] = i; hi[sp] = h; sp = sp + 1 }
    }
    free(lo); free(hi)
}

function main() -> i32 {
    let mut i: i64 = 2
    while i <= 13 {
        FACT = FACT * i
        i = i + 1
    }
    FPRIMES = calloc(10, 8)
    FEXPS = calloc(10, 4)
    # factors of 13!
    FPRIMES[0] = 2; FEXPS[0] = 10
    FPRIMES[1] = 3; FEXPS[1] = 5
    FPRIMES[2] = 5; FEXPS[2] = 2
    FPRIMES[3] = 7; FEXPS[3] = 1
    FPRIMES[4] = 11; FEXPS[4] = 1
    FPRIMES[5] = 13; FEXPS[5] = 1
    NF = 6
    CANDS = calloc(10000, 8)
    RESULTS = calloc(200000, 8)
    if CANDS == null || RESULTS == null { return 1 }
    find_cands(1, 0)
    sort_i64(CANDS, NC)
    # unique
    if NC > 0 {
        let mut w: i64 = 1
        let mut r: i64 = 1
        while r < NC {
            if CANDS[r] != CANDS[w - 1] {
                CANDS[w] = CANDS[r]
                w = w + 1
            }
            r = r + 1
        }
        NC = w
    }
    search(1, 1, 1, 0)
    sort_i64(RESULTS, NR)
    printf("%lld\n", RESULTS[149999])
    free(CANDS); free(RESULTS); free(FPRIMES); free(FEXPS)
    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 addmod_i64_i64_i64(int64_t a, int64_t b, int64_t mod);
int64_t mulmod_i64_i64_i64(int64_t a0, int64_t b0, int64_t mod);
int64_t modpow_i64_i64_i64(int64_t base, int64_t exp, int64_t mod);
bool is_prime_i64(int64_t value);
void find_cands_i64_i32(int64_t number, int32_t last_idx);
void search_i64_i64_i64_i64(int64_t number, int64_t phi, int64_t largest, int64_t start);
void sort_i64_ptr_i64_i64(int64_t* a, int64_t n);
int32_t main(void);

/* Module statics */
static int64_t* CANDS = NULL;
static int64_t NC = 0;
static int64_t* RESULTS = NULL;
static int64_t NR = 0;
static int64_t FACT = 1;
static int64_t* FPRIMES = NULL;
static int32_t* FEXPS = NULL;
static int32_t NF = 0;



int64_t addmod_i64_i64_i64(int64_t a, int64_t b, int64_t mod) {
    int64_t s = (a + b);
    if ((s >= mod || s < a)) {
        return (s - mod);
    }
    return s;
}

int64_t mulmod_i64_i64_i64(int64_t a0, int64_t b0, int64_t mod) {
    int64_t a = FLOW_CHECKED_MOD((a0), (mod));
    int64_t b = FLOW_CHECKED_MOD((b0), (mod));
    if (a < 0) {
        a = (a + mod);
    }
    if (b < 0) {
        b = (b + mod);
    }
    int64_t result = 0;
    while (b > 0) {
        if (FLOW_CHECKED_MOD((b), (2)) == 1) {
            result = addmod_i64_i64_i64(result, a, mod);
        }
        a = addmod_i64_i64_i64(a, a, mod);
        b = FLOW_CHECKED_DIV((b), (2));
    }
    return result;
}

int64_t modpow_i64_i64_i64(int64_t base, int64_t exp, int64_t mod) {
    int64_t r = 1;
    int64_t b = FLOW_CHECKED_MOD((base), (mod));
    int64_t e = exp;
    while (e > 0) {
        if (FLOW_CHECKED_MOD((e), (2)) == 1) {
            r = mulmod_i64_i64_i64(r, b, mod);
        }
        b = mulmod_i64_i64_i64(b, b, mod);
        e = FLOW_CHECKED_DIV((e), (2));
    }
    return r;
}

bool is_prime_i64(int64_t value) {
    if (value < 2) {
        return 0;
    }
    if (FLOW_CHECKED_MOD((value), (2)) == 0) {
        return value == 2;
    }
    if (FLOW_CHECKED_MOD((value), (3)) == 0) {
        return value == 3;
    }
    if (FLOW_CHECKED_MOD((value), (5)) == 0) {
        return value == 5;
    }
    if (FLOW_CHECKED_MOD((value), (7)) == 0) {
        return value == 7;
    }
    if (FLOW_CHECKED_MOD((value), (11)) == 0) {
        return value == 11;
    }
    if (FLOW_CHECKED_MOD((value), (13)) == 0) {
        return value == 13;
    }
    if (FLOW_CHECKED_MOD((value), (17)) == 0) {
        return value == 17;
    }
    if (FLOW_CHECKED_MOD((value), (19)) == 0) {
        return value == 19;
    }
    if (FLOW_CHECKED_MOD((value), (23)) == 0) {
        return value == 23;
    }
    if (FLOW_CHECKED_MOD((value), (29)) == 0) {
        return value == 29;
    }
    int64_t d = (value - 1);
    int32_t shifts = 0;
    while (FLOW_CHECKED_MOD((d), (2)) == 0) {
        d = FLOW_CHECKED_DIV((d), (2));
        shifts = (shifts + 1);
    }
    int64_t* bases = (int64_t*)(calloc(7, 8));
    bases[0] = 2;
    bases[1] = 325;
    bases[2] = 9375;
    bases[3] = 28178;
    bases[4] = 450775;
    bases[5] = 9780504;
    bases[6] = 1795265022;
    int32_t __flow_step_1 = 1;
    for (int32_t bi = 0; (0 <= 7) ? bi < 7 : bi > 7; bi += (0 <= 7) ? 1 : -1) {
        int64_t base = FLOW_CHECKED_MOD((bases[bi]), (value));
        if (base != 0) {
            int64_t x = modpow_i64_i64_i64(base, d, value);
            if ((!((x == 1 || x == (value - 1))))) {
                bool ok = 0;
                int32_t r = 0;
                while (r < (shifts - 1)) {
                    x = mulmod_i64_i64_i64(x, x, value);
                    if (x == (value - 1)) {
                        ok = 1;
                        break;
                    }
                    r = (r + 1);
                }
                if ((!(ok))) {
                    free(bases);
                    return 0;
                }
            }
        }
    }
    free(bases);
    return 1;
}

void find_cands_i64_i32(int64_t number, int32_t last_idx) {
    if (last_idx >= NF) {
        if (is_prime_i64((number + 1))) {
            CANDS[NC] = (number + 1);
            NC = (NC + 1);
        }
        return;
    }
    int64_t base = FPRIMES[last_idx];
    int32_t exp = FEXPS[last_idx];
    int64_t num = number;
    int32_t __flow_step_2 = 1;
    for (int32_t e = 0; (0 <= (exp + 1)) ? e < (exp + 1) : e > (exp + 1); e += (0 <= (exp + 1)) ? 1 : -1) {
        find_cands_i64_i32(num, (last_idx + 1));
        num = (num * base);
    }
}

void search_i64_i64_i64_i64(int64_t number, int64_t phi, int64_t largest, int64_t start) {
    int64_t i = start;
    while (i < NC) {
        int64_t current = CANDS[i];
        if (current < largest) {
            i = (i + 1);
            continue;
        }
        int64_t next_number = (number * current);
        int64_t next_phi = (phi * (current - 1));
        if (current == largest) {
            next_phi = (next_phi + phi);
        }
        if (next_phi > FACT) {
            break;
        }
        if (next_phi == FACT) {
            RESULTS[NR] = next_number;
            NR = (NR + 1);
            break;
        }
        if (FLOW_CHECKED_MOD((FACT), (next_phi)) == 0) {
            search_i64_i64_i64_i64(next_number, next_phi, current, i);
        }
        i = (i + 1);
    }
}

void sort_i64_ptr_i64_i64(int64_t* a, int64_t n) {
    int64_t* lo = (int64_t*)(calloc(64, 8));
    int64_t* hi = (int64_t*)(calloc(64, 8));
    int32_t sp = 0;
    lo[0] = 0;
    hi[0] = (n - 1);
    sp = 1;
    while (sp > 0) {
        sp = (sp - 1);
        int64_t l = lo[sp];
        int64_t h = hi[sp];
        if (l >= h) {
            continue;
        }
        int64_t pivot = a[FLOW_CHECKED_DIV(((l + h)), (2))];
        int64_t i = l;
        int64_t j = h;
        while (i <= j) {
            while (a[i] < pivot) {
                i = (i + 1);
            }
            while (a[j] > pivot) {
                j = (j - 1);
            }
            if (i <= j) {
                int64_t t = a[i];
                a[i] = a[j];
                a[j] = t;
                i = (i + 1);
                j = (j - 1);
            }
        }
        if (l < j) {
            lo[sp] = l;
            hi[sp] = j;
            sp = (sp + 1);
        }
        if (i < h) {
            lo[sp] = i;
            hi[sp] = h;
            sp = (sp + 1);
        }
    }
    free(lo);
    free(hi);
}

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