Problem 673

Beds and Desks: count permutations commuting with two involutions. Build graph from B/D edges, find connected components, classify, compute automorphism count.

Answer700325380
Output700325380
StatusPASS
Native helperno
Runtime0 ms
Peak memory1120 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(n)
ApproachFlow solutionPermutation enumeration or constraint search
VerdictOptimal

Flow source

# Project Euler 673
# Beds and Desks: count permutations commuting with two involutions.
# Build graph from B/D edges, find connected components, classify, compute automorphism count.

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 MOD: i64 = 999999937
const MAXN: i32 = 501

function mod_pow(base: i64, exp: i64, m: i64) -> i64 {
    let mut r: i64 = 1
    let mut b: i64 = base % m
    let mut e: i64 = exp
    while e > 0 {
        if (e & 1) != 0 {
            r = r * b % m
        }
        b = b * b % m
        e = e >> 1
    }
    return r
}

# Parse a file of "a,b" pairs into an involution array.
function parse_file(path: string, inv: ptr<i32>) -> void {
    let f: ptr<void> = fopen(path, "r")
    let mut c: i32 = fgetc(f)
    while c >= 0 {
        # Skip non-digit characters until we find the first digit
        while c >= 0 && (c < 48 || c > 57) {
            c = fgetc(f)
        }
        if c < 0 { break }
        # Parse first number a
        let mut a: i32 = 0
        while c >= 48 && c <= 57 {
            a = a * 10 + (c - 48)
            c = fgetc(f)
        }
        # Skip non-digit characters until second number
        while c >= 0 && (c < 48 || c > 57) {
            c = fgetc(f)
        }
        if c < 0 { break }
        # Parse second number b
        let mut b: i32 = 0
        while c >= 48 && c <= 57 {
            b = b * 10 + (c - 48)
            c = fgetc(f)
        }
        if a > 0 && b > 0 {
            inv[a] = b
            inv[b] = a
        }
    }
    fclose(f)
}

function main() -> i32 {
    let n: i32 = 500

    let B: ptr<i32> = calloc((MAXN as i64), 4) as ptr<i32>
    let D: ptr<i32> = calloc((MAXN as i64), 4) as ptr<i32>
    let visited: ptr<i32> = calloc((MAXN as i64), 4) as ptr<i32>
    let stack_arr: ptr<i32> = calloc((MAXN as i64), 4) as ptr<i32>
    let comp: ptr<i32> = calloc((MAXN as i64), 4) as ptr<i32>
    let fact: ptr<i64> = calloc((MAXN as i64), 8) as ptr<i64>

    let mut i: i32 = 0
    while i <= n {
        B[i] = i
        D[i] = i
        visited[i] = 0
        i = i + 1
    }

    parse_file("data/p673_beds.txt", B)
    parse_file("data/p673_desks.txt", D)

    fact[0] = 1
    let mut fi: i32 = 1
    while fi <= n {
        fact[fi] = fact[fi - 1] * (fi as i64) % MOD
        fi = fi + 1
    }

    # Component type arrays
    let tc_cycle: ptr<i32> = calloc((MAXN as i64), 4) as ptr<i32>
    let tc_k: ptr<i32> = calloc((MAXN as i64), 4) as ptr<i32>
    let tc_color: ptr<i32> = calloc((MAXN as i64), 4) as ptr<i32>
    let tc_count: ptr<i32> = calloc((MAXN as i64), 4) as ptr<i32>
    let tc_aut: ptr<i64> = calloc((MAXN as i64), 8) as ptr<i64>
    let mut num_types: i32 = 0

    let mut start: i32 = 1
    while start <= n {
        if visited[start] != 0 {
            start = start + 1
            continue
        }

        let mut sp: i32 = 0
        let mut cp: i32 = 0
        stack_arr[sp] = start
        sp = sp + 1
        visited[start] = 1

        while sp > 0 {
            sp = sp - 1
            let v: i32 = stack_arr[sp]
            comp[cp] = v
            cp = cp + 1
            let u1: i32 = B[v]
            let u2: i32 = D[v]
            if visited[u1] == 0 {
                visited[u1] = 1
                stack_arr[sp] = u1
                sp = sp + 1
            }
            if visited[u2] == 0 {
                visited[u2] = 1
                stack_arr[sp] = u2
                sp = sp + 1
            }
        }

        let k: i32 = cp
        let mut has_loop: bool = false
        let mut ci: i32 = 0
        while ci < cp {
            let v: i32 = comp[ci]
            if B[v] == v || D[v] == v {
                has_loop = true
                break
            }
            ci = ci + 1
        }

        let mut is_cycle: i32 = 0
        if !has_loop { is_cycle = 1 }
        let mut end_color: i32 = 0
        let mut aut: i64 = 0

        if is_cycle != 0 {
            aut = k as i64
        } else {
            if k % 2 == 1 {
                aut = 1
            } else {
                let mut ci2: i32 = 0
                while ci2 < cp {
                    let v: i32 = comp[ci2]
                    if B[v] == v && D[v] != v {
                        end_color = 1
                        break
                    }
                    if D[v] == v && B[v] != v {
                        end_color = 2
                        break
                    }
                    ci2 = ci2 + 1
                }
                aut = 2
            }
        }

        let mut found: i32 = -1
        let mut t: i32 = 0
        while t < num_types {
            if tc_cycle[t] == is_cycle && tc_k[t] == k && tc_color[t] == end_color {
                found = t
                break
            }
            t = t + 1
        }
        if found >= 0 {
            tc_count[found] = tc_count[found] + 1
        } else {
            tc_cycle[num_types] = is_cycle
            tc_k[num_types] = k
            tc_color[num_types] = end_color
            tc_aut[num_types] = aut
            tc_count[num_types] = 1
            num_types = num_types + 1
        }

        start = start + 1
    }

    let mut answer: i64 = 1
    let mut t: i32 = 0
    while t < num_types {
        answer = answer * mod_pow(tc_aut[t], (tc_count[t] as i64), MOD) % MOD
        answer = answer * fact[tc_count[t]] % MOD
        t = t + 1
    }

    printf("%lld\n", answer)

    free(B as ptr<void>)
    free(D as ptr<void>)
    free(visited as ptr<void>)
    free(stack_arr as ptr<void>)
    free(comp as ptr<void>)
    free(fact as ptr<void>)
    free(tc_cycle as ptr<void>)
    free(tc_k as ptr<void>)
    free(tc_color as ptr<void>)
    free(tc_count as ptr<void>)
    free(tc_aut as ptr<void>)

    return 0
}

Generated C

#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* Flow runtime helpers */
typedef struct flow_temp_node { struct flow_temp_node* next; } flow_temp_node;
static flow_temp_node* flow_temp_head = NULL;
static int flow_temp_atexit_set = 0;
__attribute__((unused)) static void flow_temp_free_all(void) {
    while (flow_temp_head) {
        flow_temp_node* n = flow_temp_head;
        flow_temp_head = n->next;
        free(n);
    }
}
__attribute__((unused)) static void* flow_temp_alloc(size_t nbytes) {
    flow_temp_node* node = (flow_temp_node*)malloc(sizeof(flow_temp_node) + nbytes);
    if (!node) return NULL;
    node->next = flow_temp_head;
    flow_temp_head = node;
    if (!flow_temp_atexit_set) {
        flow_temp_atexit_set = 1;
        atexit(flow_temp_free_all);
    }
    return (void*)(node + 1);
}
#ifndef FLOW_DIAG
#define FLOW_DIAG(msg) fprintf(stderr, "%s", (msg))
#endif
#ifndef FLOW_LOG
#define FLOW_LOG(fmt, ...) printf(fmt, __VA_ARGS__)
#endif
#ifndef FLOW_LOG_EMPTY
#define FLOW_LOG_EMPTY(fmt) printf(fmt)
#endif
static char* flow_strcat(const char* a, const char* b) {
    size_t la = strlen(a ? a : ""), lb = strlen(b ? b : "");
    char* r = (char*)flow_temp_alloc(la + lb + 1);
    if (!r) return NULL;
    if (la) memcpy(r, a, la);
    if (lb) memcpy(r + la, b, lb);
    r[la + lb] = '\0';
    return r;
}

#define __flow_in_arr(arr, val) __extension__ ({ \
    int _found = 0; \
    size_t _n = sizeof(arr)/sizeof((arr)[0]); \
    for (size_t _i = 0; _i < _n; _i++) { \
        if ((arr)[_i] == (val)) { _found = 1; break; } \
    } _found; })

/* Unified fault handler (MISRA #279) — override with -DFLOW_FAULT_HANDLER=fn */
#ifndef FLOW_FAULT_HANDLER
__attribute__((unused)) static inline void flow_fault_handler(const char* msg) {
    fprintf(stderr, "flow: %s\n", msg ? msg : "fault");
    abort();
#if defined(__GNUC__) || defined(__clang__)
    __builtin_unreachable();
#endif
}
#else
#define flow_fault_handler FLOW_FAULT_HANDLER
#endif
#define flow_div_by_zero_handler() flow_fault_handler("division by zero")
#define flow_shift_ub_handler() flow_fault_handler("invalid shift (amount out of range or left-shift of negative)")

#ifndef FLOW_CHECKED_DIV
#define FLOW_CHECKED_DIV(L, R) (((R) != 0) ? ((L) / (R)) : (flow_div_by_zero_handler(), (L) * 0))
#endif
#ifndef FLOW_CHECKED_MOD
#define FLOW_CHECKED_MOD(L, R) (((R) != 0) ? ((L) % (R)) : (flow_div_by_zero_handler(), (L) * 0))
#endif
#ifndef FLOW_CHECKED_SHL
#define FLOW_CHECKED_SHL(L, R) ((((R) >= 0) && ((unsigned long long)(R) < (sizeof(L) * 8ull)) && ((L) >= 0)) ? ((L) << (R)) : (flow_shift_ub_handler(), (L) * 0))
#endif
#ifndef FLOW_CHECKED_SHR
#define FLOW_CHECKED_SHR(L, R) ((((R) >= 0) && ((unsigned long long)(R) < (sizeof(L) * 8ull))) ? ((L) >> (R)) : (flow_shift_ub_handler(), (L) * 0))
#endif

#include <math.h>

void* _ui_state = NULL;

static inline float i32_to_f32(int32_t v) { return (float)v; }

/* Host stub for @gpu kernels (device codegen replaces this). */
static inline int32_t gpu_thread_id(void) { return 0; }

int64_t mod_pow_i64_i64_i64(int64_t base, int64_t exp, int64_t m);
void parse_file_string_ptr_i32(char* path, int32_t* inv);
int32_t main(void);

static const int64_t MOD = 999999937;
static const int32_t MAXN = 501;






int64_t mod_pow_i64_i64_i64(int64_t base, int64_t exp, int64_t m) {
    int64_t r = 1;
    int64_t b = FLOW_CHECKED_MOD((base), (m));
    int64_t e = exp;
    while (e > 0) {
        if ((e & 1) != 0) {
            r = FLOW_CHECKED_MOD(((r * b)), (m));
        }
        b = FLOW_CHECKED_MOD(((b * b)), (m));
        e = FLOW_CHECKED_SHR((e), (1));
    }
    return r;
}

void parse_file_string_ptr_i32(char* path, int32_t* inv) {
    void* f = (void*)(fopen(path, "r"));
    int32_t c = fgetc(f);
    while (c >= 0) {
        while ((c >= 0 && (c < 48 || c > 57))) {
            c = fgetc(f);
        }
        if (c < 0) {
            break;
        }
        int32_t a = 0;
        while ((c >= 48 && c <= 57)) {
            a = ((a * 10) + (c - 48));
            c = fgetc(f);
        }
        while ((c >= 0 && (c < 48 || c > 57))) {
            c = fgetc(f);
        }
        if (c < 0) {
            break;
        }
        int32_t b = 0;
        while ((c >= 48 && c <= 57)) {
            b = ((b * 10) + (c - 48));
            c = fgetc(f);
        }
        if ((a > 0 && b > 0)) {
            inv[a] = b;
            inv[b] = a;
        }
    }
    fclose(f);
}

int32_t main(void) {
    int32_t n = 500;
    int32_t* B = (int32_t*)(((int32_t*)(calloc(((int64_t)(MAXN)), 4))));
    int32_t* D = (int32_t*)(((int32_t*)(calloc(((int64_t)(MAXN)), 4))));
    int32_t* visited = (int32_t*)(((int32_t*)(calloc(((int64_t)(MAXN)), 4))));
    int32_t* stack_arr = (int32_t*)(((int32_t*)(calloc(((int64_t)(MAXN)), 4))));
    int32_t* comp = (int32_t*)(((int32_t*)(calloc(((int64_t)(MAXN)), 4))));
    int64_t* fact = (int64_t*)(((int64_t*)(calloc(((int64_t)(MAXN)), 8))));
    int32_t i = 0;
    while (i <= n) {
        B[i] = i;
        D[i] = i;
        visited[i] = 0;
        i = (i + 1);
    }
    parse_file_string_ptr_i32("data/p673_beds.txt", B);
    parse_file_string_ptr_i32("data/p673_desks.txt", D);
    fact[0] = 1;
    int32_t fi = 1;
    while (fi <= n) {
        fact[fi] = FLOW_CHECKED_MOD(((fact[(fi - 1)] * ((int64_t)(fi)))), (MOD));
        fi = (fi + 1);
    }
    int32_t* tc_cycle = (int32_t*)(((int32_t*)(calloc(((int64_t)(MAXN)), 4))));
    int32_t* tc_k = (int32_t*)(((int32_t*)(calloc(((int64_t)(MAXN)), 4))));
    int32_t* tc_color = (int32_t*)(((int32_t*)(calloc(((int64_t)(MAXN)), 4))));
    int32_t* tc_count = (int32_t*)(((int32_t*)(calloc(((int64_t)(MAXN)), 4))));
    int64_t* tc_aut = (int64_t*)(((int64_t*)(calloc(((int64_t)(MAXN)), 8))));
    int32_t num_types = 0;
    int32_t start = 1;
    while (start <= n) {
        if (visited[start] != 0) {
            start = (start + 1);
            continue;
        }
        int32_t sp = 0;
        int32_t cp = 0;
        stack_arr[sp] = start;
        sp = (sp + 1);
        visited[start] = 1;
        while (sp > 0) {
            sp = (sp - 1);
            int32_t v = stack_arr[sp];
            comp[cp] = v;
            cp = (cp + 1);
            int32_t u1 = B[v];
            int32_t u2 = D[v];
            if (visited[u1] == 0) {
                visited[u1] = 1;
                stack_arr[sp] = u1;
                sp = (sp + 1);
            }
            if (visited[u2] == 0) {
                visited[u2] = 1;
                stack_arr[sp] = u2;
                sp = (sp + 1);
            }
        }
        int32_t k = cp;
        bool has_loop = 0;
        int32_t ci = 0;
        while (ci < cp) {
            int32_t v = comp[ci];
            if ((B[v] == v || D[v] == v)) {
                has_loop = 1;
                break;
            }
            ci = (ci + 1);
        }
        int32_t is_cycle = 0;
        if ((!(has_loop))) {
            is_cycle = 1;
        }
        int32_t end_color = 0;
        int64_t aut = 0;
        if (is_cycle != 0) {
            aut = ((int64_t)(k));
        } else {
            if (FLOW_CHECKED_MOD((k), (2)) == 1) {
                aut = 1;
            } else {
                int32_t ci2 = 0;
                while (ci2 < cp) {
                    int32_t v = comp[ci2];
                    if ((B[v] == v && D[v] != v)) {
                        end_color = 1;
                        break;
                    }
                    if ((D[v] == v && B[v] != v)) {
                        end_color = 2;
                        break;
                    }
                    ci2 = (ci2 + 1);
                }
                aut = 2;
            }
        }
        int32_t found = (-1);
        int32_t t = 0;
        while (t < num_types) {
            if (((tc_cycle[t] == is_cycle && tc_k[t] == k) && tc_color[t] == end_color)) {
                found = t;
                break;
            }
            t = (t + 1);
        }
        if (found >= 0) {
            tc_count[found] = (tc_count[found] + 1);
        } else {
            tc_cycle[num_types] = is_cycle;
            tc_k[num_types] = k;
            tc_color[num_types] = end_color;
            tc_aut[num_types] = aut;
            tc_count[num_types] = 1;
            num_types = (num_types + 1);
        }
        start = (start + 1);
    }
    int64_t answer = 1;
    int32_t t = 0;
    while (t < num_types) {
        answer = FLOW_CHECKED_MOD(((answer * mod_pow_i64_i64_i64(tc_aut[t], ((int64_t)(tc_count[t])), MOD))), (MOD));
        answer = FLOW_CHECKED_MOD(((answer * fact[tc_count[t]])), (MOD));
        t = (t + 1);
    }
    printf("%lld\n", answer);
    free(((void*)(B)));
    free(((void*)(D)));
    free(((void*)(visited)));
    free(((void*)(stack_arr)));
    free(((void*)(comp)));
    free(((void*)(fact)));
    free(((void*)(tc_cycle)));
    free(((void*)(tc_k)));
    free(((void*)(tc_color)));
    free(((void*)(tc_count)));
    free(((void*)(tc_aut)));
    return 0;
}

Generated MLIR

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