Problem 690

Tom and Jerry: T(2019) mod 1e9+7. Tom graphs = forests of lobster trees. Uses generating functions and Euler transform.

Answer415157690
Output415157690
StatusPASS
Native helperno
Runtime160 ms
Peak memory1440 KB
Time complexityO(n^2) (estimated)
Space complexityO(n^2) (estimated)

Performance comparison

MetricOur solutionBest known
Time complexityO(n^2)O(e log v)
Space complexityO(n^2)O(v)
ApproachFlow solutionKruskal or Prim algorithm
VerdictUnknown

Flow source

# Project Euler 690
# Tom and Jerry: T(2019) mod 1e9+7.
# Tom graphs = forests of lobster trees. Uses generating functions and Euler transform.

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

const MOD: i64 = 1000000007

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

function mod_inv(a: i64, mod: i64) -> i64 {
    return mod_pow(a, mod - 2, mod)
}

# Multiply two series a,b mod MOD, truncated to degree n.
function poly_mul(a: ptr<i64>, b: ptr<i64>, res: ptr<i64>, n: i64) -> void {
    for i in 0..(n + 1) { res[i] = 0 }
    for i in 0..(n + 1) {
        let ai: i64 = a[i]
        if ai == 0 { continue }
        let maxj: i64 = n - i
        for j in 0..(maxj + 1) {
            let v: i128 = (res[i + j] as i128) + (ai as i128) * (b[j] as i128)
            res[i + j] = (v % (MOD as i128)) as i64
        }
    }
}

# Series inverse g = 1/f mod x^(n+1), assuming f[0] != 0.
function inv_series(f: ptr<i64>, g: ptr<i64>, n: i64) -> void {
    let g0: i64 = mod_inv(f[0], MOD)
    g[0] = g0
    for i in 1..(n + 1) {
        let mut s: i128 = 0
        for k in 1..(i + 1) {
            s = s + (f[k] as i128) * (g[i - k] as i128)
            s = s % (MOD as i128)
        }
        g[i] = ((MOD - (s as i64)) * g0 % MOD) % MOD
    }
}

function main() -> i32 {
    let N: i64 = 2019

    # Allocate working arrays
    let P: ptr<i64> = calloc(N + 1, 8)
    let Q: ptr<i64> = calloc(N + 1, 8)
    let num: ptr<i64> = calloc(N + 1, 8)
    let den: ptr<i64> = calloc(N + 1, 8)
    let inv_den: ptr<i64> = calloc(N + 1, 8)
    let term: ptr<i64> = calloc(N + 1, 8)
    let term2: ptr<i64> = calloc(N + 1, 8)
    let P2: ptr<i64> = calloc(N + 1, 8)
    let Q2: ptr<i64> = calloc(N + 1, 8)
    let one_plus: ptr<i64> = calloc(N + 1, 8)
    let s_arr: ptr<i64> = calloc(N + 1, 8)
    let main_arr: ptr<i64> = calloc(N + 1, 8)
    let xP: ptr<i64> = calloc(N + 1, 8)
    let A1: ptr<i64> = calloc(N + 1, 8)
    let A2: ptr<i64> = calloc(N + 1, 8)
    let temp: ptr<i64> = calloc(N + 1, 8)
    let last: ptr<i64> = calloc(N + 1, 8)
    let A: ptr<i64> = calloc(N + 1, 8)
    let c: ptr<i64> = calloc(N + 1, 8)
    let inv: ptr<i64> = calloc(N + 1, 8)
    let a: ptr<i64> = calloc(N + 1, 8)
    let tmp: ptr<i64> = calloc(N + 1, 8)

    if P == null || A == null || a == null { return 1 }

    let inv2: i64 = (MOD + 1) / 2

    # partitions_upto: p[0..N] mod MOD
    P[0] = 1
    for k in 1..(N + 1) {
        for i in k..(N + 1) {
            P[i] = P[i] + P[i - k]
            if P[i] >= MOD { P[i] = P[i] - MOD }
        }
    }

    # Q = P - 1/(1-x) = P - 1 (since 1/(1-x) = 1 + x + x^2 + ...)
    for i in 0..(N + 1) {
        Q[i] = (P[i] - 1 + MOD) % MOD
    }

    # term1 = Q^2 / (1 - x*P)
    poly_mul(Q, Q, num, N)
    den[0] = 1
    for i in 1..(N + 1) {
        den[i] = (MOD - P[i - 1]) % MOD
    }
    inv_series(den, inv_den, N)
    poly_mul(num, inv_den, term, N)

    # P2 = P(x^2), Q2 = P(x^2) - 1
    for i in 0..(N + 1) { P2[i] = 0 }
    for i in 0..(N / 2 + 1) {
        P2[2 * i] = P[i]
        Q2[2 * i] = (P[i] - 1 + MOD) % MOD
    }
    for i in 0..(N + 1) {
        if i % 2 == 1 { Q2[i] = 0 }
    }

    # one_plus = 1 + x*P
    one_plus[0] = 1
    for i in 1..(N + 1) {
        one_plus[i] = P[i - 1]
    }

    # term2 = Q2*(1 + x*P) / (1 - x^2*P(x^2))
    poly_mul(Q2, one_plus, num, N)
    for i in 0..(N + 1) { den[i] = 0 }
    den[0] = 1
    for i in 2..(N + 1) {
        den[i] = (MOD - P2[i - 2]) % MOD
    }
    inv_series(den, inv_den, N)
    poly_mul(num, inv_den, term2, N)

    # s = (term1 + term2) / 2
    for i in 0..(N + 1) {
        s_arr[i] = (term[i] + term2[i]) % MOD * inv2 % MOD
    }

    # main = x^2 * s
    for i in 0..(N + 1) { main_arr[i] = 0 }
    for i in 0..(N - 1) {
        main_arr[i + 2] = s_arr[i]
    }

    # xP = x * P
    for i in 0..(N + 1) { xP[i] = 0 }
    for i in 1..(N + 1) {
        xP[i] = P[i - 1]
    }

    # last = x^3 / ((1-x)^2 * (1+x))
    # (1-x)^-2 = sum (m+1) x^m
    for i in 0..(N + 1) {
        A1[i] = (i + 1) % MOD
    }
    # (1+x)^-1 = sum (-1)^m x^m
    for i in 0..(N + 1) {
        if i % 2 == 0 { A2[i] = 1 }
        else { A2[i] = MOD - 1 }
    }
    poly_mul(A1, A2, temp, N)
    for i in 0..(N + 1) { last[i] = 0 }
    for i in 0..(N - 2) {
        last[i + 3] = temp[i]
    }

    # A = main + xP - last  (lobster counts)
    for i in 0..(N + 1) {
        A[i] = (main_arr[i] + xP[i] - last[i] % MOD + MOD) % MOD
    }

    # Euler transform: a(x) = prod_{k>=1} (1 - x^k)^(-b[k])
    # c[k] = sum_{d|k} d * b[d]
    for i in 0..(N + 1) { c[i] = 0 }
    for d in 1..(N + 1) {
        let bd: i64 = A[d]
        if bd == 0 { continue }
        let addv: i64 = (d % MOD) * bd % MOD
        let mut k: i64 = d
        while k <= N {
            c[k] = c[k] + addv
            if c[k] >= MOD { c[k] = c[k] - MOD }
            k = k + d
        }
    }

    # inv[i] = i^(-1) mod MOD
    inv[0] = 0
    for i in 1..(N + 1) {
        inv[i] = mod_inv(i, MOD)
    }

    # a[0] = 1, a[m] = (sum_{k=1..m} c[k]*a[m-k]) * inv[m] mod MOD
    a[0] = 1
    for m in 1..(N + 1) {
        let mut s: i128 = 0
        for k in 1..(m + 1) {
            s = s + (c[k] as i128) * (a[m - k] as i128)
            s = s % (MOD as i128)
        }
        a[m] = ((s % (MOD as i128)) as i64) * inv[m] % MOD
    }

    printf("%lld\n", a[N])

    free(tmp); free(a); free(inv); free(c); free(A); free(last); free(temp)
    free(A2); free(A1); free(xP); free(main_arr); free(s_arr); free(one_plus)
    free(Q2); free(P2); free(term2); free(term); free(inv_den); free(den)
    free(num); free(Q); free(P)
    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 mod_pow_i64_i64_i64(int64_t base0, int64_t exp0, int64_t mod);
int64_t mod_inv_i64_i64(int64_t a, int64_t mod);
void poly_mul_ptr_i64_ptr_i64_ptr_i64_i64(int64_t* a, int64_t* b, int64_t* res, int64_t n);
void inv_series_ptr_i64_ptr_i64_i64(int64_t* f, int64_t* g, int64_t n);
int32_t main(void);

static const int64_t MOD = 1000000007;



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

int64_t mod_inv_i64_i64(int64_t a, int64_t mod) {
    return mod_pow_i64_i64_i64(a, (mod - 2), mod);
}

void poly_mul_ptr_i64_ptr_i64_ptr_i64_i64(int64_t* a, int64_t* b, int64_t* res, int64_t n) {
    int32_t __flow_step_1 = 1;
    for (int32_t i = 0; (0 <= (n + 1)) ? i < (n + 1) : i > (n + 1); i += (0 <= (n + 1)) ? 1 : -1) {
        res[i] = 0;
    }
    int32_t __flow_step_2 = 1;
    for (int32_t i = 0; (0 <= (n + 1)) ? i < (n + 1) : i > (n + 1); i += (0 <= (n + 1)) ? 1 : -1) {
        int64_t ai = a[i];
        if (ai == 0) {
            continue;
        }
        int64_t maxj = (n - i);
        int32_t __flow_step_3 = 1;
        for (int32_t j = 0; (0 <= (maxj + 1)) ? j < (maxj + 1) : j > (maxj + 1); j += (0 <= (maxj + 1)) ? 1 : -1) {
            __int128 v = (((__int128)(res[(i + j)])) + (((__int128)(ai)) * ((__int128)(b[j]))));
            res[(i + j)] = ((int64_t)(FLOW_CHECKED_MOD((v), (((__int128)(MOD))))));
        }
    }
}

void inv_series_ptr_i64_ptr_i64_i64(int64_t* f, int64_t* g, int64_t n) {
    int64_t g0 = mod_inv_i64_i64(f[0], MOD);
    g[0] = g0;
    int32_t __flow_step_4 = 1;
    for (int32_t i = 1; (1 <= (n + 1)) ? i < (n + 1) : i > (n + 1); i += (1 <= (n + 1)) ? 1 : -1) {
        __int128 s = 0;
        int32_t __flow_step_5 = 1;
        for (int32_t k = 1; (1 <= (i + 1)) ? k < (i + 1) : k > (i + 1); k += (1 <= (i + 1)) ? 1 : -1) {
            s = (s + (((__int128)(f[k])) * ((__int128)(g[(i - k)]))));
            s = FLOW_CHECKED_MOD((s), (((__int128)(MOD))));
        }
        g[i] = FLOW_CHECKED_MOD((FLOW_CHECKED_MOD((((MOD - ((int64_t)(s))) * g0)), (MOD))), (MOD));
    }
}

int32_t main(void) {
    int64_t N = 2019;
    int64_t* P = (int64_t*)(calloc((N + 1), 8));
    int64_t* Q = (int64_t*)(calloc((N + 1), 8));
    int64_t* num = (int64_t*)(calloc((N + 1), 8));
    int64_t* den = (int64_t*)(calloc((N + 1), 8));
    int64_t* inv_den = (int64_t*)(calloc((N + 1), 8));
    int64_t* term = (int64_t*)(calloc((N + 1), 8));
    int64_t* term2 = (int64_t*)(calloc((N + 1), 8));
    int64_t* P2 = (int64_t*)(calloc((N + 1), 8));
    int64_t* Q2 = (int64_t*)(calloc((N + 1), 8));
    int64_t* one_plus = (int64_t*)(calloc((N + 1), 8));
    int64_t* s_arr = (int64_t*)(calloc((N + 1), 8));
    int64_t* main_arr = (int64_t*)(calloc((N + 1), 8));
    int64_t* xP = (int64_t*)(calloc((N + 1), 8));
    int64_t* A1 = (int64_t*)(calloc((N + 1), 8));
    int64_t* A2 = (int64_t*)(calloc((N + 1), 8));
    int64_t* temp = (int64_t*)(calloc((N + 1), 8));
    int64_t* last = (int64_t*)(calloc((N + 1), 8));
    int64_t* A = (int64_t*)(calloc((N + 1), 8));
    int64_t* c = (int64_t*)(calloc((N + 1), 8));
    int64_t* inv = (int64_t*)(calloc((N + 1), 8));
    int64_t* a = (int64_t*)(calloc((N + 1), 8));
    int64_t* tmp = (int64_t*)(calloc((N + 1), 8));
    if (((P == NULL || A == NULL) || a == NULL)) {
        return 1;
    }
    int64_t inv2 = FLOW_CHECKED_DIV(((MOD + 1)), (2));
    P[0] = 1;
    int32_t __flow_step_6 = 1;
    for (int32_t k = 1; (1 <= (N + 1)) ? k < (N + 1) : k > (N + 1); k += (1 <= (N + 1)) ? 1 : -1) {
        int32_t __flow_step_7 = 1;
        for (int32_t i = k; (k <= (N + 1)) ? i < (N + 1) : i > (N + 1); i += (k <= (N + 1)) ? 1 : -1) {
            P[i] = (P[i] + P[(i - k)]);
            if (P[i] >= MOD) {
                P[i] = (P[i] - MOD);
            }
        }
    }
    int32_t __flow_step_8 = 1;
    for (int32_t i = 0; (0 <= (N + 1)) ? i < (N + 1) : i > (N + 1); i += (0 <= (N + 1)) ? 1 : -1) {
        Q[i] = FLOW_CHECKED_MOD((((P[i] - 1) + MOD)), (MOD));
    }
    poly_mul_ptr_i64_ptr_i64_ptr_i64_i64(Q, Q, num, N);
    den[0] = 1;
    int32_t __flow_step_9 = 1;
    for (int32_t i = 1; (1 <= (N + 1)) ? i < (N + 1) : i > (N + 1); i += (1 <= (N + 1)) ? 1 : -1) {
        den[i] = FLOW_CHECKED_MOD(((MOD - P[(i - 1)])), (MOD));
    }
    inv_series_ptr_i64_ptr_i64_i64(den, inv_den, N);
    poly_mul_ptr_i64_ptr_i64_ptr_i64_i64(num, inv_den, term, N);
    int32_t __flow_step_10 = 1;
    for (int32_t i = 0; (0 <= (N + 1)) ? i < (N + 1) : i > (N + 1); i += (0 <= (N + 1)) ? 1 : -1) {
        P2[i] = 0;
    }
    int32_t __flow_step_11 = 1;
    for (int32_t i = 0; (0 <= (FLOW_CHECKED_DIV((N), (2)) + 1)) ? i < (FLOW_CHECKED_DIV((N), (2)) + 1) : i > (FLOW_CHECKED_DIV((N), (2)) + 1); i += (0 <= (FLOW_CHECKED_DIV((N), (2)) + 1)) ? 1 : -1) {
        P2[(2 * i)] = P[i];
        Q2[(2 * i)] = FLOW_CHECKED_MOD((((P[i] - 1) + MOD)), (MOD));
    }
    int32_t __flow_step_12 = 1;
    for (int32_t i = 0; (0 <= (N + 1)) ? i < (N + 1) : i > (N + 1); i += (0 <= (N + 1)) ? 1 : -1) {
        if (FLOW_CHECKED_MOD((i), (2)) == 1) {
            Q2[i] = 0;
        }
    }
    one_plus[0] = 1;
    int32_t __flow_step_13 = 1;
    for (int32_t i = 1; (1 <= (N + 1)) ? i < (N + 1) : i > (N + 1); i += (1 <= (N + 1)) ? 1 : -1) {
        one_plus[i] = P[(i - 1)];
    }
    poly_mul_ptr_i64_ptr_i64_ptr_i64_i64(Q2, one_plus, num, N);
    int32_t __flow_step_14 = 1;
    for (int32_t i = 0; (0 <= (N + 1)) ? i < (N + 1) : i > (N + 1); i += (0 <= (N + 1)) ? 1 : -1) {
        den[i] = 0;
    }
    den[0] = 1;
    int32_t __flow_step_15 = 1;
    for (int32_t i = 2; (2 <= (N + 1)) ? i < (N + 1) : i > (N + 1); i += (2 <= (N + 1)) ? 1 : -1) {
        den[i] = FLOW_CHECKED_MOD(((MOD - P2[(i - 2)])), (MOD));
    }
    inv_series_ptr_i64_ptr_i64_i64(den, inv_den, N);
    poly_mul_ptr_i64_ptr_i64_ptr_i64_i64(num, inv_den, term2, N);
    int32_t __flow_step_16 = 1;
    for (int32_t i = 0; (0 <= (N + 1)) ? i < (N + 1) : i > (N + 1); i += (0 <= (N + 1)) ? 1 : -1) {
        s_arr[i] = FLOW_CHECKED_MOD(((FLOW_CHECKED_MOD(((term[i] + term2[i])), (MOD)) * inv2)), (MOD));
    }
    int32_t __flow_step_17 = 1;
    for (int32_t i = 0; (0 <= (N + 1)) ? i < (N + 1) : i > (N + 1); i += (0 <= (N + 1)) ? 1 : -1) {
        main_arr[i] = 0;
    }
    int32_t __flow_step_18 = 1;
    for (int32_t i = 0; (0 <= (N - 1)) ? i < (N - 1) : i > (N - 1); i += (0 <= (N - 1)) ? 1 : -1) {
        main_arr[(i + 2)] = s_arr[i];
    }
    int32_t __flow_step_19 = 1;
    for (int32_t i = 0; (0 <= (N + 1)) ? i < (N + 1) : i > (N + 1); i += (0 <= (N + 1)) ? 1 : -1) {
        xP[i] = 0;
    }
    int32_t __flow_step_20 = 1;
    for (int32_t i = 1; (1 <= (N + 1)) ? i < (N + 1) : i > (N + 1); i += (1 <= (N + 1)) ? 1 : -1) {
        xP[i] = P[(i - 1)];
    }
    int32_t __flow_step_21 = 1;
    for (int32_t i = 0; (0 <= (N + 1)) ? i < (N + 1) : i > (N + 1); i += (0 <= (N + 1)) ? 1 : -1) {
        A1[i] = FLOW_CHECKED_MOD(((i + 1)), (MOD));
    }
    int32_t __flow_step_22 = 1;
    for (int32_t i = 0; (0 <= (N + 1)) ? i < (N + 1) : i > (N + 1); i += (0 <= (N + 1)) ? 1 : -1) {
        if (FLOW_CHECKED_MOD((i), (2)) == 0) {
            A2[i] = 1;
        } else {
            A2[i] = (MOD - 1);
        }
    }
    poly_mul_ptr_i64_ptr_i64_ptr_i64_i64(A1, A2, temp, N);
    int32_t __flow_step_23 = 1;
    for (int32_t i = 0; (0 <= (N + 1)) ? i < (N + 1) : i > (N + 1); i += (0 <= (N + 1)) ? 1 : -1) {
        last[i] = 0;
    }
    int32_t __flow_step_24 = 1;
    for (int32_t i = 0; (0 <= (N - 2)) ? i < (N - 2) : i > (N - 2); i += (0 <= (N - 2)) ? 1 : -1) {
        last[(i + 3)] = temp[i];
    }
    int32_t __flow_step_25 = 1;
    for (int32_t i = 0; (0 <= (N + 1)) ? i < (N + 1) : i > (N + 1); i += (0 <= (N + 1)) ? 1 : -1) {
        A[i] = FLOW_CHECKED_MOD(((((main_arr[i] + xP[i]) - FLOW_CHECKED_MOD((last[i]), (MOD))) + MOD)), (MOD));
    }
    int32_t __flow_step_26 = 1;
    for (int32_t i = 0; (0 <= (N + 1)) ? i < (N + 1) : i > (N + 1); i += (0 <= (N + 1)) ? 1 : -1) {
        c[i] = 0;
    }
    int32_t __flow_step_27 = 1;
    for (int32_t d = 1; (1 <= (N + 1)) ? d < (N + 1) : d > (N + 1); d += (1 <= (N + 1)) ? 1 : -1) {
        int64_t bd = A[d];
        if (bd == 0) {
            continue;
        }
        int64_t addv = FLOW_CHECKED_MOD(((FLOW_CHECKED_MOD((d), (MOD)) * bd)), (MOD));
        int64_t k = d;
        while (k <= N) {
            c[k] = (c[k] + addv);
            if (c[k] >= MOD) {
                c[k] = (c[k] - MOD);
            }
            k = (k + d);
        }
    }
    inv[0] = 0;
    int32_t __flow_step_28 = 1;
    for (int32_t i = 1; (1 <= (N + 1)) ? i < (N + 1) : i > (N + 1); i += (1 <= (N + 1)) ? 1 : -1) {
        inv[i] = mod_inv_i64_i64(i, MOD);
    }
    a[0] = 1;
    int32_t __flow_step_29 = 1;
    for (int32_t m = 1; (1 <= (N + 1)) ? m < (N + 1) : m > (N + 1); m += (1 <= (N + 1)) ? 1 : -1) {
        __int128 s = 0;
        int32_t __flow_step_30 = 1;
        for (int32_t k = 1; (1 <= (m + 1)) ? k < (m + 1) : k > (m + 1); k += (1 <= (m + 1)) ? 1 : -1) {
            s = (s + (((__int128)(c[k])) * ((__int128)(a[(m - k)]))));
            s = FLOW_CHECKED_MOD((s), (((__int128)(MOD))));
        }
        a[m] = FLOW_CHECKED_MOD(((((int64_t)(FLOW_CHECKED_MOD((s), (((__int128)(MOD)))))) * inv[m])), (MOD));
    }
    printf("%lld\n", a[N]);
    free(tmp);
    free(a);
    free(inv);
    free(c);
    free(A);
    free(last);
    free(temp);
    free(A2);
    free(A1);
    free(xP);
    free(main_arr);
    free(s_arr);
    free(one_plus);
    free(Q2);
    free(P2);
    free(term2);
    free(term);
    free(inv_den);
    free(den);
    free(num);
    free(Q);
    free(P);
    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
  func.func @mod_pow(%arg0: i64, %arg1: i64, %arg2: i64) -> i64 {
    %0 = arith.constant 1 : i32
    %1 = arith.extsi %0 : i32 to i64
    %2 = llvm.mlir.constant(1 : i64) : i64
    %3 = llvm.alloca %2 x i64 : (i64) -> !llvm.ptr
    llvm.store %1, %3 : i64, !llvm.ptr
    %4 = arith.remsi %arg0, %arg2 : i64
    %5 = llvm.mlir.constant(1 : i64) : i64
    %6 = llvm.alloca %5 x i64 : (i64) -> !llvm.ptr
    llvm.store %4, %6 : i64, !llvm.ptr
    %7 = llvm.mlir.constant(1 : i64) : i64
    %8 = llvm.alloca %7 x i64 : (i64) -> !llvm.ptr
    llvm.store %arg1, %8 : i64, !llvm.ptr
    cf.br ^bb0
    ^bb0:
    %9 = llvm.load %8 : !llvm.ptr -> i64
    %10 = arith.constant 0 : i32
    %12 = arith.extsi %10 : i32 to i64
    %11 = arith.cmpi sgt, %9, %12 : i64
    cf.cond_br %11, ^bb1, ^bb2
    ^bb1:
      %13 = llvm.load %8 : !llvm.ptr -> i64
      %14 = arith.constant 1 : i32
      %16 = arith.extsi %14 : i32 to i64
      %15 = arith.andi %13, %16 : i64
      %17 = arith.constant 1 : i32
      %19 = arith.extsi %17 : i32 to i64
      %18 = arith.cmpi eq, %15, %19 : i64
      cf.cond_br %18, ^bb3, ^bb4
      ^bb3:
        %20 = llvm.load %3 : !llvm.ptr -> i64
        %21 = arith.extsi %20 : i64 to i128
        %22 = llvm.load %6 : !llvm.ptr -> i64
        %23 = arith.extsi %22 : i64 to i128
        %25 = arith.trunci %21 : i128 to i64
        %26 = arith.trunci %23 : i128 to i64
        %24 = arith.muli %25, %26 : i64
        %27 = arith.extsi %arg2 : i64 to i128
        %29 = arith.trunci %27 : i128 to i64
        %28 = arith.remsi %24, %29 : i64
        %30 = arith.extsi %28 : i64 to i128
        %31 = arith.trunci %30 : i128 to i64
        llvm.store %31, %3 : i64, !llvm.ptr
        cf.br ^bb5
      ^bb4:
        cf.br ^bb5
      ^bb5:
      %32 = llvm.load %6 : !llvm.ptr -> i64
      %33 = arith.extsi %32 : i64 to i128
      %34 = llvm.load %6 : !llvm.ptr -> i64
      %35 = arith.extsi %34 : i64 to i128
      %37 = arith.trunci %33 : i128 to i64
      %38 = arith.trunci %35 : i128 to i64
      %36 = arith.muli %37, %38 : i64
      %39 = arith.extsi %arg2 : i64 to i128
      %41 = arith.trunci %39 : i128 to i64
      %40 = arith.remsi %36, %41 : i64
      %42 = arith.extsi %40 : i64 to i128
      %43 = arith.trunci %42 : i128 to i64
      llvm.store %43, %6 : i64, !llvm.ptr
      %44 = llvm.load %8 : !llvm.ptr -> i64
      %45 = arith.constant 2 : i32
      %47 = arith.extsi %45 : i32 to i64
      %46 = arith.divsi %44, %47 : i64
      llvm.store %46, %8 : i64, !llvm.ptr
      cf.br ^bb0
    ^bb2:
    %48 = llvm.load %3 : !llvm.ptr -> i64
    func.return %48 : i64
  }
  func.func @mod_inv(%arg0: i64, %arg1: i64) -> i64 {
    %50 = arith.constant 2 : i32
    %52 = arith.extsi %50 : i32 to i64
    %51 = arith.subi %arg1, %52 : i64
    %49 = func.call @mod_pow(%arg0, %51, %arg1) : (i64, i64, i64) -> i64
    func.return %49 : i64
  }
  func.func @poly_mul(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr, %arg3: i64) -> () {
    %53 = arith.constant 0 : i32
    %54 = arith.constant 1 : i32
    %56 = arith.extsi %54 : i32 to i64
    %55 = arith.addi %arg3, %56 : i64
    %57 = arith.index_cast %53 : i32 to index
    %58 = arith.index_cast %55 : i32 to index
    %60 = arith.constant 1 : index
    %61 = arith.constant -1 : index
    %62 = arith.cmpi sle, %57, %58 : index
    %59 = arith.select %62, %60, %61 : index
    cf.br ^bb6(%57 : index)
    ^bb6(%63: index):
    %64 = arith.cmpi slt, %63, %58 : index
    %65 = arith.cmpi sgt, %63, %58 : index
    %66 = arith.select %62, %64, %65 : i1
    cf.cond_br %66, ^bb7(%63 : index), ^bb8(%63 : index)
    ^bb7(%67: index):
      %68 = arith.constant 0 : i32
      %69 = arith.extsi %68 : i32 to i64
      %70 = arith.index_cast %67 : index to i64
      %71 = llvm.getelementptr %arg2[%70] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %69, %71 : i64, !llvm.ptr
      %72 = arith.addi %67, %59 : index
      cf.br ^bb6(%72 : index)
    ^bb8(%73: index):
    %74 = arith.constant 0 : i32
    %75 = arith.constant 1 : i32
    %77 = arith.extsi %75 : i32 to i64
    %76 = arith.addi %arg3, %77 : i64
    %78 = arith.index_cast %74 : i32 to index
    %79 = arith.index_cast %76 : i32 to index
    %81 = arith.constant 1 : index
    %82 = arith.constant -1 : index
    %83 = arith.cmpi sle, %78, %79 : index
    %80 = arith.select %83, %81, %82 : index
    cf.br ^bb9(%78 : index)
    ^bb9(%84: index):
    %85 = arith.cmpi slt, %84, %79 : index
    %86 = arith.cmpi sgt, %84, %79 : index
    %87 = arith.select %83, %85, %86 : i1
    cf.cond_br %87, ^bb10(%84 : index), ^bb11(%84 : index)
    ^bb10(%88: index):
      %90 = arith.index_cast %88 : index to i64
      %91 = llvm.getelementptr %arg0[%90] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %89 = llvm.load %91 : !llvm.ptr -> i64
      %92 = arith.constant 0 : i32
      %94 = arith.extsi %92 : i32 to i64
      %93 = arith.cmpi eq, %89, %94 : i64
      cf.cond_br %93, ^bb12, ^bb13
      ^bb12:
        %95 = arith.addi %88, %80 : index
        cf.br ^bb9(%95 : index)
      ^bb13:
        cf.br ^bb14
      ^bb14:
      %97 = arith.trunci %arg3 : i64 to i32
      %98 = arith.index_cast %88 : index to i32
      %96 = arith.subi %97, %98 : i32
      %99 = arith.extsi %96 : i32 to i64
      %100 = arith.constant 0 : i32
      %101 = arith.constant 1 : i32
      %103 = arith.extsi %101 : i32 to i64
      %102 = arith.addi %99, %103 : i64
      %104 = arith.index_cast %100 : i32 to index
      %105 = arith.index_cast %102 : i32 to index
      %107 = arith.constant 1 : index
      %108 = arith.constant -1 : index
      %109 = arith.cmpi sle, %104, %105 : index
      %106 = arith.select %109, %107, %108 : index
      cf.br ^bb15(%104 : index)
      ^bb15(%110: index):
      %111 = arith.cmpi slt, %110, %105 : index
      %112 = arith.cmpi sgt, %110, %105 : index
      %113 = arith.select %109, %111, %112 : i1
      cf.cond_br %113, ^bb16(%110 : index), ^bb17(%110 : index)
      ^bb16(%114: index):
        %116 = arith.addi %88, %114 : index
        %117 = arith.index_cast %116 : index to i64
        %118 = llvm.getelementptr %arg2[%117] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %115 = llvm.load %118 : !llvm.ptr -> i64
        %119 = arith.extsi %115 : i64 to i128
        %120 = arith.extsi %89 : i64 to i128
        %122 = arith.index_cast %114 : index to i64
        %123 = llvm.getelementptr %arg1[%122] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %121 = llvm.load %123 : !llvm.ptr -> i64
        %124 = arith.extsi %121 : i64 to i128
        %126 = arith.trunci %120 : i128 to i64
        %127 = arith.trunci %124 : i128 to i64
        %125 = arith.muli %126, %127 : i64
        %129 = arith.trunci %119 : i128 to i64
        %128 = arith.addi %129, %125 : i64
        %130 = arith.extsi %128 : i64 to i128
        %131 = llvm.mlir.addressof @MOD : !llvm.ptr
        %132 = llvm.load %131 : !llvm.ptr -> i64
        %133 = arith.extsi %132 : i64 to i128
        %135 = arith.trunci %130 : i128 to i64
        %136 = arith.trunci %133 : i128 to i64
        %134 = arith.remsi %135, %136 : i64
        %137 = arith.addi %88, %114 : index
        %138 = arith.index_cast %137 : index to i64
        %139 = llvm.getelementptr %arg2[%138] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %134, %139 : i64, !llvm.ptr
        %140 = arith.addi %114, %106 : index
        cf.br ^bb15(%140 : index)
      ^bb17(%141: index):
      %142 = arith.addi %88, %80 : index
      cf.br ^bb9(%142 : index)
    ^bb11(%143: index):
    func.return
  }
  func.func @inv_series(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: i64) -> () {
    %146 = arith.constant 0 : i32
    %147 = arith.extsi %146 : i32 to i64
    %148 = llvm.getelementptr %arg0[%147] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    %145 = llvm.load %148 : !llvm.ptr -> i64
    %149 = llvm.mlir.addressof @MOD : !llvm.ptr
    %150 = llvm.load %149 : !llvm.ptr -> i64
    %144 = func.call @mod_inv(%145, %150) : (i64, i64) -> i64
    %151 = arith.constant 0 : i32
    %152 = arith.extsi %151 : i32 to i64
    %153 = llvm.getelementptr %arg1[%152] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %144, %153 : i64, !llvm.ptr
    %154 = arith.constant 1 : i32
    %155 = arith.constant 1 : i32
    %157 = arith.extsi %155 : i32 to i64
    %156 = arith.addi %arg2, %157 : i64
    %158 = arith.index_cast %154 : i32 to index
    %159 = arith.index_cast %156 : i32 to index
    %161 = arith.constant 1 : index
    %162 = arith.constant -1 : index
    %163 = arith.cmpi sle, %158, %159 : index
    %160 = arith.select %163, %161, %162 : index
    cf.br ^bb18(%158 : index)
    ^bb18(%164: index):
    %165 = arith.cmpi slt, %164, %159 : index
    %166 = arith.cmpi sgt, %164, %159 : index
    %167 = arith.select %163, %165, %166 : i1
    cf.cond_br %167, ^bb19(%164 : index), ^bb20(%164 : index)
    ^bb19(%168: index):
      %169 = arith.constant 0 : i32
      %170 = arith.extsi %169 : i32 to i128
      %171 = llvm.mlir.constant(1 : i64) : i64
      %172 = llvm.alloca %171 x i128 : (i64) -> !llvm.ptr
      llvm.store %170, %172 : i128, !llvm.ptr
      %173 = arith.constant 1 : i32
      %174 = arith.constant 1 : i32
      %176 = arith.index_cast %168 : index to i32
      %175 = arith.addi %176, %174 : i32
      %177 = arith.index_cast %173 : i32 to index
      %178 = arith.index_cast %175 : i32 to index
      %180 = arith.constant 1 : index
      %181 = arith.constant -1 : index
      %182 = arith.cmpi sle, %177, %178 : index
      %179 = arith.select %182, %180, %181 : index
      cf.br ^bb21(%177 : index)
      ^bb21(%183: index):
      %184 = arith.cmpi slt, %183, %178 : index
      %185 = arith.cmpi sgt, %183, %178 : index
      %186 = arith.select %182, %184, %185 : i1
      cf.cond_br %186, ^bb22(%183 : index), ^bb23(%183 : index)
      ^bb22(%187: index):
        %188 = llvm.load %172 : !llvm.ptr -> i128
        %190 = arith.index_cast %187 : index to i64
        %191 = llvm.getelementptr %arg0[%190] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %189 = llvm.load %191 : !llvm.ptr -> i64
        %192 = arith.extsi %189 : i64 to i128
        %194 = arith.subi %168, %187 : index
        %195 = arith.index_cast %194 : index to i64
        %196 = llvm.getelementptr %arg1[%195] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %193 = llvm.load %196 : !llvm.ptr -> i64
        %197 = arith.extsi %193 : i64 to i128
        %199 = arith.trunci %192 : i128 to i64
        %200 = arith.trunci %197 : i128 to i64
        %198 = arith.muli %199, %200 : i64
        %202 = arith.trunci %188 : i128 to i64
        %201 = arith.addi %202, %198 : i64
        %203 = arith.extsi %201 : i64 to i128
        llvm.store %203, %172 : i128, !llvm.ptr
        %204 = llvm.load %172 : !llvm.ptr -> i128
        %205 = llvm.mlir.addressof @MOD : !llvm.ptr
        %206 = llvm.load %205 : !llvm.ptr -> i64
        %207 = arith.extsi %206 : i64 to i128
        %209 = arith.trunci %204 : i128 to i64
        %210 = arith.trunci %207 : i128 to i64
        %208 = arith.remsi %209, %210 : i64
        %211 = arith.extsi %208 : i64 to i128
        llvm.store %211, %172 : i128, !llvm.ptr
        %212 = arith.addi %187, %179 : index
        cf.br ^bb21(%212 : index)
      ^bb23(%213: index):
      %214 = llvm.mlir.addressof @MOD : !llvm.ptr
      %215 = llvm.load %214 : !llvm.ptr -> i64
      %216 = llvm.load %172 : !llvm.ptr -> i128
      %217 = arith.trunci %216 : i128 to i64
      %218 = arith.subi %215, %217 : i64
      %219 = arith.muli %218, %144 : i64
      %220 = llvm.mlir.addressof @MOD : !llvm.ptr
      %221 = llvm.load %220 : !llvm.ptr -> i64
      %222 = arith.remsi %219, %221 : i64
      %223 = llvm.mlir.addressof @MOD : !llvm.ptr
      %224 = llvm.load %223 : !llvm.ptr -> i64
      %225 = arith.remsi %222, %224 : i64
      %226 = arith.index_cast %168 : index to i64
      %227 = llvm.getelementptr %arg1[%226] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %225, %227 : i64, !llvm.ptr
      %228 = arith.addi %168, %160 : index
      cf.br ^bb18(%228 : index)
    ^bb20(%229: index):
    func.return
  }
  func.func @main() -> i32 {
    %230 = arith.constant 2019 : i32
    %231 = arith.extsi %230 : i32 to i64
    %233 = arith.constant 1 : i32
    %235 = arith.extsi %233 : i32 to i64
    %234 = arith.addi %231, %235 : i64
    %236 = arith.constant 8 : i32
    %237 = arith.extsi %236 : i32 to i64
    %232 = func.call @calloc(%234, %237) : (i64, i64) -> !llvm.ptr
    %239 = arith.constant 1 : i32
    %241 = arith.extsi %239 : i32 to i64
    %240 = arith.addi %231, %241 : i64
    %242 = arith.constant 8 : i32
    %243 = arith.extsi %242 : i32 to i64
    %238 = func.call @calloc(%240, %243) : (i64, i64) -> !llvm.ptr
    %245 = arith.constant 1 : i32
    %247 = arith.extsi %245 : i32 to i64
    %246 = arith.addi %231, %247 : i64
    %248 = arith.constant 8 : i32
    %249 = arith.extsi %248 : i32 to i64
    %244 = func.call @calloc(%246, %249) : (i64, i64) -> !llvm.ptr
    %251 = arith.constant 1 : i32
    %253 = arith.extsi %251 : i32 to i64
    %252 = arith.addi %231, %253 : i64
    %254 = arith.constant 8 : i32
    %255 = arith.extsi %254 : i32 to i64
    %250 = func.call @calloc(%252, %255) : (i64, i64) -> !llvm.ptr
    %257 = arith.constant 1 : i32
    %259 = arith.extsi %257 : i32 to i64
    %258 = arith.addi %231, %259 : i64
    %260 = arith.constant 8 : i32
    %261 = arith.extsi %260 : i32 to i64
    %256 = func.call @calloc(%258, %261) : (i64, i64) -> !llvm.ptr
    %263 = arith.constant 1 : i32
    %265 = arith.extsi %263 : i32 to i64
    %264 = arith.addi %231, %265 : i64
    %266 = arith.constant 8 : i32
    %267 = arith.extsi %266 : i32 to i64
    %262 = func.call @calloc(%264, %267) : (i64, i64) -> !llvm.ptr
    %269 = arith.constant 1 : i32
    %271 = arith.extsi %269 : i32 to i64
    %270 = arith.addi %231, %271 : i64
    %272 = arith.constant 8 : i32
    %273 = arith.extsi %272 : i32 to i64
    %268 = func.call @calloc(%270, %273) : (i64, i64) -> !llvm.ptr
    %275 = arith.constant 1 : i32
    %277 = arith.extsi %275 : i32 to i64
    %276 = arith.addi %231, %277 : i64
    %278 = arith.constant 8 : i32
    %279 = arith.extsi %278 : i32 to i64
    %274 = func.call @calloc(%276, %279) : (i64, i64) -> !llvm.ptr
    %281 = arith.constant 1 : i32
    %283 = arith.extsi %281 : i32 to i64
    %282 = arith.addi %231, %283 : i64
    %284 = arith.constant 8 : i32
    %285 = arith.extsi %284 : i32 to i64
    %280 = func.call @calloc(%282, %285) : (i64, i64) -> !llvm.ptr
    %287 = arith.constant 1 : i32
    %289 = arith.extsi %287 : i32 to i64
    %288 = arith.addi %231, %289 : i64
    %290 = arith.constant 8 : i32
    %291 = arith.extsi %290 : i32 to i64
    %286 = func.call @calloc(%288, %291) : (i64, i64) -> !llvm.ptr
    %293 = arith.constant 1 : i32
    %295 = arith.extsi %293 : i32 to i64
    %294 = arith.addi %231, %295 : i64
    %296 = arith.constant 8 : i32
    %297 = arith.extsi %296 : i32 to i64
    %292 = func.call @calloc(%294, %297) : (i64, i64) -> !llvm.ptr
    %299 = arith.constant 1 : i32
    %301 = arith.extsi %299 : i32 to i64
    %300 = arith.addi %231, %301 : i64
    %302 = arith.constant 8 : i32
    %303 = arith.extsi %302 : i32 to i64
    %298 = func.call @calloc(%300, %303) : (i64, i64) -> !llvm.ptr
    %305 = arith.constant 1 : i32
    %307 = arith.extsi %305 : i32 to i64
    %306 = arith.addi %231, %307 : i64
    %308 = arith.constant 8 : i32
    %309 = arith.extsi %308 : i32 to i64
    %304 = func.call @calloc(%306, %309) : (i64, i64) -> !llvm.ptr
    %311 = arith.constant 1 : i32
    %313 = arith.extsi %311 : i32 to i64
    %312 = arith.addi %231, %313 : i64
    %314 = arith.constant 8 : i32
    %315 = arith.extsi %314 : i32 to i64
    %310 = func.call @calloc(%312, %315) : (i64, i64) -> !llvm.ptr
    %317 = arith.constant 1 : i32
    %319 = arith.extsi %317 : i32 to i64
    %318 = arith.addi %231, %319 : i64
    %320 = arith.constant 8 : i32
    %321 = arith.extsi %320 : i32 to i64
    %316 = func.call @calloc(%318, %321) : (i64, i64) -> !llvm.ptr
    %323 = arith.constant 1 : i32
    %325 = arith.extsi %323 : i32 to i64
    %324 = arith.addi %231, %325 : i64
    %326 = arith.constant 8 : i32
    %327 = arith.extsi %326 : i32 to i64
    %322 = func.call @calloc(%324, %327) : (i64, i64) -> !llvm.ptr
    %329 = arith.constant 1 : i32
    %331 = arith.extsi %329 : i32 to i64
    %330 = arith.addi %231, %331 : i64
    %332 = arith.constant 8 : i32
    %333 = arith.extsi %332 : i32 to i64
    %328 = func.call @calloc(%330, %333) : (i64, i64) -> !llvm.ptr
    %335 = arith.constant 1 : i32
    %337 = arith.extsi %335 : i32 to i64
    %336 = arith.addi %231, %337 : i64
    %338 = arith.constant 8 : i32
    %339 = arith.extsi %338 : i32 to i64
    %334 = func.call @calloc(%336, %339) : (i64, i64) -> !llvm.ptr
    %341 = arith.constant 1 : i32
    %343 = arith.extsi %341 : i32 to i64
    %342 = arith.addi %231, %343 : i64
    %344 = arith.constant 8 : i32
    %345 = arith.extsi %344 : i32 to i64
    %340 = func.call @calloc(%342, %345) : (i64, i64) -> !llvm.ptr
    %347 = arith.constant 1 : i32
    %349 = arith.extsi %347 : i32 to i64
    %348 = arith.addi %231, %349 : i64
    %350 = arith.constant 8 : i32
    %351 = arith.extsi %350 : i32 to i64
    %346 = func.call @calloc(%348, %351) : (i64, i64) -> !llvm.ptr
    %353 = arith.constant 1 : i32
    %355 = arith.extsi %353 : i32 to i64
    %354 = arith.addi %231, %355 : i64
    %356 = arith.constant 8 : i32
    %357 = arith.extsi %356 : i32 to i64
    %352 = func.call @calloc(%354, %357) : (i64, i64) -> !llvm.ptr
    %359 = arith.constant 1 : i32
    %361 = arith.extsi %359 : i32 to i64
    %360 = arith.addi %231, %361 : i64
    %362 = arith.constant 8 : i32
    %363 = arith.extsi %362 : i32 to i64
    %358 = func.call @calloc(%360, %363) : (i64, i64) -> !llvm.ptr
    %364 = llvm.mlir.zero : !llvm.ptr
    %365 = llvm.icmp "eq" %232, %364 : !llvm.ptr
    %366 = scf.if %365 -> (i1) {
      %367 = arith.constant true
      scf.yield %367 : i1
    } else {
      %368 = llvm.mlir.zero : !llvm.ptr
      %369 = llvm.icmp "eq" %334, %368 : !llvm.ptr
      scf.yield %369 : i1
    }
    %370 = scf.if %366 -> (i1) {
      %371 = arith.constant true
      scf.yield %371 : i1
    } else {
      %372 = llvm.mlir.zero : !llvm.ptr
      %373 = llvm.icmp "eq" %352, %372 : !llvm.ptr
      scf.yield %373 : i1
    }
    cf.cond_br %370, ^bb24, ^bb25
    ^bb24:
      %374 = arith.constant 1 : i32
      func.return %374 : i32
    ^bb25:
      cf.br ^bb26
    ^bb26:
    %375 = llvm.mlir.addressof @MOD : !llvm.ptr
    %376 = llvm.load %375 : !llvm.ptr -> i64
    %377 = arith.constant 1 : i32
    %379 = arith.extsi %377 : i32 to i64
    %378 = arith.addi %376, %379 : i64
    %380 = arith.constant 2 : i32
    %382 = arith.extsi %380 : i32 to i64
    %381 = arith.divsi %378, %382 : i64
    %383 = arith.constant 1 : i32
    %384 = arith.constant 0 : i32
    %385 = arith.extsi %383 : i32 to i64
    %386 = arith.extsi %384 : i32 to i64
    %387 = llvm.getelementptr %232[%386] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %385, %387 : i64, !llvm.ptr
    %388 = arith.constant 1 : i32
    %389 = arith.constant 1 : i32
    %391 = arith.extsi %389 : i32 to i64
    %390 = arith.addi %231, %391 : i64
    %392 = arith.index_cast %388 : i32 to index
    %393 = arith.index_cast %390 : i32 to index
    %395 = arith.constant 1 : index
    %396 = arith.constant -1 : index
    %397 = arith.cmpi sle, %392, %393 : index
    %394 = arith.select %397, %395, %396 : index
    cf.br ^bb27(%392 : index)
    ^bb27(%398: index):
    %399 = arith.cmpi slt, %398, %393 : index
    %400 = arith.cmpi sgt, %398, %393 : index
    %401 = arith.select %397, %399, %400 : i1
    cf.cond_br %401, ^bb28(%398 : index), ^bb29(%398 : index)
    ^bb28(%402: index):
      %403 = arith.constant 1 : i32
      %405 = arith.extsi %403 : i32 to i64
      %404 = arith.addi %231, %405 : i64
      %406 = arith.index_cast %402 : i32 to index
      %407 = arith.index_cast %404 : i32 to index
      %409 = arith.constant 1 : index
      %410 = arith.constant -1 : index
      %411 = arith.cmpi sle, %406, %407 : index
      %408 = arith.select %411, %409, %410 : index
      cf.br ^bb30(%406 : index)
      ^bb30(%412: index):
      %413 = arith.cmpi slt, %412, %407 : index
      %414 = arith.cmpi sgt, %412, %407 : index
      %415 = arith.select %411, %413, %414 : i1
      cf.cond_br %415, ^bb31(%412 : index), ^bb32(%412 : index)
      ^bb31(%416: index):
        %418 = arith.index_cast %416 : index to i64
        %419 = llvm.getelementptr %232[%418] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %417 = llvm.load %419 : !llvm.ptr -> i64
        %421 = arith.subi %416, %402 : index
        %422 = arith.index_cast %421 : index to i64
        %423 = llvm.getelementptr %232[%422] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %420 = llvm.load %423 : !llvm.ptr -> i64
        %424 = arith.addi %417, %420 : i64
        %425 = arith.index_cast %416 : index to i64
        %426 = llvm.getelementptr %232[%425] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %424, %426 : i64, !llvm.ptr
        %428 = arith.index_cast %416 : index to i64
        %429 = llvm.getelementptr %232[%428] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %427 = llvm.load %429 : !llvm.ptr -> i64
        %430 = llvm.mlir.addressof @MOD : !llvm.ptr
        %431 = llvm.load %430 : !llvm.ptr -> i64
        %432 = arith.cmpi sge, %427, %431 : i64
        cf.cond_br %432, ^bb33, ^bb34
        ^bb33:
          %434 = arith.index_cast %416 : index to i64
          %435 = llvm.getelementptr %232[%434] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %433 = llvm.load %435 : !llvm.ptr -> i64
          %436 = llvm.mlir.addressof @MOD : !llvm.ptr
          %437 = llvm.load %436 : !llvm.ptr -> i64
          %438 = arith.subi %433, %437 : i64
          %439 = arith.index_cast %416 : index to i64
          %440 = llvm.getelementptr %232[%439] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %438, %440 : i64, !llvm.ptr
          cf.br ^bb35
        ^bb34:
          cf.br ^bb35
        ^bb35:
        %441 = arith.addi %416, %408 : index
        cf.br ^bb30(%441 : index)
      ^bb32(%442: index):
      %443 = arith.addi %402, %394 : index
      cf.br ^bb27(%443 : index)
    ^bb29(%444: index):
    %445 = arith.constant 0 : i32
    %446 = arith.constant 1 : i32
    %448 = arith.extsi %446 : i32 to i64
    %447 = arith.addi %231, %448 : i64
    %449 = arith.index_cast %445 : i32 to index
    %450 = arith.index_cast %447 : i32 to index
    %452 = arith.constant 1 : index
    %453 = arith.constant -1 : index
    %454 = arith.cmpi sle, %449, %450 : index
    %451 = arith.select %454, %452, %453 : index
    cf.br ^bb36(%449 : index)
    ^bb36(%455: index):
    %456 = arith.cmpi slt, %455, %450 : index
    %457 = arith.cmpi sgt, %455, %450 : index
    %458 = arith.select %454, %456, %457 : i1
    cf.cond_br %458, ^bb37(%455 : index), ^bb38(%455 : index)
    ^bb37(%459: index):
      %461 = arith.index_cast %459 : index to i64
      %462 = llvm.getelementptr %232[%461] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %460 = llvm.load %462 : !llvm.ptr -> i64
      %463 = arith.constant 1 : i32
      %465 = arith.extsi %463 : i32 to i64
      %464 = arith.subi %460, %465 : i64
      %466 = llvm.mlir.addressof @MOD : !llvm.ptr
      %467 = llvm.load %466 : !llvm.ptr -> i64
      %468 = arith.addi %464, %467 : i64
      %469 = llvm.mlir.addressof @MOD : !llvm.ptr
      %470 = llvm.load %469 : !llvm.ptr -> i64
      %471 = arith.remsi %468, %470 : i64
      %472 = arith.index_cast %459 : index to i64
      %473 = llvm.getelementptr %238[%472] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %471, %473 : i64, !llvm.ptr
      %474 = arith.addi %459, %451 : index
      cf.br ^bb36(%474 : index)
    ^bb38(%475: index):
    func.call @poly_mul(%238, %238, %244, %231) : (!llvm.ptr, !llvm.ptr, !llvm.ptr, i64) -> ()
    %477 = arith.constant 1 : i32
    %478 = arith.constant 0 : i32
    %479 = arith.extsi %477 : i32 to i64
    %480 = arith.extsi %478 : i32 to i64
    %481 = llvm.getelementptr %250[%480] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %479, %481 : i64, !llvm.ptr
    %482 = arith.constant 1 : i32
    %483 = arith.constant 1 : i32
    %485 = arith.extsi %483 : i32 to i64
    %484 = arith.addi %231, %485 : i64
    %486 = arith.index_cast %482 : i32 to index
    %487 = arith.index_cast %484 : i32 to index
    %489 = arith.constant 1 : index
    %490 = arith.constant -1 : index
    %491 = arith.cmpi sle, %486, %487 : index
    %488 = arith.select %491, %489, %490 : index
    cf.br ^bb39(%486 : index)
    ^bb39(%492: index):
    %493 = arith.cmpi slt, %492, %487 : index
    %494 = arith.cmpi sgt, %492, %487 : index
    %495 = arith.select %491, %493, %494 : i1
    cf.cond_br %495, ^bb40(%492 : index), ^bb41(%492 : index)
    ^bb40(%496: index):
      %497 = llvm.mlir.addressof @MOD : !llvm.ptr
      %498 = llvm.load %497 : !llvm.ptr -> i64
      %500 = arith.constant 1 : i32
      %502 = arith.index_cast %496 : index to i32
      %501 = arith.subi %502, %500 : i32
      %503 = arith.extsi %501 : i32 to i64
      %504 = llvm.getelementptr %232[%503] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %499 = llvm.load %504 : !llvm.ptr -> i64
      %505 = arith.subi %498, %499 : i64
      %506 = llvm.mlir.addressof @MOD : !llvm.ptr
      %507 = llvm.load %506 : !llvm.ptr -> i64
      %508 = arith.remsi %505, %507 : i64
      %509 = arith.index_cast %496 : index to i64
      %510 = llvm.getelementptr %250[%509] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %508, %510 : i64, !llvm.ptr
      %511 = arith.addi %496, %488 : index
      cf.br ^bb39(%511 : index)
    ^bb41(%512: index):
    func.call @inv_series(%250, %256, %231) : (!llvm.ptr, !llvm.ptr, i64) -> ()
    func.call @poly_mul(%244, %256, %262, %231) : (!llvm.ptr, !llvm.ptr, !llvm.ptr, i64) -> ()
    %515 = arith.constant 0 : i32
    %516 = arith.constant 1 : i32
    %518 = arith.extsi %516 : i32 to i64
    %517 = arith.addi %231, %518 : i64
    %519 = arith.index_cast %515 : i32 to index
    %520 = arith.index_cast %517 : i32 to index
    %522 = arith.constant 1 : index
    %523 = arith.constant -1 : index
    %524 = arith.cmpi sle, %519, %520 : index
    %521 = arith.select %524, %522, %523 : index
    cf.br ^bb42(%519 : index)
    ^bb42(%525: index):
    %526 = arith.cmpi slt, %525, %520 : index
    %527 = arith.cmpi sgt, %525, %520 : index
    %528 = arith.select %524, %526, %527 : i1
    cf.cond_br %528, ^bb43(%525 : index), ^bb44(%525 : index)
    ^bb43(%529: index):
      %530 = arith.constant 0 : i32
      %531 = arith.extsi %530 : i32 to i64
      %532 = arith.index_cast %529 : index to i64
      %533 = llvm.getelementptr %274[%532] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %531, %533 : i64, !llvm.ptr
      %534 = arith.addi %529, %521 : index
      cf.br ^bb42(%534 : index)
    ^bb44(%535: index):
    %536 = arith.constant 0 : i32
    %537 = arith.constant 2 : i32
    %539 = arith.extsi %537 : i32 to i64
    %538 = arith.divsi %231, %539 : i64
    %540 = arith.constant 1 : i32
    %542 = arith.extsi %540 : i32 to i64
    %541 = arith.addi %538, %542 : i64
    %543 = arith.index_cast %536 : i32 to index
    %544 = arith.index_cast %541 : i32 to index
    %546 = arith.constant 1 : index
    %547 = arith.constant -1 : index
    %548 = arith.cmpi sle, %543, %544 : index
    %545 = arith.select %548, %546, %547 : index
    cf.br ^bb45(%543 : index)
    ^bb45(%549: index):
    %550 = arith.cmpi slt, %549, %544 : index
    %551 = arith.cmpi sgt, %549, %544 : index
    %552 = arith.select %548, %550, %551 : i1
    cf.cond_br %552, ^bb46(%549 : index), ^bb47(%549 : index)
    ^bb46(%553: index):
      %555 = arith.index_cast %553 : index to i64
      %556 = llvm.getelementptr %232[%555] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %554 = llvm.load %556 : !llvm.ptr -> i64
      %557 = arith.constant 2 : i32
      %559 = arith.index_cast %553 : index to i32
      %558 = arith.muli %557, %559 : i32
      %560 = arith.extsi %558 : i32 to i64
      %561 = llvm.getelementptr %274[%560] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %554, %561 : i64, !llvm.ptr
      %563 = arith.index_cast %553 : index to i64
      %564 = llvm.getelementptr %232[%563] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %562 = llvm.load %564 : !llvm.ptr -> i64
      %565 = arith.constant 1 : i32
      %567 = arith.extsi %565 : i32 to i64
      %566 = arith.subi %562, %567 : i64
      %568 = llvm.mlir.addressof @MOD : !llvm.ptr
      %569 = llvm.load %568 : !llvm.ptr -> i64
      %570 = arith.addi %566, %569 : i64
      %571 = llvm.mlir.addressof @MOD : !llvm.ptr
      %572 = llvm.load %571 : !llvm.ptr -> i64
      %573 = arith.remsi %570, %572 : i64
      %574 = arith.constant 2 : i32
      %576 = arith.index_cast %553 : index to i32
      %575 = arith.muli %574, %576 : i32
      %577 = arith.extsi %575 : i32 to i64
      %578 = llvm.getelementptr %280[%577] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %573, %578 : i64, !llvm.ptr
      %579 = arith.addi %553, %545 : index
      cf.br ^bb45(%579 : index)
    ^bb47(%580: index):
    %581 = arith.constant 0 : i32
    %582 = arith.constant 1 : i32
    %584 = arith.extsi %582 : i32 to i64
    %583 = arith.addi %231, %584 : i64
    %585 = arith.index_cast %581 : i32 to index
    %586 = arith.index_cast %583 : i32 to index
    %588 = arith.constant 1 : index
    %589 = arith.constant -1 : index
    %590 = arith.cmpi sle, %585, %586 : index
    %587 = arith.select %590, %588, %589 : index
    cf.br ^bb48(%585 : index)
    ^bb48(%591: index):
    %592 = arith.cmpi slt, %591, %586 : index
    %593 = arith.cmpi sgt, %591, %586 : index
    %594 = arith.select %590, %592, %593 : i1
    cf.cond_br %594, ^bb49(%591 : index), ^bb50(%591 : index)
    ^bb49(%595: index):
      %596 = arith.constant 2 : i32
      %598 = arith.index_cast %595 : index to i32
      %597 = arith.remsi %598, %596 : i32
      %599 = arith.constant 1 : i32
      %600 = arith.cmpi eq, %597, %599 : i32
      cf.cond_br %600, ^bb51, ^bb52
      ^bb51:
        %601 = arith.constant 0 : i32
        %602 = arith.extsi %601 : i32 to i64
        %603 = arith.index_cast %595 : index to i64
        %604 = llvm.getelementptr %280[%603] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %602, %604 : i64, !llvm.ptr
        cf.br ^bb53
      ^bb52:
        cf.br ^bb53
      ^bb53:
      %605 = arith.addi %595, %587 : index
      cf.br ^bb48(%605 : index)
    ^bb50(%606: index):
    %607 = arith.constant 1 : i32
    %608 = arith.constant 0 : i32
    %609 = arith.extsi %607 : i32 to i64
    %610 = arith.extsi %608 : i32 to i64
    %611 = llvm.getelementptr %286[%610] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %609, %611 : i64, !llvm.ptr
    %612 = arith.constant 1 : i32
    %613 = arith.constant 1 : i32
    %615 = arith.extsi %613 : i32 to i64
    %614 = arith.addi %231, %615 : i64
    %616 = arith.index_cast %612 : i32 to index
    %617 = arith.index_cast %614 : i32 to index
    %619 = arith.constant 1 : index
    %620 = arith.constant -1 : index
    %621 = arith.cmpi sle, %616, %617 : index
    %618 = arith.select %621, %619, %620 : index
    cf.br ^bb54(%616 : index)
    ^bb54(%622: index):
    %623 = arith.cmpi slt, %622, %617 : index
    %624 = arith.cmpi sgt, %622, %617 : index
    %625 = arith.select %621, %623, %624 : i1
    cf.cond_br %625, ^bb55(%622 : index), ^bb56(%622 : index)
    ^bb55(%626: index):
      %628 = arith.constant 1 : i32
      %630 = arith.index_cast %626 : index to i32
      %629 = arith.subi %630, %628 : i32
      %631 = arith.extsi %629 : i32 to i64
      %632 = llvm.getelementptr %232[%631] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %627 = llvm.load %632 : !llvm.ptr -> i64
      %633 = arith.index_cast %626 : index to i64
      %634 = llvm.getelementptr %286[%633] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %627, %634 : i64, !llvm.ptr
      %635 = arith.addi %626, %618 : index
      cf.br ^bb54(%635 : index)
    ^bb56(%636: index):
    func.call @poly_mul(%280, %286, %244, %231) : (!llvm.ptr, !llvm.ptr, !llvm.ptr, i64) -> ()
    %638 = arith.constant 0 : i32
    %639 = arith.constant 1 : i32
    %641 = arith.extsi %639 : i32 to i64
    %640 = arith.addi %231, %641 : i64
    %642 = arith.index_cast %638 : i32 to index
    %643 = arith.index_cast %640 : i32 to index
    %645 = arith.constant 1 : index
    %646 = arith.constant -1 : index
    %647 = arith.cmpi sle, %642, %643 : index
    %644 = arith.select %647, %645, %646 : index
    cf.br ^bb57(%642 : index)
    ^bb57(%648: index):
    %649 = arith.cmpi slt, %648, %643 : index
    %650 = arith.cmpi sgt, %648, %643 : index
    %651 = arith.select %647, %649, %650 : i1
    cf.cond_br %651, ^bb58(%648 : index), ^bb59(%648 : index)
    ^bb58(%652: index):
      %653 = arith.constant 0 : i32
      %654 = arith.extsi %653 : i32 to i64
      %655 = arith.index_cast %652 : index to i64
      %656 = llvm.getelementptr %250[%655] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %654, %656 : i64, !llvm.ptr
      %657 = arith.addi %652, %644 : index
      cf.br ^bb57(%657 : index)
    ^bb59(%658: index):
    %659 = arith.constant 1 : i32
    %660 = arith.constant 0 : i32
    %661 = arith.extsi %659 : i32 to i64
    %662 = arith.extsi %660 : i32 to i64
    %663 = llvm.getelementptr %250[%662] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %661, %663 : i64, !llvm.ptr
    %664 = arith.constant 2 : i32
    %665 = arith.constant 1 : i32
    %667 = arith.extsi %665 : i32 to i64
    %666 = arith.addi %231, %667 : i64
    %668 = arith.index_cast %664 : i32 to index
    %669 = arith.index_cast %666 : i32 to index
    %671 = arith.constant 1 : index
    %672 = arith.constant -1 : index
    %673 = arith.cmpi sle, %668, %669 : index
    %670 = arith.select %673, %671, %672 : index
    cf.br ^bb60(%668 : index)
    ^bb60(%674: index):
    %675 = arith.cmpi slt, %674, %669 : index
    %676 = arith.cmpi sgt, %674, %669 : index
    %677 = arith.select %673, %675, %676 : i1
    cf.cond_br %677, ^bb61(%674 : index), ^bb62(%674 : index)
    ^bb61(%678: index):
      %679 = llvm.mlir.addressof @MOD : !llvm.ptr
      %680 = llvm.load %679 : !llvm.ptr -> i64
      %682 = arith.constant 2 : i32
      %684 = arith.index_cast %678 : index to i32
      %683 = arith.subi %684, %682 : i32
      %685 = arith.extsi %683 : i32 to i64
      %686 = llvm.getelementptr %274[%685] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %681 = llvm.load %686 : !llvm.ptr -> i64
      %687 = arith.subi %680, %681 : i64
      %688 = llvm.mlir.addressof @MOD : !llvm.ptr
      %689 = llvm.load %688 : !llvm.ptr -> i64
      %690 = arith.remsi %687, %689 : i64
      %691 = arith.index_cast %678 : index to i64
      %692 = llvm.getelementptr %250[%691] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %690, %692 : i64, !llvm.ptr
      %693 = arith.addi %678, %670 : index
      cf.br ^bb60(%693 : index)
    ^bb62(%694: index):
    func.call @inv_series(%250, %256, %231) : (!llvm.ptr, !llvm.ptr, i64) -> ()
    func.call @poly_mul(%244, %256, %268, %231) : (!llvm.ptr, !llvm.ptr, !llvm.ptr, i64) -> ()
    %697 = arith.constant 0 : i32
    %698 = arith.constant 1 : i32
    %700 = arith.extsi %698 : i32 to i64
    %699 = arith.addi %231, %700 : i64
    %701 = arith.index_cast %697 : i32 to index
    %702 = arith.index_cast %699 : i32 to index
    %704 = arith.constant 1 : index
    %705 = arith.constant -1 : index
    %706 = arith.cmpi sle, %701, %702 : index
    %703 = arith.select %706, %704, %705 : index
    cf.br ^bb63(%701 : index)
    ^bb63(%707: index):
    %708 = arith.cmpi slt, %707, %702 : index
    %709 = arith.cmpi sgt, %707, %702 : index
    %710 = arith.select %706, %708, %709 : i1
    cf.cond_br %710, ^bb64(%707 : index), ^bb65(%707 : index)
    ^bb64(%711: index):
      %713 = arith.index_cast %711 : index to i64
      %714 = llvm.getelementptr %262[%713] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %712 = llvm.load %714 : !llvm.ptr -> i64
      %716 = arith.index_cast %711 : index to i64
      %717 = llvm.getelementptr %268[%716] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %715 = llvm.load %717 : !llvm.ptr -> i64
      %718 = arith.addi %712, %715 : i64
      %719 = llvm.mlir.addressof @MOD : !llvm.ptr
      %720 = llvm.load %719 : !llvm.ptr -> i64
      %721 = arith.remsi %718, %720 : i64
      %722 = arith.muli %721, %381 : i64
      %723 = llvm.mlir.addressof @MOD : !llvm.ptr
      %724 = llvm.load %723 : !llvm.ptr -> i64
      %725 = arith.remsi %722, %724 : i64
      %726 = arith.index_cast %711 : index to i64
      %727 = llvm.getelementptr %292[%726] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %725, %727 : i64, !llvm.ptr
      %728 = arith.addi %711, %703 : index
      cf.br ^bb63(%728 : index)
    ^bb65(%729: index):
    %730 = arith.constant 0 : i32
    %731 = arith.constant 1 : i32
    %733 = arith.extsi %731 : i32 to i64
    %732 = arith.addi %231, %733 : i64
    %734 = arith.index_cast %730 : i32 to index
    %735 = arith.index_cast %732 : i32 to index
    %737 = arith.constant 1 : index
    %738 = arith.constant -1 : index
    %739 = arith.cmpi sle, %734, %735 : index
    %736 = arith.select %739, %737, %738 : index
    cf.br ^bb66(%734 : index)
    ^bb66(%740: index):
    %741 = arith.cmpi slt, %740, %735 : index
    %742 = arith.cmpi sgt, %740, %735 : index
    %743 = arith.select %739, %741, %742 : i1
    cf.cond_br %743, ^bb67(%740 : index), ^bb68(%740 : index)
    ^bb67(%744: index):
      %745 = arith.constant 0 : i32
      %746 = arith.extsi %745 : i32 to i64
      %747 = arith.index_cast %744 : index to i64
      %748 = llvm.getelementptr %298[%747] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %746, %748 : i64, !llvm.ptr
      %749 = arith.addi %744, %736 : index
      cf.br ^bb66(%749 : index)
    ^bb68(%750: index):
    %751 = arith.constant 0 : i32
    %752 = arith.constant 1 : i32
    %754 = arith.extsi %752 : i32 to i64
    %753 = arith.subi %231, %754 : i64
    %755 = arith.index_cast %751 : i32 to index
    %756 = arith.index_cast %753 : i32 to index
    %758 = arith.constant 1 : index
    %759 = arith.constant -1 : index
    %760 = arith.cmpi sle, %755, %756 : index
    %757 = arith.select %760, %758, %759 : index
    cf.br ^bb69(%755 : index)
    ^bb69(%761: index):
    %762 = arith.cmpi slt, %761, %756 : index
    %763 = arith.cmpi sgt, %761, %756 : index
    %764 = arith.select %760, %762, %763 : i1
    cf.cond_br %764, ^bb70(%761 : index), ^bb71(%761 : index)
    ^bb70(%765: index):
      %767 = arith.index_cast %765 : index to i64
      %768 = llvm.getelementptr %292[%767] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %766 = llvm.load %768 : !llvm.ptr -> i64
      %769 = arith.constant 2 : i32
      %771 = arith.index_cast %765 : index to i32
      %770 = arith.addi %771, %769 : i32
      %772 = arith.extsi %770 : i32 to i64
      %773 = llvm.getelementptr %298[%772] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %766, %773 : i64, !llvm.ptr
      %774 = arith.addi %765, %757 : index
      cf.br ^bb69(%774 : index)
    ^bb71(%775: index):
    %776 = arith.constant 0 : i32
    %777 = arith.constant 1 : i32
    %779 = arith.extsi %777 : i32 to i64
    %778 = arith.addi %231, %779 : i64
    %780 = arith.index_cast %776 : i32 to index
    %781 = arith.index_cast %778 : i32 to index
    %783 = arith.constant 1 : index
    %784 = arith.constant -1 : index
    %785 = arith.cmpi sle, %780, %781 : index
    %782 = arith.select %785, %783, %784 : index
    cf.br ^bb72(%780 : index)
    ^bb72(%786: index):
    %787 = arith.cmpi slt, %786, %781 : index
    %788 = arith.cmpi sgt, %786, %781 : index
    %789 = arith.select %785, %787, %788 : i1
    cf.cond_br %789, ^bb73(%786 : index), ^bb74(%786 : index)
    ^bb73(%790: index):
      %791 = arith.constant 0 : i32
      %792 = arith.extsi %791 : i32 to i64
      %793 = arith.index_cast %790 : index to i64
      %794 = llvm.getelementptr %304[%793] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %792, %794 : i64, !llvm.ptr
      %795 = arith.addi %790, %782 : index
      cf.br ^bb72(%795 : index)
    ^bb74(%796: index):
    %797 = arith.constant 1 : i32
    %798 = arith.constant 1 : i32
    %800 = arith.extsi %798 : i32 to i64
    %799 = arith.addi %231, %800 : i64
    %801 = arith.index_cast %797 : i32 to index
    %802 = arith.index_cast %799 : i32 to index
    %804 = arith.constant 1 : index
    %805 = arith.constant -1 : index
    %806 = arith.cmpi sle, %801, %802 : index
    %803 = arith.select %806, %804, %805 : index
    cf.br ^bb75(%801 : index)
    ^bb75(%807: index):
    %808 = arith.cmpi slt, %807, %802 : index
    %809 = arith.cmpi sgt, %807, %802 : index
    %810 = arith.select %806, %808, %809 : i1
    cf.cond_br %810, ^bb76(%807 : index), ^bb77(%807 : index)
    ^bb76(%811: index):
      %813 = arith.constant 1 : i32
      %815 = arith.index_cast %811 : index to i32
      %814 = arith.subi %815, %813 : i32
      %816 = arith.extsi %814 : i32 to i64
      %817 = llvm.getelementptr %232[%816] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %812 = llvm.load %817 : !llvm.ptr -> i64
      %818 = arith.index_cast %811 : index to i64
      %819 = llvm.getelementptr %304[%818] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %812, %819 : i64, !llvm.ptr
      %820 = arith.addi %811, %803 : index
      cf.br ^bb75(%820 : index)
    ^bb77(%821: index):
    %822 = arith.constant 0 : i32
    %823 = arith.constant 1 : i32
    %825 = arith.extsi %823 : i32 to i64
    %824 = arith.addi %231, %825 : i64
    %826 = arith.index_cast %822 : i32 to index
    %827 = arith.index_cast %824 : i32 to index
    %829 = arith.constant 1 : index
    %830 = arith.constant -1 : index
    %831 = arith.cmpi sle, %826, %827 : index
    %828 = arith.select %831, %829, %830 : index
    cf.br ^bb78(%826 : index)
    ^bb78(%832: index):
    %833 = arith.cmpi slt, %832, %827 : index
    %834 = arith.cmpi sgt, %832, %827 : index
    %835 = arith.select %831, %833, %834 : i1
    cf.cond_br %835, ^bb79(%832 : index), ^bb80(%832 : index)
    ^bb79(%836: index):
      %837 = arith.constant 1 : i32
      %839 = arith.index_cast %836 : index to i32
      %838 = arith.addi %839, %837 : i32
      %840 = llvm.mlir.addressof @MOD : !llvm.ptr
      %841 = llvm.load %840 : !llvm.ptr -> i64
      %843 = arith.extsi %838 : i32 to i64
      %842 = arith.remsi %843, %841 : i64
      %844 = arith.index_cast %836 : index to i64
      %845 = llvm.getelementptr %310[%844] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %842, %845 : i64, !llvm.ptr
      %846 = arith.addi %836, %828 : index
      cf.br ^bb78(%846 : index)
    ^bb80(%847: index):
    %848 = arith.constant 0 : i32
    %849 = arith.constant 1 : i32
    %851 = arith.extsi %849 : i32 to i64
    %850 = arith.addi %231, %851 : i64
    %852 = arith.index_cast %848 : i32 to index
    %853 = arith.index_cast %850 : i32 to index
    %855 = arith.constant 1 : index
    %856 = arith.constant -1 : index
    %857 = arith.cmpi sle, %852, %853 : index
    %854 = arith.select %857, %855, %856 : index
    cf.br ^bb81(%852 : index)
    ^bb81(%858: index):
    %859 = arith.cmpi slt, %858, %853 : index
    %860 = arith.cmpi sgt, %858, %853 : index
    %861 = arith.select %857, %859, %860 : i1
    cf.cond_br %861, ^bb82(%858 : index), ^bb83(%858 : index)
    ^bb82(%862: index):
      %863 = arith.constant 2 : i32
      %865 = arith.index_cast %862 : index to i32
      %864 = arith.remsi %865, %863 : i32
      %866 = arith.constant 0 : i32
      %867 = arith.cmpi eq, %864, %866 : i32
      cf.cond_br %867, ^bb84, ^bb85
      ^bb84:
        %868 = arith.constant 1 : i32
        %869 = arith.extsi %868 : i32 to i64
        %870 = arith.index_cast %862 : index to i64
        %871 = llvm.getelementptr %316[%870] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %869, %871 : i64, !llvm.ptr
        cf.br ^bb86
      ^bb85:
        %872 = llvm.mlir.addressof @MOD : !llvm.ptr
        %873 = llvm.load %872 : !llvm.ptr -> i64
        %874 = arith.constant 1 : i32
        %876 = arith.extsi %874 : i32 to i64
        %875 = arith.subi %873, %876 : i64
        %877 = arith.index_cast %862 : index to i64
        %878 = llvm.getelementptr %316[%877] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %875, %878 : i64, !llvm.ptr
        cf.br ^bb86
      ^bb86:
      %879 = arith.addi %862, %854 : index
      cf.br ^bb81(%879 : index)
    ^bb83(%880: index):
    func.call @poly_mul(%310, %316, %322, %231) : (!llvm.ptr, !llvm.ptr, !llvm.ptr, i64) -> ()
    %882 = arith.constant 0 : i32
    %883 = arith.constant 1 : i32
    %885 = arith.extsi %883 : i32 to i64
    %884 = arith.addi %231, %885 : i64
    %886 = arith.index_cast %882 : i32 to index
    %887 = arith.index_cast %884 : i32 to index
    %889 = arith.constant 1 : index
    %890 = arith.constant -1 : index
    %891 = arith.cmpi sle, %886, %887 : index
    %888 = arith.select %891, %889, %890 : index
    cf.br ^bb87(%886 : index)
    ^bb87(%892: index):
    %893 = arith.cmpi slt, %892, %887 : index
    %894 = arith.cmpi sgt, %892, %887 : index
    %895 = arith.select %891, %893, %894 : i1
    cf.cond_br %895, ^bb88(%892 : index), ^bb89(%892 : index)
    ^bb88(%896: index):
      %897 = arith.constant 0 : i32
      %898 = arith.extsi %897 : i32 to i64
      %899 = arith.index_cast %896 : index to i64
      %900 = llvm.getelementptr %328[%899] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %898, %900 : i64, !llvm.ptr
      %901 = arith.addi %896, %888 : index
      cf.br ^bb87(%901 : index)
    ^bb89(%902: index):
    %903 = arith.constant 0 : i32
    %904 = arith.constant 2 : i32
    %906 = arith.extsi %904 : i32 to i64
    %905 = arith.subi %231, %906 : i64
    %907 = arith.index_cast %903 : i32 to index
    %908 = arith.index_cast %905 : i32 to index
    %910 = arith.constant 1 : index
    %911 = arith.constant -1 : index
    %912 = arith.cmpi sle, %907, %908 : index
    %909 = arith.select %912, %910, %911 : index
    cf.br ^bb90(%907 : index)
    ^bb90(%913: index):
    %914 = arith.cmpi slt, %913, %908 : index
    %915 = arith.cmpi sgt, %913, %908 : index
    %916 = arith.select %912, %914, %915 : i1
    cf.cond_br %916, ^bb91(%913 : index), ^bb92(%913 : index)
    ^bb91(%917: index):
      %919 = arith.index_cast %917 : index to i64
      %920 = llvm.getelementptr %322[%919] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %918 = llvm.load %920 : !llvm.ptr -> i64
      %921 = arith.constant 3 : i32
      %923 = arith.index_cast %917 : index to i32
      %922 = arith.addi %923, %921 : i32
      %924 = arith.extsi %922 : i32 to i64
      %925 = llvm.getelementptr %328[%924] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %918, %925 : i64, !llvm.ptr
      %926 = arith.addi %917, %909 : index
      cf.br ^bb90(%926 : index)
    ^bb92(%927: index):
    %928 = arith.constant 0 : i32
    %929 = arith.constant 1 : i32
    %931 = arith.extsi %929 : i32 to i64
    %930 = arith.addi %231, %931 : i64
    %932 = arith.index_cast %928 : i32 to index
    %933 = arith.index_cast %930 : i32 to index
    %935 = arith.constant 1 : index
    %936 = arith.constant -1 : index
    %937 = arith.cmpi sle, %932, %933 : index
    %934 = arith.select %937, %935, %936 : index
    cf.br ^bb93(%932 : index)
    ^bb93(%938: index):
    %939 = arith.cmpi slt, %938, %933 : index
    %940 = arith.cmpi sgt, %938, %933 : index
    %941 = arith.select %937, %939, %940 : i1
    cf.cond_br %941, ^bb94(%938 : index), ^bb95(%938 : index)
    ^bb94(%942: index):
      %944 = arith.index_cast %942 : index to i64
      %945 = llvm.getelementptr %298[%944] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %943 = llvm.load %945 : !llvm.ptr -> i64
      %947 = arith.index_cast %942 : index to i64
      %948 = llvm.getelementptr %304[%947] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %946 = llvm.load %948 : !llvm.ptr -> i64
      %949 = arith.addi %943, %946 : i64
      %951 = arith.index_cast %942 : index to i64
      %952 = llvm.getelementptr %328[%951] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %950 = llvm.load %952 : !llvm.ptr -> i64
      %953 = llvm.mlir.addressof @MOD : !llvm.ptr
      %954 = llvm.load %953 : !llvm.ptr -> i64
      %955 = arith.remsi %950, %954 : i64
      %956 = arith.subi %949, %955 : i64
      %957 = llvm.mlir.addressof @MOD : !llvm.ptr
      %958 = llvm.load %957 : !llvm.ptr -> i64
      %959 = arith.addi %956, %958 : i64
      %960 = llvm.mlir.addressof @MOD : !llvm.ptr
      %961 = llvm.load %960 : !llvm.ptr -> i64
      %962 = arith.remsi %959, %961 : i64
      %963 = arith.index_cast %942 : index to i64
      %964 = llvm.getelementptr %334[%963] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %962, %964 : i64, !llvm.ptr
      %965 = arith.addi %942, %934 : index
      cf.br ^bb93(%965 : index)
    ^bb95(%966: index):
    %967 = arith.constant 0 : i32
    %968 = arith.constant 1 : i32
    %970 = arith.extsi %968 : i32 to i64
    %969 = arith.addi %231, %970 : i64
    %971 = arith.index_cast %967 : i32 to index
    %972 = arith.index_cast %969 : i32 to index
    %974 = arith.constant 1 : index
    %975 = arith.constant -1 : index
    %976 = arith.cmpi sle, %971, %972 : index
    %973 = arith.select %976, %974, %975 : index
    cf.br ^bb96(%971 : index)
    ^bb96(%977: index):
    %978 = arith.cmpi slt, %977, %972 : index
    %979 = arith.cmpi sgt, %977, %972 : index
    %980 = arith.select %976, %978, %979 : i1
    cf.cond_br %980, ^bb97(%977 : index), ^bb98(%977 : index)
    ^bb97(%981: index):
      %982 = arith.constant 0 : i32
      %983 = arith.extsi %982 : i32 to i64
      %984 = arith.index_cast %981 : index to i64
      %985 = llvm.getelementptr %340[%984] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %983, %985 : i64, !llvm.ptr
      %986 = arith.addi %981, %973 : index
      cf.br ^bb96(%986 : index)
    ^bb98(%987: index):
    %988 = arith.constant 1 : i32
    %989 = arith.constant 1 : i32
    %991 = arith.extsi %989 : i32 to i64
    %990 = arith.addi %231, %991 : i64
    %992 = arith.index_cast %988 : i32 to index
    %993 = arith.index_cast %990 : i32 to index
    %995 = arith.constant 1 : index
    %996 = arith.constant -1 : index
    %997 = arith.cmpi sle, %992, %993 : index
    %994 = arith.select %997, %995, %996 : index
    cf.br ^bb99(%992 : index)
    ^bb99(%998: index):
    %999 = arith.cmpi slt, %998, %993 : index
    %1000 = arith.cmpi sgt, %998, %993 : index
    %1001 = arith.select %997, %999, %1000 : i1
    cf.cond_br %1001, ^bb100(%998 : index), ^bb101(%998 : index)
    ^bb100(%1002: index):
      %1004 = arith.index_cast %1002 : index to i64
      %1005 = llvm.getelementptr %334[%1004] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %1003 = llvm.load %1005 : !llvm.ptr -> i64
      %1006 = arith.constant 0 : i32
      %1008 = arith.extsi %1006 : i32 to i64
      %1007 = arith.cmpi eq, %1003, %1008 : i64
      cf.cond_br %1007, ^bb102, ^bb103
      ^bb102:
        %1009 = arith.addi %1002, %994 : index
        cf.br ^bb99(%1009 : index)
      ^bb103:
        cf.br ^bb104
      ^bb104:
      %1010 = llvm.mlir.addressof @MOD : !llvm.ptr
      %1011 = llvm.load %1010 : !llvm.ptr -> i64
      %1013 = arith.index_cast %1002 : index to i32
      %1014 = arith.trunci %1011 : i64 to i32
      %1012 = arith.remsi %1013, %1014 : i32
      %1016 = arith.extsi %1012 : i32 to i64
      %1015 = arith.muli %1016, %1003 : i64
      %1017 = llvm.mlir.addressof @MOD : !llvm.ptr
      %1018 = llvm.load %1017 : !llvm.ptr -> i64
      %1019 = arith.remsi %1015, %1018 : i64
      %1020 = arith.index_cast %1002 : index to i64
      %1021 = llvm.mlir.constant(1 : i64) : i64
      %1022 = llvm.alloca %1021 x i64 : (i64) -> !llvm.ptr
      llvm.store %1020, %1022 : i64, !llvm.ptr
      cf.br ^bb105
      ^bb105:
      %1023 = llvm.load %1022 : !llvm.ptr -> i64
      %1024 = arith.cmpi sle, %1023, %231 : i64
      cf.cond_br %1024, ^bb106, ^bb107
      ^bb106:
        %1026 = llvm.load %1022 : !llvm.ptr -> i64
        %1027 = llvm.getelementptr %340[%1026] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %1025 = llvm.load %1027 : !llvm.ptr -> i64
        %1028 = arith.addi %1025, %1019 : i64
        %1029 = llvm.load %1022 : !llvm.ptr -> i64
        %1030 = llvm.getelementptr %340[%1029] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %1028, %1030 : i64, !llvm.ptr
        %1032 = llvm.load %1022 : !llvm.ptr -> i64
        %1033 = llvm.getelementptr %340[%1032] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %1031 = llvm.load %1033 : !llvm.ptr -> i64
        %1034 = llvm.mlir.addressof @MOD : !llvm.ptr
        %1035 = llvm.load %1034 : !llvm.ptr -> i64
        %1036 = arith.cmpi sge, %1031, %1035 : i64
        cf.cond_br %1036, ^bb108, ^bb109
        ^bb108:
          %1038 = llvm.load %1022 : !llvm.ptr -> i64
          %1039 = llvm.getelementptr %340[%1038] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %1037 = llvm.load %1039 : !llvm.ptr -> i64
          %1040 = llvm.mlir.addressof @MOD : !llvm.ptr
          %1041 = llvm.load %1040 : !llvm.ptr -> i64
          %1042 = arith.subi %1037, %1041 : i64
          %1043 = llvm.load %1022 : !llvm.ptr -> i64
          %1044 = llvm.getelementptr %340[%1043] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %1042, %1044 : i64, !llvm.ptr
          cf.br ^bb110
        ^bb109:
          cf.br ^bb110
        ^bb110:
        %1045 = llvm.load %1022 : !llvm.ptr -> i64
        %1047 = arith.trunci %1045 : i64 to i32
        %1048 = arith.index_cast %1002 : index to i32
        %1046 = arith.addi %1047, %1048 : i32
        %1049 = arith.extsi %1046 : i32 to i64
        llvm.store %1049, %1022 : i64, !llvm.ptr
        cf.br ^bb105
      ^bb107:
      %1050 = arith.addi %1002, %994 : index
      cf.br ^bb99(%1050 : index)
    ^bb101(%1051: index):
    %1052 = arith.constant 0 : i32
    %1053 = arith.constant 0 : i32
    %1054 = arith.extsi %1052 : i32 to i64
    %1055 = arith.extsi %1053 : i32 to i64
    %1056 = llvm.getelementptr %346[%1055] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %1054, %1056 : i64, !llvm.ptr
    %1057 = arith.constant 1 : i32
    %1058 = arith.constant 1 : i32
    %1060 = arith.extsi %1058 : i32 to i64
    %1059 = arith.addi %231, %1060 : i64
    %1061 = arith.index_cast %1057 : i32 to index
    %1062 = arith.index_cast %1059 : i32 to index
    %1064 = arith.constant 1 : index
    %1065 = arith.constant -1 : index
    %1066 = arith.cmpi sle, %1061, %1062 : index
    %1063 = arith.select %1066, %1064, %1065 : index
    cf.br ^bb111(%1061 : index)
    ^bb111(%1067: index):
    %1068 = arith.cmpi slt, %1067, %1062 : index
    %1069 = arith.cmpi sgt, %1067, %1062 : index
    %1070 = arith.select %1066, %1068, %1069 : i1
    cf.cond_br %1070, ^bb112(%1067 : index), ^bb113(%1067 : index)
    ^bb112(%1071: index):
      %1073 = llvm.mlir.addressof @MOD : !llvm.ptr
      %1074 = llvm.load %1073 : !llvm.ptr -> i64
      %1075 = arith.index_cast %1071 : index to i64
      %1072 = func.call @mod_inv(%1075, %1074) : (i64, i64) -> i64
      %1076 = arith.index_cast %1071 : index to i64
      %1077 = llvm.getelementptr %346[%1076] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %1072, %1077 : i64, !llvm.ptr
      %1078 = arith.addi %1071, %1063 : index
      cf.br ^bb111(%1078 : index)
    ^bb113(%1079: index):
    %1080 = arith.constant 1 : i32
    %1081 = arith.constant 0 : i32
    %1082 = arith.extsi %1080 : i32 to i64
    %1083 = arith.extsi %1081 : i32 to i64
    %1084 = llvm.getelementptr %352[%1083] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %1082, %1084 : i64, !llvm.ptr
    %1085 = arith.constant 1 : i32
    %1086 = arith.constant 1 : i32
    %1088 = arith.extsi %1086 : i32 to i64
    %1087 = arith.addi %231, %1088 : i64
    %1089 = arith.index_cast %1085 : i32 to index
    %1090 = arith.index_cast %1087 : i32 to index
    %1092 = arith.constant 1 : index
    %1093 = arith.constant -1 : index
    %1094 = arith.cmpi sle, %1089, %1090 : index
    %1091 = arith.select %1094, %1092, %1093 : index
    cf.br ^bb114(%1089 : index)
    ^bb114(%1095: index):
    %1096 = arith.cmpi slt, %1095, %1090 : index
    %1097 = arith.cmpi sgt, %1095, %1090 : index
    %1098 = arith.select %1094, %1096, %1097 : i1
    cf.cond_br %1098, ^bb115(%1095 : index), ^bb116(%1095 : index)
    ^bb115(%1099: index):
      %1100 = arith.constant 0 : i32
      %1101 = arith.extsi %1100 : i32 to i128
      %1102 = llvm.mlir.constant(1 : i64) : i64
      %1103 = llvm.alloca %1102 x i128 : (i64) -> !llvm.ptr
      llvm.store %1101, %1103 : i128, !llvm.ptr
      %1104 = arith.constant 1 : i32
      %1105 = arith.constant 1 : i32
      %1107 = arith.index_cast %1099 : index to i32
      %1106 = arith.addi %1107, %1105 : i32
      %1108 = arith.index_cast %1104 : i32 to index
      %1109 = arith.index_cast %1106 : i32 to index
      %1111 = arith.constant 1 : index
      %1112 = arith.constant -1 : index
      %1113 = arith.cmpi sle, %1108, %1109 : index
      %1110 = arith.select %1113, %1111, %1112 : index
      cf.br ^bb117(%1108 : index)
      ^bb117(%1114: index):
      %1115 = arith.cmpi slt, %1114, %1109 : index
      %1116 = arith.cmpi sgt, %1114, %1109 : index
      %1117 = arith.select %1113, %1115, %1116 : i1
      cf.cond_br %1117, ^bb118(%1114 : index), ^bb119(%1114 : index)
      ^bb118(%1118: index):
        %1119 = llvm.load %1103 : !llvm.ptr -> i128
        %1121 = arith.index_cast %1118 : index to i64
        %1122 = llvm.getelementptr %340[%1121] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %1120 = llvm.load %1122 : !llvm.ptr -> i64
        %1123 = arith.extsi %1120 : i64 to i128
        %1125 = arith.subi %1099, %1118 : index
        %1126 = arith.index_cast %1125 : index to i64
        %1127 = llvm.getelementptr %352[%1126] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %1124 = llvm.load %1127 : !llvm.ptr -> i64
        %1128 = arith.extsi %1124 : i64 to i128
        %1130 = arith.trunci %1123 : i128 to i64
        %1131 = arith.trunci %1128 : i128 to i64
        %1129 = arith.muli %1130, %1131 : i64
        %1133 = arith.trunci %1119 : i128 to i64
        %1132 = arith.addi %1133, %1129 : i64
        %1134 = arith.extsi %1132 : i64 to i128
        llvm.store %1134, %1103 : i128, !llvm.ptr
        %1135 = llvm.load %1103 : !llvm.ptr -> i128
        %1136 = llvm.mlir.addressof @MOD : !llvm.ptr
        %1137 = llvm.load %1136 : !llvm.ptr -> i64
        %1138 = arith.extsi %1137 : i64 to i128
        %1140 = arith.trunci %1135 : i128 to i64
        %1141 = arith.trunci %1138 : i128 to i64
        %1139 = arith.remsi %1140, %1141 : i64
        %1142 = arith.extsi %1139 : i64 to i128
        llvm.store %1142, %1103 : i128, !llvm.ptr
        %1143 = arith.addi %1118, %1110 : index
        cf.br ^bb117(%1143 : index)
      ^bb119(%1144: index):
      %1145 = llvm.load %1103 : !llvm.ptr -> i128
      %1146 = llvm.mlir.addressof @MOD : !llvm.ptr
      %1147 = llvm.load %1146 : !llvm.ptr -> i64
      %1148 = arith.extsi %1147 : i64 to i128
      %1150 = arith.trunci %1145 : i128 to i64
      %1151 = arith.trunci %1148 : i128 to i64
      %1149 = arith.remsi %1150, %1151 : i64
      %1153 = arith.index_cast %1099 : index to i64
      %1154 = llvm.getelementptr %346[%1153] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %1152 = llvm.load %1154 : !llvm.ptr -> i64
      %1155 = arith.muli %1149, %1152 : i64
      %1156 = llvm.mlir.addressof @MOD : !llvm.ptr
      %1157 = llvm.load %1156 : !llvm.ptr -> i64
      %1158 = arith.remsi %1155, %1157 : i64
      %1159 = arith.index_cast %1099 : index to i64
      %1160 = llvm.getelementptr %352[%1159] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %1158, %1160 : i64, !llvm.ptr
      %1161 = arith.addi %1099, %1091 : index
      cf.br ^bb114(%1161 : index)
    ^bb116(%1162: index):
    %1163 = llvm.mlir.addressof @str_0 : !llvm.ptr
    %1165 = llvm.getelementptr %352[%231] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    %1164 = llvm.load %1165 : !llvm.ptr -> i64
    %1166 = llvm.call @printf(%1163, %1164) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i64) -> i32
    func.call @free(%358) : (!llvm.ptr) -> ()
    func.call @free(%352) : (!llvm.ptr) -> ()
    func.call @free(%346) : (!llvm.ptr) -> ()
    func.call @free(%340) : (!llvm.ptr) -> ()
    func.call @free(%334) : (!llvm.ptr) -> ()
    func.call @free(%328) : (!llvm.ptr) -> ()
    func.call @free(%322) : (!llvm.ptr) -> ()
    func.call @free(%316) : (!llvm.ptr) -> ()
    func.call @free(%310) : (!llvm.ptr) -> ()
    func.call @free(%304) : (!llvm.ptr) -> ()
    func.call @free(%298) : (!llvm.ptr) -> ()
    func.call @free(%292) : (!llvm.ptr) -> ()
    func.call @free(%286) : (!llvm.ptr) -> ()
    func.call @free(%280) : (!llvm.ptr) -> ()
    func.call @free(%274) : (!llvm.ptr) -> ()
    func.call @free(%268) : (!llvm.ptr) -> ()
    func.call @free(%262) : (!llvm.ptr) -> ()
    func.call @free(%256) : (!llvm.ptr) -> ()
    func.call @free(%250) : (!llvm.ptr) -> ()
    func.call @free(%244) : (!llvm.ptr) -> ()
    func.call @free(%238) : (!llvm.ptr) -> ()
    func.call @free(%232) : (!llvm.ptr) -> ()
    %1189 = arith.constant 0 : i32
    func.return %1189 : i32
  }
}