Problem 383

T5(10^18): count i with s5(2i-1) >= 2*s5(i) via base-5 digit DP.

Answer22173624649806
Output22173624649806
StatusPASS
Native helperno
Runtime0 ms
Peak memory1872 KB
Time complexityO(n^3) (estimated)
Space complexityO(n^2) (estimated)

Performance comparison

MetricOur solutionBest known
Time complexityO(n^3)O(n * d * s)
Space complexityO(n^2)O(d * s)
ApproachFlow solutionDigit DP
VerdictUnknown

Flow source

# Project Euler 383
# T5(10^18): count i with s5(2i-1) >= 2*s5(i) via base-5 digit DP.

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

function state_key(pos: i32, tight: i32, cn: i32, bn: i32, del_off: i32, DMAX: i32) -> i64 {
    return (((((pos as i64) * 2 + (tight as i64)) * 2 + (cn as i64)) * 2 + (bn as i64)) * (DMAX as i64) + (del_off as i64))
}

function dfs(pos: i32, tight: i32, cn: i32, bn: i32, delta: i32, L: i32, digs: ptr<i32>,
             r_cin: ptr<i32>, r_bin: ptr<i32>, r_e: ptr<i32>, r_cnt: ptr<i32>,
             memo: ptr<i64>, seen: ptr<i8>, DOFF: i32, DMAX: i32) -> i64 {
    if pos == L {
        if cn == 0 && bn == 1 && delta >= 0 { return 1 }
        return 0
    }
    let del_off: i32 = delta + DOFF
    if del_off < 0 || del_off >= DMAX { return 0 }
    let key: i64 = state_key(pos, tight, cn, bn, del_off, DMAX)
    if seen[key] == 1 { return memo[key] }

    let mut limit: i32 = 4
    if tight == 1 { limit = digs[pos] }
    let mut total: i64 = 0
    let mut d: i32 = 0
    while d <= limit {
        let mut tight2: i32 = 0
        if tight == 1 && d == limit { tight2 = 1 }
        let kkey: i32 = (cn * 2 + bn) * 5 + d
        let cnt: i32 = r_cnt[kkey]
        let mut s: i32 = 0
        while s < cnt {
            let base: i32 = kkey * 8 + s
            total = total + dfs(pos + 1, tight2, r_cin[base], r_bin[base], delta + r_e[base] - 2 * d,
                                L, digs, r_cin, r_bin, r_e, r_cnt, memo, seen, DOFF, DMAX)
            s = s + 1
        }
        d = d + 1
    }
    seen[key] = 1
    memo[key] = total
    return total
}

function main() -> i32 {
    let N: i64 = 1000000000000000000
    let digs: ptr<i32> = calloc(40, 4)
    let rev: ptr<i32> = calloc(40, 4)
    if digs == null || rev == null { return 1 }
    let mut tmp: i64 = N
    let mut L: i32 = 0
    while tmp > 0 {
        rev[L] = (tmp % 5) as i32
        tmp = tmp / 5
        L = L + 1
    }
    let mut i: i32 = 0
    while i < L {
        digs[i] = rev[L - 1 - i]
        i = i + 1
    }

    let r_cin: ptr<i32> = calloc(2 * 2 * 5 * 8, 4)
    let r_bin: ptr<i32> = calloc(2 * 2 * 5 * 8, 4)
    let r_e: ptr<i32> = calloc(2 * 2 * 5 * 8, 4)
    let r_cnt: ptr<i32> = calloc(2 * 2 * 5, 4)
    if r_cin == null || r_bin == null || r_e == null || r_cnt == null { return 1 }

    let mut cin: i32 = 0
    while cin <= 1 {
        let mut bin: i32 = 0
        while bin <= 1 {
            let mut d: i32 = 0
            while d < 5 {
                let raw0: i32 = 2 * d + cin - bin
                let mut raw: i32 = raw0
                let mut bout: i32 = 0
                if raw0 < 0 {
                    raw = raw0 + 5
                    bout = 1
                }
                let e: i32 = raw % 5
                let cout: i32 = raw / 5
                let key: i32 = (cout * 2 + bout) * 5 + d
                let slot: i32 = r_cnt[key]
                let base: i32 = key * 8 + slot
                r_cin[base] = cin
                r_bin[base] = bin
                r_e[base] = e
                r_cnt[key] = slot + 1
                d = d + 1
            }
            bin = bin + 1
        }
        cin = cin + 1
    }

    let DOFF: i32 = 250
    let DMAX: i32 = 401
    let SZ: i64 = (L + 1) as i64 * 2 * 2 * 2 * (DMAX as i64)
    let memo: ptr<i64> = calloc(SZ, 8)
    let seen: ptr<i8> = calloc(SZ, 1)
    if memo == null || seen == null { return 1 }

    let mut ans: i64 = 0
    let mut cf: i32 = 0
    while cf <= 1 {
        ans = ans + dfs(0, 1, cf, 0, cf, L, digs, r_cin, r_bin, r_e, r_cnt, memo, seen, DOFF, DMAX)
        cf = cf + 1
    }

    printf("%lld\n", ans)
    free(seen)
    free(memo)
    free(r_cnt)
    free(r_e)
    free(r_bin)
    free(r_cin)
    free(rev)
    free(digs)
    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 state_key_i32_i32_i32_i32_i32_i32(int32_t pos, int32_t tight, int32_t cn, int32_t bn, int32_t del_off, int32_t DMAX);
int64_t dfs_i32_i32_i32_i32_i32_i32_ptr_i32_ptr_i32_ptr_i32_ptr_i32_ptr_i32_ptr_i64_ptr_i8_i32_i32(int32_t pos, int32_t tight, int32_t cn, int32_t bn, int32_t delta, int32_t L, int32_t* digs, int32_t* r_cin, int32_t* r_bin, int32_t* r_e, int32_t* r_cnt, int64_t* memo, int8_t* seen, int32_t DOFF, int32_t DMAX);
int32_t main(void);



int64_t state_key_i32_i32_i32_i32_i32_i32(int32_t pos, int32_t tight, int32_t cn, int32_t bn, int32_t del_off, int32_t DMAX) {
    return ((((((((((int64_t)(pos)) * 2) + ((int64_t)(tight))) * 2) + ((int64_t)(cn))) * 2) + ((int64_t)(bn))) * ((int64_t)(DMAX))) + ((int64_t)(del_off)));
}

int64_t dfs_i32_i32_i32_i32_i32_i32_ptr_i32_ptr_i32_ptr_i32_ptr_i32_ptr_i32_ptr_i64_ptr_i8_i32_i32(int32_t pos, int32_t tight, int32_t cn, int32_t bn, int32_t delta, int32_t L, int32_t* digs, int32_t* r_cin, int32_t* r_bin, int32_t* r_e, int32_t* r_cnt, int64_t* memo, int8_t* seen, int32_t DOFF, int32_t DMAX) {
    if (pos == L) {
        if (((cn == 0 && bn == 1) && delta >= 0)) {
            return 1;
        }
        return 0;
    }
    int32_t del_off = (delta + DOFF);
    if ((del_off < 0 || del_off >= DMAX)) {
        return 0;
    }
    int64_t key = state_key_i32_i32_i32_i32_i32_i32(pos, tight, cn, bn, del_off, DMAX);
    if (seen[key] == 1) {
        return memo[key];
    }
    int32_t limit = 4;
    if (tight == 1) {
        limit = digs[pos];
    }
    int64_t total = 0;
    int32_t d = 0;
    while (d <= limit) {
        int32_t tight2 = 0;
        if ((tight == 1 && d == limit)) {
            tight2 = 1;
        }
        int32_t kkey = ((((cn * 2) + bn) * 5) + d);
        int32_t cnt = r_cnt[kkey];
        int32_t s = 0;
        while (s < cnt) {
            int32_t base = ((kkey * 8) + s);
            total = (total + dfs_i32_i32_i32_i32_i32_i32_ptr_i32_ptr_i32_ptr_i32_ptr_i32_ptr_i32_ptr_i64_ptr_i8_i32_i32((pos + 1), tight2, r_cin[base], r_bin[base], ((delta + r_e[base]) - (2 * d)), L, digs, r_cin, r_bin, r_e, r_cnt, memo, seen, DOFF, DMAX));
            s = (s + 1);
        }
        d = (d + 1);
    }
    seen[key] = 1;
    memo[key] = total;
    return total;
}

int32_t main(void) {
    int64_t N = 1000000000000000000;
    int32_t* digs = (int32_t*)(calloc(40, 4));
    int32_t* rev = (int32_t*)(calloc(40, 4));
    if ((digs == NULL || rev == NULL)) {
        return 1;
    }
    int64_t tmp = N;
    int32_t L = 0;
    while (tmp > 0) {
        rev[L] = ((int32_t)(FLOW_CHECKED_MOD((tmp), (5))));
        tmp = FLOW_CHECKED_DIV((tmp), (5));
        L = (L + 1);
    }
    int32_t i = 0;
    while (i < L) {
        digs[i] = rev[((L - 1) - i)];
        i = (i + 1);
    }
    int32_t* r_cin = (int32_t*)(calloc((((2 * 2) * 5) * 8), 4));
    int32_t* r_bin = (int32_t*)(calloc((((2 * 2) * 5) * 8), 4));
    int32_t* r_e = (int32_t*)(calloc((((2 * 2) * 5) * 8), 4));
    int32_t* r_cnt = (int32_t*)(calloc(((2 * 2) * 5), 4));
    if ((((r_cin == NULL || r_bin == NULL) || r_e == NULL) || r_cnt == NULL)) {
        return 1;
    }
    int32_t cin = 0;
    while (cin <= 1) {
        int32_t bin = 0;
        while (bin <= 1) {
            int32_t d = 0;
            while (d < 5) {
                int32_t raw0 = (((2 * d) + cin) - bin);
                int32_t raw = raw0;
                int32_t bout = 0;
                if (raw0 < 0) {
                    raw = (raw0 + 5);
                    bout = 1;
                }
                int32_t e = FLOW_CHECKED_MOD((raw), (5));
                int32_t cout = FLOW_CHECKED_DIV((raw), (5));
                int32_t key = ((((cout * 2) + bout) * 5) + d);
                int32_t slot = r_cnt[key];
                int32_t base = ((key * 8) + slot);
                r_cin[base] = cin;
                r_bin[base] = bin;
                r_e[base] = e;
                r_cnt[key] = (slot + 1);
                d = (d + 1);
            }
            bin = (bin + 1);
        }
        cin = (cin + 1);
    }
    int32_t DOFF = 250;
    int32_t DMAX = 401;
    int64_t SZ = ((((((int64_t)((L + 1))) * 2) * 2) * 2) * ((int64_t)(DMAX)));
    int64_t* memo = (int64_t*)(calloc(SZ, 8));
    int8_t* seen = (int8_t*)(calloc(SZ, 1));
    if ((memo == NULL || seen == NULL)) {
        return 1;
    }
    int64_t ans = 0;
    int32_t cf = 0;
    while (cf <= 1) {
        ans = (ans + dfs_i32_i32_i32_i32_i32_i32_ptr_i32_ptr_i32_ptr_i32_ptr_i32_ptr_i32_ptr_i64_ptr_i8_i32_i32(0, 1, cf, 0, cf, L, digs, r_cin, r_bin, r_e, r_cnt, memo, seen, DOFF, DMAX));
        cf = (cf + 1);
    }
    printf("%lld\n", ans);
    free(seen);
    free(memo);
    free(r_cnt);
    free(r_e);
    free(r_bin);
    free(r_cin);
    free(rev);
    free(digs);
    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) -> ()
  func.func @state_key(%arg0: i32, %arg1: i32, %arg2: i32, %arg3: i32, %arg4: i32, %arg5: i32) -> i64 {
    %0 = arith.extsi %arg0 : i32 to i64
    %1 = arith.constant 2 : i32
    %3 = arith.extsi %1 : i32 to i64
    %2 = arith.muli %0, %3 : i64
    %4 = arith.extsi %arg1 : i32 to i64
    %5 = arith.addi %2, %4 : i64
    %6 = arith.constant 2 : i32
    %8 = arith.extsi %6 : i32 to i64
    %7 = arith.muli %5, %8 : i64
    %9 = arith.extsi %arg2 : i32 to i64
    %10 = arith.addi %7, %9 : i64
    %11 = arith.constant 2 : i32
    %13 = arith.extsi %11 : i32 to i64
    %12 = arith.muli %10, %13 : i64
    %14 = arith.extsi %arg3 : i32 to i64
    %15 = arith.addi %12, %14 : i64
    %16 = arith.extsi %arg5 : i32 to i64
    %17 = arith.muli %15, %16 : i64
    %18 = arith.extsi %arg4 : i32 to i64
    %19 = arith.addi %17, %18 : i64
    func.return %19 : i64
  }
  func.func @dfs(%arg0: i32, %arg1: i32, %arg2: i32, %arg3: i32, %arg4: i32, %arg5: i32, %arg6: !llvm.ptr, %arg7: !llvm.ptr, %arg8: !llvm.ptr, %arg9: !llvm.ptr, %arg10: !llvm.ptr, %arg11: !llvm.ptr, %arg12: !llvm.ptr, %arg13: i32, %arg14: i32) -> i64 {
    %20 = arith.cmpi eq, %arg0, %arg5 : i32
    cf.cond_br %20, ^bb0, ^bb1
    ^bb0:
      %21 = arith.constant 0 : i32
      %22 = arith.cmpi eq, %arg2, %21 : i32
      %23 = scf.if %22 -> (i1) {
        %24 = arith.constant 1 : i32
        %25 = arith.cmpi eq, %arg3, %24 : i32
        scf.yield %25 : i1
      } else {
        %26 = arith.constant false
        scf.yield %26 : i1
      }
      %27 = scf.if %23 -> (i1) {
        %28 = arith.constant 0 : i32
        %29 = arith.cmpi sge, %arg4, %28 : i32
        scf.yield %29 : i1
      } else {
        %30 = arith.constant false
        scf.yield %30 : i1
      }
      cf.cond_br %27, ^bb3, ^bb4
      ^bb3:
        %31 = arith.constant 1 : i32
        %32 = arith.extsi %31 : i32 to i64
        func.return %32 : i64
      ^bb4:
        cf.br ^bb5
      ^bb5:
      %33 = arith.constant 0 : i32
      %34 = arith.extsi %33 : i32 to i64
      func.return %34 : i64
    ^bb1:
      cf.br ^bb2
    ^bb2:
    %35 = arith.addi %arg4, %arg13 : i32
    %36 = arith.constant 0 : i32
    %37 = arith.cmpi slt, %35, %36 : i32
    %38 = scf.if %37 -> (i1) {
      %39 = arith.constant true
      scf.yield %39 : i1
    } else {
      %40 = arith.cmpi sge, %35, %arg14 : i32
      scf.yield %40 : i1
    }
    cf.cond_br %38, ^bb6, ^bb7
    ^bb6:
      %41 = arith.constant 0 : i32
      %42 = arith.extsi %41 : i32 to i64
      func.return %42 : i64
    ^bb7:
      cf.br ^bb8
    ^bb8:
    %43 = func.call @state_key(%arg0, %arg1, %arg2, %arg3, %35, %arg14) : (i32, i32, i32, i32, i32, i32) -> i64
    %45 = llvm.getelementptr %arg12[%43] : (!llvm.ptr, i64) -> !llvm.ptr, i8
    %44 = llvm.load %45 : !llvm.ptr -> i8
    %46 = arith.constant 1 : i32
    %48 = arith.extsi %44 : i8 to i32
    %47 = arith.cmpi eq, %48, %46 : i32
    cf.cond_br %47, ^bb9, ^bb10
    ^bb9:
      %50 = llvm.getelementptr %arg11[%43] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %49 = llvm.load %50 : !llvm.ptr -> i64
      func.return %49 : i64
    ^bb10:
      cf.br ^bb11
    ^bb11:
    %51 = arith.constant 4 : i32
    %52 = llvm.mlir.constant(1 : i64) : i64
    %53 = llvm.alloca %52 x i32 : (i64) -> !llvm.ptr
    llvm.store %51, %53 : i32, !llvm.ptr
    %54 = arith.constant 1 : i32
    %55 = arith.cmpi eq, %arg1, %54 : i32
    cf.cond_br %55, ^bb12, ^bb13
    ^bb12:
      %57 = arith.extsi %arg0 : i32 to i64
      %58 = llvm.getelementptr %arg6[%57] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %56 = llvm.load %58 : !llvm.ptr -> i32
      llvm.store %56, %53 : i32, !llvm.ptr
      cf.br ^bb14
    ^bb13:
      cf.br ^bb14
    ^bb14:
    %59 = arith.constant 0 : i32
    %60 = arith.extsi %59 : i32 to i64
    %61 = llvm.mlir.constant(1 : i64) : i64
    %62 = llvm.alloca %61 x i64 : (i64) -> !llvm.ptr
    llvm.store %60, %62 : i64, !llvm.ptr
    %63 = arith.constant 0 : i32
    %64 = llvm.mlir.constant(1 : i64) : i64
    %65 = llvm.alloca %64 x i32 : (i64) -> !llvm.ptr
    llvm.store %63, %65 : i32, !llvm.ptr
    cf.br ^bb15
    ^bb15:
    %66 = llvm.load %65 : !llvm.ptr -> i32
    %67 = llvm.load %53 : !llvm.ptr -> i32
    %68 = arith.cmpi sle, %66, %67 : i32
    cf.cond_br %68, ^bb16, ^bb17
    ^bb16:
      %69 = arith.constant 0 : i32
      %70 = llvm.mlir.constant(1 : i64) : i64
      %71 = llvm.alloca %70 x i32 : (i64) -> !llvm.ptr
      llvm.store %69, %71 : i32, !llvm.ptr
      %72 = arith.constant 1 : i32
      %73 = arith.cmpi eq, %arg1, %72 : i32
      %74 = scf.if %73 -> (i1) {
        %75 = llvm.load %65 : !llvm.ptr -> i32
        %76 = llvm.load %53 : !llvm.ptr -> i32
        %77 = arith.cmpi eq, %75, %76 : i32
        scf.yield %77 : i1
      } else {
        %78 = arith.constant false
        scf.yield %78 : i1
      }
      cf.cond_br %74, ^bb18, ^bb19
      ^bb18:
        %79 = arith.constant 1 : i32
        llvm.store %79, %71 : i32, !llvm.ptr
        cf.br ^bb20
      ^bb19:
        cf.br ^bb20
      ^bb20:
      %80 = arith.constant 2 : i32
      %81 = arith.muli %arg2, %80 : i32
      %82 = arith.addi %81, %arg3 : i32
      %83 = arith.constant 5 : i32
      %84 = arith.muli %82, %83 : i32
      %85 = llvm.load %65 : !llvm.ptr -> i32
      %86 = arith.addi %84, %85 : i32
      %88 = arith.extsi %86 : i32 to i64
      %89 = llvm.getelementptr %arg10[%88] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %87 = llvm.load %89 : !llvm.ptr -> i32
      %90 = arith.constant 0 : i32
      %91 = llvm.mlir.constant(1 : i64) : i64
      %92 = llvm.alloca %91 x i32 : (i64) -> !llvm.ptr
      llvm.store %90, %92 : i32, !llvm.ptr
      cf.br ^bb21
      ^bb21:
      %93 = llvm.load %92 : !llvm.ptr -> i32
      %94 = arith.cmpi slt, %93, %87 : i32
      cf.cond_br %94, ^bb22, ^bb23
      ^bb22:
        %95 = arith.constant 8 : i32
        %96 = arith.muli %86, %95 : i32
        %97 = llvm.load %92 : !llvm.ptr -> i32
        %98 = arith.addi %96, %97 : i32
        %99 = llvm.load %62 : !llvm.ptr -> i64
        %101 = arith.constant 1 : i32
        %102 = arith.addi %arg0, %101 : i32
        %103 = llvm.load %71 : !llvm.ptr -> i32
        %105 = arith.extsi %98 : i32 to i64
        %106 = llvm.getelementptr %arg7[%105] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %104 = llvm.load %106 : !llvm.ptr -> i32
        %108 = arith.extsi %98 : i32 to i64
        %109 = llvm.getelementptr %arg8[%108] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %107 = llvm.load %109 : !llvm.ptr -> i32
        %111 = arith.extsi %98 : i32 to i64
        %112 = llvm.getelementptr %arg9[%111] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %110 = llvm.load %112 : !llvm.ptr -> i32
        %113 = arith.addi %arg4, %110 : i32
        %114 = arith.constant 2 : i32
        %115 = llvm.load %65 : !llvm.ptr -> i32
        %116 = arith.muli %114, %115 : i32
        %117 = arith.subi %113, %116 : i32
        %100 = func.call @dfs(%102, %103, %104, %107, %117, %arg5, %arg6, %arg7, %arg8, %arg9, %arg10, %arg11, %arg12, %arg13, %arg14) : (i32, i32, i32, i32, i32, i32, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, i32, i32) -> i64
        %118 = arith.addi %99, %100 : i64
        llvm.store %118, %62 : i64, !llvm.ptr
        %119 = llvm.load %92 : !llvm.ptr -> i32
        %120 = arith.constant 1 : i32
        %121 = arith.addi %119, %120 : i32
        llvm.store %121, %92 : i32, !llvm.ptr
        cf.br ^bb21
      ^bb23:
      %122 = llvm.load %65 : !llvm.ptr -> i32
      %123 = arith.constant 1 : i32
      %124 = arith.addi %122, %123 : i32
      llvm.store %124, %65 : i32, !llvm.ptr
      cf.br ^bb15
    ^bb17:
    %125 = arith.constant 1 : i32
    %126 = arith.trunci %125 : i32 to i8
    %127 = llvm.getelementptr %arg12[%43] : (!llvm.ptr, i64) -> !llvm.ptr, i8
    llvm.store %126, %127 : i8, !llvm.ptr
    %128 = llvm.load %62 : !llvm.ptr -> i64
    %129 = llvm.getelementptr %arg11[%43] : (!llvm.ptr, i64) -> !llvm.ptr, i64
    llvm.store %128, %129 : i64, !llvm.ptr
    %130 = llvm.load %62 : !llvm.ptr -> i64
    func.return %130 : i64
  }
  func.func @main() -> i32 {
    %131 = arith.constant 999999995705032704 : i32
    %132 = arith.extsi %131 : i32 to i64
    %134 = arith.constant 40 : i32
    %135 = arith.constant 4 : i32
    %136 = arith.extsi %134 : i32 to i64
    %137 = arith.extsi %135 : i32 to i64
    %133 = func.call @calloc(%136, %137) : (i64, i64) -> !llvm.ptr
    %139 = arith.constant 40 : i32
    %140 = arith.constant 4 : i32
    %141 = arith.extsi %139 : i32 to i64
    %142 = arith.extsi %140 : i32 to i64
    %138 = func.call @calloc(%141, %142) : (i64, i64) -> !llvm.ptr
    %143 = llvm.mlir.zero : !llvm.ptr
    %144 = llvm.icmp "eq" %133, %143 : !llvm.ptr
    %145 = scf.if %144 -> (i1) {
      %146 = arith.constant true
      scf.yield %146 : i1
    } else {
      %147 = llvm.mlir.zero : !llvm.ptr
      %148 = llvm.icmp "eq" %138, %147 : !llvm.ptr
      scf.yield %148 : i1
    }
    cf.cond_br %145, ^bb24, ^bb25
    ^bb24:
      %149 = arith.constant 1 : i32
      func.return %149 : i32
    ^bb25:
      cf.br ^bb26
    ^bb26:
    %150 = llvm.mlir.constant(1 : i64) : i64
    %151 = llvm.alloca %150 x i64 : (i64) -> !llvm.ptr
    llvm.store %132, %151 : i64, !llvm.ptr
    %152 = arith.constant 0 : i32
    %153 = llvm.mlir.constant(1 : i64) : i64
    %154 = llvm.alloca %153 x i32 : (i64) -> !llvm.ptr
    llvm.store %152, %154 : i32, !llvm.ptr
    cf.br ^bb27
    ^bb27:
    %155 = llvm.load %151 : !llvm.ptr -> i64
    %156 = arith.constant 0 : i32
    %158 = arith.extsi %156 : i32 to i64
    %157 = arith.cmpi sgt, %155, %158 : i64
    cf.cond_br %157, ^bb28, ^bb29
    ^bb28:
      %159 = llvm.load %151 : !llvm.ptr -> i64
      %160 = arith.constant 5 : i32
      %162 = arith.extsi %160 : i32 to i64
      %161 = arith.remsi %159, %162 : i64
      %163 = arith.trunci %161 : i64 to i32
      %164 = llvm.load %154 : !llvm.ptr -> i32
      %165 = arith.extsi %164 : i32 to i64
      %166 = llvm.getelementptr %138[%165] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %163, %166 : i32, !llvm.ptr
      %167 = llvm.load %151 : !llvm.ptr -> i64
      %168 = arith.constant 5 : i32
      %170 = arith.extsi %168 : i32 to i64
      %169 = arith.divsi %167, %170 : i64
      llvm.store %169, %151 : i64, !llvm.ptr
      %171 = llvm.load %154 : !llvm.ptr -> i32
      %172 = arith.constant 1 : i32
      %173 = arith.addi %171, %172 : i32
      llvm.store %173, %154 : i32, !llvm.ptr
      cf.br ^bb27
    ^bb29:
    %174 = arith.constant 0 : i32
    %175 = llvm.mlir.constant(1 : i64) : i64
    %176 = llvm.alloca %175 x i32 : (i64) -> !llvm.ptr
    llvm.store %174, %176 : i32, !llvm.ptr
    cf.br ^bb30
    ^bb30:
    %177 = llvm.load %176 : !llvm.ptr -> i32
    %178 = llvm.load %154 : !llvm.ptr -> i32
    %179 = arith.cmpi slt, %177, %178 : i32
    cf.cond_br %179, ^bb31, ^bb32
    ^bb31:
      %181 = llvm.load %154 : !llvm.ptr -> i32
      %182 = arith.constant 1 : i32
      %183 = arith.subi %181, %182 : i32
      %184 = llvm.load %176 : !llvm.ptr -> i32
      %185 = arith.subi %183, %184 : i32
      %186 = arith.extsi %185 : i32 to i64
      %187 = llvm.getelementptr %138[%186] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %180 = llvm.load %187 : !llvm.ptr -> i32
      %188 = llvm.load %176 : !llvm.ptr -> i32
      %189 = arith.extsi %188 : i32 to i64
      %190 = llvm.getelementptr %133[%189] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %180, %190 : i32, !llvm.ptr
      %191 = llvm.load %176 : !llvm.ptr -> i32
      %192 = arith.constant 1 : i32
      %193 = arith.addi %191, %192 : i32
      llvm.store %193, %176 : i32, !llvm.ptr
      cf.br ^bb30
    ^bb32:
    %195 = arith.constant 2 : i32
    %196 = arith.constant 2 : i32
    %197 = arith.muli %195, %196 : i32
    %198 = arith.constant 5 : i32
    %199 = arith.muli %197, %198 : i32
    %200 = arith.constant 8 : i32
    %201 = arith.muli %199, %200 : i32
    %202 = arith.constant 4 : i32
    %203 = arith.extsi %201 : i32 to i64
    %204 = arith.extsi %202 : i32 to i64
    %194 = func.call @calloc(%203, %204) : (i64, i64) -> !llvm.ptr
    %206 = arith.constant 2 : i32
    %207 = arith.constant 2 : i32
    %208 = arith.muli %206, %207 : i32
    %209 = arith.constant 5 : i32
    %210 = arith.muli %208, %209 : i32
    %211 = arith.constant 8 : i32
    %212 = arith.muli %210, %211 : i32
    %213 = arith.constant 4 : i32
    %214 = arith.extsi %212 : i32 to i64
    %215 = arith.extsi %213 : i32 to i64
    %205 = func.call @calloc(%214, %215) : (i64, i64) -> !llvm.ptr
    %217 = arith.constant 2 : i32
    %218 = arith.constant 2 : i32
    %219 = arith.muli %217, %218 : i32
    %220 = arith.constant 5 : i32
    %221 = arith.muli %219, %220 : i32
    %222 = arith.constant 8 : i32
    %223 = arith.muli %221, %222 : i32
    %224 = arith.constant 4 : i32
    %225 = arith.extsi %223 : i32 to i64
    %226 = arith.extsi %224 : i32 to i64
    %216 = func.call @calloc(%225, %226) : (i64, i64) -> !llvm.ptr
    %228 = arith.constant 2 : i32
    %229 = arith.constant 2 : i32
    %230 = arith.muli %228, %229 : i32
    %231 = arith.constant 5 : i32
    %232 = arith.muli %230, %231 : i32
    %233 = arith.constant 4 : i32
    %234 = arith.extsi %232 : i32 to i64
    %235 = arith.extsi %233 : i32 to i64
    %227 = func.call @calloc(%234, %235) : (i64, i64) -> !llvm.ptr
    %236 = llvm.mlir.zero : !llvm.ptr
    %237 = llvm.icmp "eq" %194, %236 : !llvm.ptr
    %238 = scf.if %237 -> (i1) {
      %239 = arith.constant true
      scf.yield %239 : i1
    } else {
      %240 = llvm.mlir.zero : !llvm.ptr
      %241 = llvm.icmp "eq" %205, %240 : !llvm.ptr
      scf.yield %241 : i1
    }
    %242 = scf.if %238 -> (i1) {
      %243 = arith.constant true
      scf.yield %243 : i1
    } else {
      %244 = llvm.mlir.zero : !llvm.ptr
      %245 = llvm.icmp "eq" %216, %244 : !llvm.ptr
      scf.yield %245 : i1
    }
    %246 = scf.if %242 -> (i1) {
      %247 = arith.constant true
      scf.yield %247 : i1
    } else {
      %248 = llvm.mlir.zero : !llvm.ptr
      %249 = llvm.icmp "eq" %227, %248 : !llvm.ptr
      scf.yield %249 : i1
    }
    cf.cond_br %246, ^bb33, ^bb34
    ^bb33:
      %250 = arith.constant 1 : i32
      func.return %250 : i32
    ^bb34:
      cf.br ^bb35
    ^bb35:
    %251 = arith.constant 0 : i32
    %252 = llvm.mlir.constant(1 : i64) : i64
    %253 = llvm.alloca %252 x i32 : (i64) -> !llvm.ptr
    llvm.store %251, %253 : i32, !llvm.ptr
    cf.br ^bb36
    ^bb36:
    %254 = llvm.load %253 : !llvm.ptr -> i32
    %255 = arith.constant 1 : i32
    %256 = arith.cmpi sle, %254, %255 : i32
    cf.cond_br %256, ^bb37, ^bb38
    ^bb37:
      %257 = arith.constant 0 : i32
      %258 = llvm.mlir.constant(1 : i64) : i64
      %259 = llvm.alloca %258 x i32 : (i64) -> !llvm.ptr
      llvm.store %257, %259 : i32, !llvm.ptr
      cf.br ^bb39
      ^bb39:
      %260 = llvm.load %259 : !llvm.ptr -> i32
      %261 = arith.constant 1 : i32
      %262 = arith.cmpi sle, %260, %261 : i32
      cf.cond_br %262, ^bb40, ^bb41
      ^bb40:
        %263 = arith.constant 0 : i32
        %264 = llvm.mlir.constant(1 : i64) : i64
        %265 = llvm.alloca %264 x i32 : (i64) -> !llvm.ptr
        llvm.store %263, %265 : i32, !llvm.ptr
        cf.br ^bb42
        ^bb42:
        %266 = llvm.load %265 : !llvm.ptr -> i32
        %267 = arith.constant 5 : i32
        %268 = arith.cmpi slt, %266, %267 : i32
        cf.cond_br %268, ^bb43, ^bb44
        ^bb43:
          %269 = arith.constant 2 : i32
          %270 = llvm.load %265 : !llvm.ptr -> i32
          %271 = arith.muli %269, %270 : i32
          %272 = llvm.load %253 : !llvm.ptr -> i32
          %273 = arith.addi %271, %272 : i32
          %274 = llvm.load %259 : !llvm.ptr -> i32
          %275 = arith.subi %273, %274 : i32
          %276 = llvm.mlir.constant(1 : i64) : i64
          %277 = llvm.alloca %276 x i32 : (i64) -> !llvm.ptr
          llvm.store %275, %277 : i32, !llvm.ptr
          %278 = arith.constant 0 : i32
          %279 = llvm.mlir.constant(1 : i64) : i64
          %280 = llvm.alloca %279 x i32 : (i64) -> !llvm.ptr
          llvm.store %278, %280 : i32, !llvm.ptr
          %281 = arith.constant 0 : i32
          %282 = arith.cmpi slt, %275, %281 : i32
          cf.cond_br %282, ^bb45, ^bb46
          ^bb45:
            %283 = arith.constant 5 : i32
            %284 = arith.addi %275, %283 : i32
            llvm.store %284, %277 : i32, !llvm.ptr
            %285 = arith.constant 1 : i32
            llvm.store %285, %280 : i32, !llvm.ptr
            cf.br ^bb47
          ^bb46:
            cf.br ^bb47
          ^bb47:
          %286 = llvm.load %277 : !llvm.ptr -> i32
          %287 = arith.constant 5 : i32
          %288 = arith.remsi %286, %287 : i32
          %289 = llvm.load %277 : !llvm.ptr -> i32
          %290 = arith.constant 5 : i32
          %291 = arith.divsi %289, %290 : i32
          %292 = arith.constant 2 : i32
          %293 = arith.muli %291, %292 : i32
          %294 = llvm.load %280 : !llvm.ptr -> i32
          %295 = arith.addi %293, %294 : i32
          %296 = arith.constant 5 : i32
          %297 = arith.muli %295, %296 : i32
          %298 = llvm.load %265 : !llvm.ptr -> i32
          %299 = arith.addi %297, %298 : i32
          %301 = arith.extsi %299 : i32 to i64
          %302 = llvm.getelementptr %227[%301] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %300 = llvm.load %302 : !llvm.ptr -> i32
          %303 = arith.constant 8 : i32
          %304 = arith.muli %299, %303 : i32
          %305 = arith.addi %304, %300 : i32
          %306 = llvm.load %253 : !llvm.ptr -> i32
          %307 = arith.extsi %305 : i32 to i64
          %308 = llvm.getelementptr %194[%307] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %306, %308 : i32, !llvm.ptr
          %309 = llvm.load %259 : !llvm.ptr -> i32
          %310 = arith.extsi %305 : i32 to i64
          %311 = llvm.getelementptr %205[%310] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %309, %311 : i32, !llvm.ptr
          %312 = arith.extsi %305 : i32 to i64
          %313 = llvm.getelementptr %216[%312] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %288, %313 : i32, !llvm.ptr
          %314 = arith.constant 1 : i32
          %315 = arith.addi %300, %314 : i32
          %316 = arith.extsi %299 : i32 to i64
          %317 = llvm.getelementptr %227[%316] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %315, %317 : i32, !llvm.ptr
          %318 = llvm.load %265 : !llvm.ptr -> i32
          %319 = arith.constant 1 : i32
          %320 = arith.addi %318, %319 : i32
          llvm.store %320, %265 : i32, !llvm.ptr
          cf.br ^bb42
        ^bb44:
        %321 = llvm.load %259 : !llvm.ptr -> i32
        %322 = arith.constant 1 : i32
        %323 = arith.addi %321, %322 : i32
        llvm.store %323, %259 : i32, !llvm.ptr
        cf.br ^bb39
      ^bb41:
      %324 = llvm.load %253 : !llvm.ptr -> i32
      %325 = arith.constant 1 : i32
      %326 = arith.addi %324, %325 : i32
      llvm.store %326, %253 : i32, !llvm.ptr
      cf.br ^bb36
    ^bb38:
    %327 = arith.constant 250 : i32
    %328 = arith.constant 401 : i32
    %329 = llvm.load %154 : !llvm.ptr -> i32
    %330 = arith.constant 1 : i32
    %331 = arith.addi %329, %330 : i32
    %332 = arith.extsi %331 : i32 to i64
    %333 = arith.constant 2 : i32
    %335 = arith.extsi %333 : i32 to i64
    %334 = arith.muli %332, %335 : i64
    %336 = arith.constant 2 : i32
    %338 = arith.extsi %336 : i32 to i64
    %337 = arith.muli %334, %338 : i64
    %339 = arith.constant 2 : i32
    %341 = arith.extsi %339 : i32 to i64
    %340 = arith.muli %337, %341 : i64
    %342 = arith.extsi %328 : i32 to i64
    %343 = arith.muli %340, %342 : i64
    %345 = arith.constant 8 : i32
    %346 = arith.extsi %345 : i32 to i64
    %344 = func.call @calloc(%343, %346) : (i64, i64) -> !llvm.ptr
    %348 = arith.constant 1 : i32
    %349 = arith.extsi %348 : i32 to i64
    %347 = func.call @calloc(%343, %349) : (i64, i64) -> !llvm.ptr
    %350 = llvm.mlir.zero : !llvm.ptr
    %351 = llvm.icmp "eq" %344, %350 : !llvm.ptr
    %352 = scf.if %351 -> (i1) {
      %353 = arith.constant true
      scf.yield %353 : i1
    } else {
      %354 = llvm.mlir.zero : !llvm.ptr
      %355 = llvm.icmp "eq" %347, %354 : !llvm.ptr
      scf.yield %355 : i1
    }
    cf.cond_br %352, ^bb48, ^bb49
    ^bb48:
      %356 = arith.constant 1 : i32
      func.return %356 : i32
    ^bb49:
      cf.br ^bb50
    ^bb50:
    %357 = arith.constant 0 : i32
    %358 = arith.extsi %357 : i32 to i64
    %359 = llvm.mlir.constant(1 : i64) : i64
    %360 = llvm.alloca %359 x i64 : (i64) -> !llvm.ptr
    llvm.store %358, %360 : i64, !llvm.ptr
    %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
    cf.br ^bb51
    ^bb51:
    %364 = llvm.load %363 : !llvm.ptr -> i32
    %365 = arith.constant 1 : i32
    %366 = arith.cmpi sle, %364, %365 : i32
    cf.cond_br %366, ^bb52, ^bb53
    ^bb52:
      %367 = llvm.load %360 : !llvm.ptr -> i64
      %369 = arith.constant 0 : i32
      %370 = arith.constant 1 : i32
      %371 = llvm.load %363 : !llvm.ptr -> i32
      %372 = arith.constant 0 : i32
      %373 = llvm.load %363 : !llvm.ptr -> i32
      %374 = llvm.load %154 : !llvm.ptr -> i32
      %368 = func.call @dfs(%369, %370, %371, %372, %373, %374, %133, %194, %205, %216, %227, %344, %347, %327, %328) : (i32, i32, i32, i32, i32, i32, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, i32, i32) -> i64
      %375 = arith.addi %367, %368 : i64
      llvm.store %375, %360 : i64, !llvm.ptr
      %376 = llvm.load %363 : !llvm.ptr -> i32
      %377 = arith.constant 1 : i32
      %378 = arith.addi %376, %377 : i32
      llvm.store %378, %363 : i32, !llvm.ptr
      cf.br ^bb51
    ^bb53:
    %379 = llvm.mlir.addressof @str_0 : !llvm.ptr
    %380 = llvm.load %360 : !llvm.ptr -> i64
    %381 = llvm.call @printf(%379, %380) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i64) -> i32
    func.call @free(%347) : (!llvm.ptr) -> ()
    func.call @free(%344) : (!llvm.ptr) -> ()
    func.call @free(%227) : (!llvm.ptr) -> ()
    func.call @free(%216) : (!llvm.ptr) -> ()
    func.call @free(%205) : (!llvm.ptr) -> ()
    func.call @free(%194) : (!llvm.ptr) -> ()
    func.call @free(%138) : (!llvm.ptr) -> ()
    func.call @free(%133) : (!llvm.ptr) -> ()
    %390 = arith.constant 0 : i32
    func.return %390 : i32
  }
}