Problem 465

Polar Polygons — P(7^13) mod 10^9+7 via Du Jiao totient sums (i128).

Answer585965659
Output585965659
StatusPASS
Native helperno
Runtime930 ms
Peak memory321040 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 465
# Polar Polygons — P(7^13) mod 10^9+7 via Du Jiao totient sums (i128).

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

const MOD: i64 = 1000000007
const PRE: i64 = 20000000
const CAP: i64 = 4194304

let mut G_pref: ptr<i64> = null
let mut G_keys: ptr<i64> = null
let mut G_vals: ptr<i128> = null
let mut G_used: ptr<i8> = null

function modpow(base0: i64, exp0: i64, mod: i64) -> i64 {
    let mut r: i64 = 1
    let mut b: i64 = base0 % mod
    if b < 0 { b = b + mod }
    let mut e: i64 = exp0
    while e > 0 {
        if (e & 1) == 1 {
            r = ((r as i128) * (b as i128) % (mod as i128)) as i64
        }
        b = ((b as i128) * (b as i128) % (mod as i128)) as i64
        e = e / 2
    }
    return r
}

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

function tot_sum(n: i64) -> i128 {
    if n <= 0 { return 0 as i128 }
    if n <= PRE { return G_pref[n] as i128 }
    let s: i64 = hslot(n)
    if G_used[s] == 1 { return G_vals[s] }
    let nn: i128 = n as i128
    let mut res: i128 = nn * (nn + 1) / 2
    let mut lo: i64 = 2
    while lo <= n {
        let q: i64 = n / lo
        let hi: i64 = n / q
        res = res - ((hi - lo + 1) as i128) * tot_sum(q)
        lo = hi + 1
    }
    G_used[s] = 1
    G_keys[s] = n
    G_vals[s] = res
    return res
}

function i128_mod(x0: i128, m: i64) -> i64 {
    let mm: i128 = m as i128
    let mut r: i128 = x0 % mm
    if r < 0 { r = r + mm }
    return r as i64
}

function polar_polygons_mod(n: i64) -> i64 {
    let mut B: i64 = 1
    let mut S1: i64 = 0
    let mut S2: i64 = 0
    let mut lo: i64 = 1
    let mut prev_phi: i128 = 0
    let modm1: i64 = MOD - 1
    let mut B_zero: i64 = 0
    while lo <= n {
        let q: i64 = n / lo
        let hi: i64 = n / q
        let curr: i128 = tot_sum(hi)
        let sum_phi: i128 = curr - prev_phi
        prev_phi = curr
        let sum_phi_mod: i64 = i128_mod(sum_phi, MOD)
        let c_mod: i64 = (sum_phi_mod * 4) % MOD
        let q_mod: i64 = q % MOD
        S1 = (S1 + c_mod * q_mod) % MOD
        let q2: i64 = (q_mod * q_mod) % MOD
        S2 = (S2 + c_mod * q2) % MOD
        if B_zero == 0 {
            let base: i64 = (q + 1) % MOD
            if base == 0 {
                B = 0
                B_zero = 1
            } else {
                let expv: i64 = (i128_mod(sum_phi, modm1) * 4) % modm1
                B = (B * modpow(base, expv, MOD)) % MOD
            }
        }
        lo = hi + 1
    }
    let mut ans: i64 = (B * B) % MOD
    ans = (ans - (2 * B % MOD) * S1 % MOD) % MOD
    ans = (ans + S2) % MOD
    ans = (ans - 1) % MOD
    if ans < 0 { ans = ans + MOD }
    return ans
}

function main() -> i32 {
    G_pref = calloc(PRE + 1, 8)
    let phi: ptr<i32> = calloc(PRE + 1, 4)
    let primes: ptr<i32> = calloc(PRE / 5 + 16, 4)
    G_keys = calloc(CAP, 8)
    G_vals = calloc(CAP, 16)
    G_used = calloc(CAP, 1)
    if G_pref == null || phi == null || primes == null || G_keys == null || G_vals == null || G_used == null {
        return 1
    }

    phi[1] = 1
    let mut pc: i64 = 0
    let mut i: i64 = 2
    while i <= PRE {
        if phi[i] == 0 {
            phi[i] = (i - 1) as i32
            primes[pc] = i as i32
            pc = pc + 1
        }
        let mut j: i64 = 0
        while j < pc {
            let p: i64 = primes[j] as i64
            let ip: i64 = i * p
            if ip > PRE { break }
            if i % p == 0 {
                phi[ip] = ((phi[i] as i64) * p) as i32
                break
            } else {
                phi[ip] = ((phi[i] as i64) * (p - 1)) as i32
            }
            j = j + 1
        }
        i = i + 1
    }
    let mut s: i64 = 0
    i = 1
    while i <= PRE {
        s = s + (phi[i] as i64)
        G_pref[i] = s
        i = i + 1
    }
    free(primes)
    free(phi)

    let mut n: i64 = 1
    let mut t: i64 = 0
    while t < 13 {
        n = n * 7
        t = t + 1
    }
    printf("%lld\n", polar_polygons_mod(n))
    free(G_used)
    free(G_vals)
    free(G_keys)
    free(G_pref)
    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 modpow_i64_i64_i64(int64_t base0, int64_t exp0, int64_t mod);
int64_t hslot_i64(int64_t key);
__int128 tot_sum_i64(int64_t n);
int64_t i128_mod_i128_i64(__int128 x0, int64_t m);
int64_t polar_polygons_mod_i64(int64_t n);
int32_t main(void);

static const int64_t MOD = 1000000007;
static const int64_t PRE = 20000000;
static const int64_t CAP = 4194304;

/* Module statics */
static int64_t* G_pref = NULL;
static int64_t* G_keys = NULL;
static __int128* G_vals = NULL;
static int8_t* G_used = NULL;



int64_t modpow_i64_i64_i64(int64_t base0, int64_t exp0, int64_t mod) {
    int64_t r = 1;
    int64_t b = FLOW_CHECKED_MOD((base0), (mod));
    if (b < 0) {
        b = (b + mod);
    }
    int64_t e = exp0;
    while (e > 0) {
        if ((e & 1) == 1) {
            r = ((int64_t)(FLOW_CHECKED_MOD(((((__int128)(r)) * ((__int128)(b)))), (((__int128)(mod))))));
        }
        b = ((int64_t)(FLOW_CHECKED_MOD(((((__int128)(b)) * ((__int128)(b)))), (((__int128)(mod))))));
        e = FLOW_CHECKED_DIV((e), (2));
    }
    return r;
}

int64_t hslot_i64(int64_t key) {
    int64_t h = FLOW_CHECKED_MOD((key), (CAP));
    if (h < 0) {
        h = (h + CAP);
    }
    while ((G_used[h] == 1 && G_keys[h] != key)) {
        h = (h + 1);
        if (h == CAP) {
            h = 0;
        }
    }
    return h;
}

__int128 tot_sum_i64(int64_t n) {
    if (n <= 0) {
        return ((__int128)(0));
    }
    if (n <= PRE) {
        return ((__int128)(G_pref[n]));
    }
    int64_t s = hslot_i64(n);
    if (G_used[s] == 1) {
        return G_vals[s];
    }
    __int128 nn = ((__int128)(n));
    __int128 res = FLOW_CHECKED_DIV(((nn * (nn + 1))), (2));
    int64_t lo = 2;
    while (lo <= n) {
        int64_t q = FLOW_CHECKED_DIV((n), (lo));
        int64_t hi = FLOW_CHECKED_DIV((n), (q));
        res = (res - (((__int128)(((hi - lo) + 1))) * tot_sum_i64(q)));
        lo = (hi + 1);
    }
    G_used[s] = 1;
    G_keys[s] = n;
    G_vals[s] = res;
    return res;
}

int64_t i128_mod_i128_i64(__int128 x0, int64_t m) {
    __int128 mm = ((__int128)(m));
    __int128 r = FLOW_CHECKED_MOD((x0), (mm));
    if (r < 0) {
        r = (r + mm);
    }
    return ((int64_t)(r));
}

int64_t polar_polygons_mod_i64(int64_t n) {
    int64_t B = 1;
    int64_t S1 = 0;
    int64_t S2 = 0;
    int64_t lo = 1;
    __int128 prev_phi = 0;
    int64_t modm1 = (MOD - 1);
    int64_t B_zero = 0;
    while (lo <= n) {
        int64_t q = FLOW_CHECKED_DIV((n), (lo));
        int64_t hi = FLOW_CHECKED_DIV((n), (q));
        __int128 curr = tot_sum_i64(hi);
        __int128 sum_phi = (curr - prev_phi);
        prev_phi = curr;
        int64_t sum_phi_mod = i128_mod_i128_i64(sum_phi, MOD);
        int64_t c_mod = FLOW_CHECKED_MOD(((sum_phi_mod * 4)), (MOD));
        int64_t q_mod = FLOW_CHECKED_MOD((q), (MOD));
        S1 = FLOW_CHECKED_MOD(((S1 + (c_mod * q_mod))), (MOD));
        int64_t q2 = FLOW_CHECKED_MOD(((q_mod * q_mod)), (MOD));
        S2 = FLOW_CHECKED_MOD(((S2 + (c_mod * q2))), (MOD));
        if (B_zero == 0) {
            int64_t base = FLOW_CHECKED_MOD(((q + 1)), (MOD));
            if (base == 0) {
                B = 0;
                B_zero = 1;
            } else {
                int64_t expv = FLOW_CHECKED_MOD(((i128_mod_i128_i64(sum_phi, modm1) * 4)), (modm1));
                B = FLOW_CHECKED_MOD(((B * modpow_i64_i64_i64(base, expv, MOD))), (MOD));
            }
        }
        lo = (hi + 1);
    }
    int64_t ans = FLOW_CHECKED_MOD(((B * B)), (MOD));
    ans = FLOW_CHECKED_MOD(((ans - FLOW_CHECKED_MOD(((FLOW_CHECKED_MOD(((2 * B)), (MOD)) * S1)), (MOD)))), (MOD));
    ans = FLOW_CHECKED_MOD(((ans + S2)), (MOD));
    ans = FLOW_CHECKED_MOD(((ans - 1)), (MOD));
    if (ans < 0) {
        ans = (ans + MOD);
    }
    return ans;
}

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