Problem 674

Solving I-equations: sum of least simultaneous values over all pairs of expressions in data/p674.txt, last nine digits. I(x,y) = (1+x+y)^2 + y - x is injective on N^2 (value ranges for consecutive argument sums are disjoint) and strictly exceeds both arguments, so e1 = e2 reduces to syntactic unification: I nodes match argument-wise, variables bind via union-find, and any binding cycle (occurs check) means no solution. I is increasing in both arguments, so the least simultaneous value is the unified expression evaluated with all free variables set to 0, mod 10^9. Expressions are hash-consed; unification memoises visited node pairs and evaluation memoises per pair via epoch stamps.

Answer416678753
Output416678753
StatusPASS
Native helperno
Runtime580 ms
Peak memory23168 KB
Time complexityO(n log n) (estimated)
Space complexityO(n^2) (estimated)

Performance comparison

MetricOur solutionBest known
Time complexityO(n log n)O(n log n)
Space complexityO(n^2)O(n)
ApproachFlow solutionModular DP or matrix exponentiation
VerdictOptimal

Flow source

# Project Euler 674
# Solving I-equations: sum of least simultaneous values over all pairs of
# expressions in data/p674.txt, last nine digits.
#
# I(x,y) = (1+x+y)^2 + y - x is injective on N^2 (value ranges for
# consecutive argument sums are disjoint) and strictly exceeds both
# arguments, so e1 = e2 reduces to syntactic unification: I nodes match
# argument-wise, variables bind via union-find, and any binding cycle
# (occurs check) means no solution.  I is increasing in both arguments,
# so the least simultaneous value is the unified expression evaluated
# with all free variables set to 0, mod 10^9.
# Expressions are hash-consed; unification memoises visited node pairs
# and evaluation memoises per pair via epoch stamps.

extern {
    function fopen(path: string, mode: string) -> ptr<void>
    function fgetc(f: ptr<void>) -> i32
    function fclose(f: ptr<void>) -> i32
    function calloc(n: i64, size: i64) -> ptr<void>
    function free(p: ptr<void>) -> void
}

const MODV: i64 = 1000000000
const NCAP: i64 = 40000
const HB: i64 = 131072         # node hash slots (power of two)
const VCAP: i64 = 19684        # base-27 packed variable ids
const SB: i64 = 1048576        # seen-set slots (power of two)

# node arrays: typ (0 = var, 1 = I), le (var id or left node), ri
# ctx layout (single i64 buffer offsets documented in main)

function node_get(typ: ptr<i64>, le: ptr<i64>, ri: ptr<i64>,
                  hkey: ptr<i64>, hval: ptr<i64>, ncnt: ptr<i64>,
                  t: i64, a: i64, b: i64) -> i64 {
    let key: i64 = (t * 40009 + a) * 40009 + b + 1
    let mut h: i64 = key % HB
    if h < 0 {
        h = h + HB
    }
    while hkey[h] != 0 {
        if hkey[h] == key {
            return hval[h]
        }
        h = (h + 1) & (HB - 1)
    }
    let id: i64 = ncnt[0]
    ncnt[0] = id + 1
    typ[id] = t
    le[id] = a
    ri[id] = b
    hkey[h] = key
    hval[h] = id
    return id
}

function uf_find(parent: ptr<i64>, pep: ptr<i64>, ep: i64, v0: i64) -> i64 {
    let mut v: i64 = v0
    while pep[v] == ep && parent[v] != v {
        v = parent[v]
    }
    return v
}

function unify(typ: ptr<i64>, le: ptr<i64>, ri: ptr<i64>,
               parent: ptr<i64>, pep: ptr<i64>,
               bnd: ptr<i64>, bep: ptr<i64>,
               skey: ptr<i64>, sep: ptr<i64>, ep: i64,
               a: i64, b: i64) -> i64 {
    if a == b {
        return 1
    }
    if typ[a] == 1 && typ[b] == 1 {
        # seen check on (a, b)
        let key: i64 = a * NCAP + b + 1
        let mut h: i64 = key % SB
        while sep[h] == ep {
            if skey[h] == key {
                return 1
            }
            h = (h + 1) & (SB - 1)
        }
        skey[h] = key
        sep[h] = ep
        if unify(typ, le, ri, parent, pep, bnd, bep, skey, sep, ep, le[a], le[b]) == 0 {
            return 0
        }
        return unify(typ, le, ri, parent, pep, bnd, bep, skey, sep, ep, ri[a], ri[b])
    }
    if typ[a] == 0 {
        let ra: i64 = uf_find(parent, pep, ep, le[a])
        if bep[ra] == ep {
            return unify(typ, le, ri, parent, pep, bnd, bep, skey, sep, ep, bnd[ra], b)
        }
        if typ[b] == 0 {
            let rb: i64 = uf_find(parent, pep, ep, le[b])
            if ra == rb {
                return 1
            }
            if bep[rb] == ep {
                # bind a-side var to b's binding (re-run with node)
                return unify(typ, le, ri, parent, pep, bnd, bep, skey, sep, ep, a, bnd[rb])
            }
            parent[ra] = rb
            pep[ra] = ep
            parent[rb] = rb
            pep[rb] = ep
            return 1
        }
        bnd[ra] = b
        bep[ra] = ep
        return 1
    }
    # a is I, b is var
    return unify(typ, le, ri, parent, pep, bnd, bep, skey, sep, ep, b, a)
}

# evaluate node with free vars = 0; est: 0 untouched, 1 in progress, 2 done
# returns value, or -1 if a binding cycle was hit (no solution)
function ev(typ: ptr<i64>, le: ptr<i64>, ri: ptr<i64>,
            parent: ptr<i64>, pep: ptr<i64>,
            bnd: ptr<i64>, bep: ptr<i64>,
            memo: ptr<i64>, est: ptr<i64>, eep: ptr<i64>, ep: i64,
            n: i64) -> i64 {
    if eep[n] == ep && est[n] == 2 {
        return memo[n]
    }
    if eep[n] == ep && est[n] == 1 {
        return 0 - 1
    }
    eep[n] = ep
    est[n] = 1
    let mut v: i64 = 0
    if typ[n] == 0 {
        let r: i64 = uf_find(parent, pep, ep, le[n])
        if bep[r] == ep {
            v = ev(typ, le, ri, parent, pep, bnd, bep, memo, est, eep, ep, bnd[r])
            if v < 0 {
                return 0 - 1
            }
        } else {
            v = 0
        }
    } else {
        let x: i64 = ev(typ, le, ri, parent, pep, bnd, bep, memo, est, eep, ep, le[n])
        if x < 0 {
            return 0 - 1
        }
        let y: i64 = ev(typ, le, ri, parent, pep, bnd, bep, memo, est, eep, ep, ri[n])
        if y < 0 {
            return 0 - 1
        }
        let s: i64 = (1 + x + y) % MODV
        v = ((s * s + y - x) % MODV + MODV) % MODV
    }
    est[n] = 2
    memo[n] = v
    return v
}

function main() -> i32 {
    let typ: ptr<i64> = calloc(NCAP, 8)
    let le: ptr<i64> = calloc(NCAP, 8)
    let ri: ptr<i64> = calloc(NCAP, 8)
    let hkey: ptr<i64> = calloc(HB, 8)
    let hval: ptr<i64> = calloc(HB, 8)
    let ncnt: ptr<i64> = calloc(1, 8)

    let roots: ptr<i64> = calloc(200, 8)
    let mut nexpr: i64 = 0

    # parse file with an explicit stack machine (avoids parser recursion):
    # stack entries: node ids or -1 marker for pending 'I('
    let stack: ptr<i64> = calloc(20000, 8)
    let mut sp: i64 = 0
    let f: ptr<void> = fopen("data/p674.txt", "r")
    if f == 0 {
        printf("failed to read data/p674.txt\n")
        return 1
    }
    let mut vid: i64 = 0
    let mut inv: i64 = 0
    let mut c: i32 = fgetc(f)
    while c >= 0 {
        let ch: i64 = c as i64
        if ch >= 97 && ch <= 122 {
            vid = vid * 27 + (ch - 96)
            inv = 1
        } else {
            if inv == 1 {
                stack[sp] = node_get(typ, le, ri, hkey, hval, ncnt, 0, vid, 0)
                sp = sp + 1
                vid = 0
                inv = 0
            }
            if ch == 73 {          # 'I'
                stack[sp] = 0 - 1  # marker
                sp = sp + 1
            }
            if ch == 41 {          # ')' -> combine top two nodes under marker
                let b: i64 = stack[sp - 1]
                let a: i64 = stack[sp - 2]
                sp = sp - 3        # pop b, a, marker
                stack[sp] = node_get(typ, le, ri, hkey, hval, ncnt, 1, a, b)
                sp = sp + 1
            }
            if ch == 10 {          # newline: expression complete
                if sp > 0 {
                    roots[nexpr] = stack[sp - 1]
                    nexpr = nexpr + 1
                    sp = 0
                }
            }
        }
        c = fgetc(f)
    }
    if inv == 1 {
        stack[sp] = node_get(typ, le, ri, hkey, hval, ncnt, 0, vid, 0)
        sp = sp + 1
    }
    if sp > 0 {
        roots[nexpr] = stack[sp - 1]
        nexpr = nexpr + 1
    }
    fclose(f)

    let parent: ptr<i64> = calloc(VCAP, 8)
    let pep: ptr<i64> = calloc(VCAP, 8)
    let bnd: ptr<i64> = calloc(VCAP, 8)
    let bep: ptr<i64> = calloc(VCAP, 8)
    let skey: ptr<i64> = calloc(SB, 8)
    let sepp: ptr<i64> = calloc(SB, 8)
    let memo: ptr<i64> = calloc(NCAP, 8)
    let est: ptr<i64> = calloc(NCAP, 8)
    let eep: ptr<i64> = calloc(NCAP, 8)

    let mut total: i64 = 0
    let mut ep: i64 = 0
    let mut i: i64 = 0
    while i < nexpr {
        let mut j: i64 = i + 1
        while j < nexpr {
            ep = ep + 1
            if unify(typ, le, ri, parent, pep, bnd, bep, skey, sepp, ep,
                     roots[i], roots[j]) == 1 {
                let v: i64 = ev(typ, le, ri, parent, pep, bnd, bep,
                                memo, est, eep, ep, roots[i])
                if v >= 0 {
                    total = (total + v) % MODV
                }
            }
            j = j + 1
        }
        i = i + 1
    }
    printf("%lld\n", total)

    free(typ)
    free(le)
    free(ri)
    free(hkey)
    free(hval)
    free(ncnt)
    free(roots)
    free(stack)
    free(parent)
    free(pep)
    free(bnd)
    free(bep)
    free(skey)
    free(sepp)
    free(memo)
    free(est)
    free(eep)
    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 node_get_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_i64_i64_i64(int64_t* typ, int64_t* le, int64_t* ri, int64_t* hkey, int64_t* hval, int64_t* ncnt, int64_t t, int64_t a, int64_t b);
int64_t uf_find_ptr_i64_ptr_i64_i64_i64(int64_t* parent, int64_t* pep, int64_t ep, int64_t v0);
int64_t unify_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_i64_i64_i64(int64_t* typ, int64_t* le, int64_t* ri, int64_t* parent, int64_t* pep, int64_t* bnd, int64_t* bep, int64_t* skey, int64_t* sep, int64_t ep, int64_t a, int64_t b);
int64_t ev_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_i64_i64(int64_t* typ, int64_t* le, int64_t* ri, int64_t* parent, int64_t* pep, int64_t* bnd, int64_t* bep, int64_t* memo, int64_t* est, int64_t* eep, int64_t ep, int64_t n);
int32_t main(void);

static const int64_t MODV = 1000000000;
static const int64_t NCAP = 40000;
static const int64_t HB = 131072;
static const int64_t VCAP = 19684;
static const int64_t SB = 1048576;






int64_t node_get_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_i64_i64_i64(int64_t* typ, int64_t* le, int64_t* ri, int64_t* hkey, int64_t* hval, int64_t* ncnt, int64_t t, int64_t a, int64_t b) {
    int64_t key = (((((t * 40009) + a) * 40009) + b) + 1);
    int64_t h = FLOW_CHECKED_MOD((key), (HB));
    if (h < 0) {
        h = (h + HB);
    }
    while (hkey[h] != 0) {
        if (hkey[h] == key) {
            return hval[h];
        }
        h = ((h + 1) & (HB - 1));
    }
    int64_t id = ncnt[0];
    ncnt[0] = (id + 1);
    typ[id] = t;
    le[id] = a;
    ri[id] = b;
    hkey[h] = key;
    hval[h] = id;
    return id;
}

int64_t uf_find_ptr_i64_ptr_i64_i64_i64(int64_t* parent, int64_t* pep, int64_t ep, int64_t v0) {
    int64_t v = v0;
    while ((pep[v] == ep && parent[v] != v)) {
        v = parent[v];
    }
    return v;
}

int64_t unify_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_i64_i64_i64(int64_t* typ, int64_t* le, int64_t* ri, int64_t* parent, int64_t* pep, int64_t* bnd, int64_t* bep, int64_t* skey, int64_t* sep, int64_t ep, int64_t a, int64_t b) {
    for (;;) {
        if (a == b) {
            return 1;
        }
        if ((typ[a] == 1 && typ[b] == 1)) {
            int64_t key = (((a * NCAP) + b) + 1);
            int64_t h = FLOW_CHECKED_MOD((key), (SB));
            while (sep[h] == ep) {
                if (skey[h] == key) {
                    return 1;
                }
                h = ((h + 1) & (SB - 1));
            }
            skey[h] = key;
            sep[h] = ep;
            if (unify_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_i64_i64_i64(typ, le, ri, parent, pep, bnd, bep, skey, sep, ep, le[a], le[b]) == 0) {
                return 0;
            }
            int64_t* _tco_0_31008 = typ;
            int64_t* _tco_1_31008 = le;
            int64_t* _tco_2_31008 = ri;
            int64_t* _tco_3_31008 = parent;
            int64_t* _tco_4_31008 = pep;
            int64_t* _tco_5_31008 = bnd;
            int64_t* _tco_6_31008 = bep;
            int64_t* _tco_7_31008 = skey;
            int64_t* _tco_8_31008 = sep;
            int64_t _tco_9_31008 = ep;
            int64_t _tco_10_31008 = ri[a];
            int64_t _tco_11_31008 = ri[b];
            typ = _tco_0_31008;
            le = _tco_1_31008;
            ri = _tco_2_31008;
            parent = _tco_3_31008;
            pep = _tco_4_31008;
            bnd = _tco_5_31008;
            bep = _tco_6_31008;
            skey = _tco_7_31008;
            sep = _tco_8_31008;
            ep = _tco_9_31008;
            a = _tco_10_31008;
            b = _tco_11_31008;
            continue;
        }
        if (typ[a] == 0) {
            int64_t ra = uf_find_ptr_i64_ptr_i64_i64_i64(parent, pep, ep, le[a]);
            if (bep[ra] == ep) {
                int64_t* _tco_0_31872 = typ;
                int64_t* _tco_1_31872 = le;
                int64_t* _tco_2_31872 = ri;
                int64_t* _tco_3_31872 = parent;
                int64_t* _tco_4_31872 = pep;
                int64_t* _tco_5_31872 = bnd;
                int64_t* _tco_6_31872 = bep;
                int64_t* _tco_7_31872 = skey;
                int64_t* _tco_8_31872 = sep;
                int64_t _tco_9_31872 = ep;
                int64_t _tco_10_31872 = bnd[ra];
                int64_t _tco_11_31872 = b;
                typ = _tco_0_31872;
                le = _tco_1_31872;
                ri = _tco_2_31872;
                parent = _tco_3_31872;
                pep = _tco_4_31872;
                bnd = _tco_5_31872;
                bep = _tco_6_31872;
                skey = _tco_7_31872;
                sep = _tco_8_31872;
                ep = _tco_9_31872;
                a = _tco_10_31872;
                b = _tco_11_31872;
                continue;
            }
            if (typ[b] == 0) {
                int64_t rb = uf_find_ptr_i64_ptr_i64_i64_i64(parent, pep, ep, le[b]);
                if (ra == rb) {
                    return 1;
                }
                if (bep[rb] == ep) {
                    int64_t* _tco_0_49376 = typ;
                    int64_t* _tco_1_49376 = le;
                    int64_t* _tco_2_49376 = ri;
                    int64_t* _tco_3_49376 = parent;
                    int64_t* _tco_4_49376 = pep;
                    int64_t* _tco_5_49376 = bnd;
                    int64_t* _tco_6_49376 = bep;
                    int64_t* _tco_7_49376 = skey;
                    int64_t* _tco_8_49376 = sep;
                    int64_t _tco_9_49376 = ep;
                    int64_t _tco_10_49376 = a;
                    int64_t _tco_11_49376 = bnd[rb];
                    typ = _tco_0_49376;
                    le = _tco_1_49376;
                    ri = _tco_2_49376;
                    parent = _tco_3_49376;
                    pep = _tco_4_49376;
                    bnd = _tco_5_49376;
                    bep = _tco_6_49376;
                    skey = _tco_7_49376;
                    sep = _tco_8_49376;
                    ep = _tco_9_49376;
                    a = _tco_10_49376;
                    b = _tco_11_49376;
                    continue;
                }
                parent[ra] = rb;
                pep[ra] = ep;
                parent[rb] = rb;
                pep[rb] = ep;
                return 1;
            }
            bnd[ra] = b;
            bep[ra] = ep;
            return 1;
        }
        int64_t* _tco_0_50672 = typ;
        int64_t* _tco_1_50672 = le;
        int64_t* _tco_2_50672 = ri;
        int64_t* _tco_3_50672 = parent;
        int64_t* _tco_4_50672 = pep;
        int64_t* _tco_5_50672 = bnd;
        int64_t* _tco_6_50672 = bep;
        int64_t* _tco_7_50672 = skey;
        int64_t* _tco_8_50672 = sep;
        int64_t _tco_9_50672 = ep;
        int64_t _tco_10_50672 = b;
        int64_t _tco_11_50672 = a;
        typ = _tco_0_50672;
        le = _tco_1_50672;
        ri = _tco_2_50672;
        parent = _tco_3_50672;
        pep = _tco_4_50672;
        bnd = _tco_5_50672;
        bep = _tco_6_50672;
        skey = _tco_7_50672;
        sep = _tco_8_50672;
        ep = _tco_9_50672;
        a = _tco_10_50672;
        b = _tco_11_50672;
        continue;
    }
    return 0;
}

int64_t ev_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_i64_i64(int64_t* typ, int64_t* le, int64_t* ri, int64_t* parent, int64_t* pep, int64_t* bnd, int64_t* bep, int64_t* memo, int64_t* est, int64_t* eep, int64_t ep, int64_t n) {
    if ((eep[n] == ep && est[n] == 2)) {
        return memo[n];
    }
    if ((eep[n] == ep && est[n] == 1)) {
        return (0 - 1);
    }
    eep[n] = ep;
    est[n] = 1;
    int64_t v = 0;
    if (typ[n] == 0) {
        int64_t r = uf_find_ptr_i64_ptr_i64_i64_i64(parent, pep, ep, le[n]);
        if (bep[r] == ep) {
            v = ev_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_i64_i64(typ, le, ri, parent, pep, bnd, bep, memo, est, eep, ep, bnd[r]);
            if (v < 0) {
                return (0 - 1);
            }
        } else {
            v = 0;
        }
    } else {
        int64_t x = ev_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_i64_i64(typ, le, ri, parent, pep, bnd, bep, memo, est, eep, ep, le[n]);
        if (x < 0) {
            return (0 - 1);
        }
        int64_t y = ev_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_i64_i64(typ, le, ri, parent, pep, bnd, bep, memo, est, eep, ep, ri[n]);
        if (y < 0) {
            return (0 - 1);
        }
        int64_t s = FLOW_CHECKED_MOD((((1 + x) + y)), (MODV));
        v = FLOW_CHECKED_MOD(((FLOW_CHECKED_MOD(((((s * s) + y) - x)), (MODV)) + MODV)), (MODV));
    }
    est[n] = 2;
    memo[n] = v;
    return v;
}

int32_t main(void) {
    int64_t* typ = (int64_t*)(calloc(NCAP, 8));
    int64_t* le = (int64_t*)(calloc(NCAP, 8));
    int64_t* ri = (int64_t*)(calloc(NCAP, 8));
    int64_t* hkey = (int64_t*)(calloc(HB, 8));
    int64_t* hval = (int64_t*)(calloc(HB, 8));
    int64_t* ncnt = (int64_t*)(calloc(1, 8));
    int64_t* roots = (int64_t*)(calloc(200, 8));
    int64_t nexpr = 0;
    int64_t* stack = (int64_t*)(calloc(20000, 8));
    int64_t sp = 0;
    void* f = (void*)(fopen("data/p674.txt", "r"));
    if (f == 0) {
        printf("failed to read data/p674.txt\n");
        return 1;
    }
    int64_t vid = 0;
    int64_t inv = 0;
    int32_t c = fgetc(f);
    while (c >= 0) {
        int64_t ch = ((int64_t)(c));
        if ((ch >= 97 && ch <= 122)) {
            vid = ((vid * 27) + (ch - 96));
            inv = 1;
        } else {
            if (inv == 1) {
                stack[sp] = node_get_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_i64_i64_i64(typ, le, ri, hkey, hval, ncnt, 0, vid, 0);
                sp = (sp + 1);
                vid = 0;
                inv = 0;
            }
            if (ch == 73) {
                stack[sp] = (0 - 1);
                sp = (sp + 1);
            }
            if (ch == 41) {
                int64_t b = stack[(sp - 1)];
                int64_t a = stack[(sp - 2)];
                sp = (sp - 3);
                stack[sp] = node_get_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_i64_i64_i64(typ, le, ri, hkey, hval, ncnt, 1, a, b);
                sp = (sp + 1);
            }
            if (ch == 10) {
                if (sp > 0) {
                    roots[nexpr] = stack[(sp - 1)];
                    nexpr = (nexpr + 1);
                    sp = 0;
                }
            }
        }
        c = fgetc(f);
    }
    if (inv == 1) {
        stack[sp] = node_get_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_i64_i64_i64(typ, le, ri, hkey, hval, ncnt, 0, vid, 0);
        sp = (sp + 1);
    }
    if (sp > 0) {
        roots[nexpr] = stack[(sp - 1)];
        nexpr = (nexpr + 1);
    }
    fclose(f);
    int64_t* parent = (int64_t*)(calloc(VCAP, 8));
    int64_t* pep = (int64_t*)(calloc(VCAP, 8));
    int64_t* bnd = (int64_t*)(calloc(VCAP, 8));
    int64_t* bep = (int64_t*)(calloc(VCAP, 8));
    int64_t* skey = (int64_t*)(calloc(SB, 8));
    int64_t* sepp = (int64_t*)(calloc(SB, 8));
    int64_t* memo = (int64_t*)(calloc(NCAP, 8));
    int64_t* est = (int64_t*)(calloc(NCAP, 8));
    int64_t* eep = (int64_t*)(calloc(NCAP, 8));
    int64_t total = 0;
    int64_t ep = 0;
    int64_t i = 0;
    while (i < nexpr) {
        int64_t j = (i + 1);
        while (j < nexpr) {
            ep = (ep + 1);
            if (unify_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_i64_i64_i64(typ, le, ri, parent, pep, bnd, bep, skey, sepp, ep, roots[i], roots[j]) == 1) {
                int64_t v = ev_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_ptr_i64_i64_i64(typ, le, ri, parent, pep, bnd, bep, memo, est, eep, ep, roots[i]);
                if (v >= 0) {
                    total = FLOW_CHECKED_MOD(((total + v)), (MODV));
                }
            }
            j = (j + 1);
        }
        i = (i + 1);
    }
    printf("%lld\n", total);
    free(typ);
    free(le);
    free(ri);
    free(hkey);
    free(hval);
    free(ncnt);
    free(roots);
    free(stack);
    free(parent);
    free(pep);
    free(bnd);
    free(bep);
    free(skey);
    free(sepp);
    free(memo);
    free(est);
    free(eep);
    return 0;
}

Generated MLIR

module {
  llvm.func @printf(!llvm.ptr, ...) -> i32
  llvm.mlir.global internal constant @str_0("data/p674.txt\00") {addr_space = 0 : i32} : !llvm.array<14 x i8>
  llvm.mlir.global internal constant @str_1("r\00") {addr_space = 0 : i32} : !llvm.array<2 x i8>
  llvm.mlir.global internal constant @str_2("failed to read data/p674.txt\n\00") {addr_space = 0 : i32} : !llvm.array<30 x i8>
  llvm.mlir.global internal constant @str_3("%lld\n\00") {addr_space = 0 : i32} : !llvm.array<6 x i8>
  func.func private @fopen(!llvm.ptr, !llvm.ptr) -> !llvm.ptr
  func.func private @fgetc(!llvm.ptr) -> i32
  func.func private @fclose(!llvm.ptr) -> i32
  func.func private @calloc(i64, i64) -> !llvm.ptr
  func.func private @free(!llvm.ptr) -> ()
  // Constant: MODV
  llvm.mlir.global internal constant @MODV(1000000000 : i64) : i64
  // Constant: NCAP
  llvm.mlir.global internal constant @NCAP(40000 : i64) : i64
  // Constant: HB
  llvm.mlir.global internal constant @HB(131072 : i64) : i64
  // Constant: VCAP
  llvm.mlir.global internal constant @VCAP(19684 : i64) : i64
  // Constant: SB
  llvm.mlir.global internal constant @SB(1048576 : i64) : i64
  func.func @node_get(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr, %arg3: !llvm.ptr, %arg4: !llvm.ptr, %arg5: !llvm.ptr, %arg6: i64, %arg7: i64, %arg8: i64) -> i64 {
    %0 = arith.constant 40009 : i32
    %2 = arith.extsi %0 : i32 to i64
    %1 = arith.muli %arg6, %2 : i64
    %3 = arith.addi %1, %arg7 : i64
    %4 = arith.constant 40009 : i32
    %6 = arith.extsi %4 : i32 to i64
    %5 = arith.muli %3, %6 : i64
    %7 = arith.addi %5, %arg8 : i64
    %8 = arith.constant 1 : i32
    %10 = arith.extsi %8 : i32 to i64
    %9 = arith.addi %7, %10 : i64
    %11 = llvm.mlir.addressof @HB : !llvm.ptr
    %12 = llvm.load %11 : !llvm.ptr -> i64
    %13 = arith.remsi %9, %12 : i64
    %14 = llvm.mlir.constant(1 : i64) : i64
    %15 = llvm.alloca %14 x i64 : (i64) -> !llvm.ptr
    llvm.store %13, %15 : i64, !llvm.ptr
    %16 = llvm.load %15 : !llvm.ptr -> i64
    %17 = arith.constant 0 : i32
    %19 = arith.extsi %17 : i32 to i64
    %18 = arith.cmpi slt, %16, %19 : i64
    cf.cond_br %18, ^bb0, ^bb1
    ^bb0:
      %20 = llvm.load %15 : !llvm.ptr -> i64
      %21 = llvm.mlir.addressof @HB : !llvm.ptr
      %22 = llvm.load %21 : !llvm.ptr -> i64
      %23 = arith.addi %20, %22 : i64
      llvm.store %23, %15 : i64, !llvm.ptr
      cf.br ^bb2
    ^bb1:
      cf.br ^bb2
    ^bb2:
    cf.br ^bb3
    ^bb3:
    %25 = llvm.load %15 : !llvm.ptr -> i64
    %26 = llvm.getelementptr %arg3[%25] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    %24 = llvm.load %26 : !llvm.ptr -> i64
    %27 = arith.constant 0 : i32
    %29 = arith.extsi %27 : i32 to i64
    %28 = arith.cmpi ne, %24, %29 : i64
    cf.cond_br %28, ^bb4, ^bb5
    ^bb4:
      %31 = llvm.load %15 : !llvm.ptr -> i64
      %32 = llvm.getelementptr %arg3[%31] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %30 = llvm.load %32 : !llvm.ptr -> i64
      %33 = arith.cmpi eq, %30, %9 : i64
      cf.cond_br %33, ^bb6, ^bb7
      ^bb6:
        %35 = llvm.load %15 : !llvm.ptr -> i64
        %36 = llvm.getelementptr %arg4[%35] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %34 = llvm.load %36 : !llvm.ptr -> i64
        func.return %34 : i64
      ^bb7:
        cf.br ^bb8
      ^bb8:
      %37 = llvm.load %15 : !llvm.ptr -> i64
      %38 = arith.constant 1 : i32
      %40 = arith.extsi %38 : i32 to i64
      %39 = arith.addi %37, %40 : i64
      %41 = llvm.mlir.addressof @HB : !llvm.ptr
      %42 = llvm.load %41 : !llvm.ptr -> i64
      %43 = arith.constant 1 : i32
      %45 = arith.extsi %43 : i32 to i64
      %44 = arith.subi %42, %45 : i64
      %46 = arith.andi %39, %44 : i64
      llvm.store %46, %15 : i64, !llvm.ptr
      cf.br ^bb3
    ^bb5:
    %48 = arith.constant 0 : i32
    %49 = arith.extsi %48 : i32 to i64
    %50 = llvm.getelementptr %arg5[%49] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    %47 = llvm.load %50 : !llvm.ptr -> i64
    %51 = arith.constant 1 : i32
    %53 = arith.extsi %51 : i32 to i64
    %52 = arith.addi %47, %53 : i64
    %54 = arith.constant 0 : i32
    %55 = arith.extsi %54 : i32 to i64
    %56 = llvm.getelementptr %arg5[%55] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %52, %56 : i64, !llvm.ptr
    %57 = llvm.getelementptr %arg0[%47] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %arg6, %57 : i64, !llvm.ptr
    %58 = llvm.getelementptr %arg1[%47] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %arg7, %58 : i64, !llvm.ptr
    %59 = llvm.getelementptr %arg2[%47] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %arg8, %59 : i64, !llvm.ptr
    %60 = llvm.load %15 : !llvm.ptr -> i64
    %61 = llvm.getelementptr %arg3[%60] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %9, %61 : i64, !llvm.ptr
    %62 = llvm.load %15 : !llvm.ptr -> i64
    %63 = llvm.getelementptr %arg4[%62] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %47, %63 : i64, !llvm.ptr
    func.return %47 : i64
  }
  func.func @uf_find(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: i64, %arg3: i64) -> i64 {
    %64 = llvm.mlir.constant(1 : i64) : i64
    %65 = llvm.alloca %64 x i64 : (i64) -> !llvm.ptr
    llvm.store %arg3, %65 : i64, !llvm.ptr
    cf.br ^bb9
    ^bb9:
    %67 = llvm.load %65 : !llvm.ptr -> i64
    %68 = llvm.getelementptr %arg1[%67] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    %66 = llvm.load %68 : !llvm.ptr -> i64
    %69 = arith.cmpi eq, %66, %arg2 : i64
    %70 = scf.if %69 -> (i1) {
      %72 = llvm.load %65 : !llvm.ptr -> i64
      %73 = llvm.getelementptr %arg0[%72] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %71 = llvm.load %73 : !llvm.ptr -> i64
      %74 = llvm.load %65 : !llvm.ptr -> i64
      %75 = arith.cmpi ne, %71, %74 : i64
      scf.yield %75 : i1
    } else {
      %76 = arith.constant false
      scf.yield %76 : i1
    }
    cf.cond_br %70, ^bb10, ^bb11
    ^bb10:
      %78 = llvm.load %65 : !llvm.ptr -> i64
      %79 = llvm.getelementptr %arg0[%78] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %77 = llvm.load %79 : !llvm.ptr -> i64
      llvm.store %77, %65 : i64, !llvm.ptr
      cf.br ^bb9
    ^bb11:
    %80 = llvm.load %65 : !llvm.ptr -> i64
    func.return %80 : i64
  }
  func.func @unify(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr, %arg3: !llvm.ptr, %arg4: !llvm.ptr, %arg5: !llvm.ptr, %arg6: !llvm.ptr, %arg7: !llvm.ptr, %arg8: !llvm.ptr, %arg9: i64, %arg10: i64, %arg11: i64) -> i64 {
    %81 = arith.cmpi eq, %arg10, %arg11 : i64
    cf.cond_br %81, ^bb12, ^bb13
    ^bb12:
      %82 = arith.constant 1 : i32
      %83 = arith.extsi %82 : i32 to i64
      func.return %83 : i64
    ^bb13:
      cf.br ^bb14
    ^bb14:
    %85 = llvm.getelementptr %arg0[%arg10] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    %84 = llvm.load %85 : !llvm.ptr -> i64
    %86 = arith.constant 1 : i32
    %88 = arith.extsi %86 : i32 to i64
    %87 = arith.cmpi eq, %84, %88 : i64
    %89 = scf.if %87 -> (i1) {
      %91 = llvm.getelementptr %arg0[%arg11] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %90 = llvm.load %91 : !llvm.ptr -> i64
      %92 = arith.constant 1 : i32
      %94 = arith.extsi %92 : i32 to i64
      %93 = arith.cmpi eq, %90, %94 : i64
      scf.yield %93 : i1
    } else {
      %95 = arith.constant false
      scf.yield %95 : i1
    }
    cf.cond_br %89, ^bb15, ^bb16
    ^bb15:
      %96 = llvm.mlir.addressof @NCAP : !llvm.ptr
      %97 = llvm.load %96 : !llvm.ptr -> i64
      %98 = arith.muli %arg10, %97 : i64
      %99 = arith.addi %98, %arg11 : i64
      %100 = arith.constant 1 : i32
      %102 = arith.extsi %100 : i32 to i64
      %101 = arith.addi %99, %102 : i64
      %103 = llvm.mlir.addressof @SB : !llvm.ptr
      %104 = llvm.load %103 : !llvm.ptr -> i64
      %105 = arith.remsi %101, %104 : i64
      %106 = llvm.mlir.constant(1 : i64) : i64
      %107 = llvm.alloca %106 x i64 : (i64) -> !llvm.ptr
      llvm.store %105, %107 : i64, !llvm.ptr
      cf.br ^bb18
      ^bb18:
      %109 = llvm.load %107 : !llvm.ptr -> i64
      %110 = llvm.getelementptr %arg8[%109] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %108 = llvm.load %110 : !llvm.ptr -> i64
      %111 = arith.cmpi eq, %108, %arg9 : i64
      cf.cond_br %111, ^bb19, ^bb20
      ^bb19:
        %113 = llvm.load %107 : !llvm.ptr -> i64
        %114 = llvm.getelementptr %arg7[%113] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %112 = llvm.load %114 : !llvm.ptr -> i64
        %115 = arith.cmpi eq, %112, %101 : i64
        cf.cond_br %115, ^bb21, ^bb22
        ^bb21:
          %116 = arith.constant 1 : i32
          %117 = arith.extsi %116 : i32 to i64
          func.return %117 : i64
        ^bb22:
          cf.br ^bb23
        ^bb23:
        %118 = llvm.load %107 : !llvm.ptr -> i64
        %119 = arith.constant 1 : i32
        %121 = arith.extsi %119 : i32 to i64
        %120 = arith.addi %118, %121 : i64
        %122 = llvm.mlir.addressof @SB : !llvm.ptr
        %123 = llvm.load %122 : !llvm.ptr -> i64
        %124 = arith.constant 1 : i32
        %126 = arith.extsi %124 : i32 to i64
        %125 = arith.subi %123, %126 : i64
        %127 = arith.andi %120, %125 : i64
        llvm.store %127, %107 : i64, !llvm.ptr
        cf.br ^bb18
      ^bb20:
      %128 = llvm.load %107 : !llvm.ptr -> i64
      %129 = llvm.getelementptr %arg7[%128] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %101, %129 : i64, !llvm.ptr
      %130 = llvm.load %107 : !llvm.ptr -> i64
      %131 = llvm.getelementptr %arg8[%130] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %arg9, %131 : i64, !llvm.ptr
      %134 = llvm.getelementptr %arg1[%arg10] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %133 = llvm.load %134 : !llvm.ptr -> i64
      %136 = llvm.getelementptr %arg1[%arg11] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %135 = llvm.load %136 : !llvm.ptr -> i64
      %132 = func.call @unify(%arg0, %arg1, %arg2, %arg3, %arg4, %arg5, %arg6, %arg7, %arg8, %arg9, %133, %135) : (!llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, i64, i64, i64) -> i64
      %137 = arith.constant 0 : i32
      %139 = arith.extsi %137 : i32 to i64
      %138 = arith.cmpi eq, %132, %139 : i64
      cf.cond_br %138, ^bb24, ^bb25
      ^bb24:
        %140 = arith.constant 0 : i32
        %141 = arith.extsi %140 : i32 to i64
        func.return %141 : i64
      ^bb25:
        cf.br ^bb26
      ^bb26:
      %144 = llvm.getelementptr %arg2[%arg10] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %143 = llvm.load %144 : !llvm.ptr -> i64
      %146 = llvm.getelementptr %arg2[%arg11] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %145 = llvm.load %146 : !llvm.ptr -> i64
      %142 = func.call @unify(%arg0, %arg1, %arg2, %arg3, %arg4, %arg5, %arg6, %arg7, %arg8, %arg9, %143, %145) : (!llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, i64, i64, i64) -> i64
      func.return %142 : i64
    ^bb16:
      cf.br ^bb17
    ^bb17:
    %148 = llvm.getelementptr %arg0[%arg10] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    %147 = llvm.load %148 : !llvm.ptr -> i64
    %149 = arith.constant 0 : i32
    %151 = arith.extsi %149 : i32 to i64
    %150 = arith.cmpi eq, %147, %151 : i64
    cf.cond_br %150, ^bb27, ^bb28
    ^bb27:
      %154 = llvm.getelementptr %arg1[%arg10] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %153 = llvm.load %154 : !llvm.ptr -> i64
      %152 = func.call @uf_find(%arg3, %arg4, %arg9, %153) : (!llvm.ptr, !llvm.ptr, i64, i64) -> i64
      %156 = llvm.getelementptr %arg6[%152] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %155 = llvm.load %156 : !llvm.ptr -> i64
      %157 = arith.cmpi eq, %155, %arg9 : i64
      cf.cond_br %157, ^bb30, ^bb31
      ^bb30:
        %160 = llvm.getelementptr %arg5[%152] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %159 = llvm.load %160 : !llvm.ptr -> i64
        %158 = func.call @unify(%arg0, %arg1, %arg2, %arg3, %arg4, %arg5, %arg6, %arg7, %arg8, %arg9, %159, %arg11) : (!llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, i64, i64, i64) -> i64
        func.return %158 : i64
      ^bb31:
        cf.br ^bb32
      ^bb32:
      %162 = llvm.getelementptr %arg0[%arg11] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %161 = llvm.load %162 : !llvm.ptr -> i64
      %163 = arith.constant 0 : i32
      %165 = arith.extsi %163 : i32 to i64
      %164 = arith.cmpi eq, %161, %165 : i64
      cf.cond_br %164, ^bb33, ^bb34
      ^bb33:
        %168 = llvm.getelementptr %arg1[%arg11] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %167 = llvm.load %168 : !llvm.ptr -> i64
        %166 = func.call @uf_find(%arg3, %arg4, %arg9, %167) : (!llvm.ptr, !llvm.ptr, i64, i64) -> i64
        %169 = arith.cmpi eq, %152, %166 : i64
        cf.cond_br %169, ^bb36, ^bb37
        ^bb36:
          %170 = arith.constant 1 : i32
          %171 = arith.extsi %170 : i32 to i64
          func.return %171 : i64
        ^bb37:
          cf.br ^bb38
        ^bb38:
        %173 = llvm.getelementptr %arg6[%166] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %172 = llvm.load %173 : !llvm.ptr -> i64
        %174 = arith.cmpi eq, %172, %arg9 : i64
        cf.cond_br %174, ^bb39, ^bb40
        ^bb39:
          %177 = llvm.getelementptr %arg5[%166] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %176 = llvm.load %177 : !llvm.ptr -> i64
          %175 = func.call @unify(%arg0, %arg1, %arg2, %arg3, %arg4, %arg5, %arg6, %arg7, %arg8, %arg9, %arg10, %176) : (!llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, i64, i64, i64) -> i64
          func.return %175 : i64
        ^bb40:
          cf.br ^bb41
        ^bb41:
        %178 = llvm.getelementptr %arg3[%152] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %166, %178 : i64, !llvm.ptr
        %179 = llvm.getelementptr %arg4[%152] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %arg9, %179 : i64, !llvm.ptr
        %180 = llvm.getelementptr %arg3[%166] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %166, %180 : i64, !llvm.ptr
        %181 = llvm.getelementptr %arg4[%166] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %arg9, %181 : i64, !llvm.ptr
        %182 = arith.constant 1 : i32
        %183 = arith.extsi %182 : i32 to i64
        func.return %183 : i64
      ^bb34:
        cf.br ^bb35
      ^bb35:
      %184 = llvm.getelementptr %arg5[%152] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %arg11, %184 : i64, !llvm.ptr
      %185 = llvm.getelementptr %arg6[%152] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %arg9, %185 : i64, !llvm.ptr
      %186 = arith.constant 1 : i32
      %187 = arith.extsi %186 : i32 to i64
      func.return %187 : i64
    ^bb28:
      cf.br ^bb29
    ^bb29:
    %188 = func.call @unify(%arg0, %arg1, %arg2, %arg3, %arg4, %arg5, %arg6, %arg7, %arg8, %arg9, %arg11, %arg10) : (!llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, i64, i64, i64) -> i64
    func.return %188 : i64
  }
  func.func @ev(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr, %arg3: !llvm.ptr, %arg4: !llvm.ptr, %arg5: !llvm.ptr, %arg6: !llvm.ptr, %arg7: !llvm.ptr, %arg8: !llvm.ptr, %arg9: !llvm.ptr, %arg10: i64, %arg11: i64) -> i64 {
    %190 = llvm.getelementptr %arg9[%arg11] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    %189 = llvm.load %190 : !llvm.ptr -> i64
    %191 = arith.cmpi eq, %189, %arg10 : i64
    %192 = scf.if %191 -> (i1) {
      %194 = llvm.getelementptr %arg8[%arg11] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %193 = llvm.load %194 : !llvm.ptr -> i64
      %195 = arith.constant 2 : i32
      %197 = arith.extsi %195 : i32 to i64
      %196 = arith.cmpi eq, %193, %197 : i64
      scf.yield %196 : i1
    } else {
      %198 = arith.constant false
      scf.yield %198 : i1
    }
    cf.cond_br %192, ^bb42, ^bb43
    ^bb42:
      %200 = llvm.getelementptr %arg7[%arg11] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %199 = llvm.load %200 : !llvm.ptr -> i64
      func.return %199 : i64
    ^bb43:
      cf.br ^bb44
    ^bb44:
    %202 = llvm.getelementptr %arg9[%arg11] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    %201 = llvm.load %202 : !llvm.ptr -> i64
    %203 = arith.cmpi eq, %201, %arg10 : i64
    %204 = scf.if %203 -> (i1) {
      %206 = llvm.getelementptr %arg8[%arg11] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %205 = llvm.load %206 : !llvm.ptr -> i64
      %207 = arith.constant 1 : i32
      %209 = arith.extsi %207 : i32 to i64
      %208 = arith.cmpi eq, %205, %209 : i64
      scf.yield %208 : i1
    } else {
      %210 = arith.constant false
      scf.yield %210 : i1
    }
    cf.cond_br %204, ^bb45, ^bb46
    ^bb45:
      %211 = arith.constant 0 : i32
      %212 = arith.constant 1 : i32
      %213 = arith.subi %211, %212 : i32
      %214 = arith.extsi %213 : i32 to i64
      func.return %214 : i64
    ^bb46:
      cf.br ^bb47
    ^bb47:
    %215 = llvm.getelementptr %arg9[%arg11] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %arg10, %215 : i64, !llvm.ptr
    %216 = arith.constant 1 : i32
    %217 = arith.extsi %216 : i32 to i64
    %218 = llvm.getelementptr %arg8[%arg11] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %217, %218 : i64, !llvm.ptr
    %219 = arith.constant 0 : i32
    %220 = arith.extsi %219 : i32 to i64
    %221 = llvm.mlir.constant(1 : i64) : i64
    %222 = llvm.alloca %221 x i64 : (i64) -> !llvm.ptr
    llvm.store %220, %222 : i64, !llvm.ptr
    %224 = llvm.getelementptr %arg0[%arg11] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    %223 = llvm.load %224 : !llvm.ptr -> i64
    %225 = arith.constant 0 : i32
    %227 = arith.extsi %225 : i32 to i64
    %226 = arith.cmpi eq, %223, %227 : i64
    cf.cond_br %226, ^bb48, ^bb49
    ^bb48:
      %230 = llvm.getelementptr %arg1[%arg11] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %229 = llvm.load %230 : !llvm.ptr -> i64
      %228 = func.call @uf_find(%arg3, %arg4, %arg10, %229) : (!llvm.ptr, !llvm.ptr, i64, i64) -> i64
      %232 = llvm.getelementptr %arg6[%228] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %231 = llvm.load %232 : !llvm.ptr -> i64
      %233 = arith.cmpi eq, %231, %arg10 : i64
      cf.cond_br %233, ^bb51, ^bb52
      ^bb51:
        %236 = llvm.getelementptr %arg5[%228] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %235 = llvm.load %236 : !llvm.ptr -> i64
        %234 = func.call @ev(%arg0, %arg1, %arg2, %arg3, %arg4, %arg5, %arg6, %arg7, %arg8, %arg9, %arg10, %235) : (!llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, i64, i64) -> i64
        llvm.store %234, %222 : i64, !llvm.ptr
        %237 = llvm.load %222 : !llvm.ptr -> i64
        %238 = arith.constant 0 : i32
        %240 = arith.extsi %238 : i32 to i64
        %239 = arith.cmpi slt, %237, %240 : i64
        cf.cond_br %239, ^bb54, ^bb55
        ^bb54:
          %241 = arith.constant 0 : i32
          %242 = arith.constant 1 : i32
          %243 = arith.subi %241, %242 : i32
          %244 = arith.extsi %243 : i32 to i64
          func.return %244 : i64
        ^bb55:
          cf.br ^bb56
        ^bb56:
        cf.br ^bb53
      ^bb52:
        %245 = arith.constant 0 : i32
        %246 = arith.extsi %245 : i32 to i64
        llvm.store %246, %222 : i64, !llvm.ptr
        cf.br ^bb53
      ^bb53:
      cf.br ^bb50
    ^bb49:
      %249 = llvm.getelementptr %arg1[%arg11] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %248 = llvm.load %249 : !llvm.ptr -> i64
      %247 = func.call @ev(%arg0, %arg1, %arg2, %arg3, %arg4, %arg5, %arg6, %arg7, %arg8, %arg9, %arg10, %248) : (!llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, i64, i64) -> i64
      %250 = arith.constant 0 : i32
      %252 = arith.extsi %250 : i32 to i64
      %251 = arith.cmpi slt, %247, %252 : i64
      cf.cond_br %251, ^bb57, ^bb58
      ^bb57:
        %253 = arith.constant 0 : i32
        %254 = arith.constant 1 : i32
        %255 = arith.subi %253, %254 : i32
        %256 = arith.extsi %255 : i32 to i64
        func.return %256 : i64
      ^bb58:
        cf.br ^bb59
      ^bb59:
      %259 = llvm.getelementptr %arg2[%arg11] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %258 = llvm.load %259 : !llvm.ptr -> i64
      %257 = func.call @ev(%arg0, %arg1, %arg2, %arg3, %arg4, %arg5, %arg6, %arg7, %arg8, %arg9, %arg10, %258) : (!llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, i64, i64) -> i64
      %260 = arith.constant 0 : i32
      %262 = arith.extsi %260 : i32 to i64
      %261 = arith.cmpi slt, %257, %262 : i64
      cf.cond_br %261, ^bb60, ^bb61
      ^bb60:
        %263 = arith.constant 0 : i32
        %264 = arith.constant 1 : i32
        %265 = arith.subi %263, %264 : i32
        %266 = arith.extsi %265 : i32 to i64
        func.return %266 : i64
      ^bb61:
        cf.br ^bb62
      ^bb62:
      %267 = arith.constant 1 : i32
      %269 = arith.extsi %267 : i32 to i64
      %268 = arith.addi %269, %247 : i64
      %270 = arith.addi %268, %257 : i64
      %271 = llvm.mlir.addressof @MODV : !llvm.ptr
      %272 = llvm.load %271 : !llvm.ptr -> i64
      %273 = arith.remsi %270, %272 : i64
      %274 = arith.muli %273, %273 : i64
      %275 = arith.addi %274, %257 : i64
      %276 = arith.subi %275, %247 : i64
      %277 = llvm.mlir.addressof @MODV : !llvm.ptr
      %278 = llvm.load %277 : !llvm.ptr -> i64
      %279 = arith.remsi %276, %278 : i64
      %280 = llvm.mlir.addressof @MODV : !llvm.ptr
      %281 = llvm.load %280 : !llvm.ptr -> i64
      %282 = arith.addi %279, %281 : i64
      %283 = llvm.mlir.addressof @MODV : !llvm.ptr
      %284 = llvm.load %283 : !llvm.ptr -> i64
      %285 = arith.remsi %282, %284 : i64
      llvm.store %285, %222 : i64, !llvm.ptr
      cf.br ^bb50
    ^bb50:
    %286 = arith.constant 2 : i32
    %287 = arith.extsi %286 : i32 to i64
    %288 = llvm.getelementptr %arg8[%arg11] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %287, %288 : i64, !llvm.ptr
    %289 = llvm.load %222 : !llvm.ptr -> i64
    %290 = llvm.getelementptr %arg7[%arg11] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %289, %290 : i64, !llvm.ptr
    %291 = llvm.load %222 : !llvm.ptr -> i64
    func.return %291 : i64
  }
  func.func @main() -> i32 {
    %293 = llvm.mlir.addressof @NCAP : !llvm.ptr
    %294 = llvm.load %293 : !llvm.ptr -> i64
    %295 = arith.constant 8 : i32
    %296 = arith.extsi %295 : i32 to i64
    %292 = func.call @calloc(%294, %296) : (i64, i64) -> !llvm.ptr
    %298 = llvm.mlir.addressof @NCAP : !llvm.ptr
    %299 = llvm.load %298 : !llvm.ptr -> i64
    %300 = arith.constant 8 : i32
    %301 = arith.extsi %300 : i32 to i64
    %297 = func.call @calloc(%299, %301) : (i64, i64) -> !llvm.ptr
    %303 = llvm.mlir.addressof @NCAP : !llvm.ptr
    %304 = llvm.load %303 : !llvm.ptr -> i64
    %305 = arith.constant 8 : i32
    %306 = arith.extsi %305 : i32 to i64
    %302 = func.call @calloc(%304, %306) : (i64, i64) -> !llvm.ptr
    %308 = llvm.mlir.addressof @HB : !llvm.ptr
    %309 = llvm.load %308 : !llvm.ptr -> i64
    %310 = arith.constant 8 : i32
    %311 = arith.extsi %310 : i32 to i64
    %307 = func.call @calloc(%309, %311) : (i64, i64) -> !llvm.ptr
    %313 = llvm.mlir.addressof @HB : !llvm.ptr
    %314 = llvm.load %313 : !llvm.ptr -> i64
    %315 = arith.constant 8 : i32
    %316 = arith.extsi %315 : i32 to i64
    %312 = func.call @calloc(%314, %316) : (i64, i64) -> !llvm.ptr
    %318 = arith.constant 1 : i32
    %319 = arith.constant 8 : i32
    %320 = arith.extsi %318 : i32 to i64
    %321 = arith.extsi %319 : i32 to i64
    %317 = func.call @calloc(%320, %321) : (i64, i64) -> !llvm.ptr
    %323 = arith.constant 200 : i32
    %324 = arith.constant 8 : i32
    %325 = arith.extsi %323 : i32 to i64
    %326 = arith.extsi %324 : i32 to i64
    %322 = func.call @calloc(%325, %326) : (i64, i64) -> !llvm.ptr
    %327 = arith.constant 0 : i32
    %328 = arith.extsi %327 : i32 to i64
    %329 = llvm.mlir.constant(1 : i64) : i64
    %330 = llvm.alloca %329 x i64 : (i64) -> !llvm.ptr
    llvm.store %328, %330 : i64, !llvm.ptr
    %332 = arith.constant 20000 : i32
    %333 = arith.constant 8 : i32
    %334 = arith.extsi %332 : i32 to i64
    %335 = arith.extsi %333 : i32 to i64
    %331 = func.call @calloc(%334, %335) : (i64, i64) -> !llvm.ptr
    %336 = arith.constant 0 : i32
    %337 = arith.extsi %336 : i32 to i64
    %338 = llvm.mlir.constant(1 : i64) : i64
    %339 = llvm.alloca %338 x i64 : (i64) -> !llvm.ptr
    llvm.store %337, %339 : i64, !llvm.ptr
    %341 = llvm.mlir.addressof @str_0 : !llvm.ptr
    %342 = llvm.mlir.addressof @str_1 : !llvm.ptr
    %340 = func.call @fopen(%341, %342) : (!llvm.ptr, !llvm.ptr) -> !llvm.ptr
    %343 = arith.constant 0 : i32
    %345 = llvm.inttoptr %343 : i32 to !llvm.ptr
    %344 = llvm.icmp "eq" %340, %345 : !llvm.ptr
    cf.cond_br %344, ^bb63, ^bb64
    ^bb63:
      %346 = llvm.mlir.addressof @str_2 : !llvm.ptr
      %347 = llvm.call @printf(%346) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr) -> i32
      %348 = arith.constant 1 : i32
      func.return %348 : i32
    ^bb64:
      cf.br ^bb65
    ^bb65:
    %349 = arith.constant 0 : i32
    %350 = arith.extsi %349 : i32 to i64
    %351 = llvm.mlir.constant(1 : i64) : i64
    %352 = llvm.alloca %351 x i64 : (i64) -> !llvm.ptr
    llvm.store %350, %352 : i64, !llvm.ptr
    %353 = arith.constant 0 : i32
    %354 = arith.extsi %353 : i32 to i64
    %355 = llvm.mlir.constant(1 : i64) : i64
    %356 = llvm.alloca %355 x i64 : (i64) -> !llvm.ptr
    llvm.store %354, %356 : i64, !llvm.ptr
    %357 = func.call @fgetc(%340) : (!llvm.ptr) -> i32
    %358 = llvm.mlir.constant(1 : i64) : i64
    %359 = llvm.alloca %358 x i32 : (i64) -> !llvm.ptr
    llvm.store %357, %359 : i32, !llvm.ptr
    cf.br ^bb66
    ^bb66:
    %360 = llvm.load %359 : !llvm.ptr -> i32
    %361 = arith.constant 0 : i32
    %362 = arith.cmpi sge, %360, %361 : i32
    cf.cond_br %362, ^bb67, ^bb68
    ^bb67:
      %363 = llvm.load %359 : !llvm.ptr -> i32
      %364 = arith.extsi %363 : i32 to i64
      %365 = arith.constant 97 : i32
      %367 = arith.extsi %365 : i32 to i64
      %366 = arith.cmpi sge, %364, %367 : i64
      %368 = scf.if %366 -> (i1) {
        %369 = arith.constant 122 : i32
        %371 = arith.extsi %369 : i32 to i64
        %370 = arith.cmpi sle, %364, %371 : i64
        scf.yield %370 : i1
      } else {
        %372 = arith.constant false
        scf.yield %372 : i1
      }
      cf.cond_br %368, ^bb69, ^bb70
      ^bb69:
        %373 = llvm.load %352 : !llvm.ptr -> i64
        %374 = arith.constant 27 : i32
        %376 = arith.extsi %374 : i32 to i64
        %375 = arith.muli %373, %376 : i64
        %377 = arith.constant 96 : i32
        %379 = arith.extsi %377 : i32 to i64
        %378 = arith.subi %364, %379 : i64
        %380 = arith.addi %375, %378 : i64
        llvm.store %380, %352 : i64, !llvm.ptr
        %381 = arith.constant 1 : i32
        %382 = arith.extsi %381 : i32 to i64
        llvm.store %382, %356 : i64, !llvm.ptr
        cf.br ^bb71
      ^bb70:
        %383 = llvm.load %356 : !llvm.ptr -> i64
        %384 = arith.constant 1 : i32
        %386 = arith.extsi %384 : i32 to i64
        %385 = arith.cmpi eq, %383, %386 : i64
        cf.cond_br %385, ^bb72, ^bb73
        ^bb72:
          %388 = arith.constant 0 : i32
          %389 = llvm.load %352 : !llvm.ptr -> i64
          %390 = arith.constant 0 : i32
          %391 = arith.extsi %388 : i32 to i64
          %392 = arith.extsi %390 : i32 to i64
          %387 = func.call @node_get(%292, %297, %302, %307, %312, %317, %391, %389, %392) : (!llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, i64, i64, i64) -> i64
          %393 = llvm.load %339 : !llvm.ptr -> i64
          %394 = llvm.getelementptr %331[%393] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %387, %394 : i64, !llvm.ptr
          %395 = llvm.load %339 : !llvm.ptr -> i64
          %396 = arith.constant 1 : i32
          %398 = arith.extsi %396 : i32 to i64
          %397 = arith.addi %395, %398 : i64
          llvm.store %397, %339 : i64, !llvm.ptr
          %399 = arith.constant 0 : i32
          %400 = arith.extsi %399 : i32 to i64
          llvm.store %400, %352 : i64, !llvm.ptr
          %401 = arith.constant 0 : i32
          %402 = arith.extsi %401 : i32 to i64
          llvm.store %402, %356 : i64, !llvm.ptr
          cf.br ^bb74
        ^bb73:
          cf.br ^bb74
        ^bb74:
        %403 = arith.constant 73 : i32
        %405 = arith.extsi %403 : i32 to i64
        %404 = arith.cmpi eq, %364, %405 : i64
        cf.cond_br %404, ^bb75, ^bb76
        ^bb75:
          %406 = arith.constant 0 : i32
          %407 = arith.constant 1 : i32
          %408 = arith.subi %406, %407 : i32
          %409 = llvm.load %339 : !llvm.ptr -> i64
          %410 = arith.extsi %408 : i32 to i64
          %411 = llvm.getelementptr %331[%409] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %410, %411 : i64, !llvm.ptr
          %412 = llvm.load %339 : !llvm.ptr -> i64
          %413 = arith.constant 1 : i32
          %415 = arith.extsi %413 : i32 to i64
          %414 = arith.addi %412, %415 : i64
          llvm.store %414, %339 : i64, !llvm.ptr
          cf.br ^bb77
        ^bb76:
          cf.br ^bb77
        ^bb77:
        %416 = arith.constant 41 : i32
        %418 = arith.extsi %416 : i32 to i64
        %417 = arith.cmpi eq, %364, %418 : i64
        cf.cond_br %417, ^bb78, ^bb79
        ^bb78:
          %420 = llvm.load %339 : !llvm.ptr -> i64
          %421 = arith.constant 1 : i32
          %423 = arith.extsi %421 : i32 to i64
          %422 = arith.subi %420, %423 : i64
          %424 = llvm.getelementptr %331[%422] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %419 = llvm.load %424 : !llvm.ptr -> i64
          %426 = llvm.load %339 : !llvm.ptr -> i64
          %427 = arith.constant 2 : i32
          %429 = arith.extsi %427 : i32 to i64
          %428 = arith.subi %426, %429 : i64
          %430 = llvm.getelementptr %331[%428] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %425 = llvm.load %430 : !llvm.ptr -> i64
          %431 = llvm.load %339 : !llvm.ptr -> i64
          %432 = arith.constant 3 : i32
          %434 = arith.extsi %432 : i32 to i64
          %433 = arith.subi %431, %434 : i64
          llvm.store %433, %339 : i64, !llvm.ptr
          %436 = arith.constant 1 : i32
          %437 = arith.extsi %436 : i32 to i64
          %435 = func.call @node_get(%292, %297, %302, %307, %312, %317, %437, %425, %419) : (!llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, i64, i64, i64) -> i64
          %438 = llvm.load %339 : !llvm.ptr -> i64
          %439 = llvm.getelementptr %331[%438] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %435, %439 : i64, !llvm.ptr
          %440 = llvm.load %339 : !llvm.ptr -> i64
          %441 = arith.constant 1 : i32
          %443 = arith.extsi %441 : i32 to i64
          %442 = arith.addi %440, %443 : i64
          llvm.store %442, %339 : i64, !llvm.ptr
          cf.br ^bb80
        ^bb79:
          cf.br ^bb80
        ^bb80:
        %444 = arith.constant 10 : i32
        %446 = arith.extsi %444 : i32 to i64
        %445 = arith.cmpi eq, %364, %446 : i64
        cf.cond_br %445, ^bb81, ^bb82
        ^bb81:
          %447 = llvm.load %339 : !llvm.ptr -> i64
          %448 = arith.constant 0 : i32
          %450 = arith.extsi %448 : i32 to i64
          %449 = arith.cmpi sgt, %447, %450 : i64
          cf.cond_br %449, ^bb84, ^bb85
          ^bb84:
            %452 = llvm.load %339 : !llvm.ptr -> i64
            %453 = arith.constant 1 : i32
            %455 = arith.extsi %453 : i32 to i64
            %454 = arith.subi %452, %455 : i64
            %456 = llvm.getelementptr %331[%454] : (!llvm.ptr, i64) -> !llvm.ptr, i64
            %451 = llvm.load %456 : !llvm.ptr -> i64
            %457 = llvm.load %330 : !llvm.ptr -> i64
            %458 = llvm.getelementptr %322[%457] : (!llvm.ptr, i64) -> !llvm.ptr, i64
            llvm.store %451, %458 : i64, !llvm.ptr
            %459 = llvm.load %330 : !llvm.ptr -> i64
            %460 = arith.constant 1 : i32
            %462 = arith.extsi %460 : i32 to i64
            %461 = arith.addi %459, %462 : i64
            llvm.store %461, %330 : i64, !llvm.ptr
            %463 = arith.constant 0 : i32
            %464 = arith.extsi %463 : i32 to i64
            llvm.store %464, %339 : i64, !llvm.ptr
            cf.br ^bb86
          ^bb85:
            cf.br ^bb86
          ^bb86:
          cf.br ^bb83
        ^bb82:
          cf.br ^bb83
        ^bb83:
        cf.br ^bb71
      ^bb71:
      %465 = func.call @fgetc(%340) : (!llvm.ptr) -> i32
      llvm.store %465, %359 : i32, !llvm.ptr
      cf.br ^bb66
    ^bb68:
    %466 = llvm.load %356 : !llvm.ptr -> i64
    %467 = arith.constant 1 : i32
    %469 = arith.extsi %467 : i32 to i64
    %468 = arith.cmpi eq, %466, %469 : i64
    cf.cond_br %468, ^bb87, ^bb88
    ^bb87:
      %471 = arith.constant 0 : i32
      %472 = llvm.load %352 : !llvm.ptr -> i64
      %473 = arith.constant 0 : i32
      %474 = arith.extsi %471 : i32 to i64
      %475 = arith.extsi %473 : i32 to i64
      %470 = func.call @node_get(%292, %297, %302, %307, %312, %317, %474, %472, %475) : (!llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, i64, i64, i64) -> i64
      %476 = llvm.load %339 : !llvm.ptr -> i64
      %477 = llvm.getelementptr %331[%476] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %470, %477 : i64, !llvm.ptr
      %478 = llvm.load %339 : !llvm.ptr -> i64
      %479 = arith.constant 1 : i32
      %481 = arith.extsi %479 : i32 to i64
      %480 = arith.addi %478, %481 : i64
      llvm.store %480, %339 : i64, !llvm.ptr
      cf.br ^bb89
    ^bb88:
      cf.br ^bb89
    ^bb89:
    %482 = llvm.load %339 : !llvm.ptr -> i64
    %483 = arith.constant 0 : i32
    %485 = arith.extsi %483 : i32 to i64
    %484 = arith.cmpi sgt, %482, %485 : i64
    cf.cond_br %484, ^bb90, ^bb91
    ^bb90:
      %487 = llvm.load %339 : !llvm.ptr -> i64
      %488 = arith.constant 1 : i32
      %490 = arith.extsi %488 : i32 to i64
      %489 = arith.subi %487, %490 : i64
      %491 = llvm.getelementptr %331[%489] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %486 = llvm.load %491 : !llvm.ptr -> i64
      %492 = llvm.load %330 : !llvm.ptr -> i64
      %493 = llvm.getelementptr %322[%492] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %486, %493 : i64, !llvm.ptr
      %494 = llvm.load %330 : !llvm.ptr -> i64
      %495 = arith.constant 1 : i32
      %497 = arith.extsi %495 : i32 to i64
      %496 = arith.addi %494, %497 : i64
      llvm.store %496, %330 : i64, !llvm.ptr
      cf.br ^bb92
    ^bb91:
      cf.br ^bb92
    ^bb92:
    %498 = func.call @fclose(%340) : (!llvm.ptr) -> i32
    %500 = llvm.mlir.addressof @VCAP : !llvm.ptr
    %501 = llvm.load %500 : !llvm.ptr -> i64
    %502 = arith.constant 8 : i32
    %503 = arith.extsi %502 : i32 to i64
    %499 = func.call @calloc(%501, %503) : (i64, i64) -> !llvm.ptr
    %505 = llvm.mlir.addressof @VCAP : !llvm.ptr
    %506 = llvm.load %505 : !llvm.ptr -> i64
    %507 = arith.constant 8 : i32
    %508 = arith.extsi %507 : i32 to i64
    %504 = func.call @calloc(%506, %508) : (i64, i64) -> !llvm.ptr
    %510 = llvm.mlir.addressof @VCAP : !llvm.ptr
    %511 = llvm.load %510 : !llvm.ptr -> i64
    %512 = arith.constant 8 : i32
    %513 = arith.extsi %512 : i32 to i64
    %509 = func.call @calloc(%511, %513) : (i64, i64) -> !llvm.ptr
    %515 = llvm.mlir.addressof @VCAP : !llvm.ptr
    %516 = llvm.load %515 : !llvm.ptr -> i64
    %517 = arith.constant 8 : i32
    %518 = arith.extsi %517 : i32 to i64
    %514 = func.call @calloc(%516, %518) : (i64, i64) -> !llvm.ptr
    %520 = llvm.mlir.addressof @SB : !llvm.ptr
    %521 = llvm.load %520 : !llvm.ptr -> i64
    %522 = arith.constant 8 : i32
    %523 = arith.extsi %522 : i32 to i64
    %519 = func.call @calloc(%521, %523) : (i64, i64) -> !llvm.ptr
    %525 = llvm.mlir.addressof @SB : !llvm.ptr
    %526 = llvm.load %525 : !llvm.ptr -> i64
    %527 = arith.constant 8 : i32
    %528 = arith.extsi %527 : i32 to i64
    %524 = func.call @calloc(%526, %528) : (i64, i64) -> !llvm.ptr
    %530 = llvm.mlir.addressof @NCAP : !llvm.ptr
    %531 = llvm.load %530 : !llvm.ptr -> i64
    %532 = arith.constant 8 : i32
    %533 = arith.extsi %532 : i32 to i64
    %529 = func.call @calloc(%531, %533) : (i64, i64) -> !llvm.ptr
    %535 = llvm.mlir.addressof @NCAP : !llvm.ptr
    %536 = llvm.load %535 : !llvm.ptr -> i64
    %537 = arith.constant 8 : i32
    %538 = arith.extsi %537 : i32 to i64
    %534 = func.call @calloc(%536, %538) : (i64, i64) -> !llvm.ptr
    %540 = llvm.mlir.addressof @NCAP : !llvm.ptr
    %541 = llvm.load %540 : !llvm.ptr -> i64
    %542 = arith.constant 8 : i32
    %543 = arith.extsi %542 : i32 to i64
    %539 = func.call @calloc(%541, %543) : (i64, i64) -> !llvm.ptr
    %544 = arith.constant 0 : i32
    %545 = arith.extsi %544 : i32 to i64
    %546 = llvm.mlir.constant(1 : i64) : i64
    %547 = llvm.alloca %546 x i64 : (i64) -> !llvm.ptr
    llvm.store %545, %547 : i64, !llvm.ptr
    %548 = arith.constant 0 : i32
    %549 = arith.extsi %548 : i32 to i64
    %550 = llvm.mlir.constant(1 : i64) : i64
    %551 = llvm.alloca %550 x i64 : (i64) -> !llvm.ptr
    llvm.store %549, %551 : i64, !llvm.ptr
    %552 = arith.constant 0 : i32
    %553 = arith.extsi %552 : i32 to i64
    %554 = llvm.mlir.constant(1 : i64) : i64
    %555 = llvm.alloca %554 x i64 : (i64) -> !llvm.ptr
    llvm.store %553, %555 : i64, !llvm.ptr
    cf.br ^bb93
    ^bb93:
    %556 = llvm.load %555 : !llvm.ptr -> i64
    %557 = llvm.load %330 : !llvm.ptr -> i64
    %558 = arith.cmpi slt, %556, %557 : i64
    cf.cond_br %558, ^bb94, ^bb95
    ^bb94:
      %559 = llvm.load %555 : !llvm.ptr -> i64
      %560 = arith.constant 1 : i32
      %562 = arith.extsi %560 : i32 to i64
      %561 = arith.addi %559, %562 : i64
      %563 = llvm.mlir.constant(1 : i64) : i64
      %564 = llvm.alloca %563 x i64 : (i64) -> !llvm.ptr
      llvm.store %561, %564 : i64, !llvm.ptr
      cf.br ^bb96
      ^bb96:
      %565 = llvm.load %564 : !llvm.ptr -> i64
      %566 = llvm.load %330 : !llvm.ptr -> i64
      %567 = arith.cmpi slt, %565, %566 : i64
      cf.cond_br %567, ^bb97, ^bb98
      ^bb97:
        %568 = llvm.load %551 : !llvm.ptr -> i64
        %569 = arith.constant 1 : i32
        %571 = arith.extsi %569 : i32 to i64
        %570 = arith.addi %568, %571 : i64
        llvm.store %570, %551 : i64, !llvm.ptr
        %573 = llvm.load %551 : !llvm.ptr -> i64
        %575 = llvm.load %555 : !llvm.ptr -> i64
        %576 = llvm.getelementptr %322[%575] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %574 = llvm.load %576 : !llvm.ptr -> i64
        %578 = llvm.load %564 : !llvm.ptr -> i64
        %579 = llvm.getelementptr %322[%578] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %577 = llvm.load %579 : !llvm.ptr -> i64
        %572 = func.call @unify(%292, %297, %302, %499, %504, %509, %514, %519, %524, %573, %574, %577) : (!llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, i64, i64, i64) -> i64
        %580 = arith.constant 1 : i32
        %582 = arith.extsi %580 : i32 to i64
        %581 = arith.cmpi eq, %572, %582 : i64
        cf.cond_br %581, ^bb99, ^bb100
        ^bb99:
          %584 = llvm.load %551 : !llvm.ptr -> i64
          %586 = llvm.load %555 : !llvm.ptr -> i64
          %587 = llvm.getelementptr %322[%586] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %585 = llvm.load %587 : !llvm.ptr -> i64
          %583 = func.call @ev(%292, %297, %302, %499, %504, %509, %514, %529, %534, %539, %584, %585) : (!llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, i64, i64) -> i64
          %588 = arith.constant 0 : i32
          %590 = arith.extsi %588 : i32 to i64
          %589 = arith.cmpi sge, %583, %590 : i64
          cf.cond_br %589, ^bb102, ^bb103
          ^bb102:
            %591 = llvm.load %547 : !llvm.ptr -> i64
            %592 = arith.addi %591, %583 : i64
            %593 = llvm.mlir.addressof @MODV : !llvm.ptr
            %594 = llvm.load %593 : !llvm.ptr -> i64
            %595 = arith.remsi %592, %594 : i64
            llvm.store %595, %547 : i64, !llvm.ptr
            cf.br ^bb104
          ^bb103:
            cf.br ^bb104
          ^bb104:
          cf.br ^bb101
        ^bb100:
          cf.br ^bb101
        ^bb101:
        %596 = llvm.load %564 : !llvm.ptr -> i64
        %597 = arith.constant 1 : i32
        %599 = arith.extsi %597 : i32 to i64
        %598 = arith.addi %596, %599 : i64
        llvm.store %598, %564 : i64, !llvm.ptr
        cf.br ^bb96
      ^bb98:
      %600 = llvm.load %555 : !llvm.ptr -> i64
      %601 = arith.constant 1 : i32
      %603 = arith.extsi %601 : i32 to i64
      %602 = arith.addi %600, %603 : i64
      llvm.store %602, %555 : i64, !llvm.ptr
      cf.br ^bb93
    ^bb95:
    %604 = llvm.mlir.addressof @str_3 : !llvm.ptr
    %605 = llvm.load %547 : !llvm.ptr -> i64
    %606 = llvm.call @printf(%604, %605) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i64) -> i32
    func.call @free(%292) : (!llvm.ptr) -> ()
    func.call @free(%297) : (!llvm.ptr) -> ()
    func.call @free(%302) : (!llvm.ptr) -> ()
    func.call @free(%307) : (!llvm.ptr) -> ()
    func.call @free(%312) : (!llvm.ptr) -> ()
    func.call @free(%317) : (!llvm.ptr) -> ()
    func.call @free(%322) : (!llvm.ptr) -> ()
    func.call @free(%331) : (!llvm.ptr) -> ()
    func.call @free(%499) : (!llvm.ptr) -> ()
    func.call @free(%504) : (!llvm.ptr) -> ()
    func.call @free(%509) : (!llvm.ptr) -> ()
    func.call @free(%514) : (!llvm.ptr) -> ()
    func.call @free(%519) : (!llvm.ptr) -> ()
    func.call @free(%524) : (!llvm.ptr) -> ()
    func.call @free(%529) : (!llvm.ptr) -> ()
    func.call @free(%534) : (!llvm.ptr) -> ()
    func.call @free(%539) : (!llvm.ptr) -> ()
    %624 = arith.constant 0 : i32
    func.return %624 : i32
  }
}