Problem 275

Balanced sculptures of order 18 (reflections identified).

Answer15030564
Output15030564
StatusPASS
Native helperno
Runtime8610 ms
Peak memory1152 KB
Time complexityO(n^2) (estimated)
Space complexityO(n^2) (estimated)

Performance comparison

MetricOur solutionBest known
Time complexityO(n^2)O(n)
Space complexityO(n^2)O(1)
ApproachFlow solutionIterative reflection simulation
VerdictSuboptimal

Flow source

# Project Euler 275
# Balanced sculptures of order 18 (reflections identified).

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

let mut G_n: i64 = 18
let mut G_XMAX: i64 = 17
let mut G_W: i64 = 35
let mut G_SHIFT: i64 = 17
let mut G_GRID: i64 = 630
let mut G_root: i64 = 17
let mut G_x_of: ptr<i64> = null
let mut G_neigh: ptr<i64> = null
let mut G_neigh_cnt: ptr<i64> = null
let mut G_seen: ptr<i8> = null
let mut G_Q: ptr<i64> = null
let mut G_ans: i64 = 0

function rec_total(q_begin: i64, q_end: i64, size: i64, moment: i64, minx: i64, maxx: i64) -> void {
    if size == G_n {
        if moment == 0 { G_ans = G_ans + 1 }
        return
    }
    let r: i64 = G_n - size
    let min_possible_x: i64 = minx - r
    let max_possible_x: i64 = maxx + r
    if moment + r * min_possible_x > 0 { return }
    if moment + r * max_possible_x < 0 { return }

    let mut i: i64 = q_begin
    while i < q_end {
        let cell: i64 = G_Q[i]
        let x: i64 = G_x_of[cell]

        let mut added: i64 = 0
        let nb: i64 = G_neigh_cnt[cell]
        let mut k: i64 = 0
        while k < nb {
            let nb_idx: i64 = G_neigh[cell * 4 + k]
            if G_seen[nb_idx] == 0 {
                G_seen[nb_idx] = 1
                G_Q[q_end + added] = nb_idx
                added = added + 1
            }
            k = k + 1
        }

        let mut nmin: i64 = minx
        if x < nmin { nmin = x }
        let mut nmax: i64 = maxx
        if x > nmax { nmax = x }

        rec_total(i + 1, q_end + added, size + 1, moment + x, nmin, nmax)

        let mut j: i64 = q_end
        while j < q_end + added {
            G_seen[G_Q[j]] = 0
            j = j + 1
        }
        i = i + 1
    }
}

function count_total(n: i64) -> i64 {
    G_n = n
    G_XMAX = n - 1
    G_W = 2 * G_XMAX + 1
    G_SHIFT = G_XMAX
    G_GRID = G_W * (G_XMAX + 1)
    G_root = G_SHIFT

    G_x_of = calloc(G_GRID, 8)
    G_neigh = calloc(G_GRID * 4, 8)
    G_neigh_cnt = calloc(G_GRID, 8)
    G_seen = calloc(G_GRID, 1)
    G_Q = calloc(8 * n + 50, 8)

    let mut y: i64 = 0
    while y <= G_XMAX {
        let base: i64 = y * G_W
        let mut xi: i64 = 0
        while xi < G_W {
            G_x_of[base + xi] = xi - G_SHIFT
            xi = xi + 1
        }
        y = y + 1
    }

    y = 0
    while y <= G_XMAX {
        let row: i64 = y * G_W
        let mut xi: i64 = 0
        while xi < G_W {
            let idx: i64 = row + xi
            let mut cnt: i64 = 0
            if xi > 0 {
                G_neigh[idx * 4 + cnt] = idx - 1
                cnt = cnt + 1
            }
            if xi < G_W - 1 {
                G_neigh[idx * 4 + cnt] = idx + 1
                cnt = cnt + 1
            }
            if y > 0 {
                G_neigh[idx * 4 + cnt] = idx - G_W
                cnt = cnt + 1
            }
            if y < G_XMAX {
                G_neigh[idx * 4 + cnt] = idx + G_W
                cnt = cnt + 1
            }
            G_neigh_cnt[idx] = cnt
            xi = xi + 1
        }
        y = y + 1
    }

    G_seen[G_root] = 1
    let mut q_end: i64 = 0
    let nb0: i64 = G_neigh_cnt[G_root]
    let mut k: i64 = 0
    while k < nb0 {
        let nb_idx: i64 = G_neigh[G_root * 4 + k]
        if G_seen[nb_idx] == 0 {
            G_seen[nb_idx] = 1
            G_Q[q_end] = nb_idx
            q_end = q_end + 1
        }
        k = k + 1
    }

    G_ans = 0
    rec_total(0, q_end, 1, 0, 0, 0)
    let ans: i64 = G_ans
    free(G_x_of); free(G_neigh); free(G_neigh_cnt); free(G_seen); free(G_Q)
    return ans
}

function rec_sym(q_begin: i64, q_end: i64, full_size: i64) -> void {
    if full_size == G_n {
        G_ans = G_ans + 1
        return
    }
    let mut i: i64 = q_begin
    while i < q_end {
        let cell: i64 = G_Q[i]
        let x: i64 = G_x_of[cell]
        let add: i64 = 1
        let mut add2: i64 = 2
        if x == 0 { add2 = 1 }
        let new_full: i64 = full_size + add2
        if new_full > G_n {
            i = i + 1
            continue
        }

        let mut added: i64 = 0
        let nb: i64 = G_neigh_cnt[cell]
        let mut k: i64 = 0
        while k < nb {
            let nb_idx: i64 = G_neigh[cell * 4 + k]
            if G_seen[nb_idx] == 0 {
                G_seen[nb_idx] = 1
                G_Q[q_end + added] = nb_idx
                added = added + 1
            }
            k = k + 1
        }

        rec_sym(i + 1, q_end + added, new_full)

        let mut j: i64 = q_end
        while j < q_end + added {
            G_seen[G_Q[j]] = 0
            j = j + 1
        }
        i = i + 1
    }
}

function count_symmetric(n: i64) -> i64 {
    G_n = n
    G_XMAX = n - 1
    G_W = 2 * G_XMAX + 1
    G_SHIFT = G_XMAX
    G_GRID = G_W * (G_XMAX + 1)
    G_root = G_SHIFT

    G_x_of = calloc(G_GRID, 8)
    G_neigh = calloc(G_GRID * 4, 8)
    G_neigh_cnt = calloc(G_GRID, 8)
    G_seen = calloc(G_GRID, 1)
    G_Q = calloc(8 * n + 50, 8)

    let mut y: i64 = 0
    while y <= G_XMAX {
        let base: i64 = y * G_W
        let mut xi: i64 = 0
        while xi < G_W {
            G_x_of[base + xi] = xi - G_SHIFT
            xi = xi + 1
        }
        y = y + 1
    }

    y = 0
    while y <= G_XMAX {
        let row: i64 = y * G_W
        let mut xi: i64 = 0
        while xi < G_W {
            let idx: i64 = row + xi
            let x: i64 = xi - G_SHIFT
            let mut cnt: i64 = 0
            if x >= 0 {
                if xi > G_SHIFT {
                    G_neigh[idx * 4 + cnt] = idx - 1
                    cnt = cnt + 1
                }
                if xi < G_W - 1 {
                    G_neigh[idx * 4 + cnt] = idx + 1
                    cnt = cnt + 1
                }
                if y > 0 {
                    G_neigh[idx * 4 + cnt] = idx - G_W
                    cnt = cnt + 1
                }
                if y < G_XMAX {
                    G_neigh[idx * 4 + cnt] = idx + G_W
                    cnt = cnt + 1
                }
            }
            G_neigh_cnt[idx] = cnt
            xi = xi + 1
        }
        y = y + 1
    }

    G_seen[G_root] = 1
    let mut q_end: i64 = 0
    let nb0: i64 = G_neigh_cnt[G_root]
    let mut k: i64 = 0
    while k < nb0 {
        let nb_idx: i64 = G_neigh[G_root * 4 + k]
        if G_seen[nb_idx] == 0 {
            G_seen[nb_idx] = 1
            G_Q[q_end] = nb_idx
            q_end = q_end + 1
        }
        k = k + 1
    }

    G_ans = 0
    rec_sym(0, q_end, 1)
    let ans: i64 = G_ans
    free(G_x_of); free(G_neigh); free(G_neigh_cnt); free(G_seen); free(G_Q)
    return ans
}

function main() -> i32 {
    let n: i64 = 18
    let total: i64 = count_total(n)
    let sym: i64 = count_symmetric(n)
    let ans: i64 = (total + sym) / 2
    printf("%lld\n", ans)
    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; }

void rec_total_i64_i64_i64_i64_i64_i64(int64_t q_begin, int64_t q_end, int64_t size, int64_t moment, int64_t minx, int64_t maxx);
int64_t count_total_i64(int64_t n);
void rec_sym_i64_i64_i64(int64_t q_begin, int64_t q_end, int64_t full_size);
int64_t count_symmetric_i64(int64_t n);
int32_t main(void);

/* Module statics */
static int64_t G_n = 18;
static int64_t G_XMAX = 17;
static int64_t G_W = 35;
static int64_t G_SHIFT = 17;
static int64_t G_GRID = 630;
static int64_t G_root = 17;
static int64_t* G_x_of = NULL;
static int64_t* G_neigh = NULL;
static int64_t* G_neigh_cnt = NULL;
static int8_t* G_seen = NULL;
static int64_t* G_Q = NULL;
static int64_t G_ans = 0;



void rec_total_i64_i64_i64_i64_i64_i64(int64_t q_begin, int64_t q_end, int64_t size, int64_t moment, int64_t minx, int64_t maxx) {
    if (size == G_n) {
        if (moment == 0) {
            G_ans = (G_ans + 1);
        }
        return;
    }
    int64_t r = (G_n - size);
    int64_t min_possible_x = (minx - r);
    int64_t max_possible_x = (maxx + r);
    if ((moment + (r * min_possible_x)) > 0) {
        return;
    }
    if ((moment + (r * max_possible_x)) < 0) {
        return;
    }
    int64_t i = q_begin;
    while (i < q_end) {
        int64_t cell = G_Q[i];
        int64_t x = G_x_of[cell];
        int64_t added = 0;
        int64_t nb = G_neigh_cnt[cell];
        int64_t k = 0;
        while (k < nb) {
            int64_t nb_idx = G_neigh[((cell * 4) + k)];
            if (G_seen[nb_idx] == 0) {
                G_seen[nb_idx] = 1;
                G_Q[(q_end + added)] = nb_idx;
                added = (added + 1);
            }
            k = (k + 1);
        }
        int64_t nmin = minx;
        if (x < nmin) {
            nmin = x;
        }
        int64_t nmax = maxx;
        if (x > nmax) {
            nmax = x;
        }
        rec_total_i64_i64_i64_i64_i64_i64((i + 1), (q_end + added), (size + 1), (moment + x), nmin, nmax);
        int64_t j = q_end;
        while (j < (q_end + added)) {
            G_seen[G_Q[j]] = 0;
            j = (j + 1);
        }
        i = (i + 1);
    }
}

int64_t count_total_i64(int64_t n) {
    G_n = n;
    G_XMAX = (n - 1);
    G_W = ((2 * G_XMAX) + 1);
    G_SHIFT = G_XMAX;
    G_GRID = (G_W * (G_XMAX + 1));
    G_root = G_SHIFT;
    G_x_of = calloc(G_GRID, 8);
    G_neigh = calloc((G_GRID * 4), 8);
    G_neigh_cnt = calloc(G_GRID, 8);
    G_seen = calloc(G_GRID, 1);
    G_Q = calloc(((8 * n) + 50), 8);
    int64_t y = 0;
    while (y <= G_XMAX) {
        int64_t base = (y * G_W);
        int64_t xi = 0;
        while (xi < G_W) {
            G_x_of[(base + xi)] = (xi - G_SHIFT);
            xi = (xi + 1);
        }
        y = (y + 1);
    }
    y = 0;
    while (y <= G_XMAX) {
        int64_t row = (y * G_W);
        int64_t xi = 0;
        while (xi < G_W) {
            int64_t idx = (row + xi);
            int64_t cnt = 0;
            if (xi > 0) {
                G_neigh[((idx * 4) + cnt)] = (idx - 1);
                cnt = (cnt + 1);
            }
            if (xi < (G_W - 1)) {
                G_neigh[((idx * 4) + cnt)] = (idx + 1);
                cnt = (cnt + 1);
            }
            if (y > 0) {
                G_neigh[((idx * 4) + cnt)] = (idx - G_W);
                cnt = (cnt + 1);
            }
            if (y < G_XMAX) {
                G_neigh[((idx * 4) + cnt)] = (idx + G_W);
                cnt = (cnt + 1);
            }
            G_neigh_cnt[idx] = cnt;
            xi = (xi + 1);
        }
        y = (y + 1);
    }
    G_seen[G_root] = 1;
    int64_t q_end = 0;
    int64_t nb0 = G_neigh_cnt[G_root];
    int64_t k = 0;
    while (k < nb0) {
        int64_t nb_idx = G_neigh[((G_root * 4) + k)];
        if (G_seen[nb_idx] == 0) {
            G_seen[nb_idx] = 1;
            G_Q[q_end] = nb_idx;
            q_end = (q_end + 1);
        }
        k = (k + 1);
    }
    G_ans = 0;
    rec_total_i64_i64_i64_i64_i64_i64(0, q_end, 1, 0, 0, 0);
    int64_t ans = G_ans;
    free(G_x_of);
    free(G_neigh);
    free(G_neigh_cnt);
    free(G_seen);
    free(G_Q);
    return ans;
}

void rec_sym_i64_i64_i64(int64_t q_begin, int64_t q_end, int64_t full_size) {
    if (full_size == G_n) {
        G_ans = (G_ans + 1);
        return;
    }
    int64_t i = q_begin;
    while (i < q_end) {
        int64_t cell = G_Q[i];
        int64_t x = G_x_of[cell];
        int64_t add = 1;
        int64_t add2 = 2;
        if (x == 0) {
            add2 = 1;
        }
        int64_t new_full = (full_size + add2);
        if (new_full > G_n) {
            i = (i + 1);
            continue;
        }
        int64_t added = 0;
        int64_t nb = G_neigh_cnt[cell];
        int64_t k = 0;
        while (k < nb) {
            int64_t nb_idx = G_neigh[((cell * 4) + k)];
            if (G_seen[nb_idx] == 0) {
                G_seen[nb_idx] = 1;
                G_Q[(q_end + added)] = nb_idx;
                added = (added + 1);
            }
            k = (k + 1);
        }
        rec_sym_i64_i64_i64((i + 1), (q_end + added), new_full);
        int64_t j = q_end;
        while (j < (q_end + added)) {
            G_seen[G_Q[j]] = 0;
            j = (j + 1);
        }
        i = (i + 1);
    }
}

int64_t count_symmetric_i64(int64_t n) {
    G_n = n;
    G_XMAX = (n - 1);
    G_W = ((2 * G_XMAX) + 1);
    G_SHIFT = G_XMAX;
    G_GRID = (G_W * (G_XMAX + 1));
    G_root = G_SHIFT;
    G_x_of = calloc(G_GRID, 8);
    G_neigh = calloc((G_GRID * 4), 8);
    G_neigh_cnt = calloc(G_GRID, 8);
    G_seen = calloc(G_GRID, 1);
    G_Q = calloc(((8 * n) + 50), 8);
    int64_t y = 0;
    while (y <= G_XMAX) {
        int64_t base = (y * G_W);
        int64_t xi = 0;
        while (xi < G_W) {
            G_x_of[(base + xi)] = (xi - G_SHIFT);
            xi = (xi + 1);
        }
        y = (y + 1);
    }
    y = 0;
    while (y <= G_XMAX) {
        int64_t row = (y * G_W);
        int64_t xi = 0;
        while (xi < G_W) {
            int64_t idx = (row + xi);
            int64_t x = (xi - G_SHIFT);
            int64_t cnt = 0;
            if (x >= 0) {
                if (xi > G_SHIFT) {
                    G_neigh[((idx * 4) + cnt)] = (idx - 1);
                    cnt = (cnt + 1);
                }
                if (xi < (G_W - 1)) {
                    G_neigh[((idx * 4) + cnt)] = (idx + 1);
                    cnt = (cnt + 1);
                }
                if (y > 0) {
                    G_neigh[((idx * 4) + cnt)] = (idx - G_W);
                    cnt = (cnt + 1);
                }
                if (y < G_XMAX) {
                    G_neigh[((idx * 4) + cnt)] = (idx + G_W);
                    cnt = (cnt + 1);
                }
            }
            G_neigh_cnt[idx] = cnt;
            xi = (xi + 1);
        }
        y = (y + 1);
    }
    G_seen[G_root] = 1;
    int64_t q_end = 0;
    int64_t nb0 = G_neigh_cnt[G_root];
    int64_t k = 0;
    while (k < nb0) {
        int64_t nb_idx = G_neigh[((G_root * 4) + k)];
        if (G_seen[nb_idx] == 0) {
            G_seen[nb_idx] = 1;
            G_Q[q_end] = nb_idx;
            q_end = (q_end + 1);
        }
        k = (k + 1);
    }
    G_ans = 0;
    rec_sym_i64_i64_i64(0, q_end, 1);
    int64_t ans = G_ans;
    free(G_x_of);
    free(G_neigh);
    free(G_neigh_cnt);
    free(G_seen);
    free(G_Q);
    return ans;
}

int32_t main(void) {
    int64_t n = 18;
    int64_t total = count_total_i64(n);
    int64_t sym = count_symmetric_i64(n);
    int64_t ans = FLOW_CHECKED_DIV(((total + sym)), (2));
    printf("%lld\n", ans);
    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) -> ()
  // Module static: G_n
  llvm.mlir.global internal @G_n(18 : i64) : i64
  // Module static: G_XMAX
  llvm.mlir.global internal @G_XMAX(17 : i64) : i64
  // Module static: G_W
  llvm.mlir.global internal @G_W(35 : i64) : i64
  // Module static: G_SHIFT
  llvm.mlir.global internal @G_SHIFT(17 : i64) : i64
  // Module static: G_GRID
  llvm.mlir.global internal @G_GRID(630 : i64) : i64
  // Module static: G_root
  llvm.mlir.global internal @G_root(17 : i64) : i64
  // Module static: G_x_of
  llvm.mlir.global internal @G_x_of() {addr_space = 0 : i32} : !llvm.ptr {
    %0 = llvm.mlir.zero : !llvm.ptr
    llvm.return %0 : !llvm.ptr
  }
  // Module static: G_neigh
  llvm.mlir.global internal @G_neigh() {addr_space = 0 : i32} : !llvm.ptr {
    %1 = llvm.mlir.zero : !llvm.ptr
    llvm.return %1 : !llvm.ptr
  }
  // Module static: G_neigh_cnt
  llvm.mlir.global internal @G_neigh_cnt() {addr_space = 0 : i32} : !llvm.ptr {
    %2 = llvm.mlir.zero : !llvm.ptr
    llvm.return %2 : !llvm.ptr
  }
  // Module static: G_seen
  llvm.mlir.global internal @G_seen() {addr_space = 0 : i32} : !llvm.ptr {
    %3 = llvm.mlir.zero : !llvm.ptr
    llvm.return %3 : !llvm.ptr
  }
  // Module static: G_Q
  llvm.mlir.global internal @G_Q() {addr_space = 0 : i32} : !llvm.ptr {
    %4 = llvm.mlir.zero : !llvm.ptr
    llvm.return %4 : !llvm.ptr
  }
  // Module static: G_ans
  llvm.mlir.global internal @G_ans(0 : i64) : i64
  func.func @rec_total(%arg0: i64, %arg1: i64, %arg2: i64, %arg3: i64, %arg4: i64, %arg5: i64) -> () {
    %5 = llvm.mlir.addressof @G_n : !llvm.ptr
    %6 = llvm.load %5 : !llvm.ptr -> i64
    %7 = arith.cmpi eq, %arg2, %6 : i64
    cf.cond_br %7, ^bb0, ^bb1
    ^bb0:
      %8 = arith.constant 0 : i32
      %10 = arith.extsi %8 : i32 to i64
      %9 = arith.cmpi eq, %arg3, %10 : i64
      cf.cond_br %9, ^bb3, ^bb4
      ^bb3:
        %11 = llvm.mlir.addressof @G_ans : !llvm.ptr
        %12 = llvm.load %11 : !llvm.ptr -> i64
        %13 = arith.constant 1 : i32
        %15 = arith.extsi %13 : i32 to i64
        %14 = arith.addi %12, %15 : i64
        %16 = llvm.mlir.addressof @G_ans : !llvm.ptr
        llvm.store %14, %16 : i64, !llvm.ptr
        cf.br ^bb5
      ^bb4:
        cf.br ^bb5
      ^bb5:
      func.return
    ^bb1:
      cf.br ^bb2
    ^bb2:
    %17 = llvm.mlir.addressof @G_n : !llvm.ptr
    %18 = llvm.load %17 : !llvm.ptr -> i64
    %19 = arith.subi %18, %arg2 : i64
    %20 = arith.subi %arg4, %19 : i64
    %21 = arith.addi %arg5, %19 : i64
    %22 = arith.muli %19, %20 : i64
    %23 = arith.addi %arg3, %22 : i64
    %24 = arith.constant 0 : i32
    %26 = arith.extsi %24 : i32 to i64
    %25 = arith.cmpi sgt, %23, %26 : i64
    cf.cond_br %25, ^bb6, ^bb7
    ^bb6:
      func.return
    ^bb7:
      cf.br ^bb8
    ^bb8:
    %27 = arith.muli %19, %21 : i64
    %28 = arith.addi %arg3, %27 : i64
    %29 = arith.constant 0 : i32
    %31 = arith.extsi %29 : i32 to i64
    %30 = arith.cmpi slt, %28, %31 : i64
    cf.cond_br %30, ^bb9, ^bb10
    ^bb9:
      func.return
    ^bb10:
      cf.br ^bb11
    ^bb11:
    %32 = llvm.mlir.constant(1 : i64) : i64
    %33 = llvm.alloca %32 x i64 : (i64) -> !llvm.ptr
    llvm.store %arg0, %33 : i64, !llvm.ptr
    cf.br ^bb12
    ^bb12:
    %34 = llvm.load %33 : !llvm.ptr -> i64
    %35 = arith.cmpi slt, %34, %arg1 : i64
    cf.cond_br %35, ^bb13, ^bb14
    ^bb13:
      %37 = llvm.mlir.addressof @G_Q : !llvm.ptr
      %38 = llvm.load %37 : !llvm.ptr -> !llvm.ptr
      %39 = llvm.load %33 : !llvm.ptr -> i64
      %40 = llvm.getelementptr %38[%39] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %36 = llvm.load %40 : !llvm.ptr -> i64
      %42 = llvm.mlir.addressof @G_x_of : !llvm.ptr
      %43 = llvm.load %42 : !llvm.ptr -> !llvm.ptr
      %44 = llvm.getelementptr %43[%36] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %41 = llvm.load %44 : !llvm.ptr -> i64
      %45 = arith.constant 0 : i32
      %46 = arith.extsi %45 : i32 to i64
      %47 = llvm.mlir.constant(1 : i64) : i64
      %48 = llvm.alloca %47 x i64 : (i64) -> !llvm.ptr
      llvm.store %46, %48 : i64, !llvm.ptr
      %50 = llvm.mlir.addressof @G_neigh_cnt : !llvm.ptr
      %51 = llvm.load %50 : !llvm.ptr -> !llvm.ptr
      %52 = llvm.getelementptr %51[%36] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %49 = llvm.load %52 : !llvm.ptr -> i64
      %53 = arith.constant 0 : i32
      %54 = arith.extsi %53 : i32 to i64
      %55 = llvm.mlir.constant(1 : i64) : i64
      %56 = llvm.alloca %55 x i64 : (i64) -> !llvm.ptr
      llvm.store %54, %56 : i64, !llvm.ptr
      cf.br ^bb15
      ^bb15:
      %57 = llvm.load %56 : !llvm.ptr -> i64
      %58 = arith.cmpi slt, %57, %49 : i64
      cf.cond_br %58, ^bb16, ^bb17
      ^bb16:
        %60 = llvm.mlir.addressof @G_neigh : !llvm.ptr
        %61 = llvm.load %60 : !llvm.ptr -> !llvm.ptr
        %62 = arith.constant 4 : i32
        %64 = arith.extsi %62 : i32 to i64
        %63 = arith.muli %36, %64 : i64
        %65 = llvm.load %56 : !llvm.ptr -> i64
        %66 = arith.addi %63, %65 : i64
        %67 = llvm.getelementptr %61[%66] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %59 = llvm.load %67 : !llvm.ptr -> i64
        %69 = llvm.mlir.addressof @G_seen : !llvm.ptr
        %70 = llvm.load %69 : !llvm.ptr -> !llvm.ptr
        %71 = llvm.getelementptr %70[%59] : (!llvm.ptr, i64) -> !llvm.ptr, i8
        %68 = llvm.load %71 : !llvm.ptr -> i8
        %72 = arith.constant 0 : i32
        %74 = arith.extsi %68 : i8 to i32
        %73 = arith.cmpi eq, %74, %72 : i32
        cf.cond_br %73, ^bb18, ^bb19
        ^bb18:
          %75 = arith.constant 1 : i32
          %76 = llvm.mlir.addressof @G_seen : !llvm.ptr
          %77 = llvm.load %76 : !llvm.ptr -> !llvm.ptr
          %78 = arith.trunci %75 : i32 to i8
          %79 = llvm.getelementptr %77[%59] : (!llvm.ptr, i64) -> !llvm.ptr, i8
          llvm.store %78, %79 : i8, !llvm.ptr
          %80 = llvm.mlir.addressof @G_Q : !llvm.ptr
          %81 = llvm.load %80 : !llvm.ptr -> !llvm.ptr
          %82 = llvm.load %48 : !llvm.ptr -> i64
          %83 = arith.addi %arg1, %82 : i64
          %84 = llvm.getelementptr %81[%83] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %59, %84 : i64, !llvm.ptr
          %85 = llvm.load %48 : !llvm.ptr -> i64
          %86 = arith.constant 1 : i32
          %88 = arith.extsi %86 : i32 to i64
          %87 = arith.addi %85, %88 : i64
          llvm.store %87, %48 : i64, !llvm.ptr
          cf.br ^bb20
        ^bb19:
          cf.br ^bb20
        ^bb20:
        %89 = llvm.load %56 : !llvm.ptr -> i64
        %90 = arith.constant 1 : i32
        %92 = arith.extsi %90 : i32 to i64
        %91 = arith.addi %89, %92 : i64
        llvm.store %91, %56 : i64, !llvm.ptr
        cf.br ^bb15
      ^bb17:
      %93 = llvm.mlir.constant(1 : i64) : i64
      %94 = llvm.alloca %93 x i64 : (i64) -> !llvm.ptr
      llvm.store %arg4, %94 : i64, !llvm.ptr
      %95 = llvm.load %94 : !llvm.ptr -> i64
      %96 = arith.cmpi slt, %41, %95 : i64
      cf.cond_br %96, ^bb21, ^bb22
      ^bb21:
        llvm.store %41, %94 : i64, !llvm.ptr
        cf.br ^bb23
      ^bb22:
        cf.br ^bb23
      ^bb23:
      %97 = llvm.mlir.constant(1 : i64) : i64
      %98 = llvm.alloca %97 x i64 : (i64) -> !llvm.ptr
      llvm.store %arg5, %98 : i64, !llvm.ptr
      %99 = llvm.load %98 : !llvm.ptr -> i64
      %100 = arith.cmpi sgt, %41, %99 : i64
      cf.cond_br %100, ^bb24, ^bb25
      ^bb24:
        llvm.store %41, %98 : i64, !llvm.ptr
        cf.br ^bb26
      ^bb25:
        cf.br ^bb26
      ^bb26:
      %102 = llvm.load %33 : !llvm.ptr -> i64
      %103 = arith.constant 1 : i32
      %105 = arith.extsi %103 : i32 to i64
      %104 = arith.addi %102, %105 : i64
      %106 = llvm.load %48 : !llvm.ptr -> i64
      %107 = arith.addi %arg1, %106 : i64
      %108 = arith.constant 1 : i32
      %110 = arith.extsi %108 : i32 to i64
      %109 = arith.addi %arg2, %110 : i64
      %111 = arith.addi %arg3, %41 : i64
      %112 = llvm.load %94 : !llvm.ptr -> i64
      %113 = llvm.load %98 : !llvm.ptr -> i64
      func.call @rec_total(%104, %107, %109, %111, %112, %113) : (i64, i64, i64, i64, i64, i64) -> ()
      %114 = llvm.mlir.constant(1 : i64) : i64
      %115 = llvm.alloca %114 x i64 : (i64) -> !llvm.ptr
      llvm.store %arg1, %115 : i64, !llvm.ptr
      cf.br ^bb27
      ^bb27:
      %116 = llvm.load %115 : !llvm.ptr -> i64
      %117 = llvm.load %48 : !llvm.ptr -> i64
      %118 = arith.addi %arg1, %117 : i64
      %119 = arith.cmpi slt, %116, %118 : i64
      cf.cond_br %119, ^bb28, ^bb29
      ^bb28:
        %120 = arith.constant 0 : i32
        %121 = llvm.mlir.addressof @G_seen : !llvm.ptr
        %122 = llvm.load %121 : !llvm.ptr -> !llvm.ptr
        %124 = llvm.mlir.addressof @G_Q : !llvm.ptr
        %125 = llvm.load %124 : !llvm.ptr -> !llvm.ptr
        %126 = llvm.load %115 : !llvm.ptr -> i64
        %127 = llvm.getelementptr %125[%126] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %123 = llvm.load %127 : !llvm.ptr -> i64
        %128 = arith.trunci %120 : i32 to i8
        %129 = llvm.getelementptr %122[%123] : (!llvm.ptr, i64) -> !llvm.ptr, i8
        llvm.store %128, %129 : i8, !llvm.ptr
        %130 = llvm.load %115 : !llvm.ptr -> i64
        %131 = arith.constant 1 : i32
        %133 = arith.extsi %131 : i32 to i64
        %132 = arith.addi %130, %133 : i64
        llvm.store %132, %115 : i64, !llvm.ptr
        cf.br ^bb27
      ^bb29:
      %134 = llvm.load %33 : !llvm.ptr -> i64
      %135 = arith.constant 1 : i32
      %137 = arith.extsi %135 : i32 to i64
      %136 = arith.addi %134, %137 : i64
      llvm.store %136, %33 : i64, !llvm.ptr
      cf.br ^bb12
    ^bb14:
    func.return
  }
  func.func @count_total(%arg0: i64) -> i64 {
    %138 = llvm.mlir.addressof @G_n : !llvm.ptr
    llvm.store %arg0, %138 : i64, !llvm.ptr
    %139 = arith.constant 1 : i32
    %141 = arith.extsi %139 : i32 to i64
    %140 = arith.subi %arg0, %141 : i64
    %142 = llvm.mlir.addressof @G_XMAX : !llvm.ptr
    llvm.store %140, %142 : i64, !llvm.ptr
    %143 = arith.constant 2 : i32
    %144 = llvm.mlir.addressof @G_XMAX : !llvm.ptr
    %145 = llvm.load %144 : !llvm.ptr -> i64
    %147 = arith.extsi %143 : i32 to i64
    %146 = arith.muli %147, %145 : i64
    %148 = arith.constant 1 : i32
    %150 = arith.extsi %148 : i32 to i64
    %149 = arith.addi %146, %150 : i64
    %151 = llvm.mlir.addressof @G_W : !llvm.ptr
    llvm.store %149, %151 : i64, !llvm.ptr
    %152 = llvm.mlir.addressof @G_XMAX : !llvm.ptr
    %153 = llvm.load %152 : !llvm.ptr -> i64
    %154 = llvm.mlir.addressof @G_SHIFT : !llvm.ptr
    llvm.store %153, %154 : i64, !llvm.ptr
    %155 = llvm.mlir.addressof @G_W : !llvm.ptr
    %156 = llvm.load %155 : !llvm.ptr -> i64
    %157 = llvm.mlir.addressof @G_XMAX : !llvm.ptr
    %158 = llvm.load %157 : !llvm.ptr -> i64
    %159 = arith.constant 1 : i32
    %161 = arith.extsi %159 : i32 to i64
    %160 = arith.addi %158, %161 : i64
    %162 = arith.muli %156, %160 : i64
    %163 = llvm.mlir.addressof @G_GRID : !llvm.ptr
    llvm.store %162, %163 : i64, !llvm.ptr
    %164 = llvm.mlir.addressof @G_SHIFT : !llvm.ptr
    %165 = llvm.load %164 : !llvm.ptr -> i64
    %166 = llvm.mlir.addressof @G_root : !llvm.ptr
    llvm.store %165, %166 : i64, !llvm.ptr
    %168 = llvm.mlir.addressof @G_GRID : !llvm.ptr
    %169 = llvm.load %168 : !llvm.ptr -> i64
    %170 = arith.constant 8 : i32
    %171 = arith.extsi %170 : i32 to i64
    %167 = func.call @calloc(%169, %171) : (i64, i64) -> !llvm.ptr
    %172 = llvm.mlir.addressof @G_x_of : !llvm.ptr
    llvm.store %167, %172 : !llvm.ptr, !llvm.ptr
    %174 = llvm.mlir.addressof @G_GRID : !llvm.ptr
    %175 = llvm.load %174 : !llvm.ptr -> i64
    %176 = arith.constant 4 : i32
    %178 = arith.extsi %176 : i32 to i64
    %177 = arith.muli %175, %178 : i64
    %179 = arith.constant 8 : i32
    %180 = arith.extsi %179 : i32 to i64
    %173 = func.call @calloc(%177, %180) : (i64, i64) -> !llvm.ptr
    %181 = llvm.mlir.addressof @G_neigh : !llvm.ptr
    llvm.store %173, %181 : !llvm.ptr, !llvm.ptr
    %183 = llvm.mlir.addressof @G_GRID : !llvm.ptr
    %184 = llvm.load %183 : !llvm.ptr -> i64
    %185 = arith.constant 8 : i32
    %186 = arith.extsi %185 : i32 to i64
    %182 = func.call @calloc(%184, %186) : (i64, i64) -> !llvm.ptr
    %187 = llvm.mlir.addressof @G_neigh_cnt : !llvm.ptr
    llvm.store %182, %187 : !llvm.ptr, !llvm.ptr
    %189 = llvm.mlir.addressof @G_GRID : !llvm.ptr
    %190 = llvm.load %189 : !llvm.ptr -> i64
    %191 = arith.constant 1 : i32
    %192 = arith.extsi %191 : i32 to i64
    %188 = func.call @calloc(%190, %192) : (i64, i64) -> !llvm.ptr
    %193 = llvm.mlir.addressof @G_seen : !llvm.ptr
    llvm.store %188, %193 : !llvm.ptr, !llvm.ptr
    %195 = arith.constant 8 : i32
    %197 = arith.extsi %195 : i32 to i64
    %196 = arith.muli %197, %arg0 : i64
    %198 = arith.constant 50 : i32
    %200 = arith.extsi %198 : i32 to i64
    %199 = arith.addi %196, %200 : i64
    %201 = arith.constant 8 : i32
    %202 = arith.extsi %201 : i32 to i64
    %194 = func.call @calloc(%199, %202) : (i64, i64) -> !llvm.ptr
    %203 = llvm.mlir.addressof @G_Q : !llvm.ptr
    llvm.store %194, %203 : !llvm.ptr, !llvm.ptr
    %204 = arith.constant 0 : i32
    %205 = arith.extsi %204 : i32 to i64
    %206 = llvm.mlir.constant(1 : i64) : i64
    %207 = llvm.alloca %206 x i64 : (i64) -> !llvm.ptr
    llvm.store %205, %207 : i64, !llvm.ptr
    cf.br ^bb30
    ^bb30:
    %208 = llvm.load %207 : !llvm.ptr -> i64
    %209 = llvm.mlir.addressof @G_XMAX : !llvm.ptr
    %210 = llvm.load %209 : !llvm.ptr -> i64
    %211 = arith.cmpi sle, %208, %210 : i64
    cf.cond_br %211, ^bb31, ^bb32
    ^bb31:
      %212 = llvm.load %207 : !llvm.ptr -> i64
      %213 = llvm.mlir.addressof @G_W : !llvm.ptr
      %214 = llvm.load %213 : !llvm.ptr -> i64
      %215 = arith.muli %212, %214 : i64
      %216 = arith.constant 0 : i32
      %217 = arith.extsi %216 : i32 to i64
      %218 = llvm.mlir.constant(1 : i64) : i64
      %219 = llvm.alloca %218 x i64 : (i64) -> !llvm.ptr
      llvm.store %217, %219 : i64, !llvm.ptr
      cf.br ^bb33
      ^bb33:
      %220 = llvm.load %219 : !llvm.ptr -> i64
      %221 = llvm.mlir.addressof @G_W : !llvm.ptr
      %222 = llvm.load %221 : !llvm.ptr -> i64
      %223 = arith.cmpi slt, %220, %222 : i64
      cf.cond_br %223, ^bb34, ^bb35
      ^bb34:
        %224 = llvm.load %219 : !llvm.ptr -> i64
        %225 = llvm.mlir.addressof @G_SHIFT : !llvm.ptr
        %226 = llvm.load %225 : !llvm.ptr -> i64
        %227 = arith.subi %224, %226 : i64
        %228 = llvm.mlir.addressof @G_x_of : !llvm.ptr
        %229 = llvm.load %228 : !llvm.ptr -> !llvm.ptr
        %230 = llvm.load %219 : !llvm.ptr -> i64
        %231 = arith.addi %215, %230 : i64
        %232 = llvm.getelementptr %229[%231] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %227, %232 : i64, !llvm.ptr
        %233 = llvm.load %219 : !llvm.ptr -> i64
        %234 = arith.constant 1 : i32
        %236 = arith.extsi %234 : i32 to i64
        %235 = arith.addi %233, %236 : i64
        llvm.store %235, %219 : i64, !llvm.ptr
        cf.br ^bb33
      ^bb35:
      %237 = llvm.load %207 : !llvm.ptr -> i64
      %238 = arith.constant 1 : i32
      %240 = arith.extsi %238 : i32 to i64
      %239 = arith.addi %237, %240 : i64
      llvm.store %239, %207 : i64, !llvm.ptr
      cf.br ^bb30
    ^bb32:
    %241 = arith.constant 0 : i32
    %242 = arith.extsi %241 : i32 to i64
    llvm.store %242, %207 : i64, !llvm.ptr
    cf.br ^bb36
    ^bb36:
    %243 = llvm.load %207 : !llvm.ptr -> i64
    %244 = llvm.mlir.addressof @G_XMAX : !llvm.ptr
    %245 = llvm.load %244 : !llvm.ptr -> i64
    %246 = arith.cmpi sle, %243, %245 : i64
    cf.cond_br %246, ^bb37, ^bb38
    ^bb37:
      %247 = llvm.load %207 : !llvm.ptr -> i64
      %248 = llvm.mlir.addressof @G_W : !llvm.ptr
      %249 = llvm.load %248 : !llvm.ptr -> i64
      %250 = arith.muli %247, %249 : i64
      %251 = arith.constant 0 : i32
      %252 = arith.extsi %251 : i32 to i64
      %253 = llvm.mlir.constant(1 : i64) : i64
      %254 = llvm.alloca %253 x i64 : (i64) -> !llvm.ptr
      llvm.store %252, %254 : i64, !llvm.ptr
      cf.br ^bb39
      ^bb39:
      %255 = llvm.load %254 : !llvm.ptr -> i64
      %256 = llvm.mlir.addressof @G_W : !llvm.ptr
      %257 = llvm.load %256 : !llvm.ptr -> i64
      %258 = arith.cmpi slt, %255, %257 : i64
      cf.cond_br %258, ^bb40, ^bb41
      ^bb40:
        %259 = llvm.load %254 : !llvm.ptr -> i64
        %260 = arith.addi %250, %259 : i64
        %261 = arith.constant 0 : i32
        %262 = arith.extsi %261 : i32 to i64
        %263 = llvm.mlir.constant(1 : i64) : i64
        %264 = llvm.alloca %263 x i64 : (i64) -> !llvm.ptr
        llvm.store %262, %264 : i64, !llvm.ptr
        %265 = llvm.load %254 : !llvm.ptr -> i64
        %266 = arith.constant 0 : i32
        %268 = arith.extsi %266 : i32 to i64
        %267 = arith.cmpi sgt, %265, %268 : i64
        cf.cond_br %267, ^bb42, ^bb43
        ^bb42:
          %269 = arith.constant 1 : i32
          %271 = arith.extsi %269 : i32 to i64
          %270 = arith.subi %260, %271 : i64
          %272 = llvm.mlir.addressof @G_neigh : !llvm.ptr
          %273 = llvm.load %272 : !llvm.ptr -> !llvm.ptr
          %274 = arith.constant 4 : i32
          %276 = arith.extsi %274 : i32 to i64
          %275 = arith.muli %260, %276 : i64
          %277 = llvm.load %264 : !llvm.ptr -> i64
          %278 = arith.addi %275, %277 : i64
          %279 = llvm.getelementptr %273[%278] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %270, %279 : i64, !llvm.ptr
          %280 = llvm.load %264 : !llvm.ptr -> i64
          %281 = arith.constant 1 : i32
          %283 = arith.extsi %281 : i32 to i64
          %282 = arith.addi %280, %283 : i64
          llvm.store %282, %264 : i64, !llvm.ptr
          cf.br ^bb44
        ^bb43:
          cf.br ^bb44
        ^bb44:
        %284 = llvm.load %254 : !llvm.ptr -> i64
        %285 = llvm.mlir.addressof @G_W : !llvm.ptr
        %286 = llvm.load %285 : !llvm.ptr -> i64
        %287 = arith.constant 1 : i32
        %289 = arith.extsi %287 : i32 to i64
        %288 = arith.subi %286, %289 : i64
        %290 = arith.cmpi slt, %284, %288 : i64
        cf.cond_br %290, ^bb45, ^bb46
        ^bb45:
          %291 = arith.constant 1 : i32
          %293 = arith.extsi %291 : i32 to i64
          %292 = arith.addi %260, %293 : i64
          %294 = llvm.mlir.addressof @G_neigh : !llvm.ptr
          %295 = llvm.load %294 : !llvm.ptr -> !llvm.ptr
          %296 = arith.constant 4 : i32
          %298 = arith.extsi %296 : i32 to i64
          %297 = arith.muli %260, %298 : i64
          %299 = llvm.load %264 : !llvm.ptr -> i64
          %300 = arith.addi %297, %299 : i64
          %301 = llvm.getelementptr %295[%300] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %292, %301 : i64, !llvm.ptr
          %302 = llvm.load %264 : !llvm.ptr -> i64
          %303 = arith.constant 1 : i32
          %305 = arith.extsi %303 : i32 to i64
          %304 = arith.addi %302, %305 : i64
          llvm.store %304, %264 : i64, !llvm.ptr
          cf.br ^bb47
        ^bb46:
          cf.br ^bb47
        ^bb47:
        %306 = llvm.load %207 : !llvm.ptr -> i64
        %307 = arith.constant 0 : i32
        %309 = arith.extsi %307 : i32 to i64
        %308 = arith.cmpi sgt, %306, %309 : i64
        cf.cond_br %308, ^bb48, ^bb49
        ^bb48:
          %310 = llvm.mlir.addressof @G_W : !llvm.ptr
          %311 = llvm.load %310 : !llvm.ptr -> i64
          %312 = arith.subi %260, %311 : i64
          %313 = llvm.mlir.addressof @G_neigh : !llvm.ptr
          %314 = llvm.load %313 : !llvm.ptr -> !llvm.ptr
          %315 = arith.constant 4 : i32
          %317 = arith.extsi %315 : i32 to i64
          %316 = arith.muli %260, %317 : i64
          %318 = llvm.load %264 : !llvm.ptr -> i64
          %319 = arith.addi %316, %318 : i64
          %320 = llvm.getelementptr %314[%319] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %312, %320 : i64, !llvm.ptr
          %321 = llvm.load %264 : !llvm.ptr -> i64
          %322 = arith.constant 1 : i32
          %324 = arith.extsi %322 : i32 to i64
          %323 = arith.addi %321, %324 : i64
          llvm.store %323, %264 : i64, !llvm.ptr
          cf.br ^bb50
        ^bb49:
          cf.br ^bb50
        ^bb50:
        %325 = llvm.load %207 : !llvm.ptr -> i64
        %326 = llvm.mlir.addressof @G_XMAX : !llvm.ptr
        %327 = llvm.load %326 : !llvm.ptr -> i64
        %328 = arith.cmpi slt, %325, %327 : i64
        cf.cond_br %328, ^bb51, ^bb52
        ^bb51:
          %329 = llvm.mlir.addressof @G_W : !llvm.ptr
          %330 = llvm.load %329 : !llvm.ptr -> i64
          %331 = arith.addi %260, %330 : i64
          %332 = llvm.mlir.addressof @G_neigh : !llvm.ptr
          %333 = llvm.load %332 : !llvm.ptr -> !llvm.ptr
          %334 = arith.constant 4 : i32
          %336 = arith.extsi %334 : i32 to i64
          %335 = arith.muli %260, %336 : i64
          %337 = llvm.load %264 : !llvm.ptr -> i64
          %338 = arith.addi %335, %337 : i64
          %339 = llvm.getelementptr %333[%338] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %331, %339 : i64, !llvm.ptr
          %340 = llvm.load %264 : !llvm.ptr -> i64
          %341 = arith.constant 1 : i32
          %343 = arith.extsi %341 : i32 to i64
          %342 = arith.addi %340, %343 : i64
          llvm.store %342, %264 : i64, !llvm.ptr
          cf.br ^bb53
        ^bb52:
          cf.br ^bb53
        ^bb53:
        %344 = llvm.load %264 : !llvm.ptr -> i64
        %345 = llvm.mlir.addressof @G_neigh_cnt : !llvm.ptr
        %346 = llvm.load %345 : !llvm.ptr -> !llvm.ptr
        %347 = llvm.getelementptr %346[%260] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %344, %347 : i64, !llvm.ptr
        %348 = llvm.load %254 : !llvm.ptr -> i64
        %349 = arith.constant 1 : i32
        %351 = arith.extsi %349 : i32 to i64
        %350 = arith.addi %348, %351 : i64
        llvm.store %350, %254 : i64, !llvm.ptr
        cf.br ^bb39
      ^bb41:
      %352 = llvm.load %207 : !llvm.ptr -> i64
      %353 = arith.constant 1 : i32
      %355 = arith.extsi %353 : i32 to i64
      %354 = arith.addi %352, %355 : i64
      llvm.store %354, %207 : i64, !llvm.ptr
      cf.br ^bb36
    ^bb38:
    %356 = arith.constant 1 : i32
    %357 = llvm.mlir.addressof @G_seen : !llvm.ptr
    %358 = llvm.load %357 : !llvm.ptr -> !llvm.ptr
    %359 = llvm.mlir.addressof @G_root : !llvm.ptr
    %360 = llvm.load %359 : !llvm.ptr -> i64
    %361 = arith.trunci %356 : i32 to i8
    %362 = llvm.getelementptr %358[%360] : (!llvm.ptr, i64) -> !llvm.ptr, i8
    llvm.store %361, %362 : i8, !llvm.ptr
    %363 = arith.constant 0 : i32
    %364 = arith.extsi %363 : i32 to i64
    %365 = llvm.mlir.constant(1 : i64) : i64
    %366 = llvm.alloca %365 x i64 : (i64) -> !llvm.ptr
    llvm.store %364, %366 : i64, !llvm.ptr
    %368 = llvm.mlir.addressof @G_neigh_cnt : !llvm.ptr
    %369 = llvm.load %368 : !llvm.ptr -> !llvm.ptr
    %370 = llvm.mlir.addressof @G_root : !llvm.ptr
    %371 = llvm.load %370 : !llvm.ptr -> i64
    %372 = llvm.getelementptr %369[%371] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    %367 = llvm.load %372 : !llvm.ptr -> i64
    %373 = arith.constant 0 : i32
    %374 = arith.extsi %373 : i32 to i64
    %375 = llvm.mlir.constant(1 : i64) : i64
    %376 = llvm.alloca %375 x i64 : (i64) -> !llvm.ptr
    llvm.store %374, %376 : i64, !llvm.ptr
    cf.br ^bb54
    ^bb54:
    %377 = llvm.load %376 : !llvm.ptr -> i64
    %378 = arith.cmpi slt, %377, %367 : i64
    cf.cond_br %378, ^bb55, ^bb56
    ^bb55:
      %380 = llvm.mlir.addressof @G_neigh : !llvm.ptr
      %381 = llvm.load %380 : !llvm.ptr -> !llvm.ptr
      %382 = llvm.mlir.addressof @G_root : !llvm.ptr
      %383 = llvm.load %382 : !llvm.ptr -> i64
      %384 = arith.constant 4 : i32
      %386 = arith.extsi %384 : i32 to i64
      %385 = arith.muli %383, %386 : i64
      %387 = llvm.load %376 : !llvm.ptr -> i64
      %388 = arith.addi %385, %387 : i64
      %389 = llvm.getelementptr %381[%388] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %379 = llvm.load %389 : !llvm.ptr -> i64
      %391 = llvm.mlir.addressof @G_seen : !llvm.ptr
      %392 = llvm.load %391 : !llvm.ptr -> !llvm.ptr
      %393 = llvm.getelementptr %392[%379] : (!llvm.ptr, i64) -> !llvm.ptr, i8
      %390 = llvm.load %393 : !llvm.ptr -> i8
      %394 = arith.constant 0 : i32
      %396 = arith.extsi %390 : i8 to i32
      %395 = arith.cmpi eq, %396, %394 : i32
      cf.cond_br %395, ^bb57, ^bb58
      ^bb57:
        %397 = arith.constant 1 : i32
        %398 = llvm.mlir.addressof @G_seen : !llvm.ptr
        %399 = llvm.load %398 : !llvm.ptr -> !llvm.ptr
        %400 = arith.trunci %397 : i32 to i8
        %401 = llvm.getelementptr %399[%379] : (!llvm.ptr, i64) -> !llvm.ptr, i8
        llvm.store %400, %401 : i8, !llvm.ptr
        %402 = llvm.mlir.addressof @G_Q : !llvm.ptr
        %403 = llvm.load %402 : !llvm.ptr -> !llvm.ptr
        %404 = llvm.load %366 : !llvm.ptr -> i64
        %405 = llvm.getelementptr %403[%404] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %379, %405 : i64, !llvm.ptr
        %406 = llvm.load %366 : !llvm.ptr -> i64
        %407 = arith.constant 1 : i32
        %409 = arith.extsi %407 : i32 to i64
        %408 = arith.addi %406, %409 : i64
        llvm.store %408, %366 : i64, !llvm.ptr
        cf.br ^bb59
      ^bb58:
        cf.br ^bb59
      ^bb59:
      %410 = llvm.load %376 : !llvm.ptr -> i64
      %411 = arith.constant 1 : i32
      %413 = arith.extsi %411 : i32 to i64
      %412 = arith.addi %410, %413 : i64
      llvm.store %412, %376 : i64, !llvm.ptr
      cf.br ^bb54
    ^bb56:
    %414 = arith.constant 0 : i32
    %415 = arith.extsi %414 : i32 to i64
    %416 = llvm.mlir.addressof @G_ans : !llvm.ptr
    llvm.store %415, %416 : i64, !llvm.ptr
    %418 = arith.constant 0 : i32
    %419 = llvm.load %366 : !llvm.ptr -> i64
    %420 = arith.constant 1 : i32
    %421 = arith.constant 0 : i32
    %422 = arith.constant 0 : i32
    %423 = arith.constant 0 : i32
    %424 = arith.extsi %418 : i32 to i64
    %425 = arith.extsi %420 : i32 to i64
    %426 = arith.extsi %421 : i32 to i64
    %427 = arith.extsi %422 : i32 to i64
    %428 = arith.extsi %423 : i32 to i64
    func.call @rec_total(%424, %419, %425, %426, %427, %428) : (i64, i64, i64, i64, i64, i64) -> ()
    %429 = llvm.mlir.addressof @G_ans : !llvm.ptr
    %430 = llvm.load %429 : !llvm.ptr -> i64
    %432 = llvm.mlir.addressof @G_x_of : !llvm.ptr
    %433 = llvm.load %432 : !llvm.ptr -> !llvm.ptr
    func.call @free(%433) : (!llvm.ptr) -> ()
    %435 = llvm.mlir.addressof @G_neigh : !llvm.ptr
    %436 = llvm.load %435 : !llvm.ptr -> !llvm.ptr
    func.call @free(%436) : (!llvm.ptr) -> ()
    %438 = llvm.mlir.addressof @G_neigh_cnt : !llvm.ptr
    %439 = llvm.load %438 : !llvm.ptr -> !llvm.ptr
    func.call @free(%439) : (!llvm.ptr) -> ()
    %441 = llvm.mlir.addressof @G_seen : !llvm.ptr
    %442 = llvm.load %441 : !llvm.ptr -> !llvm.ptr
    func.call @free(%442) : (!llvm.ptr) -> ()
    %444 = llvm.mlir.addressof @G_Q : !llvm.ptr
    %445 = llvm.load %444 : !llvm.ptr -> !llvm.ptr
    func.call @free(%445) : (!llvm.ptr) -> ()
    func.return %430 : i64
  }
  func.func @rec_sym(%arg0: i64, %arg1: i64, %arg2: i64) -> () {
    %446 = llvm.mlir.addressof @G_n : !llvm.ptr
    %447 = llvm.load %446 : !llvm.ptr -> i64
    %448 = arith.cmpi eq, %arg2, %447 : i64
    cf.cond_br %448, ^bb60, ^bb61
    ^bb60:
      %449 = llvm.mlir.addressof @G_ans : !llvm.ptr
      %450 = llvm.load %449 : !llvm.ptr -> i64
      %451 = arith.constant 1 : i32
      %453 = arith.extsi %451 : i32 to i64
      %452 = arith.addi %450, %453 : i64
      %454 = llvm.mlir.addressof @G_ans : !llvm.ptr
      llvm.store %452, %454 : i64, !llvm.ptr
      func.return
    ^bb61:
      cf.br ^bb62
    ^bb62:
    %455 = llvm.mlir.constant(1 : i64) : i64
    %456 = llvm.alloca %455 x i64 : (i64) -> !llvm.ptr
    llvm.store %arg0, %456 : i64, !llvm.ptr
    cf.br ^bb63
    ^bb63:
    %457 = llvm.load %456 : !llvm.ptr -> i64
    %458 = arith.cmpi slt, %457, %arg1 : i64
    cf.cond_br %458, ^bb64, ^bb65
    ^bb64:
      %460 = llvm.mlir.addressof @G_Q : !llvm.ptr
      %461 = llvm.load %460 : !llvm.ptr -> !llvm.ptr
      %462 = llvm.load %456 : !llvm.ptr -> i64
      %463 = llvm.getelementptr %461[%462] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %459 = llvm.load %463 : !llvm.ptr -> i64
      %465 = llvm.mlir.addressof @G_x_of : !llvm.ptr
      %466 = llvm.load %465 : !llvm.ptr -> !llvm.ptr
      %467 = llvm.getelementptr %466[%459] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %464 = llvm.load %467 : !llvm.ptr -> i64
      %468 = arith.constant 1 : i32
      %469 = arith.extsi %468 : i32 to i64
      %470 = arith.constant 2 : i32
      %471 = arith.extsi %470 : i32 to i64
      %472 = llvm.mlir.constant(1 : i64) : i64
      %473 = llvm.alloca %472 x i64 : (i64) -> !llvm.ptr
      llvm.store %471, %473 : i64, !llvm.ptr
      %474 = arith.constant 0 : i32
      %476 = arith.extsi %474 : i32 to i64
      %475 = arith.cmpi eq, %464, %476 : i64
      cf.cond_br %475, ^bb66, ^bb67
      ^bb66:
        %477 = arith.constant 1 : i32
        %478 = arith.extsi %477 : i32 to i64
        llvm.store %478, %473 : i64, !llvm.ptr
        cf.br ^bb68
      ^bb67:
        cf.br ^bb68
      ^bb68:
      %479 = llvm.load %473 : !llvm.ptr -> i64
      %480 = arith.addi %arg2, %479 : i64
      %481 = llvm.mlir.addressof @G_n : !llvm.ptr
      %482 = llvm.load %481 : !llvm.ptr -> i64
      %483 = arith.cmpi sgt, %480, %482 : i64
      cf.cond_br %483, ^bb69, ^bb70
      ^bb69:
        %484 = llvm.load %456 : !llvm.ptr -> i64
        %485 = arith.constant 1 : i32
        %487 = arith.extsi %485 : i32 to i64
        %486 = arith.addi %484, %487 : i64
        llvm.store %486, %456 : i64, !llvm.ptr
        cf.br ^bb63
      ^bb70:
        cf.br ^bb71
      ^bb71:
      %488 = arith.constant 0 : i32
      %489 = arith.extsi %488 : i32 to i64
      %490 = llvm.mlir.constant(1 : i64) : i64
      %491 = llvm.alloca %490 x i64 : (i64) -> !llvm.ptr
      llvm.store %489, %491 : i64, !llvm.ptr
      %493 = llvm.mlir.addressof @G_neigh_cnt : !llvm.ptr
      %494 = llvm.load %493 : !llvm.ptr -> !llvm.ptr
      %495 = llvm.getelementptr %494[%459] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %492 = llvm.load %495 : !llvm.ptr -> i64
      %496 = arith.constant 0 : i32
      %497 = arith.extsi %496 : i32 to i64
      %498 = llvm.mlir.constant(1 : i64) : i64
      %499 = llvm.alloca %498 x i64 : (i64) -> !llvm.ptr
      llvm.store %497, %499 : i64, !llvm.ptr
      cf.br ^bb72
      ^bb72:
      %500 = llvm.load %499 : !llvm.ptr -> i64
      %501 = arith.cmpi slt, %500, %492 : i64
      cf.cond_br %501, ^bb73, ^bb74
      ^bb73:
        %503 = llvm.mlir.addressof @G_neigh : !llvm.ptr
        %504 = llvm.load %503 : !llvm.ptr -> !llvm.ptr
        %505 = arith.constant 4 : i32
        %507 = arith.extsi %505 : i32 to i64
        %506 = arith.muli %459, %507 : i64
        %508 = llvm.load %499 : !llvm.ptr -> i64
        %509 = arith.addi %506, %508 : i64
        %510 = llvm.getelementptr %504[%509] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %502 = llvm.load %510 : !llvm.ptr -> i64
        %512 = llvm.mlir.addressof @G_seen : !llvm.ptr
        %513 = llvm.load %512 : !llvm.ptr -> !llvm.ptr
        %514 = llvm.getelementptr %513[%502] : (!llvm.ptr, i64) -> !llvm.ptr, i8
        %511 = llvm.load %514 : !llvm.ptr -> i8
        %515 = arith.constant 0 : i32
        %517 = arith.extsi %511 : i8 to i32
        %516 = arith.cmpi eq, %517, %515 : i32
        cf.cond_br %516, ^bb75, ^bb76
        ^bb75:
          %518 = arith.constant 1 : i32
          %519 = llvm.mlir.addressof @G_seen : !llvm.ptr
          %520 = llvm.load %519 : !llvm.ptr -> !llvm.ptr
          %521 = arith.trunci %518 : i32 to i8
          %522 = llvm.getelementptr %520[%502] : (!llvm.ptr, i64) -> !llvm.ptr, i8
          llvm.store %521, %522 : i8, !llvm.ptr
          %523 = llvm.mlir.addressof @G_Q : !llvm.ptr
          %524 = llvm.load %523 : !llvm.ptr -> !llvm.ptr
          %525 = llvm.load %491 : !llvm.ptr -> i64
          %526 = arith.addi %arg1, %525 : i64
          %527 = llvm.getelementptr %524[%526] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          llvm.store %502, %527 : i64, !llvm.ptr
          %528 = llvm.load %491 : !llvm.ptr -> i64
          %529 = arith.constant 1 : i32
          %531 = arith.extsi %529 : i32 to i64
          %530 = arith.addi %528, %531 : i64
          llvm.store %530, %491 : i64, !llvm.ptr
          cf.br ^bb77
        ^bb76:
          cf.br ^bb77
        ^bb77:
        %532 = llvm.load %499 : !llvm.ptr -> i64
        %533 = arith.constant 1 : i32
        %535 = arith.extsi %533 : i32 to i64
        %534 = arith.addi %532, %535 : i64
        llvm.store %534, %499 : i64, !llvm.ptr
        cf.br ^bb72
      ^bb74:
      %537 = llvm.load %456 : !llvm.ptr -> i64
      %538 = arith.constant 1 : i32
      %540 = arith.extsi %538 : i32 to i64
      %539 = arith.addi %537, %540 : i64
      %541 = llvm.load %491 : !llvm.ptr -> i64
      %542 = arith.addi %arg1, %541 : i64
      func.call @rec_sym(%539, %542, %480) : (i64, i64, i64) -> ()
      %543 = llvm.mlir.constant(1 : i64) : i64
      %544 = llvm.alloca %543 x i64 : (i64) -> !llvm.ptr
      llvm.store %arg1, %544 : i64, !llvm.ptr
      cf.br ^bb78
      ^bb78:
      %545 = llvm.load %544 : !llvm.ptr -> i64
      %546 = llvm.load %491 : !llvm.ptr -> i64
      %547 = arith.addi %arg1, %546 : i64
      %548 = arith.cmpi slt, %545, %547 : i64
      cf.cond_br %548, ^bb79, ^bb80
      ^bb79:
        %549 = arith.constant 0 : i32
        %550 = llvm.mlir.addressof @G_seen : !llvm.ptr
        %551 = llvm.load %550 : !llvm.ptr -> !llvm.ptr
        %553 = llvm.mlir.addressof @G_Q : !llvm.ptr
        %554 = llvm.load %553 : !llvm.ptr -> !llvm.ptr
        %555 = llvm.load %544 : !llvm.ptr -> i64
        %556 = llvm.getelementptr %554[%555] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        %552 = llvm.load %556 : !llvm.ptr -> i64
        %557 = arith.trunci %549 : i32 to i8
        %558 = llvm.getelementptr %551[%552] : (!llvm.ptr, i64) -> !llvm.ptr, i8
        llvm.store %557, %558 : i8, !llvm.ptr
        %559 = llvm.load %544 : !llvm.ptr -> i64
        %560 = arith.constant 1 : i32
        %562 = arith.extsi %560 : i32 to i64
        %561 = arith.addi %559, %562 : i64
        llvm.store %561, %544 : i64, !llvm.ptr
        cf.br ^bb78
      ^bb80:
      %563 = llvm.load %456 : !llvm.ptr -> i64
      %564 = arith.constant 1 : i32
      %566 = arith.extsi %564 : i32 to i64
      %565 = arith.addi %563, %566 : i64
      llvm.store %565, %456 : i64, !llvm.ptr
      cf.br ^bb63
    ^bb65:
    func.return
  }
  func.func @count_symmetric(%arg0: i64) -> i64 {
    %567 = llvm.mlir.addressof @G_n : !llvm.ptr
    llvm.store %arg0, %567 : i64, !llvm.ptr
    %568 = arith.constant 1 : i32
    %570 = arith.extsi %568 : i32 to i64
    %569 = arith.subi %arg0, %570 : i64
    %571 = llvm.mlir.addressof @G_XMAX : !llvm.ptr
    llvm.store %569, %571 : i64, !llvm.ptr
    %572 = arith.constant 2 : i32
    %573 = llvm.mlir.addressof @G_XMAX : !llvm.ptr
    %574 = llvm.load %573 : !llvm.ptr -> i64
    %576 = arith.extsi %572 : i32 to i64
    %575 = arith.muli %576, %574 : i64
    %577 = arith.constant 1 : i32
    %579 = arith.extsi %577 : i32 to i64
    %578 = arith.addi %575, %579 : i64
    %580 = llvm.mlir.addressof @G_W : !llvm.ptr
    llvm.store %578, %580 : i64, !llvm.ptr
    %581 = llvm.mlir.addressof @G_XMAX : !llvm.ptr
    %582 = llvm.load %581 : !llvm.ptr -> i64
    %583 = llvm.mlir.addressof @G_SHIFT : !llvm.ptr
    llvm.store %582, %583 : i64, !llvm.ptr
    %584 = llvm.mlir.addressof @G_W : !llvm.ptr
    %585 = llvm.load %584 : !llvm.ptr -> i64
    %586 = llvm.mlir.addressof @G_XMAX : !llvm.ptr
    %587 = llvm.load %586 : !llvm.ptr -> i64
    %588 = arith.constant 1 : i32
    %590 = arith.extsi %588 : i32 to i64
    %589 = arith.addi %587, %590 : i64
    %591 = arith.muli %585, %589 : i64
    %592 = llvm.mlir.addressof @G_GRID : !llvm.ptr
    llvm.store %591, %592 : i64, !llvm.ptr
    %593 = llvm.mlir.addressof @G_SHIFT : !llvm.ptr
    %594 = llvm.load %593 : !llvm.ptr -> i64
    %595 = llvm.mlir.addressof @G_root : !llvm.ptr
    llvm.store %594, %595 : i64, !llvm.ptr
    %597 = llvm.mlir.addressof @G_GRID : !llvm.ptr
    %598 = llvm.load %597 : !llvm.ptr -> i64
    %599 = arith.constant 8 : i32
    %600 = arith.extsi %599 : i32 to i64
    %596 = func.call @calloc(%598, %600) : (i64, i64) -> !llvm.ptr
    %601 = llvm.mlir.addressof @G_x_of : !llvm.ptr
    llvm.store %596, %601 : !llvm.ptr, !llvm.ptr
    %603 = llvm.mlir.addressof @G_GRID : !llvm.ptr
    %604 = llvm.load %603 : !llvm.ptr -> i64
    %605 = arith.constant 4 : i32
    %607 = arith.extsi %605 : i32 to i64
    %606 = arith.muli %604, %607 : i64
    %608 = arith.constant 8 : i32
    %609 = arith.extsi %608 : i32 to i64
    %602 = func.call @calloc(%606, %609) : (i64, i64) -> !llvm.ptr
    %610 = llvm.mlir.addressof @G_neigh : !llvm.ptr
    llvm.store %602, %610 : !llvm.ptr, !llvm.ptr
    %612 = llvm.mlir.addressof @G_GRID : !llvm.ptr
    %613 = llvm.load %612 : !llvm.ptr -> i64
    %614 = arith.constant 8 : i32
    %615 = arith.extsi %614 : i32 to i64
    %611 = func.call @calloc(%613, %615) : (i64, i64) -> !llvm.ptr
    %616 = llvm.mlir.addressof @G_neigh_cnt : !llvm.ptr
    llvm.store %611, %616 : !llvm.ptr, !llvm.ptr
    %618 = llvm.mlir.addressof @G_GRID : !llvm.ptr
    %619 = llvm.load %618 : !llvm.ptr -> i64
    %620 = arith.constant 1 : i32
    %621 = arith.extsi %620 : i32 to i64
    %617 = func.call @calloc(%619, %621) : (i64, i64) -> !llvm.ptr
    %622 = llvm.mlir.addressof @G_seen : !llvm.ptr
    llvm.store %617, %622 : !llvm.ptr, !llvm.ptr
    %624 = arith.constant 8 : i32
    %626 = arith.extsi %624 : i32 to i64
    %625 = arith.muli %626, %arg0 : i64
    %627 = arith.constant 50 : i32
    %629 = arith.extsi %627 : i32 to i64
    %628 = arith.addi %625, %629 : i64
    %630 = arith.constant 8 : i32
    %631 = arith.extsi %630 : i32 to i64
    %623 = func.call @calloc(%628, %631) : (i64, i64) -> !llvm.ptr
    %632 = llvm.mlir.addressof @G_Q : !llvm.ptr
    llvm.store %623, %632 : !llvm.ptr, !llvm.ptr
    %633 = arith.constant 0 : i32
    %634 = arith.extsi %633 : i32 to i64
    %635 = llvm.mlir.constant(1 : i64) : i64
    %636 = llvm.alloca %635 x i64 : (i64) -> !llvm.ptr
    llvm.store %634, %636 : i64, !llvm.ptr
    cf.br ^bb81
    ^bb81:
    %637 = llvm.load %636 : !llvm.ptr -> i64
    %638 = llvm.mlir.addressof @G_XMAX : !llvm.ptr
    %639 = llvm.load %638 : !llvm.ptr -> i64
    %640 = arith.cmpi sle, %637, %639 : i64
    cf.cond_br %640, ^bb82, ^bb83
    ^bb82:
      %641 = llvm.load %636 : !llvm.ptr -> i64
      %642 = llvm.mlir.addressof @G_W : !llvm.ptr
      %643 = llvm.load %642 : !llvm.ptr -> i64
      %644 = arith.muli %641, %643 : i64
      %645 = arith.constant 0 : i32
      %646 = arith.extsi %645 : i32 to i64
      %647 = llvm.mlir.constant(1 : i64) : i64
      %648 = llvm.alloca %647 x i64 : (i64) -> !llvm.ptr
      llvm.store %646, %648 : i64, !llvm.ptr
      cf.br ^bb84
      ^bb84:
      %649 = llvm.load %648 : !llvm.ptr -> i64
      %650 = llvm.mlir.addressof @G_W : !llvm.ptr
      %651 = llvm.load %650 : !llvm.ptr -> i64
      %652 = arith.cmpi slt, %649, %651 : i64
      cf.cond_br %652, ^bb85, ^bb86
      ^bb85:
        %653 = llvm.load %648 : !llvm.ptr -> i64
        %654 = llvm.mlir.addressof @G_SHIFT : !llvm.ptr
        %655 = llvm.load %654 : !llvm.ptr -> i64
        %656 = arith.subi %653, %655 : i64
        %657 = llvm.mlir.addressof @G_x_of : !llvm.ptr
        %658 = llvm.load %657 : !llvm.ptr -> !llvm.ptr
        %659 = llvm.load %648 : !llvm.ptr -> i64
        %660 = arith.addi %644, %659 : i64
        %661 = llvm.getelementptr %658[%660] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %656, %661 : i64, !llvm.ptr
        %662 = llvm.load %648 : !llvm.ptr -> i64
        %663 = arith.constant 1 : i32
        %665 = arith.extsi %663 : i32 to i64
        %664 = arith.addi %662, %665 : i64
        llvm.store %664, %648 : i64, !llvm.ptr
        cf.br ^bb84
      ^bb86:
      %666 = llvm.load %636 : !llvm.ptr -> i64
      %667 = arith.constant 1 : i32
      %669 = arith.extsi %667 : i32 to i64
      %668 = arith.addi %666, %669 : i64
      llvm.store %668, %636 : i64, !llvm.ptr
      cf.br ^bb81
    ^bb83:
    %670 = arith.constant 0 : i32
    %671 = arith.extsi %670 : i32 to i64
    llvm.store %671, %636 : i64, !llvm.ptr
    cf.br ^bb87
    ^bb87:
    %672 = llvm.load %636 : !llvm.ptr -> i64
    %673 = llvm.mlir.addressof @G_XMAX : !llvm.ptr
    %674 = llvm.load %673 : !llvm.ptr -> i64
    %675 = arith.cmpi sle, %672, %674 : i64
    cf.cond_br %675, ^bb88, ^bb89
    ^bb88:
      %676 = llvm.load %636 : !llvm.ptr -> i64
      %677 = llvm.mlir.addressof @G_W : !llvm.ptr
      %678 = llvm.load %677 : !llvm.ptr -> i64
      %679 = arith.muli %676, %678 : i64
      %680 = arith.constant 0 : i32
      %681 = arith.extsi %680 : i32 to i64
      %682 = llvm.mlir.constant(1 : i64) : i64
      %683 = llvm.alloca %682 x i64 : (i64) -> !llvm.ptr
      llvm.store %681, %683 : i64, !llvm.ptr
      cf.br ^bb90
      ^bb90:
      %684 = llvm.load %683 : !llvm.ptr -> i64
      %685 = llvm.mlir.addressof @G_W : !llvm.ptr
      %686 = llvm.load %685 : !llvm.ptr -> i64
      %687 = arith.cmpi slt, %684, %686 : i64
      cf.cond_br %687, ^bb91, ^bb92
      ^bb91:
        %688 = llvm.load %683 : !llvm.ptr -> i64
        %689 = arith.addi %679, %688 : i64
        %690 = llvm.load %683 : !llvm.ptr -> i64
        %691 = llvm.mlir.addressof @G_SHIFT : !llvm.ptr
        %692 = llvm.load %691 : !llvm.ptr -> i64
        %693 = arith.subi %690, %692 : i64
        %694 = arith.constant 0 : i32
        %695 = arith.extsi %694 : i32 to i64
        %696 = llvm.mlir.constant(1 : i64) : i64
        %697 = llvm.alloca %696 x i64 : (i64) -> !llvm.ptr
        llvm.store %695, %697 : i64, !llvm.ptr
        %698 = arith.constant 0 : i32
        %700 = arith.extsi %698 : i32 to i64
        %699 = arith.cmpi sge, %693, %700 : i64
        cf.cond_br %699, ^bb93, ^bb94
        ^bb93:
          %701 = llvm.load %683 : !llvm.ptr -> i64
          %702 = llvm.mlir.addressof @G_SHIFT : !llvm.ptr
          %703 = llvm.load %702 : !llvm.ptr -> i64
          %704 = arith.cmpi sgt, %701, %703 : i64
          cf.cond_br %704, ^bb96, ^bb97
          ^bb96:
            %705 = arith.constant 1 : i32
            %707 = arith.extsi %705 : i32 to i64
            %706 = arith.subi %689, %707 : i64
            %708 = llvm.mlir.addressof @G_neigh : !llvm.ptr
            %709 = llvm.load %708 : !llvm.ptr -> !llvm.ptr
            %710 = arith.constant 4 : i32
            %712 = arith.extsi %710 : i32 to i64
            %711 = arith.muli %689, %712 : i64
            %713 = llvm.load %697 : !llvm.ptr -> i64
            %714 = arith.addi %711, %713 : i64
            %715 = llvm.getelementptr %709[%714] : (!llvm.ptr, i64) -> !llvm.ptr, i64
            llvm.store %706, %715 : i64, !llvm.ptr
            %716 = llvm.load %697 : !llvm.ptr -> i64
            %717 = arith.constant 1 : i32
            %719 = arith.extsi %717 : i32 to i64
            %718 = arith.addi %716, %719 : i64
            llvm.store %718, %697 : i64, !llvm.ptr
            cf.br ^bb98
          ^bb97:
            cf.br ^bb98
          ^bb98:
          %720 = llvm.load %683 : !llvm.ptr -> i64
          %721 = llvm.mlir.addressof @G_W : !llvm.ptr
          %722 = llvm.load %721 : !llvm.ptr -> i64
          %723 = arith.constant 1 : i32
          %725 = arith.extsi %723 : i32 to i64
          %724 = arith.subi %722, %725 : i64
          %726 = arith.cmpi slt, %720, %724 : i64
          cf.cond_br %726, ^bb99, ^bb100
          ^bb99:
            %727 = arith.constant 1 : i32
            %729 = arith.extsi %727 : i32 to i64
            %728 = arith.addi %689, %729 : i64
            %730 = llvm.mlir.addressof @G_neigh : !llvm.ptr
            %731 = llvm.load %730 : !llvm.ptr -> !llvm.ptr
            %732 = arith.constant 4 : i32
            %734 = arith.extsi %732 : i32 to i64
            %733 = arith.muli %689, %734 : i64
            %735 = llvm.load %697 : !llvm.ptr -> i64
            %736 = arith.addi %733, %735 : i64
            %737 = llvm.getelementptr %731[%736] : (!llvm.ptr, i64) -> !llvm.ptr, i64
            llvm.store %728, %737 : i64, !llvm.ptr
            %738 = llvm.load %697 : !llvm.ptr -> i64
            %739 = arith.constant 1 : i32
            %741 = arith.extsi %739 : i32 to i64
            %740 = arith.addi %738, %741 : i64
            llvm.store %740, %697 : i64, !llvm.ptr
            cf.br ^bb101
          ^bb100:
            cf.br ^bb101
          ^bb101:
          %742 = llvm.load %636 : !llvm.ptr -> i64
          %743 = arith.constant 0 : i32
          %745 = arith.extsi %743 : i32 to i64
          %744 = arith.cmpi sgt, %742, %745 : i64
          cf.cond_br %744, ^bb102, ^bb103
          ^bb102:
            %746 = llvm.mlir.addressof @G_W : !llvm.ptr
            %747 = llvm.load %746 : !llvm.ptr -> i64
            %748 = arith.subi %689, %747 : i64
            %749 = llvm.mlir.addressof @G_neigh : !llvm.ptr
            %750 = llvm.load %749 : !llvm.ptr -> !llvm.ptr
            %751 = arith.constant 4 : i32
            %753 = arith.extsi %751 : i32 to i64
            %752 = arith.muli %689, %753 : i64
            %754 = llvm.load %697 : !llvm.ptr -> i64
            %755 = arith.addi %752, %754 : i64
            %756 = llvm.getelementptr %750[%755] : (!llvm.ptr, i64) -> !llvm.ptr, i64
            llvm.store %748, %756 : i64, !llvm.ptr
            %757 = llvm.load %697 : !llvm.ptr -> i64
            %758 = arith.constant 1 : i32
            %760 = arith.extsi %758 : i32 to i64
            %759 = arith.addi %757, %760 : i64
            llvm.store %759, %697 : i64, !llvm.ptr
            cf.br ^bb104
          ^bb103:
            cf.br ^bb104
          ^bb104:
          %761 = llvm.load %636 : !llvm.ptr -> i64
          %762 = llvm.mlir.addressof @G_XMAX : !llvm.ptr
          %763 = llvm.load %762 : !llvm.ptr -> i64
          %764 = arith.cmpi slt, %761, %763 : i64
          cf.cond_br %764, ^bb105, ^bb106
          ^bb105:
            %765 = llvm.mlir.addressof @G_W : !llvm.ptr
            %766 = llvm.load %765 : !llvm.ptr -> i64
            %767 = arith.addi %689, %766 : i64
            %768 = llvm.mlir.addressof @G_neigh : !llvm.ptr
            %769 = llvm.load %768 : !llvm.ptr -> !llvm.ptr
            %770 = arith.constant 4 : i32
            %772 = arith.extsi %770 : i32 to i64
            %771 = arith.muli %689, %772 : i64
            %773 = llvm.load %697 : !llvm.ptr -> i64
            %774 = arith.addi %771, %773 : i64
            %775 = llvm.getelementptr %769[%774] : (!llvm.ptr, i64) -> !llvm.ptr, i64
            llvm.store %767, %775 : i64, !llvm.ptr
            %776 = llvm.load %697 : !llvm.ptr -> i64
            %777 = arith.constant 1 : i32
            %779 = arith.extsi %777 : i32 to i64
            %778 = arith.addi %776, %779 : i64
            llvm.store %778, %697 : i64, !llvm.ptr
            cf.br ^bb107
          ^bb106:
            cf.br ^bb107
          ^bb107:
          cf.br ^bb95
        ^bb94:
          cf.br ^bb95
        ^bb95:
        %780 = llvm.load %697 : !llvm.ptr -> i64
        %781 = llvm.mlir.addressof @G_neigh_cnt : !llvm.ptr
        %782 = llvm.load %781 : !llvm.ptr -> !llvm.ptr
        %783 = llvm.getelementptr %782[%689] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %780, %783 : i64, !llvm.ptr
        %784 = llvm.load %683 : !llvm.ptr -> i64
        %785 = arith.constant 1 : i32
        %787 = arith.extsi %785 : i32 to i64
        %786 = arith.addi %784, %787 : i64
        llvm.store %786, %683 : i64, !llvm.ptr
        cf.br ^bb90
      ^bb92:
      %788 = llvm.load %636 : !llvm.ptr -> i64
      %789 = arith.constant 1 : i32
      %791 = arith.extsi %789 : i32 to i64
      %790 = arith.addi %788, %791 : i64
      llvm.store %790, %636 : i64, !llvm.ptr
      cf.br ^bb87
    ^bb89:
    %792 = arith.constant 1 : i32
    %793 = llvm.mlir.addressof @G_seen : !llvm.ptr
    %794 = llvm.load %793 : !llvm.ptr -> !llvm.ptr
    %795 = llvm.mlir.addressof @G_root : !llvm.ptr
    %796 = llvm.load %795 : !llvm.ptr -> i64
    %797 = arith.trunci %792 : i32 to i8
    %798 = llvm.getelementptr %794[%796] : (!llvm.ptr, i64) -> !llvm.ptr, i8
    llvm.store %797, %798 : i8, !llvm.ptr
    %799 = arith.constant 0 : i32
    %800 = arith.extsi %799 : i32 to i64
    %801 = llvm.mlir.constant(1 : i64) : i64
    %802 = llvm.alloca %801 x i64 : (i64) -> !llvm.ptr
    llvm.store %800, %802 : i64, !llvm.ptr
    %804 = llvm.mlir.addressof @G_neigh_cnt : !llvm.ptr
    %805 = llvm.load %804 : !llvm.ptr -> !llvm.ptr
    %806 = llvm.mlir.addressof @G_root : !llvm.ptr
    %807 = llvm.load %806 : !llvm.ptr -> i64
    %808 = llvm.getelementptr %805[%807] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    %803 = llvm.load %808 : !llvm.ptr -> i64
    %809 = arith.constant 0 : i32
    %810 = arith.extsi %809 : i32 to i64
    %811 = llvm.mlir.constant(1 : i64) : i64
    %812 = llvm.alloca %811 x i64 : (i64) -> !llvm.ptr
    llvm.store %810, %812 : i64, !llvm.ptr
    cf.br ^bb108
    ^bb108:
    %813 = llvm.load %812 : !llvm.ptr -> i64
    %814 = arith.cmpi slt, %813, %803 : i64
    cf.cond_br %814, ^bb109, ^bb110
    ^bb109:
      %816 = llvm.mlir.addressof @G_neigh : !llvm.ptr
      %817 = llvm.load %816 : !llvm.ptr -> !llvm.ptr
      %818 = llvm.mlir.addressof @G_root : !llvm.ptr
      %819 = llvm.load %818 : !llvm.ptr -> i64
      %820 = arith.constant 4 : i32
      %822 = arith.extsi %820 : i32 to i64
      %821 = arith.muli %819, %822 : i64
      %823 = llvm.load %812 : !llvm.ptr -> i64
      %824 = arith.addi %821, %823 : i64
      %825 = llvm.getelementptr %817[%824] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %815 = llvm.load %825 : !llvm.ptr -> i64
      %827 = llvm.mlir.addressof @G_seen : !llvm.ptr
      %828 = llvm.load %827 : !llvm.ptr -> !llvm.ptr
      %829 = llvm.getelementptr %828[%815] : (!llvm.ptr, i64) -> !llvm.ptr, i8
      %826 = llvm.load %829 : !llvm.ptr -> i8
      %830 = arith.constant 0 : i32
      %832 = arith.extsi %826 : i8 to i32
      %831 = arith.cmpi eq, %832, %830 : i32
      cf.cond_br %831, ^bb111, ^bb112
      ^bb111:
        %833 = arith.constant 1 : i32
        %834 = llvm.mlir.addressof @G_seen : !llvm.ptr
        %835 = llvm.load %834 : !llvm.ptr -> !llvm.ptr
        %836 = arith.trunci %833 : i32 to i8
        %837 = llvm.getelementptr %835[%815] : (!llvm.ptr, i64) -> !llvm.ptr, i8
        llvm.store %836, %837 : i8, !llvm.ptr
        %838 = llvm.mlir.addressof @G_Q : !llvm.ptr
        %839 = llvm.load %838 : !llvm.ptr -> !llvm.ptr
        %840 = llvm.load %802 : !llvm.ptr -> i64
        %841 = llvm.getelementptr %839[%840] : (!llvm.ptr, i64) -> !llvm.ptr, i64
        llvm.store %815, %841 : i64, !llvm.ptr
        %842 = llvm.load %802 : !llvm.ptr -> i64
        %843 = arith.constant 1 : i32
        %845 = arith.extsi %843 : i32 to i64
        %844 = arith.addi %842, %845 : i64
        llvm.store %844, %802 : i64, !llvm.ptr
        cf.br ^bb113
      ^bb112:
        cf.br ^bb113
      ^bb113:
      %846 = llvm.load %812 : !llvm.ptr -> i64
      %847 = arith.constant 1 : i32
      %849 = arith.extsi %847 : i32 to i64
      %848 = arith.addi %846, %849 : i64
      llvm.store %848, %812 : i64, !llvm.ptr
      cf.br ^bb108
    ^bb110:
    %850 = arith.constant 0 : i32
    %851 = arith.extsi %850 : i32 to i64
    %852 = llvm.mlir.addressof @G_ans : !llvm.ptr
    llvm.store %851, %852 : i64, !llvm.ptr
    %854 = arith.constant 0 : i32
    %855 = llvm.load %802 : !llvm.ptr -> i64
    %856 = arith.constant 1 : i32
    %857 = arith.extsi %854 : i32 to i64
    %858 = arith.extsi %856 : i32 to i64
    func.call @rec_sym(%857, %855, %858) : (i64, i64, i64) -> ()
    %859 = llvm.mlir.addressof @G_ans : !llvm.ptr
    %860 = llvm.load %859 : !llvm.ptr -> i64
    %862 = llvm.mlir.addressof @G_x_of : !llvm.ptr
    %863 = llvm.load %862 : !llvm.ptr -> !llvm.ptr
    func.call @free(%863) : (!llvm.ptr) -> ()
    %865 = llvm.mlir.addressof @G_neigh : !llvm.ptr
    %866 = llvm.load %865 : !llvm.ptr -> !llvm.ptr
    func.call @free(%866) : (!llvm.ptr) -> ()
    %868 = llvm.mlir.addressof @G_neigh_cnt : !llvm.ptr
    %869 = llvm.load %868 : !llvm.ptr -> !llvm.ptr
    func.call @free(%869) : (!llvm.ptr) -> ()
    %871 = llvm.mlir.addressof @G_seen : !llvm.ptr
    %872 = llvm.load %871 : !llvm.ptr -> !llvm.ptr
    func.call @free(%872) : (!llvm.ptr) -> ()
    %874 = llvm.mlir.addressof @G_Q : !llvm.ptr
    %875 = llvm.load %874 : !llvm.ptr -> !llvm.ptr
    func.call @free(%875) : (!llvm.ptr) -> ()
    func.return %860 : i64
  }
  func.func @main() -> i32 {
    %876 = arith.constant 18 : i32
    %877 = arith.extsi %876 : i32 to i64
    %878 = func.call @count_total(%877) : (i64) -> i64
    %879 = func.call @count_symmetric(%877) : (i64) -> i64
    %880 = arith.addi %878, %879 : i64
    %881 = arith.constant 2 : i32
    %883 = arith.extsi %881 : i32 to i64
    %882 = arith.divsi %880, %883 : i64
    %884 = llvm.mlir.addressof @str_0 : !llvm.ptr
    %885 = llvm.call @printf(%884, %882) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i64) -> i32
    %886 = arith.constant 0 : i32
    func.return %886 : i32
  }
}